Spaces:
Running
on
L40S
Running
on
L40S
Rishi Desai
commited on
Commit
·
ee3c968
1
Parent(s):
1fdff79
addig params
Browse files- FaceEnhancementProd.py +54 -14
- chatgpt_woman_2.png +3 -0
- main.py +76 -15
- out.png +3 -0
- out.png_dist.png +3 -0
- woman_face.jpg +3 -0
FaceEnhancementProd.py
CHANGED
@@ -61,7 +61,7 @@ def add_comfyui_directory_to_sys_path() -> None:
|
|
61 |
"""
|
62 |
Add 'ComfyUI' to the sys.path
|
63 |
"""
|
64 |
-
|
65 |
|
66 |
|
67 |
def add_extra_model_paths() -> None:
|
@@ -126,7 +126,13 @@ from nodes import (
|
|
126 |
)
|
127 |
|
128 |
|
129 |
-
def main(
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
import_custom_nodes()
|
131 |
with torch.inference_mode():
|
132 |
dualcliploader = DualCLIPLoader()
|
@@ -143,9 +149,9 @@ def main():
|
|
143 |
)
|
144 |
|
145 |
loadimage = LoadImage()
|
146 |
-
loadimage_24 = loadimage.load_image(image=
|
147 |
|
148 |
-
loadimage_40 = loadimage.load_image(image=
|
149 |
|
150 |
vaeloader = VAELoader()
|
151 |
vaeloader_95 = vaeloader.load_vae(vae_name="ae.safetensors")
|
@@ -160,7 +166,7 @@ def main():
|
|
160 |
randomnoise_39 = randomnoise.get_noise(noise_seed=random.randint(1, 2**64))
|
161 |
|
162 |
cliptextencode_42 = cliptextencode.encode(
|
163 |
-
text=
|
164 |
)
|
165 |
|
166 |
pulidfluxmodelloader = NODE_CLASS_MAPPINGS["PulidFluxModelLoader"]()
|
@@ -277,16 +283,50 @@ def main():
|
|
277 |
source=get_value_at_index(faceembeddistance_117, 1)
|
278 |
)
|
279 |
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
|
285 |
-
saveimage_129 = saveimage.save_images(
|
286 |
-
filename_prefix="FaceEmbedDist",
|
287 |
-
images=get_value_at_index(faceembeddistance_117, 0),
|
288 |
-
)
|
289 |
|
|
|
|
|
290 |
|
291 |
if __name__ == "__main__":
|
292 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
"""
|
62 |
Add 'ComfyUI' to the sys.path
|
63 |
"""
|
64 |
+
sys.path.append(COMFYUI_PATH)
|
65 |
|
66 |
|
67 |
def add_extra_model_paths() -> None:
|
|
|
126 |
)
|
127 |
|
128 |
|
129 |
+
def main(
|
130 |
+
face_image: str,
|
131 |
+
input_image: str,
|
132 |
+
output_image: str,
|
133 |
+
dist_image: str = None,
|
134 |
+
positive_prompt: str = ""
|
135 |
+
):
|
136 |
import_custom_nodes()
|
137 |
with torch.inference_mode():
|
138 |
dualcliploader = DualCLIPLoader()
|
|
|
149 |
)
|
150 |
|
151 |
loadimage = LoadImage()
|
152 |
+
loadimage_24 = loadimage.load_image(image=face_image)
|
153 |
|
154 |
+
loadimage_40 = loadimage.load_image(image=input_image)
|
155 |
|
156 |
vaeloader = VAELoader()
|
157 |
vaeloader_95 = vaeloader.load_vae(vae_name="ae.safetensors")
|
|
|
166 |
randomnoise_39 = randomnoise.get_noise(noise_seed=random.randint(1, 2**64))
|
167 |
|
168 |
cliptextencode_42 = cliptextencode.encode(
|
169 |
+
text=positive_prompt, clip=get_value_at_index(dualcliploader_94, 0)
|
170 |
)
|
171 |
|
172 |
pulidfluxmodelloader = NODE_CLASS_MAPPINGS["PulidFluxModelLoader"]()
|
|
|
283 |
source=get_value_at_index(faceembeddistance_117, 1)
|
284 |
)
|
285 |
|
286 |
+
# Save using direct image saving
|
287 |
+
save_comfy_images(get_value_at_index(vaedecode_114, 0), [output_image])
|
288 |
+
if dist_image:
|
289 |
+
save_comfy_images(get_value_at_index(faceembeddistance_117, 0), [dist_image])
|
290 |
+
|
291 |
+
|
292 |
+
def save_comfy_images(images, output_dirs):
|
293 |
+
# images is a PyTorch tensor with shape [batch_size, height, width, channels]
|
294 |
+
import numpy as np
|
295 |
+
from PIL import Image
|
296 |
+
|
297 |
+
for idx, image in enumerate(images):
|
298 |
+
# Create the output directory if it doesn't exist
|
299 |
+
output_dir = os.path.dirname(output_dirs[idx])
|
300 |
+
if output_dir and not os.path.exists(output_dir):
|
301 |
+
os.makedirs(output_dir, exist_ok=True)
|
302 |
+
|
303 |
+
numpy_image = 255. * image.cpu().numpy()
|
304 |
+
numpy_image = np.clip(numpy_image, 0, 255).astype(np.uint8)
|
305 |
+
pil_image = Image.fromarray(numpy_image)
|
306 |
+
pil_image.save(output_dirs[idx])
|
307 |
|
|
|
|
|
|
|
|
|
308 |
|
309 |
+
def enhance_face(face_image: str, input_image: str, output_image: str, dist_image: str = None, positive_prompt: str = ""):
|
310 |
+
main(face_image, input_image, output_image, dist_image, positive_prompt)
|
311 |
|
312 |
if __name__ == "__main__":
|
313 |
+
import sys
|
314 |
+
|
315 |
+
if len(sys.argv) < 4:
|
316 |
+
print("Usage: python FaceEnhancementProd.py face_image input_image output_image [dist_image] [positive_prompt]")
|
317 |
+
sys.exit(1)
|
318 |
+
|
319 |
+
face_image = sys.argv[1]
|
320 |
+
input_image = sys.argv[2]
|
321 |
+
output_image = sys.argv[3]
|
322 |
+
|
323 |
+
dist_image = None
|
324 |
+
positive_prompt = ""
|
325 |
+
|
326 |
+
if len(sys.argv) > 4:
|
327 |
+
dist_image = sys.argv[4]
|
328 |
+
|
329 |
+
if len(sys.argv) > 5:
|
330 |
+
positive_prompt = sys.argv[5]
|
331 |
+
|
332 |
+
main(face_image, input_image, output_image, dist_image, positive_prompt)
|
chatgpt_woman_2.png
ADDED
![]() |
Git LFS Details
|
main.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
import argparse
|
2 |
import os
|
3 |
-
|
|
|
4 |
|
5 |
def parse_args():
|
6 |
parser = argparse.ArgumentParser(description='Face Enhancement Tool')
|
@@ -15,6 +16,10 @@ def parse_args():
|
|
15 |
if not os.path.exists(args.input):
|
16 |
parser.error(f"Input file does not exist: {args.input}")
|
17 |
|
|
|
|
|
|
|
|
|
18 |
# Validate output directory exists
|
19 |
output_dir = os.path.dirname(args.output)
|
20 |
if output_dir and not os.path.exists(output_dir):
|
@@ -22,22 +27,78 @@ def parse_args():
|
|
22 |
|
23 |
return args
|
24 |
|
25 |
-
def
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
if
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
if __name__ == "__main__":
|
43 |
main()
|
|
|
1 |
import argparse
|
2 |
import os
|
3 |
+
import shutil
|
4 |
+
from FaceEnhancementProd import enhance_face
|
5 |
|
6 |
def parse_args():
|
7 |
parser = argparse.ArgumentParser(description='Face Enhancement Tool')
|
|
|
16 |
if not os.path.exists(args.input):
|
17 |
parser.error(f"Input file does not exist: {args.input}")
|
18 |
|
19 |
+
# Validate reference file exists
|
20 |
+
if not os.path.exists(args.ref):
|
21 |
+
parser.error(f"Reference file does not exist: {args.ref}")
|
22 |
+
|
23 |
# Validate output directory exists
|
24 |
output_dir = os.path.dirname(args.output)
|
25 |
if output_dir and not os.path.exists(output_dir):
|
|
|
27 |
|
28 |
return args
|
29 |
|
30 |
+
def create_scratch_dir():
|
31 |
+
"""Create a new numbered directory in ./ComfyUI/input/scratch"""
|
32 |
+
base_dir = "./ComfyUI/input/scratch"
|
33 |
+
|
34 |
+
# Create base directory if it doesn't exist
|
35 |
+
os.makedirs(base_dir, exist_ok=True)
|
36 |
+
|
37 |
+
# Get existing directories and find the next number
|
38 |
+
existing_dirs = [d for d in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, d)) and d.isdigit()]
|
39 |
+
next_dir_num = 1
|
40 |
+
if existing_dirs:
|
41 |
+
next_dir_num = max([int(d) for d in existing_dirs]) + 1
|
42 |
+
|
43 |
+
# Create the new directory
|
44 |
+
new_dir = os.path.join(base_dir, str(next_dir_num))
|
45 |
+
os.makedirs(new_dir, exist_ok=True)
|
46 |
+
|
47 |
+
return new_dir
|
48 |
|
49 |
+
def process_face(input_path, ref_path, crop=False, upscale=False, output_path=None):
|
50 |
+
"""
|
51 |
+
Process a face image using the given parameters.
|
52 |
+
|
53 |
+
Args:
|
54 |
+
input_path (str): Path to the input image
|
55 |
+
ref_path (str): Path to the reference image
|
56 |
+
crop (bool): Whether to crop the image
|
57 |
+
upscale (bool): Whether to upscale the image
|
58 |
+
output_path (str): Path to save the output image
|
59 |
+
|
60 |
+
Returns:
|
61 |
+
str: Path to the scratch directory used for processing
|
62 |
+
"""
|
63 |
+
print(f"Processing image: {input_path}")
|
64 |
+
print(f"Reference image: {ref_path}")
|
65 |
+
print(f"Output will be saved to: {output_path}")
|
66 |
+
|
67 |
+
# Create a new scratch directory for this run
|
68 |
+
scratch_dir = create_scratch_dir()
|
69 |
+
print(f"Created scratch directory: {scratch_dir}")
|
70 |
|
71 |
+
# Copy input and reference images to scratch directory
|
72 |
+
input_filename = os.path.basename(input_path)
|
73 |
+
ref_filename = os.path.basename(ref_path)
|
74 |
+
|
75 |
+
scratch_input = os.path.join(scratch_dir, input_filename)
|
76 |
+
scratch_ref = os.path.join(scratch_dir, ref_filename)
|
77 |
+
|
78 |
+
shutil.copy(input_path, scratch_input)
|
79 |
+
shutil.copy(ref_path, scratch_ref)
|
80 |
+
|
81 |
+
# Convert paths to ComfyUI format (relative to ComfyUI/input/)
|
82 |
+
# For example: "./ComfyUI/input/scratch/1/image.png" becomes "scratch/1/image.png"
|
83 |
+
comfy_ref_path = os.path.relpath(scratch_ref, "./ComfyUI/input")
|
84 |
+
comfy_input_path = os.path.relpath(scratch_input, "./ComfyUI/input")
|
85 |
+
|
86 |
+
enhance_face(comfy_ref_path, comfy_input_path, output_path, dist_image=f"{output_path}_dist.png")
|
87 |
+
|
88 |
+
print(f"Enhanced image saved to: {output_path}")
|
89 |
+
print(f"Working files are in: {scratch_dir}")
|
90 |
+
|
91 |
+
return scratch_dir
|
92 |
+
|
93 |
+
def main():
|
94 |
+
args = parse_args()
|
95 |
+
return process_face(
|
96 |
+
input_path=args.input,
|
97 |
+
ref_path=args.ref,
|
98 |
+
crop=args.crop,
|
99 |
+
upscale=args.upscale,
|
100 |
+
output_path=args.output
|
101 |
+
)
|
102 |
|
103 |
if __name__ == "__main__":
|
104 |
main()
|
out.png
ADDED
![]() |
Git LFS Details
|
out.png_dist.png
ADDED
![]() |
Git LFS Details
|
woman_face.jpg
ADDED
![]() |
Git LFS Details
|