emirhanno commited on
Commit
68f6e22
1 Parent(s): d9dc599

Add application file

Browse files
Files changed (1) hide show
  1. app.py +139 -0
app.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import cv2
4
+ import torch
5
+ from PIL import Image
6
+ from insightface.app import FaceAnalysis
7
+ from ip_adapter.ip_adapter_faceid import IPAdapterFaceID
8
+ from transformers import CLIPFeatureExtractor
9
+ from diffusers import StableDiffusionPipeline, EulerDiscreteScheduler, AutoencoderKL
10
+ from diffusers.pipelines.stable_diffusion import StableDiffusionSafetyChecker
11
+ import dlib
12
+ import imutils
13
+ from imutils import face_utils
14
+ import numpy as np
15
+ from skimage import transform as tf
16
+
17
+ base_model_path = "SG161222/Realistic_Vision_V6.0_B1_noVAE"
18
+ base_cache = "model-cache"
19
+ vae_model_path = "stabilityai/sd-vae-ft-mse"
20
+ ip_cache = "./ip-cache"
21
+ device = "cuda"
22
+
23
+ # Setup function to load models and other dependencies
24
+ def setup():
25
+ """Load the model into memory to make running multiple predictions efficient"""
26
+ # Get ip-adapter-faceid model
27
+ if not os.path.exists("ip-cache/ip-adapter-faceid_sd15.bin"):
28
+ os.makedirs(ip_cache, exist_ok=True)
29
+ os.system(f"wget -O ip-cache/ip-adapter-faceid_sd15.bin https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sd15.bin")
30
+
31
+ # Download shape_predictor_68_face_landmarks.dat if it doesn't exist
32
+ if not os.path.exists("faceid/shape_predictor_68_face_landmarks.dat"):
33
+ os.makedirs("faceid", exist_ok=True)
34
+ os.system("wget -O faceid/shape_predictor_68_face_landmarks.dat https://github.com/italojs/facial-landmarks-recognition/raw/master/shape_predictor_68_face_landmarks.dat")
35
+
36
+ # Face embedding
37
+ app = FaceAnalysis(name="buffalo_l", providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
38
+ app.prepare(ctx_id=0, det_size=(640, 640))
39
+
40
+ # SD
41
+ noise_scheduler = EulerDiscreteScheduler(
42
+ num_train_timesteps=1000,
43
+ beta_start=0.00085,
44
+ beta_end=0.012
45
+ )
46
+ vae = AutoencoderKL.from_pretrained(
47
+ vae_model_path
48
+ ).to(dtype=torch.float16)
49
+ pipe = StableDiffusionPipeline.from_pretrained(
50
+ base_model_path,
51
+ torch_dtype=torch.float16,
52
+ scheduler=noise_scheduler,
53
+ vae=vae,
54
+ feature_extractor=CLIPFeatureExtractor.from_pretrained("openai/clip-vit-base-patch32"),
55
+ safety_checker=StableDiffusionSafetyChecker.from_pretrained("CompVis/stable-diffusion-safety-checker"),
56
+ cache_dir=base_cache,
57
+ )
58
+ pipe = pipe.to(device)
59
+
60
+ # IP adapter
61
+ ip_model = IPAdapterFaceID(
62
+ pipe,
63
+ "ip-cache/ip-adapter-faceid_sd15.bin",
64
+ device
65
+ )
66
+
67
+ return app, ip_model
68
+
69
+ app, ip_model = setup()
70
+
71
+ def get_face_landmarks(image_path):
72
+ detector = dlib.get_frontal_face_detector()
73
+ predictor = dlib.shape_predictor('faceid/shape_predictor_68_face_landmarks.dat')
74
+ image = cv2.imread(image_path)
75
+ image = imutils.resize(image, width=512)
76
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
77
+ rects = detector(gray, 1)
78
+ for (i, rect) in enumerate(rects):
79
+ shape = predictor(gray, rect)
80
+ shape = face_utils.shape_to_np(shape)
81
+ return shape, image
82
+
83
+ def morph_faces(image1_path, image2_path, alpha=0.5):
84
+ landmarks1, image1 = get_face_landmarks(image1_path)
85
+ landmarks2, image2 = get_face_landmarks(image2_path)
86
+ average_landmarks = (landmarks1 + landmarks2) / 2
87
+ tform1 = tf.estimate_transform('similarity', landmarks1, average_landmarks)
88
+ tform2 = tf.estimate_transform('similarity', landmarks2, average_landmarks)
89
+ morphed_image1 = tf.warp(image1, inverse_map=tform1.inverse, output_shape=(512, 512))
90
+ morphed_image2 = tf.warp(image2, inverse_map=tform2.inverse, output_shape=(512, 512))
91
+ morphed_image = (1 - alpha) * morphed_image1 + alpha * morphed_image2
92
+ morphed_image = (morphed_image * 255).astype(np.uint8) # Convert to [0, 255] range
93
+ output_path = "tmp.png"
94
+ cv2.imwrite(output_path, morphed_image)
95
+ return output_path
96
+
97
+ def generate_image(face_image_1, face_image_2, prompt, negative_prompt, width, height, num_inference_steps, seed):
98
+ if seed is None:
99
+ seed = int.from_bytes(os.urandom(4), "big")
100
+
101
+ baby_image_path = morph_faces(face_image_1.name, face_image_2.name)
102
+
103
+ def generate_images(faceid_embeds, num_outputs=1):
104
+ images = ip_model.generate(
105
+ prompt=prompt,
106
+ negative_prompt=negative_prompt,
107
+ faceid_embeds=faceid_embeds,
108
+ num_samples=num_outputs,
109
+ width=width,
110
+ height=height,
111
+ num_inference_steps=num_inference_steps,
112
+ seed=seed
113
+ )
114
+ return images
115
+
116
+ faceid_embeds = app.get(cv2.imread(baby_image_path))[0].normed_embedding
117
+ faceid_embeds = torch.from_numpy(faceid_embeds).unsqueeze(0)
118
+
119
+ generated_images = generate_images(faceid_embeds)
120
+ return generated_images[0]
121
+
122
+ # Gradio Interface
123
+ gr_interface = gr.Interface(
124
+ fn=generate_image,
125
+ inputs=[
126
+ gr.Image(type="file", label="First Face Image"),
127
+ gr.Image(type="file", label="Second Face Image"),
128
+ gr.Textbox(value="portrait of a 6 y.o. boy, male child, 8k, HD, happy, in living room, perfect eyes, cute", label="Prompt"),
129
+ gr.Textbox(value="(mascara, makeup: 1.4), (breasts, boobs, naked, nude: 1.4), (beard, old, mustache, wrinkles: 1.4), (deformed iris, deformed pupils, semi-realistic, cgi, 3d, render, sketch, cartoon, drawing, anime, mutated hands and fingers:1.4), (deformed, distorted, disfigured:1.3), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, disconnected limbs, mutation, mutated, ugly, disgusting, amputation", label="Negative Prompt"),
130
+ gr.Slider(256, 1024, value=768, step=64, label="Width"),
131
+ gr.Slider(256, 1024, value=768, step=64, label="Height"),
132
+ gr.Slider(1, 200, value=30, step=1, label="Number of Inference Steps"),
133
+ gr.Number(value=None, label="Random Seed")
134
+ ],
135
+ outputs=gr.Image(label="Generated Image"),
136
+ title="Face Morphing and Image Generation with Stable Diffusion"
137
+ )
138
+
139
+ gr_interface.launch()