RICHERGIRL commited on
Commit
db9e295
·
verified ·
1 Parent(s): 0a610d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -58
app.py CHANGED
@@ -1,76 +1,61 @@
1
  import gradio as gr
2
  import cv2
3
  import numpy as np
 
 
4
  import mediapipe as mp
5
- import uuid
6
- import os
7
  from sklearn.cluster import KMeans
8
 
9
- # Create reusable face mesh
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 (Simplified based on face landmarks)
14
- def detect_face_shape(landmarks, image_shape):
15
- # Grab required landmark points
16
- left_cheek = landmarks[234]
17
- right_cheek = landmarks[454]
18
- chin = landmarks[152]
19
- forehead = landmarks[10]
20
-
21
- # Calculate distances
22
- width = np.linalg.norm(np.array([left_cheek.x, left_cheek.y]) - np.array([right_cheek.x, right_cheek.y]))
23
- height = np.linalg.norm(np.array([chin.x, chin.y]) - np.array([forehead.x, forehead.y]))
24
-
25
- ratio = width / height
26
- if ratio > 1.3:
27
- return "Round"
28
- elif ratio > 1.1:
29
- return "Oval"
30
- else:
31
- return "Long"
32
-
33
- # Skin tone using KMeans
34
- def get_skin_tone(image):
35
- h, w, _ = image.shape
36
- face_crop = image[h//4:3*h//4, w//3:2*w//3] # middle region
37
-
38
- pixels = face_crop.reshape(-1, 3)
39
- kmeans = KMeans(n_clusters=3, random_state=0).fit(pixels)
40
- dominant = kmeans.cluster_centers_.astype(int)[0]
41
- return tuple(dominant)
42
-
43
  def analyze_face(image):
44
  if image is None:
45
- return None, "No image", "No skin tone"
46
-
47
- image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
48
- results = face_mesh.process(image_rgb)
49
-
50
- if not results.multi_face_landmarks:
51
- return image, "No face detected", "N/A"
52
-
53
- landmarks = results.multi_face_landmarks[0].landmark
54
- shape = detect_face_shape(landmarks, image.shape)
55
-
56
- tone = get_skin_tone(image)
57
- tone_str = f"RGB: {tone}"
58
-
59
- return image, shape, tone_str
60
-
61
- # Gradio interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  demo = gr.Interface(
63
  fn=analyze_face,
64
- inputs=gr.Image(type="numpy", image_mode="BGR", label="Upload or Capture Face"),
65
  outputs=[
66
- gr.Image(label="Original Image"),
67
- gr.Textbox(label="Detected Face Shape"),
68
- gr.Textbox(label="Dominant Skin Tone")
69
  ],
70
- live=False,
71
- allow_flagging="never",
72
- title="Step 2: Face Shape and Skin Tone Analyzer"
73
  )
74
 
75
  if __name__ == "__main__":
76
- demo.launch()
 
1
  import gradio as gr
2
  import cv2
3
  import numpy as np
4
+ import tempfile
5
+ from PIL import Image
6
  import mediapipe as mp
 
 
7
  from sklearn.cluster import KMeans
8
 
9
+ # MediaPipe setup
10
  mp_face_mesh = mp.solutions.face_mesh
11
  face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True)
12
+ mp_drawing = mp.solutions.drawing_utils
13
 
14
+ # Step 1 & 2 combined: Capture, analyze, and return image with annotations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  def analyze_face(image):
16
  if image is None:
17
+ return "No image provided"
18
+
19
+ # Save image temporarily
20
+ temp_file = tempfile.NamedTemporaryFile(suffix=".png", delete=False)
21
+ image_pil = Image.fromarray(image)
22
+ image_pil.save(temp_file.name)
23
+
24
+ # Convert for MediaPipe
25
+ img_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
26
+ result = face_mesh.process(img_rgb)
27
+
28
+ if not result.multi_face_landmarks:
29
+ return "No face detected"
30
+
31
+ # Draw landmarks
32
+ for face_landmarks in result.multi_face_landmarks:
33
+ mp_drawing.draw_landmarks(
34
+ image=image,
35
+ landmark_list=face_landmarks,
36
+ connections=mp_face_mesh.FACEMESH_TESSELATION,
37
+ landmark_drawing_spec=None,
38
+ connection_drawing_spec=mp_drawing.DrawingSpec(color=(0,255,0), thickness=1, circle_radius=1),
39
+ )
40
+
41
+ # Skin tone detection with KMeans
42
+ pixels = img_rgb.reshape((-1, 3))
43
+ kmeans = KMeans(n_clusters=1, random_state=42).fit(pixels)
44
+ dominant_color = kmeans.cluster_centers_[0].astype(int)
45
+
46
+ return image, f"Dominant skin tone RGB: {tuple(dominant_color)}"
47
+
48
+ # Gradio Interface
49
  demo = gr.Interface(
50
  fn=analyze_face,
51
+ inputs=gr.Image(type="numpy", image_mode="BGR", label="Capture or Upload Your Face"),
52
  outputs=[
53
+ gr.Image(type="numpy", label="Face Analysis Output"),
54
+ gr.Textbox(label="Detected Skin Tone (RGB)")
 
55
  ],
56
+ title="Face Scanner for Mask Recommendation",
57
+ description="Upload or capture a photo to analyze face landmarks and detect skin tone."
 
58
  )
59
 
60
  if __name__ == "__main__":
61
+ demo.launch()