theoracle commited on
Commit
eb20c24
Β·
1 Parent(s): 93be815

πŸ”§ Add clothing inpainting step (Step 3) with independent prompt and guidance

Browse files
__pycache__/background_edit.cpython-310.pyc CHANGED
Binary files a/__pycache__/background_edit.cpython-310.pyc and b/__pycache__/background_edit.cpython-310.pyc differ
 
__pycache__/inference.cpython-310.pyc CHANGED
Binary files a/__pycache__/inference.cpython-310.pyc and b/__pycache__/inference.cpython-310.pyc differ
 
__pycache__/utils.cpython-310.pyc CHANGED
Binary files a/__pycache__/utils.cpython-310.pyc and b/__pycache__/utils.cpython-310.pyc differ
 
app.py CHANGED
@@ -7,6 +7,22 @@ import gradio as gr
7
 
8
  from inference import generate_with_lora
9
  from background_edit import run_background_removal_and_inpaint
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  # ───────────────────── Helpers ─────────────────────
12
  def _print_trace():
@@ -59,6 +75,15 @@ def safe_generate_and_inpaint(
59
  _print_trace()
60
  return None, None, f"❌ Unexpected Error: {type(e).__name__}: {str(e)}"
61
 
 
 
 
 
 
 
 
 
 
62
  # ───────────────────── Gradio UI ─────────────────────
63
  with gr.Blocks() as demo:
64
  gr.Markdown("## 🧠 Headshot + Background Generator (Full Prompt Control)")
@@ -102,4 +127,33 @@ with gr.Blocks() as demo:
102
  outputs=[output_refined, output_final, error_box]
103
  )
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  demo.launch(debug=True)
 
7
 
8
  from inference import generate_with_lora
9
  from background_edit import run_background_removal_and_inpaint
10
+ from background_edit import run_clothing_inpaint
11
+
12
+ import os
13
+
14
+ MODEL_URL = "https://huggingface.co/Bingsu/adetailer/resolve/main/deepfashion2_yolov8s-seg.pt"
15
+ MODEL_PATH = "deepfashion2_yolov8s-seg.pt"
16
+
17
+ # ─── Download DeepFashion2 model if not already present ───
18
+ if not os.path.exists(MODEL_PATH):
19
+ import urllib.request
20
+ print("[INFO] Downloading DeepFashion2 YOLOv8 model...")
21
+ urllib.request.urlretrieve(MODEL_URL, MODEL_PATH)
22
+ print("[INFO] Model downloaded.")
23
+ else:
24
+ print("[INFO] DeepFashion2 model already exists.")
25
+
26
 
27
  # ───────────────────── Helpers ─────────────────────
28
  def _print_trace():
 
75
  _print_trace()
76
  return None, None, f"❌ Unexpected Error: {type(e).__name__}: {str(e)}"
77
 
78
+ def guarded_clothing(image, prompt, neg, guidance):
79
+ try:
80
+ result, err = run_clothing_inpaint(image, prompt, neg, guidance)
81
+ return result, err
82
+ except Exception as e:
83
+ import traceback
84
+ traceback.print_exc()
85
+ return None, f"❌ Unexpected Error: {type(e).__name__}: {str(e)}"
86
+
87
  # ───────────────────── Gradio UI ─────────────────────
88
  with gr.Blocks() as demo:
89
  gr.Markdown("## 🧠 Headshot + Background Generator (Full Prompt Control)")
 
127
  outputs=[output_refined, output_final, error_box]
128
  )
129
 
130
+ gr.Markdown("### πŸ‘— Step 3: Clothing Replacement")
131
+
132
+ with gr.Row():
133
+ clothing_prompt = gr.Textbox(
134
+ label="Clothing Prompt",
135
+ value="white female CEO professional blazer, clean look"
136
+ )
137
+ clothing_negative = gr.Textbox(
138
+ label="Clothing Negative Prompt",
139
+ value="hoodie, casual wear, fantasy, cartoon, jeans, distorted, blurry"
140
+ )
141
+
142
+ with gr.Row():
143
+ clothing_guidance = gr.Slider(1, 20, value=17.0, step=0.5, label="Clothing Guidance Scale")
144
+
145
+ with gr.Row():
146
+ clothing_btn = gr.Button("🧡 Inpaint Clothing")
147
+ clothing_output = gr.Image(type="pil", label="Step 3: Final Image with New Clothing")
148
+
149
+ clothing_error = gr.Markdown(label="Clothing Error", value="", visible=True)
150
+
151
+
152
+ clothing_btn.click(
153
+ fn=guarded_clothing,
154
+ inputs=[output_final, clothing_prompt, clothing_negative, clothing_guidance],
155
+ outputs=[clothing_output, clothing_error],
156
+ preprocess=False
157
+ )
158
+
159
  demo.launch(debug=True)
background_edit.py CHANGED
@@ -21,11 +21,15 @@ from diffusers import StableDiffusionXLInpaintPipeline
21
  from utils import pil_to_cv2, cv2_to_pil
22
  import gradio as gr # βœ… Needed for error handling
23
 
 
24
 
 
 
25
 
26
  # βœ… Load models once
27
  yolo = YOLO("yolov8x-seg.pt")
28
 
 
29
  inpaint_pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
30
  "diffusers/stable-diffusion-xl-1.0-inpainting-0.1",
31
  torch_dtype=torch.float16,
@@ -51,8 +55,8 @@ def run_background_removal_and_inpaint(image_path, prompt, negative_prompt, guid
51
  dilated = cv2.dilate(background_mask, kernel, iterations=1)
52
  inpaint_mask = (dilated * 255).astype(np.uint8)
53
 
54
- mask_pil = cv2_to_pil(inpaint_mask).resize((1024, 1024)).convert("L")
55
- img_pil = image.resize((1024, 1024)).convert("RGB")
56
 
57
  result = inpaint_pipe(
58
  prompt=prompt,
@@ -64,3 +68,42 @@ def run_background_removal_and_inpaint(image_path, prompt, negative_prompt, guid
64
  ).images[0]
65
 
66
  return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  from utils import pil_to_cv2, cv2_to_pil
22
  import gradio as gr # βœ… Needed for error handling
23
 
24
+ INPAINT_SIZE = 1024
25
 
26
+ # Load clothing model
27
+ clothing_model = YOLO("deepfashion2_yolov8s-seg.pt")
28
 
29
  # βœ… Load models once
30
  yolo = YOLO("yolov8x-seg.pt")
31
 
32
+
33
  inpaint_pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
34
  "diffusers/stable-diffusion-xl-1.0-inpainting-0.1",
35
  torch_dtype=torch.float16,
 
55
  dilated = cv2.dilate(background_mask, kernel, iterations=1)
56
  inpaint_mask = (dilated * 255).astype(np.uint8)
57
 
58
+ mask_pil = cv2_to_pil(inpaint_mask).resize((INPAINT_SIZE, INPAINT_SIZE)).convert("L")
59
+ img_pil = image.resize((INPAINT_SIZE, INPAINT_SIZE)).convert("RGB")
60
 
61
  result = inpaint_pipe(
62
  prompt=prompt,
 
68
  ).images[0]
69
 
70
  return result
71
+
72
+ def run_clothing_inpaint(image, prompt, negative_prompt, guidance):
73
+ try:
74
+ print("[INFO] Step 3: Clothing segmentation and inpainting...", flush=True)
75
+
76
+ img_cv = np.array(image.convert("RGB"))[..., ::-1] # PIL β†’ OpenCV BGR
77
+ h, w = img_cv.shape[:2]
78
+
79
+ # Segment clothing
80
+ results = clothing_model(img_cv)
81
+ masks = results[0].masks.data.cpu().numpy()
82
+ if len(masks) == 0:
83
+ raise gr.Error("No clothing detected. Try a different image.")
84
+
85
+ mask = masks[0]
86
+ resized_mask = cv2.resize(mask, (w, h), interpolation=cv2.INTER_NEAREST)
87
+ binary_mask = (resized_mask > 0.5).astype(np.uint8) * 255
88
+ mask_pil = Image.fromarray(binary_mask).convert("L").resize((INPAINT_SIZE, INPAINT_SIZE))
89
+
90
+ # Resize input image
91
+ resized_image = image.convert("RGB").resize((INPAINT_SIZE, INPAINT_SIZE))
92
+
93
+ # Inpaint clothing
94
+ result = inpaint_pipe(
95
+ prompt=prompt,
96
+ negative_prompt=negative_prompt,
97
+ image=resized_image,
98
+ mask_image=mask_pil,
99
+ guidance_scale=guidance,
100
+ num_inference_steps=50
101
+ ).images[0]
102
+
103
+ return result, ""
104
+
105
+ except gr.Error as e:
106
+ return None, f"πŸ›‘ {str(e)}"
107
+ except Exception as e:
108
+ traceback.print_exc()
109
+ return None, f"❌ Unexpected Error: {type(e).__name__}: {str(e)}"