Chris commited on
Commit
b9cc655
1 Parent(s): 775d1c1
.gitignore CHANGED
@@ -3,3 +3,4 @@ lib
3
  output
4
  share
5
  input_img.jpg
 
 
3
  output
4
  share
5
  input_img.jpg
6
+ input_img.jpg
=1.12 CHANGED
@@ -1,14 +1,14 @@
1
  Requirement already satisfied: xtcocotools in ./lib/python3.10/site-packages (1.14.3)
2
- Requirement already satisfied: matplotlib>=2.1.0 in ./lib/python3.10/site-packages (from xtcocotools) (3.7.4)
3
  Requirement already satisfied: setuptools>=18.0 in ./lib/python3.10/site-packages (from xtcocotools) (65.5.0)
4
  Requirement already satisfied: cython>=0.27.3 in ./lib/python3.10/site-packages (from xtcocotools) (3.0.7)
5
- Requirement already satisfied: numpy>=1.20.0 in ./lib/python3.10/site-packages (from xtcocotools) (1.23.0)
 
6
  Requirement already satisfied: fonttools>=4.22.0 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (4.47.0)
7
- Requirement already satisfied: python-dateutil>=2.7 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (2.8.2)
8
  Requirement already satisfied: packaging>=20.0 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (23.2)
9
- Requirement already satisfied: kiwisolver>=1.0.1 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (1.4.5)
10
- Requirement already satisfied: cycler>=0.10 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (0.12.1)
11
  Requirement already satisfied: pyparsing>=2.3.1 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (2.4.5)
12
- Requirement already satisfied: contourpy>=1.0.1 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (1.2.0)
 
13
  Requirement already satisfied: pillow>=6.2.0 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (9.4.0)
14
  Requirement already satisfied: six>=1.5 in ./lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib>=2.1.0->xtcocotools) (1.16.0)
 
1
  Requirement already satisfied: xtcocotools in ./lib/python3.10/site-packages (1.14.3)
2
+ Requirement already satisfied: numpy>=1.20.0 in ./lib/python3.10/site-packages (from xtcocotools) (1.23.0)
3
  Requirement already satisfied: setuptools>=18.0 in ./lib/python3.10/site-packages (from xtcocotools) (65.5.0)
4
  Requirement already satisfied: cython>=0.27.3 in ./lib/python3.10/site-packages (from xtcocotools) (3.0.7)
5
+ Requirement already satisfied: matplotlib>=2.1.0 in ./lib/python3.10/site-packages (from xtcocotools) (3.7.4)
6
+ Requirement already satisfied: cycler>=0.10 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (0.12.1)
7
  Requirement already satisfied: fonttools>=4.22.0 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (4.47.0)
8
+ Requirement already satisfied: contourpy>=1.0.1 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (1.2.0)
9
  Requirement already satisfied: packaging>=20.0 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (23.2)
 
 
10
  Requirement already satisfied: pyparsing>=2.3.1 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (2.4.5)
11
+ Requirement already satisfied: kiwisolver>=1.0.1 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (1.4.5)
12
+ Requirement already satisfied: python-dateutil>=2.7 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (2.8.2)
13
  Requirement already satisfied: pillow>=6.2.0 in ./lib/python3.10/site-packages (from matplotlib>=2.1.0->xtcocotools) (9.4.0)
14
  Requirement already satisfied: six>=1.5 in ./lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib>=2.1.0->xtcocotools) (1.16.0)
__pycache__/keypoints_extraction.cpython-310.pyc ADDED
Binary file (1.51 kB). View file
 
app.py CHANGED
@@ -1,4 +1,6 @@
1
-
 
 
2
 
3
  import os
4
  os.system("pip install xtcocotools>=1.12")
@@ -7,75 +9,27 @@ os.system("pip install 'mmcv>=2.0.0rc4,<2.1.0'")
7
  os.system("pip install 'mmdet>=3.0.0,<4.0.0'")
8
  os.system("pip install 'mmpose'")
9
 
10
- import PIL
11
- import cv2
12
- import numpy as np
13
-
14
- import torch
15
- from mmpose.apis import MMPoseInferencer
16
- from mmpose.apis import inference_topdown, init_model
17
- from mmpose.utils import register_all_modules
18
- register_all_modules()
19
-
20
  import gradio as gr
21
 
22
- import warnings
23
-
24
- warnings.filterwarnings("ignore")
25
-
26
- def save_image(img, img_path):
27
- # Convert PIL image to OpenCV image
28
- img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
29
- # Save OpenCV image
30
- cv2.imwrite(img_path, img)
31
-
32
- def predict_pose(img):
33
- img_path = "input_img.jpg"
34
- save_image(img, img_path)
35
 
36
- result = mmpose_coco(img_path)
37
- keypoints = result[0].pred_instances['keypoints'][0]
38
 
39
- # Create a dictionary to store keypoints and their names
40
- keypoints_data = {
41
- 'keypoints': keypoints.tolist(),
42
- 'keypoint_names': [
43
- 'nose',
44
- 'left_eye',
45
- 'right_eye',
46
- 'left_ear',
47
- 'right_ear',
48
- 'left_shoulder',
49
- 'right_shoulder',
50
- 'left_elbow',
51
- 'right_elbow',
52
- 'left_wrist',
53
- 'right_wrist',
54
- 'left_hip',
55
- 'right_hip',
56
- 'left_knee',
57
- 'right_knee',
58
- 'left_ankle',
59
- 'right_ankle'
60
- ]
61
- }
62
- return (img, keypoints_data)
63
 
64
- def mmpose_coco(img_path,
65
- config_file = 'mmpose/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py',
66
- checkpoint_file = 'mmpose/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth'):
67
- device = torch.cuda.current_device() if torch.cuda.is_available() else 'cpu'
68
- # coco keypoints:
69
- # https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py#L28
70
- model = init_model(config_file, checkpoint_file, device=device)
71
- results = inference_topdown(model, img_path)
72
- return results
73
 
74
- # download_test_image()
75
- input_image = gr.inputs.Image(type='pil', label="Original Image")
76
- output_image = gr.outputs.Image(type="pil", label="Output Image")
77
- output_text = gr.outputs.Textbox(label="Output Text")
 
 
78
 
79
  title = "MMPose detection for ShopByShape"
80
- iface = gr.Interface(fn=predict_pose, inputs=[input_image], outputs=[output_image, output_text], title=title)
81
  iface.launch()
 
1
+ from keypoints_extraction import predict_pose
2
+ from calculate_measures import calculate_all_measures
3
+ from calculate_masks import calculate_seg_mask
4
 
5
  import os
6
  os.system("pip install xtcocotools>=1.12")
 
9
  os.system("pip install 'mmdet>=3.0.0,<4.0.0'")
10
  os.system("pip install 'mmpose'")
11
 
 
 
 
 
 
 
 
 
 
 
12
  import gradio as gr
13
 
14
+ def generate_output(front_img, side_img):
15
+ # TODO: These file names will need to be unique in case of multiple requests at once, and they will need to be deleted after the function is done.
16
+ front_keypoint_result = predict_pose(front_img, "front.jpg")
17
+ side_keypoint_result = predict_pose(side_img, "side.jpg")
 
 
 
 
 
 
 
 
 
18
 
19
+ front_seg_mask = calculate_seg_mask(front_img)
20
+ side_rcnn_mask = calculate_seg_mask(side_img)
21
 
22
+ measures = calculate_all_measures(front_keypoint_result, side_keypoint_result, front_seg_mask, side_rcnn_mask)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ return (front_keypoint_result[0], front_keypoint_result[1], side_keypoint_result[0], side_keypoint_result[1])
 
 
 
 
 
 
 
 
25
 
26
+ input_image_front = gr.inputs.Image(type='pil', label="Front Image")
27
+ input_image_side = gr.inputs.Image(type='pil', label="Side Image")
28
+ output_image_front = gr.outputs.Image(type="pil", label="Front Output Image")
29
+ output_text_front = gr.outputs.Textbox(label="Front Output Text")
30
+ output_image_side = gr.outputs.Image(type="pil", label="Front Output Image")
31
+ output_text_side = gr.outputs.Textbox(label="Side Output Text")
32
 
33
  title = "MMPose detection for ShopByShape"
34
+ iface = gr.Interface(fn=generate_output, inputs=[input_image_front, input_image_side], outputs=[output_image_front, output_text_front, output_image_side, output_text_side], title=title)
35
  iface.launch()
calculate_masks.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import Image
2
+ from transformers import SegformerImageProcessor, AutoModelForSemanticSegmentation
3
+ import torch.nn as nn
4
+
5
+ def calculate_seg_mask(image):
6
+ image = Image.open(image).convert("RGB")
7
+
8
+ processor = SegformerImageProcessor.from_pretrained("mattmdjaga/segformer_b2_clothes")
9
+ model = AutoModelForSemanticSegmentation.from_pretrained("mattmdjaga/segformer_b2_clothes")
10
+
11
+ class_names = {
12
+ 0: "Background", 1: "Hat", 2: "Hair", 3: "Sunglasses",
13
+ 4: "Upper-clothes", 5: "Skirt", 6: "Pants", 7: "Dress",
14
+ 8: "Belt", 9: "Left-shoe", 10: "Right-shoe", 11: "Face",
15
+ 12: "Left-leg", 13: "Right-leg", 14: "Left-arm", 15: "Right-arm",
16
+ 16: "Bag", 17: "Scarf"
17
+ }
18
+
19
+ inputs = processor(images=image, return_tensors="pt")
20
+
21
+ outputs = model(**inputs)
22
+ logits = outputs.logits.cpu()
23
+
24
+ upsampled_logits = nn.functional.interpolate(
25
+ logits,
26
+ size=image.size[::-1],
27
+ mode="bilinear",
28
+ align_corners=False,
29
+ )
30
+
31
+ pred_seg = upsampled_logits.argmax(dim=1)[0]
32
+ return pred_seg
calculate_measures.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ def get_width(mask, keypoint_y):
4
+ pred_np = mask.numpy()
5
+ # Find the index of the first occurrence of the mask label
6
+ first_index = np.argmax(pred_np[keypoint_y,:] > 0)
7
+
8
+ # Find the index of the last occurrence of the mask label
9
+ last_index = len(pred_np[keypoint_y,:]) - np.argmax(np.flip(pred_np[keypoint_y,:]) > 0) - 1
10
+
11
+ return last_index-first_index
12
+
13
+ def calculate_all_measures(front_keypoints, side_keypoints, front_seg_mask, side_rcnn_mask):
14
+ results_dict = {}
15
+
16
+ # calculate the body length
17
+ # pick the longer from the two ankle keypoints on y coordinate
18
+ side_body_length = side_keypoints[15][1] if side_keypoints[15][1] > side_keypoints[16][1] else side_keypoints[16][1]
19
+
20
+ # 5: 'left_shoulder'
21
+ left_shoulder_y = round(front_keypoints[5][1])
22
+ # print("shoulder width", get_width(front_seg_mask, left_shoulder_y))
23
+ results_dict['shoulder_width'] = get_width(front_seg_mask, left_shoulder_y)
24
+
25
+ # remove left-arm mask
26
+ front_seg_mask[front_seg_mask == 14] = 0
27
+
28
+ # remove right-arm mask
29
+ front_seg_mask[front_seg_mask == 15] = 0
30
+
31
+ # 11: 'left_hip'
32
+ left_hip_y = round(front_keypoints[11][1])
33
+ # print("hip width", get_width(front_seg_mask, left_hip_y))
34
+ results_dict['hip_width'] = get_width(front_seg_mask, left_hip_y)
35
+
36
+ # calculate shoulder_to_hip distance
37
+ shoulder_to_hip_distance = front_keypoints[11][1] - front_keypoints[5][1]
38
+ # print("Shoulder to hip distance:", shoulder_to_hip_distance)
39
+ results_dict['shoulder_to_hip_distance'] = shoulder_to_hip_distance
40
+
41
+ # calculate hip_to_ankle distance
42
+ hip_to_ankle_distance = front_keypoints[16][1] - front_keypoints[12][1]
43
+ # print("Hip to ankle distance:", hip_to_ankle_distance)
44
+ results_dict['hip_to_ankle_distance'] = hip_to_ankle_distance
45
+
46
+ # calculate torso_to_leg proportions
47
+ torso_to_leg_proportions = shoulder_to_hip_distance / hip_to_ankle_distance
48
+ # print("Torso to leg proportions:", torso_to_leg_proportions)
49
+ results_dict['torso_to_leg_ratio'] = torso_to_leg_proportions
50
+
51
+ # waist
52
+ # assuming waistline is x % higher from hips
53
+ # hip_y axis - (40 % of shoulder to hip distance)
54
+ waist_y = round(front_keypoints[11][1] - (shoulder_to_hip_distance * 0.40))
55
+ # print("waist width", get_width(front_seg_mask, waist_y))
56
+ results_dict['waist_width'] = get_width(front_seg_mask, waist_y)
57
+
58
+ # Calculate bounding box for thigh
59
+ # right_knee = side_keypoints[side_keypoint_names.index("right_knee")]
60
+ # right_hip = side_keypoints[side_keypoint_names.index("right_hip")]
61
+ # # Calculate bounding box for torso
62
+ # right_shoulder = side_keypoints[side_keypoint_names.index("right_shoulder")]
63
+
64
+ # # Replace keypoints, keypoint_names, combined_mask, and original_image with your actual data
65
+ # thigh_bbox = calculate_bbox(side_original_image, right_knee, right_hip)
66
+ # torso_bbox = calculate_bbox(side_original_image, right_hip, right_shoulder)
67
+ # # Calculate midpoint coordinates
68
+ # torso_midpoint = [0, (right_hip[1] + right_shoulder[1]) / 2]
69
+ # lower_torso_bbox = calculate_bbox(side_original_image, right_hip, torso_midpoint)
70
+ # upper_torso_bbox = calculate_bbox(side_original_image, torso_midpoint, right_shoulder)
71
+
72
+ # # Replace keypoints, keypoint_names, combined_mask, and original_image with your actual data
73
+ # thigh_area = get_volume_result(side_rcnn_mask, side_original_image, thigh_bbox[1], thigh_bbox[0], thigh_bbox[3], thigh_bbox[2]) # Thigh volume
74
+ # torso_area = get_volume_result(side_rcnn_mask, side_original_image, torso_bbox[1], torso_bbox[0], torso_bbox[3], torso_bbox[2]) # Torso volume
75
+ # lower_torso_area = get_volume_result(side_rcnn_mask, side_original_image, lower_torso_bbox[1], lower_torso_bbox[0], lower_torso_bbox[3], lower_torso_bbox[2]) # Lower torso volume
76
+ # upper_torso_area = get_volume_result(side_rcnn_mask, side_original_image, upper_torso_bbox[1], upper_torso_bbox[0], upper_torso_bbox[3], upper_torso_bbox[2]) # Upper torso volume
77
+ # full_side_body_area = (side_rcnn_mask > 0).sum()
78
+ # # print(f"Thigh area: {thigh_area}")
79
+ # # print(f"Torso area: {torso_area}")
80
+ # # print(f"Lower torso area: {lower_torso_area}")
81
+ # # print(f"Upper torso area: {upper_torso_area}")
82
+ # results_dict['thigh_area'] = thigh_area
83
+ # results_dict['torso_area'] = torso_area
84
+ # results_dict['lower_torso_area'] = lower_torso_area
85
+ # results_dict['upper_torso_area'] = upper_torso_area
86
+ # results_dict['full_side_body_area'] = full_side_body_area
87
+
88
+ # # calculate ratios
89
+ # results_dict['thigh_normalised'] = thigh_area / side_body_length
90
+ # results_dict['torso_normalised'] = torso_area / side_body_length
91
+ # results_dict['thigh_to_torso_ratio_normalised'] = results_dict['thigh_normalised'] / results_dict['torso_normalised']
92
+ # results_dict['thigh_to_torso_ratio'] = thigh_area / torso_area
93
+ # results_dict['upper_torso_normalised'] = upper_torso_area / side_body_length
94
+ # results_dict['lower_torso_normalised'] = lower_torso_area / side_body_length
95
+ # results_dict['upper_to_lower_torso_normalised_ratio'] = results_dict['upper_torso_normalised'] / results_dict['lower_torso_normalised']
96
+ # results_dict['upper_to_lower_torso_ratio'] = upper_torso_area / lower_torso_area
97
+ # results_dict['shoulder_to_hip_ratio'] = results_dict['shoulder_width'] / results_dict['hip_width']
98
+ # results_dict['shoulder_to_waist_ratio'] = results_dict['shoulder_width'] / results_dict['waist_width']
99
+ # results_dict['waist_to_hip_ratio'] = results_dict['waist_width'] / results_dict['hip_width']
100
+ # results_dict['thigh_to_body_ratio'] = thigh_area / full_side_body_area
101
+ # results_dict['upper_torso_to_body_ratio'] = upper_torso_area / full_side_body_area
102
+ # results_dict['upper_torso_to_body_ratio'] = upper_torso_area / full_side_body_area
103
+
104
+ return dict
keypoints_extraction.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import PIL
2
+ import cv2
3
+ import numpy as np
4
+
5
+ import torch
6
+ from mmpose.apis import MMPoseInferencer
7
+ from mmpose.apis import inference_topdown, init_model
8
+ from mmpose.utils import register_all_modules
9
+ register_all_modules()
10
+
11
+ def save_image(img, img_path):
12
+ # Convert PIL image to OpenCV image
13
+ img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
14
+ # Save OpenCV image
15
+ cv2.imwrite(img_path, img)
16
+
17
+ def predict_pose(img, img_path):
18
+ save_image(img, img_path)
19
+
20
+ result = mmpose_coco(img_path)
21
+ keypoints = result[0].pred_instances['keypoints'][0]
22
+
23
+ # Create a dictionary to store keypoints and their names
24
+ keypoints_data = {
25
+ 'keypoints': keypoints.tolist(),
26
+ 'keypoint_names': [
27
+ 'nose',
28
+ 'left_eye',
29
+ 'right_eye',
30
+ 'left_ear',
31
+ 'right_ear',
32
+ 'left_shoulder',
33
+ 'right_shoulder',
34
+ 'left_elbow',
35
+ 'right_elbow',
36
+ 'left_wrist',
37
+ 'right_wrist',
38
+ 'left_hip',
39
+ 'right_hip',
40
+ 'left_knee',
41
+ 'right_knee',
42
+ 'left_ankle',
43
+ 'right_ankle'
44
+ ]
45
+ }
46
+ return (img, keypoints_data)
47
+
48
+ def mmpose_coco(img_path,
49
+ config_file = 'mmpose/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py',
50
+ checkpoint_file = 'mmpose/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth'):
51
+ device = torch.cuda.current_device() if torch.cuda.is_available() else 'cpu'
52
+ # coco keypoints:
53
+ # https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py#L28
54
+ model = init_model(config_file, checkpoint_file, device=device)
55
+ results = inference_topdown(model, img_path)
56
+ return results