Spaces:
Sleeping
Sleeping
| import numpy as np | |
| import json | |
| import torch | |
| from transformers import SegformerImageProcessor, SegformerForSemanticSegmentation | |
| from PIL import Image | |
| from PIL import ImageOps | |
| import matplotlib.pyplot as plt | |
| def segmentation(input_img_path): | |
| #with open('face-parsing/config.json', 'r') as file: | |
| # data = json.load(file) | |
| #for key, value in data["id2label"].items(): | |
| #print(f"{key}: {value}") | |
| image_processor = SegformerImageProcessor.from_pretrained("jonathandinu/face-parsing") | |
| model = SegformerForSemanticSegmentation.from_pretrained("jonathandinu/face-parsing") | |
| # input_img_path = "akshay kumar img.jpeg" | |
| if isinstance(input_img_path, str): # It's a path | |
| image = Image.open(input_img_path) | |
| else: # It's already an image object | |
| image = input_img_path | |
| image = image.convert("RGB") | |
| # new_size = (128, 128) | |
| # image = image.resize(new_size) | |
| # plt.imshow(image) | |
| # plt.axis("off") | |
| # plt.show() | |
| inputs = image_processor(images=image, return_tensors="pt") | |
| outputs = model(**inputs) | |
| color_map = np.array([ | |
| [255, 255, 255], # 0 background | |
| [255, 0, 0], # 1 skin | |
| [0, 255, 0], # 2 nose | |
| [0, 0, 255], # 3 eye_g | |
| [255, 255, 0], # 4 l_eye | |
| [255, 0, 255], # 5 r_eye | |
| [0, 255, 255], # 6 l_brow | |
| [192, 192, 192], # 7 r_brow | |
| [128, 128, 128], # 8 l_ear | |
| [128, 0, 0], # 9 r_ear | |
| [128, 128, 0], # 10 mouth | |
| [0, 128, 0], # 11 u_lip | |
| [0, 128, 128], # 12 l_lip | |
| [0, 0, 128], # 13 hair | |
| [255, 165, 0], # 14 hat | |
| [75, 0, 130], # 15 ear_r | |
| [240, 230, 140], # 16 neck_l | |
| [255, 20, 147], # 17 neck | |
| [100, 149, 237] # 18 cloth | |
| ]) | |
| predicted_classes = torch.argmax(outputs["logits"], dim=1).squeeze().cpu().numpy() | |
| segmentation_map = color_map[predicted_classes] | |
| outputs["logits"] = outputs["logits"].squeeze() | |
| outputs["logits"].shape | |
| img = np.array(image) | |
| print(img.shape) | |
| print(segmentation_map.shape) | |
| face_mask = outputs["logits"][1] | |
| print(face_mask) | |
| # plt.figure(figsize=(15, 7)) | |
| # plt.subplot(1, 2, 1) | |
| # plt.title("Original Image") | |
| # plt.imshow(image) | |
| # plt.axis('off') | |
| # plt.subplot(1, 2, 2) | |
| # plt.title("Predicted Segmentation Map") | |
| # plt.imshow(segmentation_map) | |
| # plt.axis('off') | |
| # plt.show() | |
| new_size = (128, 128) | |
| image = image.resize(new_size) | |
| original_image_np = np.array(image) | |
| segmented_image_np = np.array(segmentation_map) | |
| skin_color = [255, 0, 0] | |
| eyeg_color = [0, 0, 255] | |
| nose_color = [0, 255, 0] | |
| leye_color = [255, 255, 0] | |
| reye_color = [255, 0, 255] | |
| lbrow_color = [0, 255, 255] | |
| rbrow_color = [192, 192, 192] | |
| lear_color = [128, 128, 128] | |
| rear_color = [128, 0, 0] | |
| mouth_color = [128, 128, 0] | |
| ulip_color = [0, 128, 0] | |
| llip_color = [0, 128, 128] | |
| hair_color = [0, 0, 128] | |
| hat_color = [255, 165, 0] | |
| neck_color = [255, 20, 147] | |
| skin_mask = np.all(segmented_image_np == skin_color, axis=-1) | |
| eyeg_mask = np.all(segmented_image_np == eyeg_color, axis=-1) | |
| nose_mask = np.all(segmented_image_np == nose_color, axis=-1) | |
| leye_mask = np.all(segmented_image_np == leye_color, axis=-1) | |
| reye_mask = np.all(segmented_image_np == reye_color, axis=-1) | |
| lbrow_mask = np.all(segmented_image_np == lbrow_color, axis=-1) | |
| rbrow_mask = np.all(segmented_image_np == rbrow_color, axis=-1) | |
| lear_mask = np.all(segmented_image_np == lear_color, axis=-1) | |
| rear_mask = np.all(segmented_image_np == rear_color, axis=-1) | |
| mouth_mask = np.all(segmented_image_np == mouth_color, axis=-1) | |
| ulip_mask = np.all(segmented_image_np == ulip_color, axis=-1) | |
| llip_mask = np.all(segmented_image_np == llip_color, axis=-1) | |
| hair_mask = np.all(segmented_image_np == hair_color, axis=-1) | |
| hat_mask = np.all(segmented_image_np == hat_color, axis=-1) | |
| neck_mask = np.all(segmented_image_np == neck_color, axis=-1) | |
| # combining all the masks | |
| combined_mask = np.logical_or.reduce(( | |
| skin_mask, eyeg_mask, nose_mask, leye_mask, reye_mask, | |
| lbrow_mask, rbrow_mask, lear_mask, rear_mask, | |
| mouth_mask, ulip_mask, llip_mask, hair_mask, | |
| hat_mask, neck_mask | |
| )) | |
| # applying the combined mask to the original image | |
| selected_regions = np.full_like(original_image_np, 255) | |
| selected_regions[combined_mask] = original_image_np[combined_mask] | |
| # # Visualize the results | |
| # plt.figure(figsize=(15, 5)) | |
| # # Display the original image | |
| # plt.subplot(1, 3, 1) | |
| # plt.imshow(image) | |
| # plt.title("Original Image") | |
| # plt.axis("off") | |
| # # Display the segmented image | |
| # plt.subplot(1, 3, 2) | |
| # plt.imshow(segmentation_map) | |
| # plt.title("Segmented Image") | |
| # plt.axis("off") | |
| # # Display the extracted regions | |
| # plt.subplot(1, 3, 3) | |
| # plt.imshow(Image.fromarray(selected_regions)) | |
| # plt.title("Selected Regions") | |
| # plt.axis("off") | |
| # plt.tight_layout() | |
| # plt.show() | |
| selected_regions = Image.fromarray(selected_regions) | |
| # selected_regions.save("only_face.jpg") | |
| return selected_regions | |
| """challenges as of now: | |
| 1. meme face image is not eradicated (manually remove this). (done!) | |
| 2. note down the width of the neck of meme image and make adjustements accordingly so that the target face gets fixed on the meme image. (pending) | |
| 3. background in the person's image is black, which is messing up with hair, fix that. | |
| """ | |
| def integration_with_meme(input_img_path, face_x, face_y, face_width, face_height, flip): | |
| person_image = segmentation(input_img_path) | |
| # person_image = Image.open('only_face.jpg') | |
| meme_image = Image.open('chillguy.jpeg') | |
| # Convert meme image to RGBA (for transparency handling) and to a NumPy array | |
| meme_image = meme_image.convert("RGBA") | |
| meme_data = np.array(meme_image) | |
| # Define the coordinates of the face region in the meme image | |
| # face_x, face_y, face_width, face_height = 0, 40, 180, 110 # Adjust based on meme image | |
| # Clamp the face region to ensure it is within bounds | |
| meme_height, meme_width = meme_data.shape[:2] | |
| face_width = min(face_width, meme_width - face_x) | |
| face_height = min(face_height, meme_height - face_y) | |
| # Resize the person's image to fit the face region | |
| person_resized = person_image.resize((face_width, face_height)).convert("RGBA") | |
| if flip: | |
| person_resized = ImageOps.mirror(person_resized) | |
| person_data = np.array(person_resized) | |
| r, g, b, a = person_data[..., 0], person_data[..., 1], person_data[..., 2], person_data[..., 3] | |
| white_areas = (r > 230) & (g > 230) & (b > 230) | |
| person_data[white_areas, 3] = 0 | |
| person_resized = Image.fromarray(person_data) | |
| face_region = meme_data[face_y:face_y+face_height, face_x:face_x+face_width] | |
| face_region_resized = Image.fromarray(face_region).resize((face_width, face_height)) | |
| blended_region = Image.alpha_composite(face_region_resized, person_resized) | |
| blended_region_data = np.array(blended_region) | |
| meme_data[face_y:face_y+face_height, face_x:face_x+face_width] = blended_region_data | |
| result_image = Image.fromarray(meme_data) | |
| # plt.imshow(result_image) | |
| # plt.axis("off") | |
| # plt.show() | |
| meme_image = np.array(meme_image) | |
| print(meme_image.shape) | |
| result_image = np.array(result_image) | |
| print(result_image.shape) | |
| return result_image | |
| # integration_with_meme(input_img_path="akshay kumar img.jpeg", face_x=0, face_y=40, face_width=180, face_height=110) | |