Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -675,10 +675,30 @@ def generate_image(
|
|
| 675 |
pipe.scheduler = scheduler_cls.from_config(pipe.scheduler.config, **add_kwargs)
|
| 676 |
print(f" ✓ Scheduler: {scheduler_class_name}")
|
| 677 |
|
| 678 |
-
# Apply style and process prompts
|
| 679 |
if not prompt:
|
| 680 |
prompt = "a person"
|
| 681 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 682 |
# Warn if prompt contains physical feature descriptions that might override identity
|
| 683 |
physical_keywords = ["hair", "blonde", "brown hair", "black hair", "red hair", "beard", "mustache",
|
| 684 |
"wearing", "shirt", "jacket", "suit", "blazer", "tie", "glasses"]
|
|
@@ -692,9 +712,9 @@ def generate_image(
|
|
| 692 |
if detected_gender is not None:
|
| 693 |
# Add opposite gender terms to negative prompt
|
| 694 |
if detected_gender == 0: # Female
|
| 695 |
-
gender_negative_terms += ", man, male, masculine"
|
| 696 |
elif detected_gender == 1: # Male
|
| 697 |
-
gender_negative_terms += ", woman, female, feminine"
|
| 698 |
print(f" ✓ Gender preservation enabled in negative prompt")
|
| 699 |
|
| 700 |
# Add gender preservation terms to negative prompt
|
|
@@ -717,15 +737,18 @@ def generate_image(
|
|
| 717 |
# Fallback: try to convert
|
| 718 |
face_emb = torch.tensor(face_emb_raw, device=device, dtype=dtype)
|
| 719 |
|
| 720 |
-
#
|
| 721 |
if len(face_emb.shape) == 1:
|
| 722 |
face_emb = face_emb.unsqueeze(0) # Add batch dimension: [1, 512]
|
|
|
|
|
|
|
|
|
|
| 723 |
|
| 724 |
-
#
|
| 725 |
-
|
| 726 |
|
| 727 |
print(f" Face embedding final shape: {face_emb.shape}, dtype: {face_emb.dtype}, device: {face_emb.device}")
|
| 728 |
-
print(f" Face embedding
|
| 729 |
|
| 730 |
face_kps = draw_kps(convert_from_cv2_to_image(face_image_cv2), face_info["kps"])
|
| 731 |
print(f" Face keypoints image size: {face_kps.size}")
|
|
@@ -1201,19 +1224,19 @@ with gr.Blocks() as demo:
|
|
| 1201 |
identitynet_strength_ratio = gr.Slider(
|
| 1202 |
label="Face Similarity",
|
| 1203 |
minimum=0.5,
|
| 1204 |
-
maximum=1.
|
| 1205 |
step=0.05,
|
| 1206 |
-
value=1.
|
| 1207 |
-
info="How closely the headshot resembles your photo (higher = more similar)",
|
| 1208 |
)
|
| 1209 |
|
| 1210 |
adapter_strength_ratio = gr.Slider(
|
| 1211 |
label="Face Detail Strength",
|
| 1212 |
minimum=0.3,
|
| 1213 |
-
maximum=1.
|
| 1214 |
step=0.05,
|
| 1215 |
-
value=0
|
| 1216 |
-
info="Strength of face features preservation (higher = better identity match)",
|
| 1217 |
)
|
| 1218 |
|
| 1219 |
enable_LCM = gr.Checkbox(
|
|
|
|
| 675 |
pipe.scheduler = scheduler_cls.from_config(pipe.scheduler.config, **add_kwargs)
|
| 676 |
print(f" ✓ Scheduler: {scheduler_class_name}")
|
| 677 |
|
| 678 |
+
# Apply style and process prompts (AFTER face detection so we can use gender info)
|
| 679 |
if not prompt:
|
| 680 |
prompt = "a person"
|
| 681 |
|
| 682 |
+
# Add explicit gender to prompt if detected (InstantID works better with explicit gender)
|
| 683 |
+
if detected_gender is not None:
|
| 684 |
+
prompt_lower = prompt.lower()
|
| 685 |
+
# Only add gender if not already in prompt
|
| 686 |
+
if "man" not in prompt_lower and "woman" not in prompt_lower and "male" not in prompt_lower and "female" not in prompt_lower and "person" not in prompt_lower:
|
| 687 |
+
if detected_gender == 0: # Female
|
| 688 |
+
prompt = f"a woman, {prompt}"
|
| 689 |
+
print(f" ✓ Added 'a woman' to prompt for gender preservation")
|
| 690 |
+
elif detected_gender == 1: # Male
|
| 691 |
+
prompt = f"a man, {prompt}"
|
| 692 |
+
print(f" ✓ Added 'a man' to prompt for gender preservation")
|
| 693 |
+
elif "person" in prompt_lower:
|
| 694 |
+
# Replace "person" with specific gender
|
| 695 |
+
if detected_gender == 0: # Female
|
| 696 |
+
prompt = prompt.replace("person", "woman").replace("Person", "Woman")
|
| 697 |
+
print(f" ✓ Replaced 'person' with 'woman' in prompt")
|
| 698 |
+
elif detected_gender == 1: # Male
|
| 699 |
+
prompt = prompt.replace("person", "man").replace("Person", "Man")
|
| 700 |
+
print(f" ✓ Replaced 'person' with 'man' in prompt")
|
| 701 |
+
|
| 702 |
# Warn if prompt contains physical feature descriptions that might override identity
|
| 703 |
physical_keywords = ["hair", "blonde", "brown hair", "black hair", "red hair", "beard", "mustache",
|
| 704 |
"wearing", "shirt", "jacket", "suit", "blazer", "tie", "glasses"]
|
|
|
|
| 712 |
if detected_gender is not None:
|
| 713 |
# Add opposite gender terms to negative prompt
|
| 714 |
if detected_gender == 0: # Female
|
| 715 |
+
gender_negative_terms += ", man, male, masculine, boy"
|
| 716 |
elif detected_gender == 1: # Male
|
| 717 |
+
gender_negative_terms += ", woman, female, feminine, girl"
|
| 718 |
print(f" ✓ Gender preservation enabled in negative prompt")
|
| 719 |
|
| 720 |
# Add gender preservation terms to negative prompt
|
|
|
|
| 737 |
# Fallback: try to convert
|
| 738 |
face_emb = torch.tensor(face_emb_raw, device=device, dtype=dtype)
|
| 739 |
|
| 740 |
+
# Ensure proper shape for InstantID (should be [1, 512] or [512])
|
| 741 |
if len(face_emb.shape) == 1:
|
| 742 |
face_emb = face_emb.unsqueeze(0) # Add batch dimension: [1, 512]
|
| 743 |
+
elif len(face_emb.shape) == 2 and face_emb.shape[0] > 1:
|
| 744 |
+
# If multiple faces, take the first one
|
| 745 |
+
face_emb = face_emb[0:1]
|
| 746 |
|
| 747 |
+
# DO NOT normalize - InstantID expects raw embeddings from InsightFace
|
| 748 |
+
# Normalization breaks the identity preservation
|
| 749 |
|
| 750 |
print(f" Face embedding final shape: {face_emb.shape}, dtype: {face_emb.dtype}, device: {face_emb.device}")
|
| 751 |
+
print(f" Face embedding range: [{face_emb.min().item():.4f}, {face_emb.max().item():.4f}]")
|
| 752 |
|
| 753 |
face_kps = draw_kps(convert_from_cv2_to_image(face_image_cv2), face_info["kps"])
|
| 754 |
print(f" Face keypoints image size: {face_kps.size}")
|
|
|
|
| 1224 |
identitynet_strength_ratio = gr.Slider(
|
| 1225 |
label="Face Similarity",
|
| 1226 |
minimum=0.5,
|
| 1227 |
+
maximum=1.5,
|
| 1228 |
step=0.05,
|
| 1229 |
+
value=1.2,
|
| 1230 |
+
info="How closely the headshot resembles your photo (higher = more similar, recommended: 1.0-1.2)",
|
| 1231 |
)
|
| 1232 |
|
| 1233 |
adapter_strength_ratio = gr.Slider(
|
| 1234 |
label="Face Detail Strength",
|
| 1235 |
minimum=0.3,
|
| 1236 |
+
maximum=1.5,
|
| 1237 |
step=0.05,
|
| 1238 |
+
value=1.0,
|
| 1239 |
+
info="Strength of face features preservation (higher = better identity match, recommended: 0.8-1.0)",
|
| 1240 |
)
|
| 1241 |
|
| 1242 |
enable_LCM = gr.Checkbox(
|