RICHERGIRL commited on
Commit
cbf5ccd
·
verified ·
1 Parent(s): 30b4cc3

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +55 -12
utils.py CHANGED
@@ -1,24 +1,67 @@
1
  import cv2
2
  import mediapipe as mp
3
  import numpy as np
 
4
 
 
5
  mp_face_detection = mp.solutions.face_detection
 
6
 
7
- def extract_features(image_path):
8
- """Extract face shape, skin tone, and size from an image."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  image = cv2.imread(image_path)
 
 
 
10
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
11
- return "Oval", "Medium", "Medium" # Default fallback values
12
-
13
- # Detect face (simplified example)
14
- with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detector:
15
- results = face_detector.process(image_rgb)
16
  if not results.detections:
17
  return None, None, None
 
 
 
 
 
18
 
19
- # Mock logic (replace with actual calculations)
20
- face_shape = "Oval" # Use landmarks to classify shape
21
- skin_tone = "Medium" # Estimate from cheek region
22
- face_size = "Medium" # Measure bounding box
23
 
24
- return face_shape, skin_tone, face_size
 
 
 
 
 
 
 
 
 
 
1
  import cv2
2
  import mediapipe as mp
3
  import numpy as np
4
+ from typing import Tuple, Optional
5
 
6
+ # Initialize MediaPipe face detection
7
  mp_face_detection = mp.solutions.face_detection
8
+ mp_face_mesh = mp.solutions.face_mesh # For detailed landmarks
9
 
10
+ def classify_face_shape(landmarks) -> str:
11
+ """Determine face shape using geometric ratios."""
12
+ # Example: Calculate jaw-to-forehead ratio
13
+ jaw_width = landmarks[234].x - landmarks[454].x # Left/right jaw points
14
+ forehead_height = landmarks[10].y - landmarks[152].y # Forehead to chin
15
+
16
+ ratio = jaw_width / forehead_height
17
+ if ratio > 1.1: return "Square"
18
+ elif ratio > 0.9: return "Round"
19
+ else: return "Oval"
20
+
21
+ def estimate_skin_tone(image, face_roi) -> str:
22
+ """Analyze skin tone in the cheek region."""
23
+ x, y, w, h = face_roi
24
+ cheek_region = image[y:y+h//2, x:x+w//2] # Get left cheek area
25
+
26
+ # Convert to LAB color space for skin tone analysis
27
+ lab = cv2.cvtColor(cheek_region, cv2.COLOR_BGR2LAB)
28
+ l, a, b = np.mean(lab, axis=(0,1))
29
+
30
+ if l > 160: return "Fair"
31
+ elif l > 120: return "Medium"
32
+ else: return "Dark"
33
+
34
+ def extract_features(image_path: str) -> Tuple[Optional[str], Optional[str], Optional[str]]:
35
+ """Extract face attributes from an image."""
36
+ # Read and convert image
37
  image = cv2.imread(image_path)
38
+ if image is None:
39
+ return None, None, None
40
+
41
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
42
+ height, width = image.shape[:2]
43
+
44
+ # Face detection
45
+ with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as detector:
46
+ results = detector.process(image_rgb)
47
  if not results.detections:
48
  return None, None, None
49
+
50
+ # Get face bounding box
51
+ bbox = results.detections[0].location_data.relative_bounding_box
52
+ x, y = int(bbox.xmin * width), int(bbox.ymin * height)
53
+ w, h = int(bbox.width * width), int(bbox.height * height)
54
 
55
+ # Face size classification
56
+ face_size = "Large" if w > 300 else "Medium" if w > 200 else "Small"
 
 
57
 
58
+ # Face mesh for detailed landmarks
59
+ with mp_face_mesh.FaceMesh(static_image_mode=True) as mesh:
60
+ mesh_results = mesh.process(image_rgb)
61
+ if mesh_results.multi_face_landmarks:
62
+ landmarks = mesh_results.multi_face_landmarks[0].landmark
63
+ face_shape = classify_face_shape(landmarks)
64
+ skin_tone = estimate_skin_tone(image, (x, y, w, h))
65
+ return face_shape, skin_tone, face_size
66
+
67
+ return None, None, None # Fallback if mesh detection fails