Hemant0000 commited on
Commit
4f60f15
·
verified ·
1 Parent(s): 027f59d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -0
app.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ import mediapipe as mp
5
+ import gradio as gr
6
+
7
+ # Initialize Mediapipe Pose model
8
+ mp_pose = mp.solutions.pose
9
+ pose = mp_pose.Pose(static_image_mode=True)
10
+
11
+ # Function to estimate height using dynamic calibration based on shoulder width
12
+ def estimate_real_world_height_and_area(image):
13
+ height, width, _ = image.shape
14
+ results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
15
+
16
+ if not results.pose_landmarks:
17
+ print("No landmarks detected.")
18
+ return None, None, None # Return None if no landmarks detected
19
+
20
+ landmarks = results.pose_landmarks.landmark
21
+
22
+ # Reference average shoulder width (in cm)
23
+ AVERAGE_SHOULDER_WIDTH_CM = 45
24
+
25
+ # Points for height (nose to ankle) and shoulder width
26
+ nose = landmarks[mp_pose.PoseLandmark.NOSE]
27
+ left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER]
28
+ right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER]
29
+ left_ankle = landmarks[mp_pose.PoseLandmark.LEFT_ANKLE]
30
+ right_ankle = landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE]
31
+
32
+ # Calculate pixel height between nose (head) and ankle
33
+ head_y = int(nose.y * height)
34
+ ankle_y = int((left_ankle.y + right_ankle.y) / 2 * height)
35
+ pixel_height = abs(ankle_y - head_y)
36
+
37
+ # Calculate shoulder width in pixels
38
+ shoulder_width_pixels = abs(left_shoulder.x - right_shoulder.x) * width
39
+
40
+ # Determine the pixel-to-cm ratio using shoulder width
41
+ pixel_to_cm_ratio = AVERAGE_SHOULDER_WIDTH_CM / shoulder_width_pixels if shoulder_width_pixels != 0 else 0
42
+
43
+ # Calculate real-world height using this ratio
44
+ real_world_height_cm = pixel_height * pixel_to_cm_ratio
45
+
46
+ # Estimate torso area in pixels
47
+ torso_width = abs(left_shoulder.x - right_shoulder.x) * width
48
+ torso_height = abs(left_shoulder.y - left_ankle.y) * height
49
+ torso_area_pixels = torso_width * torso_height
50
+ real_torso_area = torso_area_pixels * (pixel_to_cm_ratio ** 2)
51
+
52
+ return real_world_height_cm, real_torso_area, landmarks
53
+
54
+ # Main Gradio prediction function with scaling and plotting
55
+ def predict(image):
56
+ try:
57
+ # Classify Gender
58
+ gender = classify_gender(image) # Assuming this function is defined
59
+
60
+ # Estimate height and area
61
+ real_height, real_torso_area, landmarks = estimate_real_world_height_and_area(image)
62
+
63
+ if real_height is None or real_torso_area is None:
64
+ return "No landmarks detected; please use a clearer image.", None, None, None
65
+
66
+ # Plot with scale
67
+ fig, ax = plt.subplots(figsize=(10, 10))
68
+ ax.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
69
+
70
+ # Plot landmarks if they exist
71
+ if landmarks:
72
+ for landmark in landmarks:
73
+ ax.scatter(landmark.x * image.shape[1], landmark.y * image.shape[0], color="red", s=10)
74
+
75
+ # Add height and area text
76
+ ax.text(10, 30, f"Predicted Gender: {gender}", color="yellow", fontsize=12, backgroundcolor='black')
77
+ ax.text(10, 60, f"Estimated Height: {real_height:.2f} cm", color="yellow", fontsize=12, backgroundcolor='black')
78
+ ax.text(10, 90, f"Estimated Torso Area: {real_torso_area:.2f} cm^2", color="yellow", fontsize=12, backgroundcolor='black')
79
+
80
+ # Add grid scale to background
81
+ ax.set_xticks(np.arange(0, image.shape[1], 50))
82
+ ax.set_yticks(np.arange(0, image.shape[0], 50))
83
+ ax.grid(color='white', linestyle='--', linewidth=0.5)
84
+
85
+ # Save annotated plot for output
86
+ plt.savefig("output_plot.png")
87
+ plt.close(fig)
88
+
89
+ return gender, real_height, real_torso_area, "output_plot.png"
90
+ except Exception as e:
91
+ print(f"Error encountered: {e}")
92
+ return f"An error occurred: {e}", None, None, None
93
+
94
+ # Define Gradio interface
95
+ image_input = gr.Image(label="Input Image")
96
+ text_output = gr.Textbox(label="Predicted Gender")
97
+ height_output = gr.Textbox(label="Estimated Height (cm)")
98
+ area_output = gr.Textbox(label="Estimated Torso Area (cm^2)")
99
+ image_output = gr.Image(label="Annotated Image with Measurements")
100
+
101
+ # Set up Gradio interface
102
+ gr_interface = gr.Interface(
103
+ fn=predict,
104
+ inputs=image_input,
105
+ outputs=[text_output, height_output, area_output, image_output],
106
+ title="Gender, Height, and Body Measurement Estimation",
107
+ description="Upload an image to predict gender, estimate height, and calculate 2D torso area with a scale overlay."
108
+ )
109
+
110
+ # Launch the Gradio app
111
+ gr_interface.launch()