RICHERGIRL commited on
Commit
afb77bc
·
verified ·
1 Parent(s): f705e4a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -42
app.py CHANGED
@@ -2,52 +2,94 @@ import gradio as gr
2
  import cv2
3
  import numpy as np
4
  import tempfile
 
5
  import mediapipe as mp
6
- from PIL import Image
7
 
8
- # Mediapipe face detection setup
9
- mp_face_detection = mp.solutions.face_detection
10
  mp_face_mesh = mp.solutions.face_mesh
11
- mp_drawing = mp.solutions.drawing_utils
12
- mp_drawing_styles = mp.solutions.drawing_styles
13
-
14
- def analyze_face_features(image):
15
- # Convert to BGR for OpenCV compatibility
16
- image_np = np.array(image)
17
- image_np = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
18
-
19
- # Face Mesh Detection
20
- with mp_face_mesh.FaceMesh(static_image_mode=True, max_num_faces=1, refine_landmarks=True, min_detection_confidence=0.5) as face_mesh:
21
- results = face_mesh.process(cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB))
22
-
23
- if results.multi_face_landmarks:
24
- for face_landmarks in results.multi_face_landmarks:
25
- mp_drawing.draw_landmarks(
26
- image=image_np,
27
- landmark_list=face_landmarks,
28
- connections=mp_face_mesh.FACEMESH_TESSELATION,
29
- landmark_drawing_spec=None,
30
- connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_tesselation_style())
31
- mp_drawing.draw_landmarks(
32
- image=image_np,
33
- landmark_list=face_landmarks,
34
- connections=mp_face_mesh.FACEMESH_CONTOURS,
35
- landmark_drawing_spec=None,
36
- connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_contours_style())
37
- else:
38
- print("No facial landmarks detected")
39
-
40
- # Save processed image temporarily
41
- temp_file = tempfile.NamedTemporaryFile(suffix=".png", delete=False)
42
- cv2.imwrite(temp_file.name, image_np)
43
-
44
- return Image.fromarray(cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB))
45
-
46
- # Gradio Interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  iface = gr.Interface(
48
- fn=analyze_face_features,
49
- inputs=gr.Image(label="Upload or Capture a Face Image"),
50
- outputs=gr.Image(label="Face Mesh + Features")
 
 
 
 
 
 
51
  )
52
 
53
  iface.launch()
 
2
  import cv2
3
  import numpy as np
4
  import tempfile
5
+ import os
6
  import mediapipe as mp
7
+ from sklearn.cluster import KMeans
8
 
9
+ # --- Face analysis setup ---
 
10
  mp_face_mesh = mp.solutions.face_mesh
11
+ face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True)
12
+
13
+ # --- Face Shape Detection Logic ---
14
+ def detect_face_shape(landmarks):
15
+ jaw_width = np.linalg.norm(np.array(landmarks[234]) - np.array(landmarks[454]))
16
+ face_height = np.linalg.norm(np.array(landmarks[10]) - np.array(landmarks[152]))
17
+
18
+ ratio = jaw_width / face_height
19
+ if ratio > 1.1:
20
+ return "Round"
21
+ elif 0.9 <= ratio <= 1.1:
22
+ return "Oval"
23
+ elif ratio < 0.9:
24
+ return "Heart"
25
+ return "Unknown"
26
+
27
+ # --- Skin Tone Detection ---
28
+ def detect_skin_tone(image):
29
+ rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
30
+ pixels = rgb_image.reshape(-1, 3)
31
+ kmeans = KMeans(n_clusters=3, random_state=0).fit(pixels)
32
+ dominant_color = np.uint8(kmeans.cluster_centers_[0])
33
+
34
+ avg_brightness = np.mean(dominant_color)
35
+ if avg_brightness > 200:
36
+ return "Fair"
37
+ elif avg_brightness > 100:
38
+ return "Medium"
39
+ else:
40
+ return "Dark"
41
+
42
+ # --- Rule-Based Recommender ---
43
+ def recommend_mask(face_shape, skin_tone):
44
+ recommendations = {
45
+ ("Round", "Fair"): "Floral",
46
+ ("Oval", "Medium"): "Metallic",
47
+ ("Square", "Dark"): "Classic",
48
+ ("Heart", "Fair"): "Glitter",
49
+ ("Heart", "Medium"): "Glitter",
50
+ ("Heart", "Dark"): "Glitter",
51
+ ("Diamond", "Fair"): "Lace",
52
+ ("Diamond", "Medium"): "Lace",
53
+ ("Diamond", "Dark"): "Lace",
54
+ }
55
+ return recommendations.get((face_shape, skin_tone), "Classic")
56
+
57
+ # --- Main function ---
58
+ def analyze_face(image):
59
+ if image is None:
60
+ return None, None, None
61
+
62
+ # Save to temp file
63
+ tmp_path = tempfile.mktemp(suffix=".png")
64
+ image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
65
+ cv2.imwrite(tmp_path, image_bgr)
66
+
67
+ # Face landmarks
68
+ results = face_mesh.process(image)
69
+ if not results.multi_face_landmarks:
70
+ return "No face detected", None, None
71
+
72
+ landmarks = results.multi_face_landmarks[0].landmark
73
+ h, w, _ = image.shape
74
+ landmark_points = [(int(p.x * w), int(p.y * h)) for p in landmarks]
75
+
76
+ face_shape = detect_face_shape(landmark_points)
77
+ skin_tone = detect_skin_tone(image_bgr)
78
+ mask_style = recommend_mask(face_shape, skin_tone)
79
+
80
+ return f"Face Shape: {face_shape}, Skin Tone: {skin_tone}", f"Recommended Mask Style: {mask_style}", image
81
+
82
+ # --- Gradio UI ---
83
  iface = gr.Interface(
84
+ fn=analyze_face,
85
+ inputs=gr.Image(label="Capture Your Face", type="numpy"),
86
+ outputs=[
87
+ gr.Textbox(label="Detected Features"),
88
+ gr.Textbox(label="Recommended Mask Style"),
89
+ gr.Image(label="Your Photo")
90
+ ],
91
+ title="Party Mask Recommender 🎭",
92
+ description="Click a photo and get a party mask recommendation based on your face shape and skin tone!"
93
  )
94
 
95
  iface.launch()