This repository was archived by the owner on Aug 20, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsuggestionscript.py
More file actions
402 lines (361 loc) · 12.3 KB
/
Copy pathsuggestionscript.py
File metadata and controls
402 lines (361 loc) · 12.3 KB
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from cmath import acos
"""
Functions:
- angleCosRule: calculates angle at point p1 given three points
- processGT: creates a jointdict for the ground truth joint coordinates and relative joint positions too
- relateJoint: given a joint dict and relation type, returns the angle between the relation type
- fixPose: should be continuously called to give the user feedback on how to correct their pose to ground truth
"""
jointNames = ["neck",
"rightShoulder",
"rightElbow",
"rightWrist",
"rightHip",
"rightKnee",
"rightAnkle",
"root",
"leftHip",
"leftKnee",
"leftAnkle",
"leftShoulder",
"leftElbow",
"leftWrist"]
"""
anglecosrule: returns angle between three points. Note: This is the angle at p1
input: three arrays, p1,p2,p3 of [x,y] coords
output: returns angle at p1 in degrees
https://stackoverflow.com/questions/1211212/how-to-calculate-an-angle-from-three-points
"""
def angleCosRule(p1,p2,p3):
#Lengths of p1 to p2, p2 to p3, p3 to p1
# seg12 = math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
# seg23 = math.sqrt((p3[0] - p2[0])**2 + (p3[1] - p2[1])**2)
# seg13 = math.sqrt((p1[0] - p3[0])**2 + (p1[1] - p3[1])**2)
# return(acos((seg12**2 + seg13**2 - seg23**2)/(2*seg12*seg13)))
ang = math.degrees(math.atan2(p3[1]-p1[1], p3[0]-p1[0]) - math.atan2(p2[1]-p1[1], p2[0]-p1[0]))
return ang + 360 if ang < 0 else ang
"""
processPose: creates dictionary of pose coordinates and relative joint positions
Input: -pose: joint array example: [[3,20],None, None, [40,300] ...]
Return: joint dictionary with key as joint name and value as the corresponding row from input.
dictionary also includes angles for joint relations
"""
def processPose(pose):
poseDict = {}
for i in range(len(jointNames)):
poseDict[jointNames[i]] = pose[i]
poseDict["r_neck_elbow"] = relateJoint(poseDict,"r_neck_elbow")
poseDict["r_shoulder_wrist"] = relateJoint(poseDict,"r_shoulder_wrist")
poseDict["l_neck_elbow"] = relateJoint(poseDict,"l_neck_elbow")
poseDict["l_shoulder_wrist"] = relateJoint(poseDict,"l_shoulder_wrist")
poseDict["r_root_knee"] = relateJoint(poseDict,"r_root_knee")
poseDict["r_hip_ankle"] = relateJoint(poseDict,"r_hip_ankle")
poseDict["l_root_knee"] = relateJoint(poseDict,"l_root_knee")
poseDict["l_hip_ankle"] = relateJoint(poseDict,"l_hip_ankle")
return poseDict
"""
relateJoint: calculates a bend angle.
Input: - jdict: joint dict
- calculation type.
Type nomenclature: (side)_(start joint)_(end joint)
Ex: r_neck_elbow gives the angle at the right shoulder between neck and right elbow joint
Return: - calculated angle
"""
def relateJoint(jDict, type):
if type == "r_neck_elbow":
return angleCosRule(jDict["rightShoulder"],jDict["neck"],jDict["rightElbow"])
elif type == "r_shoulder_wrist":
return angleCosRule(jDict["rightElbow"],jDict["rightShoulder"],jDict["rightWrist"])
elif type == "l_neck_elbow":
return angleCosRule(jDict["leftShoulder"],jDict["neck"],jDict["leftElbow"])
elif type == "l_shoulder_wrist":
return angleCosRule(jDict["leftElbow"],jDict["leftShoulder"],jDict["leftWrist"])
elif type == "r_root_knee":
return angleCosRule(jDict["rightHip"],jDict["root"],jDict["rightKnee"])
elif type == "r_hip_ankle":
return angleCosRule(jDict["rightKnee"],jDict["rightHip"],jDict["rightAnkle"])
elif type == "l_root_knee":
return angleCosRule(jDict["leftHip"],jDict["root"],jDict["leftKnee"])
elif type == "l_hip_ankle":
return angleCosRule(jDict["leftKnee"],jDict["leftHip"],jDict["leftAnkle"])
"""
fixPose: Called continuoiusly and provides the user with an instruction to move a body part
to the desired position in the ground truth.
Method for each limb:
-Align limb: For each limb, instruct the user to move that limb until the center joint is similar
to the relative desired position
-Bend limb: Instruct user to bend the aligned limb until the angle between the torso, center, and
end joint form the correct angle
Example: Standard right bicep flex
1.instruct user to move arm up until the right elbow joint is parallel with the neck joint
2.instruct user to bend arm until the angle formed between right wrist,elbow,shoulder is 'correct'
Gives precedence to the body part that deviates most from the
grount truth
Moves: Start with legs to establish pose stability. Moving legs after fixing arms is bad.
Legs:
-move right/left leg in/out
-bend/straighten right/left leg
Arms:
-raise/lower right/left arm
-bend/straighten right/left arm
Input:
- Cpose: constant stream of current pose points given as an array of CGPoints: (x,y)
- GTpose: Ground truth pose points given as an array of CGPoints: (x,y)
Output:
-prints a suggestion to fix pose with an error bound of 5 degrees
"""
def fixPose(Cpose, GTdata):
#run indefinitely
# while 1:
Cdata = processPose(Cpose)
#If the person pictured is not in-frame
if len(Cpose) != 14:
return "Move back - your body is not in full-view"
#Adjusting hip angle with root,hip,knee points
elif Cdata["r_root_knee"] < GTdata["r_root_knee"] and GTdata["r_root_knee"] - Cdata["r_root_knee"] > 5:
return "Move your right leg out"
elif Cdata["r_root_knee"] > GTdata["r_root_knee"] and GTdata["r_root_knee"] - Cdata["r_root_knee"] < -5:
return "Move your right leg in"
elif Cdata["l_root_knee"] > GTdata["l_root_knee"] and GTdata["l_root_knee"] - Cdata["l_root_knee"] < -5:
return "Move your left leg out"
elif Cdata["l_root_knee"] < GTdata["l_root_knee"] and GTdata["l_root_knee"] - Cdata["l_root_knee"] > 5:
return "Move your left leg in"
#Adjusting knee angle with hip,knee,ankle points
elif Cdata["r_hip_ankle"] < GTdata["r_hip_ankle"] and GTdata["r_hip_ankle"] - Cdata["r_hip_ankle"] > 5:
return "Straighten your right knee"
elif Cdata["r_hip_ankle"] > GTdata["r_hip_ankle"] and GTdata["r_hip_ankle"] - Cdata["r_hip_ankle"] < -5:
return "Bend your right knee"
elif Cdata["l_hip_ankle"] > GTdata["l_hip_ankle"] and GTdata["l_hip_ankle"] - Cdata["l_hip_ankle"] < -5:
return "Straighten your left knee"
elif Cdata["l_hip_ankle"] < GTdata["l_hip_ankle"] and GTdata["l_hip_ankle"] - Cdata["l_hip_ankle"] > 5:
return "Bend your left knee"
#Adjusting shoulder angle with neck,shoulder,elbow points
elif Cdata["r_neck_elbow"] < GTdata["r_neck_elbow"] and GTdata["r_neck_elbow"] - Cdata["r_neck_elbow"] > 5:
return "Raise your right arm"
elif Cdata["r_neck_elbow"] > GTdata["r_neck_elbow"] and GTdata["r_neck_elbow"] - Cdata["r_neck_elbow"] < -5:
return "Lower your right arm"
elif Cdata["l_neck_elbow"] > GTdata["l_neck_elbow"] and GTdata["l_neck_elbow"] - Cdata["l_neck_elbow"] < -5:
return "Raise your left arm"
elif Cdata["l_neck_elbow"] < GTdata["l_neck_elbow"] and GTdata["l_neck_elbow"] - Cdata["l_neck_elbow"] > 5:
return "Lower your left arm"
#Adjusting elbow angle with shoulder,elbow,wrist points
elif Cdata["r_shoulder_wrist"] < GTdata["r_shoulder_wrist"] and GTdata["r_shoulder_wrist"] - Cdata["r_shoulder_wrist"] > 5:
return "Bend your right elbow"
elif Cdata["r_shoulder_wrist"] > GTdata["r_shoulder_wrist"] and GTdata["r_shoulder_wrist"] - Cdata["r_shoulder_wrist"] < -5:
return "Straighten your right elbow"
elif Cdata["l_shoulder_wrist"] < GTdata["l_shoulder_wrist"] and GTdata["l_shoulder_wrist"] - Cdata["l_shoulder_wrist"] > 5:
return "Straighten your left elbow"
elif Cdata["l_shoulder_wrist"] > GTdata["l_shoulder_wrist"] and GTdata["l_shoulder_wrist"] - Cdata["l_shoulder_wrist"] < -5:
return "Bend your left elbow"
else:
return "Nice pose!"
###########################Testing####################################
#Cosine Law to get angle at p1
p1 = [30,30]
p2 = [20,30]
p3 = [50,60]
print(angleCosRule(p1,p2,p3)) #expected 236.31
def showJoints(pose, GTData):
f = plt.figure()
f.set_figwidth(5)
f.set_figheight(7)
plt.xlim([0,600])
plt.ylim([0,700])
plt.title(fixPose(pose,GTData))
for val in pose:
if val != None:
plt.plot(val[0],val[1], "ro")
plt.show()
#Ground Truth
Tpose = [[310,520],
[370,520],
[430,520],
[500,520],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,520],
[100,520]]
#Standing in X pose
pose1 = [[310,520],
[370,520],
[430,620],
[500,680],
[350,285],
[420,200],
[450,70],
[310,280],
[270,280],
[200,200],
[180,70],
[240,520],
[170,610],
[100,680]]
#Shift right leg inwards
pose2 = [[310,520],
[370,520],
[430,620],
[500,680],
[350,285],
[355,200],
[450,70],
[310,280],
[270,280],
[200,200],
[180,70],
[240,520],
[170,610],
[100,680]]
#shift left leg inwards
pose3 = [[310,520],
[370,520],
[430,620],
[500,680],
[350,285],
[355,200],
[450,70],
[310,280],
[270,280],
[268,200],
[180,70],
[240,520],
[170,610],
[100,680]]
#Shift right foot in, bend right knee
pose4 = [[310,520],
[370,520],
[430,620],
[500,680],
[350,285],
[355,200],
[355,70],
[310,280],
[270,280],
[268,200],
[180,70],
[240,520],
[170,610],
[100,680]]
#Standing with arms raised in Y pose
pose5 = [[310,520],
[370,520],
[430,620],
[500,680],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,610],
[100,680]]
#lowered right arm
pose6 = [[310,520],
[370,520],
[500,590],
[580,650],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,610],
[100,680]]
#lower right arm more
pose6 = [[310,520],
[370,520],
[450,525],
[580,650],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,610],
[100,680]]
#lower left arm
pose7 = [[310,520],
[370,520],
[450,525],
[580,650],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,520],
[50,620]]
#straighten right elbow
pose7 = [[310,520],
[370,520],
[450,525],
[580,650],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,520],
[50,620]]
pose8 = [[310,520],
[370,520],
[450,525],
[580,525],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,520],
[50,620]]
pose9 = [[310,520],
[370,520],
[450,525],
[580,525],
[350,285],
[350,200],
[350,70],
[310,280],
[270,280],
[270,200],
[270,70],
[240,520],
[170,520],
[25,525]]
Tdata = processPose(Tpose)
showJoints(Tpose, Tdata)
showJoints(pose1, Tdata)
showJoints(pose2, Tdata)
showJoints(pose3, Tdata)
showJoints(pose4, Tdata)
showJoints(pose5, Tdata)
showJoints(pose6, Tdata)
showJoints(pose7, Tdata)
showJoints(pose8, Tdata)
showJoints(pose9, Tdata)