Spaces:
Paused
Paused
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
|