RojaKatta commited on
Commit
ccce0ef
·
verified ·
1 Parent(s): 928b7cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -44
app.py CHANGED
@@ -1,11 +1,7 @@
1
  import gradio as gr
2
  from PIL import Image
3
  import os
4
- import cv2
5
- import numpy as np
6
- import mediapipe as mp
7
 
8
- # Load hairstyles from 'hairstyles' folder
9
  def load_hairstyles():
10
  folder = "hairstyles"
11
  if not os.path.exists(folder):
@@ -16,65 +12,47 @@ def load_hairstyles():
16
  ]
17
 
18
  hairstyles = load_hairstyles()
19
- mp_face_detection = mp.solutions.face_detection
20
 
21
- # Apply hairstyle using face detection to auto-align on head
22
- def apply_hairstyle(user_img, style_index):
23
  if user_img is None or not hairstyles:
24
  return None
25
 
26
- # Convert to CV2 image for detection
27
- img_cv2 = np.array(user_img.convert("RGB"))
28
- img_cv2 = cv2.cvtColor(img_cv2, cv2.COLOR_RGB2BGR)
29
- h_img, w_img = img_cv2.shape[:2]
30
 
31
- with mp_face_detection.FaceDetection(model_selection=1, min_detection_confidence=0.5) as face_detection:
32
- results = face_detection.process(cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB))
33
 
34
- if not results.detections:
35
- return user_img # No face detected, return original
 
36
 
37
- # Use first face
38
- detection = results.detections[0]
39
- bbox = detection.location_data.relative_bounding_box
40
- x = int(bbox.xmin * w_img)
41
- y = int(bbox.ymin * h_img)
42
- w = int(bbox.width * w_img)
43
- h = int(bbox.height * h_img)
44
 
45
- # Estimate head top
46
- top_y = max(y - int(h * 0.6), 0)
 
47
 
48
- # Load and resize hairstyle
49
- hairstyle = hairstyles[style_index]
50
- new_width = int(w * 1.1) # Slightly wider than face
51
- new_height = int(hairstyle.height * (new_width / hairstyle.width))
52
- resized_hair = hairstyle.resize((new_width, new_height))
53
-
54
- # Create output image
55
- user_img = user_img.convert("RGBA")
56
- composite = Image.new("RGBA", user_img.size)
57
- paste_x = x - int((new_width - w) / 2)
58
- paste_y = top_y
59
- composite.paste(resized_hair, (paste_x, paste_y), resized_hair)
60
-
61
- final = Image.alpha_composite(user_img, composite)
62
- return final.convert("RGB")
63
-
64
- # Gradio Interface
65
  with gr.Blocks() as demo:
66
- gr.Markdown("## 💇 Salon Virtual Hairstyle Try-On (Face-Aligned, No Adjustment Needed)")
 
67
  with gr.Row():
68
  with gr.Column():
69
- image_input = gr.Image(type="pil", label="📷 Upload Your Image")
70
  style_slider = gr.Slider(0, max(len(hairstyles)-1, 0), step=1, label="🎨 Select Hairstyle")
 
 
 
71
  apply_btn = gr.Button("✨ Apply Hairstyle")
72
  with gr.Column():
73
  result_output = gr.Image(label="🔍 Result Preview")
74
 
75
  apply_btn.click(
76
  fn=apply_hairstyle,
77
- inputs=[image_input, style_slider],
78
  outputs=result_output
79
  )
80
 
 
1
  import gradio as gr
2
  from PIL import Image
3
  import os
 
 
 
4
 
 
5
  def load_hairstyles():
6
  folder = "hairstyles"
7
  if not os.path.exists(folder):
 
12
  ]
13
 
14
  hairstyles = load_hairstyles()
 
15
 
16
+ def apply_hairstyle(user_img, style_index, x_offset, y_offset, scale):
 
17
  if user_img is None or not hairstyles:
18
  return None
19
 
20
+ user_img = user_img.convert("RGBA")
21
+ base_w, base_h = user_img.size
 
 
22
 
23
+ hairstyle = hairstyles[style_index]
 
24
 
25
+ # Resize the hairstyle based on scale
26
+ new_size = (int(base_w * scale), int(hairstyle.height * (base_w * scale / hairstyle.width)))
27
+ hairstyle = hairstyle.resize(new_size)
28
 
29
+ # Create a blank transparent image to position the hairstyle
30
+ composite = Image.new("RGBA", user_img.size)
31
+ paste_x = int((base_w - new_size[0]) / 2 + x_offset)
32
+ paste_y = int(y_offset)
33
+ composite.paste(hairstyle, (paste_x, paste_y), hairstyle)
 
 
34
 
35
+ # Overlay it
36
+ result = Image.alpha_composite(user_img, composite)
37
+ return result.convert("RGB")
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  with gr.Blocks() as demo:
40
+ gr.Markdown("## 💇 Salon Virtual Hairstyle Try-On (Adjustable)")
41
+
42
  with gr.Row():
43
  with gr.Column():
44
+ image_input = gr.Image(type="pil", label="📷 Upload an Image")
45
  style_slider = gr.Slider(0, max(len(hairstyles)-1, 0), step=1, label="🎨 Select Hairstyle")
46
+ x_offset = gr.Slider(-200, 200, value=0, step=1, label="⬅️➡️ Move Left / Right")
47
+ y_offset = gr.Slider(-200, 200, value=0, step=1, label="⬆️⬇️ Move Up / Down")
48
+ scale = gr.Slider(0.3, 2.0, value=1.0, step=0.05, label="📏 Scale Hairstyle")
49
  apply_btn = gr.Button("✨ Apply Hairstyle")
50
  with gr.Column():
51
  result_output = gr.Image(label="🔍 Result Preview")
52
 
53
  apply_btn.click(
54
  fn=apply_hairstyle,
55
+ inputs=[image_input, style_slider, x_offset, y_offset, scale],
56
  outputs=result_output
57
  )
58