File size: 6,478 Bytes
938c065 8ba9416 c5ac1e3 8ba9416 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 0d3274e 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 938c065 c5ac1e3 0d3274e c5ac1e3 938c065 c5ac1e3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | import cv2
import numpy as np
import gradio as gr
import os
# Install mediapipe if not available
try:
import mediapipe as mp
except ImportError:
import pip
pip.main(['install', 'mediapipe'])
import mediapipe as mp
def process_face_image(input_image):
"""
Function processes the image, finds facial landmarks,
and returns two images: one with landmarks and one with measurements
"""
# Convert image from gradio to numpy format
if input_image is None:
return None, None
# Face mesh
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True, max_num_faces=1, min_detection_confidence=0.5)
# Get image dimensions
image = input_image.copy()
height, width, _ = image.shape
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# Create copies for landmarks and measurements
image_all_landmarks = image.copy()
image_with_lines = image.copy()
# Find landmarks
result = face_mesh.process(rgb_image)
# Check if face was detected
if not result.multi_face_landmarks:
return image, image, "No face detected"
# Process the found landmarks
for facial_landmarks in result.multi_face_landmarks:
# Draw all landmarks as thin points
for i in range(0, 468):
pt1 = facial_landmarks.landmark[i]
x = int(pt1.x * width)
y = int(pt1.y * height)
cv2.circle(image_all_landmarks, (x, y), 1, (100, 100, 0), -1)
# Add landmark numbers for important points
if i in [10, 152, 234, 454, 35, 265, 129, 358]:
cv2.putText(image_all_landmarks, str(i), (x + 2, y + 2),
cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 0, 255), 1)
# Face width (points 234 and 454)
right_face = facial_landmarks.landmark[234]
left_face = facial_landmarks.landmark[454]
right_x = int(right_face.x * width)
right_y = int(right_face.y * height)
left_x = int(left_face.x * width)
left_y = int(left_face.y * height)
# Draw face width line
cv2.line(image_with_lines, (right_x, right_y), (left_x, left_y), (0, 255, 0), 3)
face_width = ((left_x - right_x) ** 2 + (left_y - right_y) ** 2) ** 0.5
cv2.putText(image_with_lines, f"Face width: {face_width:.2f}px",
(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
# Eye distance (points 35 and 265)
right_eye = facial_landmarks.landmark[35]
left_eye = facial_landmarks.landmark[265]
right_eye_x = int(right_eye.x * width)
right_eye_y = int(right_eye.y * height)
left_eye_x = int(left_eye.x * width)
left_eye_y = int(left_eye.y * height)
# Draw eye distance line
cv2.line(image_with_lines, (right_eye_x, right_eye_y), (left_eye_x, left_eye_y), (255, 0, 0), 3)
eye_distance = ((left_eye_x - right_eye_x) ** 2 + (left_eye_y - right_eye_y) ** 2) ** 0.5
cv2.putText(image_with_lines, f"Eye distance: {eye_distance:.2f}px",
(10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 0, 0), 2)
# Nose width (points 129 and 358)
right_nose = facial_landmarks.landmark[129]
left_nose = facial_landmarks.landmark[358]
right_nose_x = int(right_nose.x * width)
right_nose_y = int(right_nose.y * height)
left_nose_x = int(left_nose.x * width)
left_nose_y = int(left_nose.y * height)
# Draw nose width line
cv2.line(image_with_lines, (right_nose_x, right_nose_y), (left_nose_x, left_nose_y), (255, 165, 0), 3)
nose_width = ((left_nose_x - right_nose_x) ** 2 + (left_nose_y - right_nose_y) ** 2) ** 0.5
cv2.putText(image_with_lines, f"Nose width: {nose_width:.2f}px",
(10, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 165, 0), 2)
# Face height (points 10 and 152)
forehead = facial_landmarks.landmark[10] # Forehead point
chin = facial_landmarks.landmark[152] # Chin point
forehead_x = int(forehead.x * width)
forehead_y = int(forehead.y * height)
chin_x = int(chin.x * width)
chin_y = int(chin.y * height)
# Draw face height line
cv2.line(image_with_lines, (forehead_x, forehead_y), (chin_x, chin_y), (0, 0, 255), 3)
face_height = ((chin_x - forehead_x) ** 2 + (chin_y - forehead_y) ** 2) ** 0.5
cv2.putText(image_with_lines, f"Face height: {face_height:.2f}px",
(10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
# Return face ratio
face_ratio = face_width / face_height if face_height > 0 else 0
cv2.putText(image_with_lines, f"Face ratio: {face_ratio:.2f}",
(10, 150), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 0, 255), 2)
# Return both images
return image_all_landmarks, image_with_lines
# Create Gradio interface
demo = gr.Interface(
fn=process_face_image,
inputs=[
gr.Image(type="numpy", label="Input Image")
],
outputs=[
gr.Image(type="numpy", label="Face Landmarks"),
gr.Image(type="numpy", label="Face Measurements")
],
title="Face Analysis with Measurements",
description="""
Upload a face image to get:
1. Image with all landmark points
2. Image with measurements (face width, eye distance, nose width, face height)
""",
)
# Add examples from the 'examples' directory if it exists
if os.path.exists("examples"):
example_list = [["examples/" + example] for example in os.listdir("examples") if
example.endswith(('.jpg', '.jpeg', '.png'))]
if example_list:
demo = gr.Interface(
fn=process_face_image,
inputs=[
gr.Image(type="numpy", label="Input Image")
],
outputs=[
gr.Image(type="numpy", label="Face Landmarks"),
gr.Image(type="numpy", label="Face Measurements")
],
title="Face Analysis with Measurements",
description="""
Upload a face image to get:
1. Image with all landmark points
2. Image with measurements (face width, eye distance, nose width, face height)
""",
examples=example_list
)
# Launch the interface
if __name__ == "__main__":
demo.launch(share=True) # share=True allows you to get a public link
|