AnishaNaik03 commited on
Commit
eb3dde8
·
verified ·
1 Parent(s): e79e8af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -527
app.py CHANGED
@@ -1,514 +1,3 @@
1
- # import torch
2
- # import numpy as np
3
- # import cv2
4
- # import json
5
- # import os
6
- # import gradio as gr
7
- # from detectron2.detectron2.engine import DefaultPredictor
8
- # from detectron2.detectron2.config import get_cfg
9
- # from detectron2 import model_zoo
10
- # import torch_utils
11
- # import dnnlib
12
- # # Create output directory if it doesn't exist
13
- # output_dir = "key/"
14
- # os.makedirs(output_dir, exist_ok=True)
15
- # output_file = os.path.join(output_dir, "keypoints.json")
16
-
17
- # # Load pre-trained Keypoint R-CNN model
18
- # cfg = get_cfg()
19
- # cfg.merge_from_file(model_zoo.get_config_file("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml"))
20
- # cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml")
21
- # cfg.MODEL.DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
22
-
23
- # # Load the predictor
24
- # predictor = DefaultPredictor(cfg)
25
-
26
- # def process_image(image, user_height_cm):
27
- # # Convert Gradio image input to OpenCV format
28
- # image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
29
-
30
- # # Run keypoint detection
31
- # outputs = predictor(image)
32
-
33
- # # Extract keypoints
34
- # instances = outputs["instances"]
35
- # keypoints = instances.pred_keypoints.cpu().numpy().tolist() if instances.has("pred_keypoints") else None
36
-
37
- # if not keypoints:
38
- # return "No keypoints detected.", None
39
-
40
- # # Save keypoints to JSON
41
- # with open(output_file, "w") as f:
42
- # json.dump({"keypoints": keypoints}, f, indent=4)
43
-
44
- # keypoints = np.array(keypoints[0])[:, :2] # Extract (x, y) coordinates
45
-
46
- # # COCO format indices
47
- # NOSE, L_SHOULDER, R_SHOULDER = 0, 5, 6
48
- # L_ELBOW, R_ELBOW = 7, 8
49
- # L_WRIST, R_WRIST = 9, 10
50
- # L_HIP, R_HIP = 11, 12
51
- # L_ANKLE, R_ANKLE = 15, 16
52
-
53
- # # Define Keypoint Pairs for Drawing Lines (COCO Format)
54
- # skeleton = [(5, 6), (5, 11), (6, 12), (11, 12)]
55
-
56
- # # Draw Keypoints
57
- # for x, y in keypoints:
58
- # cv2.circle(image, (int(x), int(y)), 5, (0, 255, 0), -1)
59
-
60
- # # Draw Skeleton
61
- # for pt1, pt2 in skeleton:
62
- # x1, y1 = map(int, keypoints[pt1])
63
- # x2, y2 = map(int, keypoints[pt2])
64
- # cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 2)
65
-
66
- # # Function to calculate Euclidean distance
67
- # def get_distance(p1, p2):
68
- # return np.linalg.norm(np.array(p1) - np.array(p2))
69
-
70
- # # Calculate full height (consider head length)
71
- # ankle_mid = ((keypoints[L_ANKLE] + keypoints[R_ANKLE]) / 2).tolist()
72
- # pixel_height = get_distance(keypoints[NOSE], ankle_mid)
73
-
74
- # # Estimated full body height (add approx head length)
75
- # estimated_full_pixel_height = pixel_height / 0.87 # Since 87% = nose to ankle
76
- # pixels_per_cm = estimated_full_pixel_height / user_height_cm
77
-
78
- # # Waist and shoulder measurements
79
- # shoulder_width_px = get_distance(keypoints[L_SHOULDER], keypoints[R_SHOULDER])
80
- # waist_width_px = get_distance(keypoints[L_HIP], keypoints[R_HIP])
81
-
82
- # # Convert to cm
83
- # shoulder_width_cm = shoulder_width_px / pixels_per_cm
84
- # waist_width_cm = waist_width_px / pixels_per_cm
85
-
86
- # # Torso Length (Neck to Pelvis)
87
- # pelvis = ((keypoints[L_HIP] + keypoints[R_HIP]) / 2).tolist()
88
- # neck = ((keypoints[L_SHOULDER] + keypoints[R_SHOULDER]) / 2).tolist()
89
- # torso_length_px = get_distance(neck, pelvis)
90
- # torso_length_cm = torso_length_px / pixels_per_cm
91
-
92
- # # Arm Length (Shoulder to Wrist)
93
- # arm_length_px = get_distance(keypoints[L_SHOULDER], keypoints[L_WRIST])
94
- # arm_length_cm = arm_length_px / pixels_per_cm
95
-
96
- # # Calculate waist and hip circumference (Ellipse approximation)
97
- # # Waist circumference ≈ π × (waist_width / 2) × 2
98
- # waist_circumference = np.pi * waist_width_cm
99
- # hip_circumference = waist_circumference / 0.75 # Assuming hip is slightly bigger than waist
100
-
101
- # # Improved body measurement calculation
102
- # def calculate_body_measurements(waist_circumference, hip_circumference, shoulder_width_cm, torso_length_cm, arm_length_cm):
103
- # return {
104
- # "Waist Circumference (cm)": round(waist_circumference, 2),
105
- # "Hip Circumference (cm)": round(hip_circumference, 2),
106
- # "Shoulder Width (cm)": round(shoulder_width_cm, 2),
107
- # "Torso Length (Neck to Pelvis, cm)": round(torso_length_cm, 2),
108
- # "Full Arm Length (Shoulder to Wrist, cm)": round(arm_length_cm, 2),
109
- # }
110
-
111
- # measurements = calculate_body_measurements(waist_circumference, hip_circumference, shoulder_width_cm, torso_length_cm, arm_length_cm)
112
-
113
- # return measurements, cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
114
-
115
- # # Gradio Interface
116
- # demo = gr.Interface(
117
- # fn=process_image,
118
- # inputs=[gr.Image(type="pil"), gr.Number(label="User Height (cm)")],
119
- # outputs=[gr.JSON(label="Measurements"), gr.Image(type="pil", label="Keypoint Overlay")],
120
- # title="Keypoint Measurement Extractor",
121
- # description="Upload an image, enter your height, and get body measurements based on keypoints.",
122
- # )
123
-
124
- # demo.launch()
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
- # from PIL import Image # Importing Image from PIL (Pillow)
152
- # import json
153
- # import base64
154
- # import requests
155
- # from io import BytesIO
156
- # import torch
157
- # import numpy as np
158
- # import cv2
159
- # import json
160
- # import os
161
- # import gradio as gr
162
- # from detectron2.detectron2.engine import DefaultPredictor
163
- # from detectron2.detectron2.config import get_cfg
164
- # from detectron2 import model_zoo
165
- # import torch_utils
166
- # import dnnlib
167
- # # Create output directory if it doesn't exist
168
- # output_dir = "key/"
169
- # os.makedirs(output_dir, exist_ok=True)
170
- # output_file = os.path.join(output_dir, "keypoints.json")
171
-
172
-
173
-
174
- # # Load pre-trained Keypoint R-CNN model
175
- # cfg = get_cfg()
176
- # cfg.merge_from_file(model_zoo.get_config_file("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml"))
177
- # cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml")
178
- # cfg.MODEL.DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
179
-
180
- # # Load the predictor
181
- # predictor = DefaultPredictor(cfg)
182
-
183
- # def process_image(image, user_height_cm):
184
- # # Convert Gradio image input to OpenCV format
185
- # image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
186
-
187
- # # Run keypoint detection
188
- # outputs = predictor(image)
189
-
190
- # # Extract keypoints
191
- # instances = outputs["instances"]
192
- # keypoints = instances.pred_keypoints.cpu().numpy().tolist() if instances.has("pred_keypoints") else None
193
-
194
- # if not keypoints:
195
- # return "No keypoints detected.", None
196
-
197
- # # Save keypoints to JSON
198
- # with open(output_file, "w") as f:
199
- # json.dump({"keypoints": keypoints}, f, indent=4)
200
-
201
- # keypoints = np.array(keypoints[0])[:, :2] # Extract (x, y) coordinates
202
-
203
- # # COCO format indices
204
- # NOSE, L_SHOULDER, R_SHOULDER = 0, 5, 6
205
- # L_ELBOW, R_ELBOW = 7, 8
206
- # L_WRIST, R_WRIST = 9, 10
207
- # L_HIP, R_HIP = 11, 12
208
- # L_ANKLE, R_ANKLE = 15, 16
209
-
210
- # # Define Keypoint Pairs for Drawing Lines (COCO Format)
211
- # skeleton = [(5, 6), (5, 11), (6, 12), (11, 12)]
212
-
213
- # # Draw Keypoints
214
- # for x, y in keypoints:
215
- # cv2.circle(image, (int(x), int(y)), 5, (0, 255, 0), -1)
216
-
217
- # # Draw Skeleton
218
- # for pt1, pt2 in skeleton:
219
- # x1, y1 = map(int, keypoints[pt1])
220
- # x2, y2 = map(int, keypoints[pt2])
221
- # cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 2)
222
-
223
- # # Function to calculate Euclidean distance
224
- # def get_distance(p1, p2):
225
- # return np.linalg.norm(np.array(p1) - np.array(p2))
226
-
227
- # # Calculate full height (consider head length)
228
- # ankle_mid = ((keypoints[L_ANKLE] + keypoints[R_ANKLE]) / 2).tolist()
229
- # pixel_height = get_distance(keypoints[NOSE], ankle_mid)
230
-
231
- # # Estimated full body height (add approx head length)
232
- # estimated_full_pixel_height = pixel_height / 0.87 # Since 87% = nose to ankle
233
- # pixels_per_cm = estimated_full_pixel_height / user_height_cm
234
-
235
- # # Waist and shoulder measurements
236
- # shoulder_width_px = get_distance(keypoints[L_SHOULDER], keypoints[R_SHOULDER])
237
- # waist_width_px = get_distance(keypoints[L_HIP], keypoints[R_HIP])
238
-
239
- # # Convert to cm
240
- # shoulder_width_cm = shoulder_width_px / pixels_per_cm
241
- # waist_width_cm = waist_width_px / pixels_per_cm
242
-
243
- # # Torso Length (Neck to Pelvis)
244
- # pelvis = ((keypoints[L_HIP] + keypoints[R_HIP]) / 2).tolist()
245
- # neck = ((keypoints[L_SHOULDER] + keypoints[R_SHOULDER]) / 2).tolist()
246
- # torso_length_px = get_distance(neck, pelvis)
247
- # torso_length_cm = torso_length_px / pixels_per_cm
248
-
249
- # # Arm Length (Shoulder to Wrist)
250
- # arm_length_px = get_distance(keypoints[L_SHOULDER], keypoints[L_WRIST])
251
- # arm_length_cm = arm_length_px / pixels_per_cm
252
-
253
- # # Calculate waist and hip circumference (Ellipse approximation)
254
- # # Waist circumference ≈ π × (waist_width / 2) × 2
255
- # waist_circumference = np.pi * waist_width_cm
256
- # hip_circumference = waist_circumference / 0.75 # Assuming hip is slightly bigger than waist
257
-
258
- # # Improved body measurement calculation
259
- # def calculate_body_measurements(waist_circumference, hip_circumference, shoulder_width_cm, torso_length_cm, arm_length_cm):
260
- # return {
261
- # "Waist Circumference (cm)": round(waist_circumference, 2),
262
- # "Hip Circumference (cm)": round(hip_circumference, 2),
263
- # "Shoulder Width (cm)": round(shoulder_width_cm, 2),
264
- # "Torso Length (Neck to Pelvis, cm)": round(torso_length_cm, 2),
265
- # "Full Arm Length (Shoulder to Wrist, cm)": round(arm_length_cm, 2),
266
- # }
267
-
268
- # measurements = calculate_body_measurements(waist_circumference, hip_circumference, shoulder_width_cm, torso_length_cm, arm_length_cm)
269
-
270
- # return measurements, cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
271
-
272
-
273
- # # Save to database function
274
- # def save_to_database(measurements, image, user_height_cm):
275
- # if measurements is None or image is None:
276
- # return "No data to save."
277
-
278
- # # Convert image to base64
279
- # buffered = BytesIO()
280
- # pil_image = Image.fromarray(image) # Convert to PIL Image from NumPy array
281
- # pil_image.save(buffered, format="JPEG")
282
- # img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
283
-
284
- # # Send POST request to save measurements and image to the database
285
- # response = requests.post(
286
- # "https://9dbc-210-212-162-140.ngrok-free.app/upload", # Replace with your actual URL
287
- # json={
288
- # "imageBase64": img_str,
289
- # "heightCm": user_height_cm,
290
- # "waistCircumferenceCm": measurements["Waist Circumference (cm)"],
291
- # "shoulderwidth": measurements["Shoulder Width (cm)"],
292
- # "hipcircumference": measurements["Hip Circumference (cm)"],
293
- # "torsolength": measurements["Torso Length (Neck to Pelvis, cm)"],
294
- # "fullarmlength": measurements["Full Arm Length (Shoulder to Wrist, cm)"]
295
- # }
296
- # )
297
-
298
- # return f"Status: {response.status_code}, Message: {response.text}"
299
-
300
- # # Example usage (integrating with your Gradio app)
301
- # import gradio as gr
302
-
303
- # # Gradio interface setup
304
- # def process_and_save(image, user_height_cm):
305
- # measurements, processed_image = process_image(image, user_height_cm)
306
- # if measurements:
307
- # save_message = save_to_database(measurements, processed_image, user_height_cm)
308
- # return processed_image, measurements, save_message
309
- # else:
310
- # return None, None, "Error in processing image."
311
-
312
- # # Gradio interface setup
313
- # iface = gr.Interface(
314
- # fn=process_and_save,
315
- # inputs=[gr.Image(type="numpy"), gr.Number(label="User Height (cm)")],
316
- # outputs=[gr.Image(type="numpy"), gr.JSON(), gr.Textbox()],
317
- # live=True
318
- # )
319
-
320
- # iface.launch(share=True)
321
-
322
-
323
-
324
- # import gradio as gr
325
- # import json
326
- # import base64
327
- # import requests
328
- # from io import BytesIO
329
- # import torch
330
- # import numpy as np
331
- # import cv2
332
- # import os
333
- # from PIL import Image
334
- # from detectron2.engine import DefaultPredictor
335
- # from detectron2.config import get_cfg
336
- # from detectron2 import model_zoo
337
-
338
- # # === Set up Detectron2 model ===
339
- # cfg = get_cfg()
340
- # cfg.merge_from_file(model_zoo.get_config_file("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml"))
341
- # cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml")
342
- # cfg.MODEL.DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
343
- # predictor = DefaultPredictor(cfg)
344
-
345
- # # === Utility ===
346
- # def get_distance(p1, p2):
347
- # return np.linalg.norm(np.array(p1) - np.array(p2))
348
-
349
- # # === Keypoint and Measurement Logic ===
350
- # def process_image(image, user_height_cm):
351
- # image_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
352
- # outputs = predictor(image_cv)
353
- # instances = outputs["instances"]
354
- # keypoints = instances.pred_keypoints.cpu().numpy().tolist() if instances.has("pred_keypoints") else None
355
-
356
- # if not keypoints:
357
- # return "No keypoints detected.", None, None
358
-
359
- # keypoints = np.array(keypoints[0])[:, :2]
360
-
361
- # # Draw keypoints and skeleton
362
- # skeleton = [(5, 6), (5, 11), (6, 12), (11, 12)]
363
- # for x, y in keypoints:
364
- # cv2.circle(image_cv, (int(x), int(y)), 5, (0, 255, 0), -1)
365
- # for pt1, pt2 in skeleton:
366
- # x1, y1 = map(int, keypoints[pt1])
367
- # x2, y2 = map(int, keypoints[pt2])
368
- # cv2.line(image_cv, (x1, y1), (x2, y2), (255, 0, 0), 2)
369
-
370
- # # Body part indices
371
- # NOSE, L_SHOULDER, R_SHOULDER = 0, 5, 6
372
- # L_WRIST, L_HIP, R_HIP, L_ANKLE, R_ANKLE = 9, 11, 12, 15, 16
373
-
374
- # ankle_mid = ((keypoints[L_ANKLE] + keypoints[R_ANKLE]) / 2).tolist()
375
- # pixel_height = get_distance(keypoints[NOSE], ankle_mid)
376
- # estimated_full_pixel_height = pixel_height / 0.87
377
- # pixels_per_cm = estimated_full_pixel_height / user_height_cm
378
-
379
- # shoulder_width_cm = get_distance(keypoints[L_SHOULDER], keypoints[R_SHOULDER]) / pixels_per_cm
380
- # waist_width_cm = get_distance(keypoints[L_HIP], keypoints[R_HIP]) / pixels_per_cm
381
- # pelvis = ((keypoints[L_HIP] + keypoints[R_HIP]) / 2).tolist()
382
- # neck = ((keypoints[L_SHOULDER] + keypoints[R_SHOULDER]) / 2).tolist()
383
- # torso_length_cm = get_distance(neck, pelvis) / pixels_per_cm
384
- # arm_length_cm = get_distance(keypoints[L_SHOULDER], keypoints[L_WRIST]) / pixels_per_cm
385
-
386
- # waist_circumference = np.pi * waist_width_cm
387
- # hip_circumference = waist_circumference / 0.75
388
-
389
- # measurements = {
390
- # "Waist Circumference (cm)": round(waist_circumference, 2),
391
- # "Hip Circumference (cm)": round(hip_circumference, 2),
392
- # "Shoulder Width (cm)": round(shoulder_width_cm, 2),
393
- # "Torso Length (Neck to Pelvis, cm)": round(torso_length_cm, 2),
394
- # "Full Arm Length (Shoulder to Wrist, cm)": round(arm_length_cm, 2),
395
- # }
396
-
397
- # return measurements, cv2.cvtColor(image_cv, cv2.COLOR_BGR2RGB), keypoints.tolist()
398
-
399
- # # === Save to DB ===
400
- # # def save_to_database(measurements, image, user_height_cm, user_id):
401
- # # if not user_id:
402
- # # return "❌ user_id missing from URL."
403
-
404
- # # if measurements is None or image is None:
405
- # # return "⚠️ No data to save."
406
-
407
- # # buffered = BytesIO()
408
- # # pil_image = Image.fromarray(image)
409
- # # pil_image.save(buffered, format="JPEG")
410
- # # img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
411
-
412
- # # payload = {
413
- # # "imageBase64": img_str,
414
- # # "heightCm": user_height_cm,
415
- # # "measurements": measurements
416
- # # }
417
-
418
- # # try:
419
- # # response = requests.post(
420
- # # f"https://9d68-210-212-162-140.ngrok-free.app/upload/{user_id}",
421
- # # json=payload
422
- # # )
423
- # # if response.status_code == 201:
424
- # # return "✅ Measurements and image saved to database!"
425
- # # else:
426
- # # return f"❌ Failed: {response.status_code} - {response.text}"
427
- # # except Exception as e:
428
- # # return f"⚠️ Error during save: {str(e)}"
429
-
430
-
431
-
432
- # def save_to_database(measurements, image, user_height_cm, user_id):
433
- # if not user_id:
434
- # return "❌ user_id missing from URL."
435
- # if measurements is None or image is None:
436
- # return "⚠️ No data to save."
437
-
438
- # buffered = BytesIO()
439
- # pil_image = Image.fromarray(image)
440
- # pil_image.save(buffered, format="JPEG")
441
- # img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
442
-
443
- # payload = {
444
- # "imageBase64": img_str,
445
- # "heightCm": user_height_cm,
446
- # "waistCircumferenceCm": measurements.get("Waist Circumference (cm)"),
447
- # "hipcircumference": measurements.get("Hip Circumference (cm)"),
448
- # "shoulderwidth": measurements.get("Shoulder Width (cm)"),
449
- # "torsolength": measurements.get("Torso Length (Neck to Pelvis, cm)"),
450
- # "fullarmlength": measurements.get("Full Arm Length (Shoulder to Wrist, cm)"),
451
- # }
452
-
453
- # try:
454
- # response = requests.post(
455
- # f"https://7da2-2409-4042-6e81-1806-de6-b8e5-836c-6b95.ngrok-free.app/upload/{user_id}",
456
- # json=payload
457
- # )
458
- # if response.status_code == 201:
459
- # return "✅ Measurements and image saved to database!"
460
- # else:
461
- # return f"❌ Failed: {response.status_code} - {response.text}"
462
- # except Exception as e:
463
- # return f"⚠️ Error during save: {str(e)}"
464
-
465
-
466
- # # === Gradio App ===
467
- # with gr.Blocks() as demo:
468
- # gr.Markdown("# 📏 AI-Powered Body Measurement Tool")
469
- # user_id_state = gr.State()
470
-
471
- # @demo.load(inputs=None, outputs=[user_id_state])
472
- # def load_user_id(request: gr.Request):
473
- # return request.query_params.get("user_id", "")
474
-
475
- # with gr.Row():
476
- # with gr.Column():
477
- # image_input = gr.Image(label="Upload Your Full Body Image", type="pil")
478
- # height_input = gr.Number(label="Your Real Height (in cm)")
479
- # process_button = gr.Button("📐 Extract Measurements")
480
-
481
- # with gr.Column():
482
- # output_image = gr.Image(label="Detected Keypoints")
483
- # measurement_output = gr.JSON(label="Body Measurements")
484
-
485
- # with gr.Row():
486
- # save_button = gr.Button("💾 Save to Backend")
487
- # save_status = gr.Textbox(label="Status", interactive=False)
488
-
489
- # # Store results for save
490
- # processed_img = gr.State()
491
- # processed_data = gr.State()
492
-
493
- # process_button.click(
494
- # fn=process_image,
495
- # inputs=[image_input, height_input],
496
- # outputs=[measurement_output, output_image, processed_data]
497
- # ).then(
498
- # fn=lambda img: img,
499
- # inputs=[output_image],
500
- # outputs=processed_img
501
- # )
502
-
503
- # save_button.click(
504
- # fn=save_to_database,
505
- # inputs=[measurement_output, processed_img, height_input, user_id_state],
506
- # outputs=save_status
507
- # )
508
-
509
- # if __name__ == "__main__":
510
- # demo.launch()
511
-
512
  import torch
513
  import numpy as np
514
  import cv2
@@ -539,7 +28,7 @@ def process_image(image, user_height_cm):
539
  keypoints = instances.pred_keypoints.cpu().numpy().tolist() if instances.has("pred_keypoints") else None
540
 
541
  if not keypoints:
542
- return "No keypoints detected.", None
543
 
544
  with open(output_file, "w") as f:
545
  json.dump({"keypoints": keypoints}, f, indent=4)
@@ -553,15 +42,6 @@ def process_image(image, user_height_cm):
553
  L_KNEE, R_KNEE = 13, 14
554
  L_ANKLE, R_ANKLE = 15, 16
555
 
556
- skeleton = [(5, 6), (5, 11), (6, 12), (11, 12)]
557
-
558
- for x, y in keypoints:
559
- cv2.circle(image, (int(x), int(y)), 5, (0, 255, 0), -1)
560
- for pt1, pt2 in skeleton:
561
- x1, y1 = map(int, keypoints[pt1])
562
- x2, y2 = map(int, keypoints[pt2])
563
- cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 2)
564
-
565
  def get_distance(p1, p2):
566
  return np.linalg.norm(np.array(p1) - np.array(p2))
567
 
@@ -594,21 +74,26 @@ def process_image(image, user_height_cm):
594
  "Neck to Knee Length (cm)": round(neck_to_knee_cm, 2)
595
  }
596
 
597
- return measurements, cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
598
 
599
  # Gradio Interface
600
  with gr.Blocks() as demo:
601
- gr.Markdown("## 🧍 Keypoint-Based Body Measurement Tool")
602
- gr.Markdown("Upload a **full-body image** and enter your **height (in cm)** to estimate body measurements using AI-powered keypoint detection.")
603
 
604
  with gr.Row():
605
  with gr.Column():
606
  image_input = gr.Image(type="pil", label="📸 Upload Image")
607
- submit_btn = gr.Button("🔍 Generate Measurements")
608
- with gr.Column():
609
  height_input = gr.Number(label="📏 Your Height (cm)", value=170)
 
 
 
610
  measurement_output = gr.JSON(label="📐 Estimated Measurements")
611
 
612
- submit_btn.click(fn=process_image, inputs=[image_input, height_input], outputs=[measurement_output])
 
 
 
 
613
 
614
  demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
  import numpy as np
3
  import cv2
 
28
  keypoints = instances.pred_keypoints.cpu().numpy().tolist() if instances.has("pred_keypoints") else None
29
 
30
  if not keypoints:
31
+ return "No keypoints detected."
32
 
33
  with open(output_file, "w") as f:
34
  json.dump({"keypoints": keypoints}, f, indent=4)
 
42
  L_KNEE, R_KNEE = 13, 14
43
  L_ANKLE, R_ANKLE = 15, 16
44
 
 
 
 
 
 
 
 
 
 
45
  def get_distance(p1, p2):
46
  return np.linalg.norm(np.array(p1) - np.array(p2))
47
 
 
74
  "Neck to Knee Length (cm)": round(neck_to_knee_cm, 2)
75
  }
76
 
77
+ return measurements
78
 
79
  # Gradio Interface
80
  with gr.Blocks() as demo:
81
+ gr.Markdown("## 🧍 AI-Powered Body Measurement Estimator")
82
+ gr.Markdown("Upload a clear **full-body image** and enter your **height (in cm)** to estimate key body dimensions using computer vision.")
83
 
84
  with gr.Row():
85
  with gr.Column():
86
  image_input = gr.Image(type="pil", label="📸 Upload Image")
 
 
87
  height_input = gr.Number(label="📏 Your Height (cm)", value=170)
88
+ submit_btn = gr.Button("🔍 Estimate Measurements")
89
+
90
+ with gr.Column():
91
  measurement_output = gr.JSON(label="📐 Estimated Measurements")
92
 
93
+ submit_btn.click(
94
+ fn=process_image,
95
+ inputs=[image_input, height_input],
96
+ outputs=[measurement_output]
97
+ )
98
 
99
  demo.launch()