Spaces:
Sleeping
Sleeping
unfinity
commited on
Commit
·
67fd17e
1
Parent(s):
4678472
full-body drawing
Browse files- app.py +7 -7
- drawing.py +109 -0
- infer.py → utils.py +0 -0
- yolov8-test.ipynb +0 -0
app.py
CHANGED
@@ -3,7 +3,7 @@ import numpy as np
|
|
3 |
from PIL import Image, ImageDraw, ImageFont
|
4 |
from ultralytics import YOLO
|
5 |
import torch
|
6 |
-
import
|
7 |
|
8 |
|
9 |
@st.cache_resource()
|
@@ -30,7 +30,7 @@ def draw_output(image_pil: Image.Image, keypoints: dict):
|
|
30 |
|
31 |
# draw extended left and right eye lines
|
32 |
if ear and eye:
|
33 |
-
left_new_point =
|
34 |
l1 = [ear, left_new_point]
|
35 |
draw.line(l1, fill='red', width=line_width)
|
36 |
# draw a horizontal line from ear forwards
|
@@ -44,11 +44,11 @@ def draw_output(image_pil: Image.Image, keypoints: dict):
|
|
44 |
l = [ear, tuple(p2.tolist())]
|
45 |
draw.line(l, fill='gray', width=line_width//2)
|
46 |
# draw angle
|
47 |
-
angle =
|
48 |
draw.text(ear, f'{angle:.2f}', fill='red', font=font)
|
49 |
|
50 |
# draw elbow angles
|
51 |
-
left_elbow_angle, right_elbow_angle =
|
52 |
if left_elbow_angle:
|
53 |
draw.text(keypoints['left_elbow'], f'{left_elbow_angle:.2f}', fill='red', font=font)
|
54 |
# draw polyline for left arm
|
@@ -84,12 +84,12 @@ if img is not None:
|
|
84 |
model = load_model()
|
85 |
pred = model(img)[0]
|
86 |
st.markdown('**Results:**')
|
87 |
-
keypoints =
|
88 |
if keypoints is not None:
|
89 |
img = draw_output(img, keypoints)
|
90 |
st.image(img, caption='Predicted image', use_column_width=True)
|
91 |
-
lea, rea =
|
92 |
-
lba, rba =
|
93 |
st.write('Angles:')
|
94 |
st.json({'left_eye_angle': lea, 'right_eye_angle': rea, 'left_elbow_angle': lba, 'right_elbow_angle': rba})
|
95 |
st.write('Raw keypoints:')
|
|
|
3 |
from PIL import Image, ImageDraw, ImageFont
|
4 |
from ultralytics import YOLO
|
5 |
import torch
|
6 |
+
import utils
|
7 |
|
8 |
|
9 |
@st.cache_resource()
|
|
|
30 |
|
31 |
# draw extended left and right eye lines
|
32 |
if ear and eye:
|
33 |
+
left_new_point = utils.extend_line(ear, eye, 3)
|
34 |
l1 = [ear, left_new_point]
|
35 |
draw.line(l1, fill='red', width=line_width)
|
36 |
# draw a horizontal line from ear forwards
|
|
|
44 |
l = [ear, tuple(p2.tolist())]
|
45 |
draw.line(l, fill='gray', width=line_width//2)
|
46 |
# draw angle
|
47 |
+
angle = utils.calculate_angle_to_horizontal(l1_vector)
|
48 |
draw.text(ear, f'{angle:.2f}', fill='red', font=font)
|
49 |
|
50 |
# draw elbow angles
|
51 |
+
left_elbow_angle, right_elbow_angle = utils.get_elbow_angles(keypoints)
|
52 |
if left_elbow_angle:
|
53 |
draw.text(keypoints['left_elbow'], f'{left_elbow_angle:.2f}', fill='red', font=font)
|
54 |
# draw polyline for left arm
|
|
|
84 |
model = load_model()
|
85 |
pred = model(img)[0]
|
86 |
st.markdown('**Results:**')
|
87 |
+
keypoints = utils.get_keypoints(pred)
|
88 |
if keypoints is not None:
|
89 |
img = draw_output(img, keypoints)
|
90 |
st.image(img, caption='Predicted image', use_column_width=True)
|
91 |
+
lea, rea = utils.get_eye_angles(keypoints)
|
92 |
+
lba, rba = utils.get_elbow_angles(keypoints)
|
93 |
st.write('Angles:')
|
94 |
st.json({'left_eye_angle': lea, 'right_eye_angle': rea, 'left_elbow_angle': lba, 'right_elbow_angle': rba})
|
95 |
st.write('Raw keypoints:')
|
drawing.py
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image, ImageDraw, ImageFont
|
2 |
+
import numpy as np
|
3 |
+
import utils
|
4 |
+
|
5 |
+
|
6 |
+
skeleton = np.array([
|
7 |
+
[16, 14],
|
8 |
+
[14, 12],
|
9 |
+
[17, 15],
|
10 |
+
[15, 13],
|
11 |
+
[12, 13],
|
12 |
+
[6, 12],
|
13 |
+
[7, 13],
|
14 |
+
[6, 7],
|
15 |
+
[6, 8],
|
16 |
+
[7, 9],
|
17 |
+
[8, 10],
|
18 |
+
[9, 11],
|
19 |
+
[2, 3],
|
20 |
+
[1, 2],
|
21 |
+
[1, 3],
|
22 |
+
[2, 4],
|
23 |
+
[3, 5],
|
24 |
+
[4, 6],
|
25 |
+
[5, 7],
|
26 |
+
]) - 1
|
27 |
+
|
28 |
+
|
29 |
+
def draw_keypoints(img: Image.Image, keypoints: dict):
|
30 |
+
draw = ImageDraw.Draw(img)
|
31 |
+
|
32 |
+
font_size = max(round(sum(img.size) / 2 * 0.035), 12)
|
33 |
+
font = ImageFont.truetype("DejaVuSerif.ttf", font_size)
|
34 |
+
|
35 |
+
color = (0, 255, 0)
|
36 |
+
lw = max(round(sum(img.size) / 2 * 0.005), 2)
|
37 |
+
lw_poly = int(round(0.75*lw))
|
38 |
+
r = max(round(sum(img.size) / 2 * 0.0132), 8)
|
39 |
+
text_margin = r
|
40 |
+
|
41 |
+
# draw skeleton
|
42 |
+
keypoint_list = list(keypoints.values())
|
43 |
+
for i, sk in enumerate(skeleton):
|
44 |
+
if keypoint_list[sk[0]] and keypoint_list[sk[1]]:
|
45 |
+
draw.line([keypoint_list[sk[0]], keypoint_list[sk[1]]], fill=color, width=lw)
|
46 |
+
# draw rectangle polygons around keypoint_list
|
47 |
+
poly1 = [keypoint_list[sk[0]][0] - r, keypoint_list[sk[0]][1] - r, keypoint_list[sk[0]][0] + r, keypoint_list[sk[0]][1] + r]
|
48 |
+
poly1 = [(poly1[0], poly1[1]), (poly1[0], poly1[3]), (poly1[2], poly1[3]), (poly1[2], poly1[1])]
|
49 |
+
draw.polygon(poly1, outline=color, width=lw_poly)
|
50 |
+
poly2 = [keypoint_list[sk[1]][0] - r, keypoint_list[sk[1]][1] - r, keypoint_list[sk[1]][0] + r, keypoint_list[sk[1]][1] + r]
|
51 |
+
poly2 = [(poly2[0], poly2[1]), (poly2[0], poly2[3]), (poly2[2], poly2[3]), (poly2[2], poly2[1])]
|
52 |
+
draw.polygon(poly2, outline=color, width=lw_poly)
|
53 |
+
|
54 |
+
# draw angles
|
55 |
+
ear, eye = None, None
|
56 |
+
is_left = None
|
57 |
+
if keypoints["left_ear"] and keypoints["left_eye"]:
|
58 |
+
ear = keypoints["left_ear"]
|
59 |
+
eye = keypoints["left_eye"]
|
60 |
+
is_left = True
|
61 |
+
elif keypoints["right_ear"] and keypoints["right_eye"]:
|
62 |
+
ear = keypoints["right_ear"]
|
63 |
+
eye = keypoints["right_eye"]
|
64 |
+
is_left = False
|
65 |
+
|
66 |
+
# draw extended left and right eye lines
|
67 |
+
if ear and eye:
|
68 |
+
left_new_point = utils.extend_line(ear, eye, 3)
|
69 |
+
l1 = [ear, left_new_point]
|
70 |
+
draw.line(l1, fill='red', width=lw)
|
71 |
+
# draw a horizontal line from ear forwards
|
72 |
+
ear = np.array(ear)
|
73 |
+
l1 = np.array(l1)
|
74 |
+
l1_vector = l1[1] - l1[0]
|
75 |
+
x_s = np.sign(l1_vector)[0]
|
76 |
+
length_l1 = np.linalg.norm(l1_vector)
|
77 |
+
p2 = ear + np.array([length_l1*x_s, 0])
|
78 |
+
ear = tuple(ear.tolist())
|
79 |
+
l = [ear, tuple(p2.tolist())]
|
80 |
+
# draw.line(l, fill='gray', width=lw//2)
|
81 |
+
# draw angle
|
82 |
+
angle = utils.calculate_angle_to_horizontal(l1_vector)
|
83 |
+
txt = f'{angle:.0f}°'
|
84 |
+
txt_w, txt_h = font.getbbox(txt)[2:]
|
85 |
+
if is_left:
|
86 |
+
text_coords = (ear[0] - txt_w - text_margin, ear[1] - txt_h - text_margin)
|
87 |
+
else:
|
88 |
+
text_coords = (ear[0] + text_margin, ear[1] - txt_h - text_margin)
|
89 |
+
draw.text(text_coords, txt, fill='red', font=font)
|
90 |
+
|
91 |
+
# draw elbow angles
|
92 |
+
left_elbow_angle, right_elbow_angle = utils.get_elbow_angles(keypoints)
|
93 |
+
if left_elbow_angle and is_left is not False:
|
94 |
+
txt = f'{left_elbow_angle:.0f}°'
|
95 |
+
txt_w, txt_h = font.getbbox(txt)[2:]
|
96 |
+
# adjust upwards and leftwards
|
97 |
+
text_coords = (keypoints['left_elbow'][0] - txt_w - text_margin, keypoints['left_elbow'][1] - txt_h - text_margin)
|
98 |
+
draw.text(text_coords, txt, fill='red', font=font)
|
99 |
+
# draw polyline for left arm
|
100 |
+
# draw.line([keypoints['left_shoulder'], keypoints['left_elbow'], keypoints['left_wrist']], fill='blue', width=lw)
|
101 |
+
if right_elbow_angle and is_left is not True:
|
102 |
+
txt = f'{right_elbow_angle:.0f}°'
|
103 |
+
txt_w, txt_h = font.getbbox(txt)[2:]
|
104 |
+
text_coords = (keypoints['right_elbow'][0] + text_margin, keypoints['right_elbow'][1] - txt_h - text_margin)
|
105 |
+
draw.text(text_coords, txt, fill='red', font=font)
|
106 |
+
# draw polyline for right arm
|
107 |
+
# draw.line([keypoints['right_shoulder'], keypoints['right_elbow'], keypoints['right_wrist']], fill='blue', width=lw)
|
108 |
+
|
109 |
+
return img
|
infer.py → utils.py
RENAMED
File without changes
|
yolov8-test.ipynb
CHANGED
The diff for this file is too large to render.
See raw diff
|
|