kataria_opticals_api / geometry.py
codernotme's picture
Update geometry.py
2abac5a verified
import numpy as np
from scipy.spatial import distance as dist
def euclidean_dist(p1, p2):
return dist.euclidean(p1, p2)
def extract_features(landmarks):
"""
Extracts geometric features from 68-point facial landmarks.
Indices based on dlib/OpenCV LBF standard.
Key Points:
- Jaw: 0-16 (8 is chin)
- Eyebrows: 17-21 (left), 22-26 (right)
- Nose: 27-35 (27 is bridge top)
- Eyes: 36-41 (left), 42-47 (right)
"""
landmarks = np.array(landmarks)
# defined points
jaw_left = landmarks[4]
jaw_right = landmarks[12]
chin = landmarks[8]
temple_left = landmarks[0]
temple_right = landmarks[16]
brow_left = landmarks[19]
brow_right = landmarks[24]
# Measurements
jaw_width = euclidean_dist(jaw_left, jaw_right)
face_width = euclidean_dist(temple_left, temple_right) # Cheekbone/Temple width
brow_mid = (brow_left + brow_right) / 2.0
face_length = euclidean_dist(chin, brow_mid)
# Approximations
forehead_width = face_width * 0.9 # Hard to measure with 68 points, assume slightly narrower than temples
# Ratios
lw_ratio = face_length / face_width if face_width > 0 else 0
jaw_ratio = jaw_width / face_width if face_width > 0 else 0
forehead_ratio = forehead_width / face_width if face_width > 0 else 0 # Will be constant-ish with this heuristic
return {
"lw_ratio": lw_ratio,
"jaw_ratio": jaw_ratio,
"forehead_ratio": forehead_ratio
}