analyse_by_npy.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. import math
  2. import sys
  3. import numpy as np
  4. from demo_func import run_openpose_for_image_front, run_openpose_for_image_side
  5. sys.path.append('../')
  6. index = sys.argv[1]
  7. height = sys.argv[2]
  8. print(height)
  9. level_0 = 2
  10. level_1 = 10
  11. level_2 = 20
  12. O_ARGUMENT_1 = 0.2
  13. X_ARGUMENT_1 = 1.1
  14. HEAD_FORWARD_ARGUMENT_0 = 2
  15. HEAD_FORWARD_ARGUMENT_1 = 8
  16. HEAD_FORWARD_ARGUMENT_2 = 15
  17. HEAD_STRESS_ARGUMENT_0 = 11
  18. HEAD_STRESS_ARGUMENT_1 = 1.02777777777769
  19. HEAD_STRESS_ARGUMENT_2 = 0.00981481481482367
  20. HEAD_STRESS_ARGUMENT_3 = -0.000567901234568158
  21. HEAD_STRESS_ARGUMENT_4 = 0.00000576131687243021
  22. SHOULDER_OFFSET_ARGUMENT_0 = 0.5
  23. SHOULDER_OFFSET_ARGUMENT_1 = 1
  24. SHOULDER_OFFSET_ARGUMENT_2 = 3
  25. HIP_OFFSET_ARGUMENT_0 = 0.5
  26. HIP_OFFSET_ARGUMENT_1 = 1
  27. HIP_OFFSET_ARGUMENT_2 = 3
  28. HIP_OFFSET_ARGUMENT_0 = 0.5
  29. HIP_OFFSET_ARGUMENT_1 = 1
  30. HIP_OFFSET_ARGUMENT_2 = 3
  31. UP_FORWARD_ARGUMENT_0 = 2
  32. UP_FORWARD_ARGUMENT_1 = 10
  33. UP_FORWARD_ARGUMENT_2 = 20
  34. HIP_FORWARD_ARGUMENT_0 = 2
  35. HIP_FORWARD_ARGUMENT_1 = 5
  36. HIP_FORWARD_ARGUMENT_2 = 10
  37. KNEE_FORWARD_ARGUMENT_0 = 1
  38. KNEE_FORWARD_ARGUMENT_1 = 5
  39. KNEE_FORWARD_ARGUMENT_2 = 10
  40. source_npy_front = "pose_temp_data/{}-0.npy".format(index)
  41. source_npy_side = "pose_temp_data/{}-1.npy".format(index)
  42. save_path = "pose_processed_txt/{}.txt".format(index)
  43. def text_save(filename, data): # filename为写入CSV文件的路径,data为要写入数据列表.
  44. file = open(filename, 'w', encoding='utf-8')
  45. for i in range(len(data)):
  46. s = str(data[i]).replace('[', '').replace(']', '')
  47. s = s.replace("'", '').replace(',', '') + '\n'
  48. file.write(s)
  49. file.close()
  50. print("保存成功")
  51. def angle(v1, v2):
  52. dx1 = v1[2] - v1[0]
  53. dy1 = v1[3] - v1[1]
  54. dx2 = v2[2] - v2[0]
  55. dy2 = v2[3] - v2[1]
  56. angle1 = math.atan2(dy1, dx1)
  57. angle1 = round(angle1 * 180.0 / math.pi, 2)
  58. # print(angle1)
  59. angle2 = math.atan2(dy2, dx2)
  60. angle2 = round(angle2 * 180.0 / math.pi, 2)
  61. # print(angle2)
  62. if angle1 * angle2 >= 0:
  63. included_angle = abs(angle1 - angle2)
  64. else:
  65. included_angle = abs(angle1) + abs(angle2)
  66. if included_angle > 180:
  67. included_angle = 360 - included_angle
  68. return included_angle
  69. def cal_head_extra_stress(angle):
  70. return (HEAD_STRESS_ARGUMENT_1 * angle + HEAD_STRESS_ARGUMENT_2 * pow(angle, 2) \
  71. + HEAD_STRESS_ARGUMENT_3 * pow(angle, 3) + HEAD_STRESS_ARGUMENT_4 * pow(angle, 4)) / HEAD_STRESS_ARGUMENT_0
  72. def analyse_npy_front(npy_front):
  73. result = []
  74. data = np.load(npy_front)
  75. print("------------------")
  76. result.append("------------------")
  77. print("正面分析内容如下:")
  78. result.append("正面分析内容如下:")
  79. # h-eye - h-elbow
  80. h_pixel_eye2elbow = abs(data[14][1] - data[3][1])
  81. # print("h_pixel{}".format(h_pixel_eye2elbow))
  82. h_real_eye2elbow = float(height) * 0.333
  83. # print("h_real{}".format(h_real_eye2elbow))
  84. # body mid x
  85. ankle_mid_x = (data[13][0] + data[10][0]) / 2
  86. # for head
  87. ear_r_x = data[16][0]
  88. ear_r_y = data[16][1]
  89. ear_l_x = data[17][0]
  90. ear_l_y = data[17][1]
  91. head_angle = angle([ear_r_x, ear_r_y, ear_l_x, ear_l_y], [0, 0, 1, 0])
  92. ear_level = ""
  93. if head_angle <= level_0:
  94. ear_level = ""
  95. elif head_angle <= level_1 and head_angle > level_0:
  96. ear_level = "轻微"
  97. elif head_angle > level_1 and head_angle <= level_2:
  98. ear_level = "中等"
  99. else:
  100. ear_level = "严重"
  101. if ear_l_y < ear_r_y and ear_level != "":
  102. print("头部分析:头部左部高,向右倾斜,角度为{}度,程度{}".format(head_angle, ear_level))
  103. result.append("头部分析:头部左部高,向右倾斜,角度为{}度,程度{}".format(head_angle, ear_level))
  104. elif ear_l_y > ear_r_y and ear_level != "":
  105. print("头部分析:头部右部高,向左倾斜,角度为{}度,程度{}".format(head_angle, ear_level))
  106. result.append("头部分析:头部右部高,向左倾斜,角度为{}度,程度{}".format(head_angle, ear_level))
  107. else:
  108. print("头部分析:头部保持完美平衡")
  109. result.append("头部分析:头部保持完美平衡")
  110. # for shoulder
  111. shoulder_r_x = data[2][0]
  112. shoulder_r_y = data[2][1]
  113. shoulder_l_x = data[5][0]
  114. shoulder_l_y = data[5][1]
  115. shoulder_mid_x = (shoulder_l_x + shoulder_r_x) / 2
  116. offset_x_shoulder = (shoulder_mid_x - ankle_mid_x) * h_real_eye2elbow / h_pixel_eye2elbow
  117. d_shoulder = abs(data[5][1] - data[2][1])
  118. l_shoulder = math.sqrt((shoulder_l_x - shoulder_r_x) ** 2 + (shoulder_l_y - shoulder_r_y) ** 2)
  119. rate_shoulder = d_shoulder / l_shoulder
  120. shoulder_angle = angle([shoulder_r_x, shoulder_r_y, shoulder_l_x, shoulder_l_y], [0, 0, 1, 0])
  121. shoulder_level = ""
  122. shoulder_offset_level = ""
  123. if shoulder_angle <= level_0:
  124. shoulder_level = ""
  125. elif shoulder_angle <= level_1 and shoulder_angle > level_0:
  126. shoulder_level = "轻微"
  127. elif shoulder_angle > level_1 and shoulder_angle <= level_2:
  128. shoulder_level = "中等"
  129. else:
  130. shoulder_level = "严重"
  131. if offset_x_shoulder <= SHOULDER_OFFSET_ARGUMENT_0:
  132. shoulder_offset_level = ""
  133. elif offset_x_shoulder <= SHOULDER_OFFSET_ARGUMENT_1 and offset_x_shoulder > SHOULDER_OFFSET_ARGUMENT_0:
  134. shoulder_offset_level = "轻微"
  135. elif offset_x_shoulder > SHOULDER_OFFSET_ARGUMENT_1 and offset_x_shoulder <= SHOULDER_OFFSET_ARGUMENT_2:
  136. shoulder_offset_level = "中等"
  137. else:
  138. shoulder_offset_level = "严重"
  139. print("肩部分析:")
  140. result.append("肩部分析:")
  141. if offset_x_shoulder > 0 and shoulder_offset_level != "":
  142. print("肩部向左横移,距离为{}cm,程度{}".format(round(abs(offset_x_shoulder), 3), shoulder_offset_level))
  143. result.append("肩部向左横移,距离为{}cm,程度{}".format(round(abs(offset_x_shoulder), 3), shoulder_offset_level))
  144. elif offset_x_shoulder < 0 and shoulder_offset_level != "":
  145. print("肩部向右横移,距离为{}cm,程度{}".format(round(abs(offset_x_shoulder), 3), shoulder_offset_level))
  146. result.append("肩部向右横移,距离为{}cm,程度{}".format(round(abs(offset_x_shoulder), 3), shoulder_offset_level))
  147. else:
  148. print("肩部中心位居中轴,位置良好")
  149. result.append("肩部中心位居中轴,位置良好")
  150. if shoulder_l_y < shoulder_r_y and shoulder_level != "":
  151. print("肩部左部高,向右倾斜,角度为{}度,程度{},高度差异与肩长比值为{}%".format(shoulder_angle, shoulder_level,
  152. round(rate_shoulder * 100, 2)))
  153. result.append("肩部左部高,向右倾斜,角度为{}度,程度{},高度差异与肩长比值为{}%".format(shoulder_angle, shoulder_level,
  154. round(rate_shoulder * 100, 2)))
  155. elif ear_l_y > ear_r_y and shoulder_level != "":
  156. print("肩部右部高,向左倾斜,角度为{}度,程度{},高度差异与肩长比值为{}%".format(shoulder_angle, shoulder_level,
  157. round(rate_shoulder * 100, 2)))
  158. result.append("肩部右部高,向左倾斜,角度为{}度,程度{},高度差异与肩长比值为{}%".format(shoulder_angle, shoulder_level,
  159. round(rate_shoulder * 100, 2)))
  160. else:
  161. print("肩部角度保持完美平衡")
  162. result.append("肩部角度保持完美平衡")
  163. # for hip
  164. hip_r_x = data[8][0]
  165. hip_r_y = data[8][1]
  166. hip_l_x = data[11][0]
  167. hip_l_y = data[11][1]
  168. hip_mid_x = (hip_r_x + hip_l_x) / 2
  169. offset_x_hip = (hip_mid_x - ankle_mid_x) * h_real_eye2elbow / h_pixel_eye2elbow
  170. hd_hip = abs(data[11][1] - data[8][1])
  171. d_hip = math.sqrt((hip_l_x - hip_r_x) ** 2 + (hip_l_y - hip_r_y) ** 2)
  172. rate_hip = hd_hip / d_hip
  173. hip_angle = angle([hip_r_x, hip_r_y, hip_l_x, hip_l_y], [0, 0, 1, 0])
  174. hip_level = ""
  175. hip_offset_level = ""
  176. if hip_angle <= level_0:
  177. hip_level = ""
  178. elif hip_angle <= level_1 and hip_angle > level_0:
  179. hip_level = "轻微"
  180. elif hip_angle > level_1 and hip_angle <= level_2:
  181. hip_level = "中等"
  182. else:
  183. hip_level = "严重"
  184. if offset_x_hip <= HIP_OFFSET_ARGUMENT_0:
  185. hip_offset_level = ""
  186. elif offset_x_hip <= HIP_OFFSET_ARGUMENT_1 and offset_x_hip > HIP_OFFSET_ARGUMENT_0:
  187. hip_offset_level = "轻微"
  188. elif offset_x_hip > HIP_OFFSET_ARGUMENT_1 and offset_x_hip <= HIP_OFFSET_ARGUMENT_2:
  189. hip_offset_level = "中等"
  190. else:
  191. hip_offset_level = "严重"
  192. print("髋部分析:")
  193. result.append("髋部分析:")
  194. if offset_x_hip > 0 and hip_offset_level != "":
  195. print("髋部向左横移,距离为{}cm,程度{}".format(round(abs(offset_x_hip), 3), hip_offset_level))
  196. result.append("髋部向左横移,距离为{}cm,程度{}".format(round(abs(offset_x_hip), 3), hip_offset_level))
  197. elif offset_x_hip < 0 and hip_offset_level != "":
  198. print("髋部向右横移,距离为{}cm,程度{}".format(round(abs(offset_x_hip), 3), hip_offset_level))
  199. result.append("髋部向右横移,距离为{}cm,程度{}".format(round(abs(offset_x_hip), 3), hip_offset_level))
  200. else:
  201. print("髋部中心位居中轴,位置良好")
  202. result.append("髋部中心位居中轴,位置良好")
  203. if hip_l_y < hip_r_y:
  204. print("髋部左部高,向右倾斜,角度为{}度,程度{},高度差异与髋宽比值为{}%".format(hip_angle, hip_level, round(rate_hip * 100, 2)))
  205. result.append("髋部左部高,向右倾斜,角度为{}度,程度{},高度差异与髋宽比值为{}%".format(hip_angle, hip_level, round(rate_hip * 100, 2)))
  206. elif ear_l_y > ear_r_y:
  207. print("髋部右部高,向左倾斜,角度为{}度,程度{},高度差异与髋宽比值为{}%".format(hip_angle, hip_level, round(rate_hip * 100, 2)))
  208. result.append("髋部右部高,向左倾斜,角度为{}度,程度{},高度差异与髋宽比值为{}%".format(hip_angle, hip_level, round(rate_hip * 100, 2)))
  209. else:
  210. print("髋部角度保持完美平衡")
  211. result.append("髋部角度保持完美平衡")
  212. #
  213. print("腿型分析:")
  214. result.append("腿型分析:")
  215. # for knee distance
  216. knee_r_x = data[9][0]
  217. knee_r_y = data[9][1]
  218. knee_l_x = data[12][0]
  219. knee_l_y = data[12][1]
  220. d_knee = math.sqrt((knee_l_x - knee_r_x) ** 2 + (knee_l_y - knee_r_y) ** 2)
  221. rate_knee = d_knee / d_hip
  222. print("双膝间距与髋宽比值为{}%".format(round(rate_knee * 100, 2)))
  223. result.append("双膝间距与髋宽比值为{}%".format(round(rate_knee * 100, 2)))
  224. # XO judgement
  225. ankle_r_x = data[10][0]
  226. ankle_r_y = data[10][1]
  227. ankle_l_x = data[13][0]
  228. ankle_l_y = data[13][1]
  229. d_ankle = math.sqrt((ankle_l_x - ankle_r_x) ** 2 + (ankle_l_y - ankle_r_y) ** 2)
  230. rate_ankle = d_ankle / d_knee
  231. print("脚踝间距与双膝间距比值为{}%".format(round(rate_ankle * 100, 2)))
  232. result.append("脚踝间距与双膝间距比值为{}%".format(round(rate_ankle * 100, 2)))
  233. if rate_ankle > X_ARGUMENT_1:
  234. print("腿型可能为X型腿")
  235. result.append("腿型可能为X型腿")
  236. elif rate_knee - rate_ankle > O_ARGUMENT_1:
  237. print("腿型可能为O型腿")
  238. result.append("腿型可能为O型腿")
  239. else:
  240. print("腿型基本正常,非X、O型腿")
  241. result.append("腿型基本正常,非X、O型腿")
  242. return result
  243. def analyse_npy_side(npy_side):
  244. result = []
  245. data = np.load(npy_side)
  246. result.append(" ")
  247. print("------------------")
  248. result.append("------------------")
  249. print("侧面分析内容如下:")
  250. result.append("侧面分析内容如下:")
  251. # for head
  252. ear_r_x = data[len(data) - 1][0]
  253. ear_r_y = data[len(data) - 1][1]
  254. shoulder_r_x = data[2][0]
  255. shoulder_r_y = data[2][1]
  256. head_forward_angle = angle([shoulder_r_x, shoulder_r_y, ear_r_x, ear_r_y, ], [0, 0, 0, -1])
  257. head_forward_level = ""
  258. head_extra_stress = 0
  259. if head_forward_angle < 90 and head_forward_angle > 0:
  260. head_extra_stress = round(cal_head_extra_stress(head_forward_angle), 3)
  261. if head_forward_angle <= HEAD_FORWARD_ARGUMENT_0:
  262. head_forward_level = ""
  263. elif head_forward_angle <= HEAD_FORWARD_ARGUMENT_1 and head_forward_angle > HEAD_FORWARD_ARGUMENT_0:
  264. head_forward_level = "轻微"
  265. elif head_forward_angle > HEAD_FORWARD_ARGUMENT_1 and head_forward_angle <= HEAD_FORWARD_ARGUMENT_2:
  266. head_forward_level = "中等"
  267. else:
  268. head_forward_level = "严重"
  269. if ear_r_x > shoulder_r_x and head_forward_level != "":
  270. print("颈椎分析:头部前倾,角度为{}度,程度{},颈椎额外承受压力为头部重量{}倍".format(round(head_forward_angle, 2), head_forward_level,
  271. head_extra_stress))
  272. result.append("颈椎分析:头部前倾,角度为{}度,程度{},颈椎额外承受压力为头部重量{}倍".format(round(head_forward_angle, 2), head_forward_level,
  273. head_extra_stress))
  274. elif ear_r_x < shoulder_r_x and head_forward_level != "":
  275. print("颈椎分析:头部后仰,角度为{}度,程度{},颈椎额外承受压力为头部重量{}倍".format(round(head_forward_angle, 2), head_forward_level,
  276. head_extra_stress))
  277. result.append("颈椎分析:头部后仰,角度为{}度,程度{},颈椎额外承受压力为头部重量{}倍".format(round(head_forward_angle, 2), head_forward_level,
  278. head_extra_stress))
  279. else:
  280. print("无头部前倾问题")
  281. result.append("无头部前倾问题")
  282. # upper part of body
  283. up_risk_level = ""
  284. up_state = ""
  285. neck_x = data[1][0]
  286. neck_y = data[1][1]
  287. ankle_r_x = data[10][0]
  288. ankle_r_y = data[10][1]
  289. up_angle = round(angle([ankle_r_x, ankle_r_y, neck_x, neck_y], [0, 0, 0, -1]), 2)
  290. if up_angle >= UP_FORWARD_ARGUMENT_0 and up_angle < UP_FORWARD_ARGUMENT_1:
  291. up_risk_level = "轻微"
  292. elif up_angle < UP_FORWARD_ARGUMENT_2 and up_angle >= UP_FORWARD_ARGUMENT_1:
  293. up_risk_level = "中度"
  294. elif up_angle >= UP_FORWARD_ARGUMENT_2:
  295. up_risk_level = "严重"
  296. else:
  297. up_risk_level = ""
  298. if neck_x < ankle_r_x and up_angle >= HIP_FORWARD_ARGUMENT_0:
  299. up_state = "身体整体后倾,程度{},身体与竖直方向角度为{}度".format(up_risk_level, up_angle)
  300. elif neck_x > ankle_r_x and up_angle >= HIP_FORWARD_ARGUMENT_0:
  301. up_state = "身体整体前倾,程度{},身体与竖直方向角度为{}度".format(up_risk_level, up_angle)
  302. else:
  303. up_state = "身体整体竖直于地面,无明显站姿前后倾斜"
  304. print("站姿分析:{}".format(up_state))
  305. result.append("站姿分析:{}".format(up_state))
  306. # for hip
  307. hip_state = ""
  308. hip_risk_level = ""
  309. hip_r_x = data[8][0]
  310. hip_r_y = data[8][1]
  311. knee_r_x = data[9][0]
  312. knee_r_y = data[9][1]
  313. hip_angle = 180 - angle([hip_r_x, hip_r_y, neck_x, neck_y], [hip_r_x, hip_r_y, knee_r_x, knee_r_y])
  314. if hip_angle >= 90:
  315. hip_angle = 180 - hip_angle
  316. if hip_angle >= HIP_FORWARD_ARGUMENT_0 and hip_angle < HIP_FORWARD_ARGUMENT_1:
  317. hip_risk_level = "轻微"
  318. elif hip_angle < HIP_FORWARD_ARGUMENT_2 and hip_angle >= HIP_FORWARD_ARGUMENT_1:
  319. hip_risk_level = "中度"
  320. elif hip_angle >= HIP_FORWARD_ARGUMENT_2:
  321. hip_risk_level = "严重"
  322. else:
  323. hip_risk_level = ""
  324. if hip_angle > 90:
  325. hip_angle = 180 - hip_angle
  326. if knee_r_x > hip_r_x and hip_angle >= HIP_FORWARD_ARGUMENT_0:
  327. hip_state = "髋部后移,程度{},躯干与腿部角度为{}度".format(hip_risk_level, round(180 - hip_angle, 2))
  328. elif knee_r_x < hip_r_x and hip_angle >= HIP_FORWARD_ARGUMENT_0:
  329. hip_state = "髋部前移,程度{},躯干与腿部角度为{}度".format(hip_risk_level, round(180 - hip_angle, 2))
  330. else:
  331. hip_state = "无明显髋部前移或后移"
  332. print("髋部分析:{}".format(hip_state))
  333. result.append("髋部分析:{}".format(hip_state))
  334. # for knee
  335. knee_angle_r = 180 - angle([hip_r_x, hip_r_y, knee_r_x, knee_r_y], [knee_r_x, knee_r_y, ankle_r_x, ankle_r_y])
  336. if knee_angle_r > 90:
  337. knee_angle_r = 180 - knee_angle_r
  338. knee_forward_risk_level = ""
  339. if knee_angle_r >= KNEE_FORWARD_ARGUMENT_0 and knee_angle_r < KNEE_FORWARD_ARGUMENT_1:
  340. knee_forward_risk_level = "轻微"
  341. elif knee_angle_r < KNEE_FORWARD_ARGUMENT_2 and knee_angle_r >= KNEE_FORWARD_ARGUMENT_1:
  342. knee_forward_risk_level = "中度"
  343. elif knee_angle_r >= KNEE_FORWARD_ARGUMENT_2:
  344. knee_forward_risk_level = "严重"
  345. else:
  346. knee_forward_risk_level = ""
  347. if knee_forward_risk_level == "":
  348. print("膝盖角度分析:膝盖无明显超伸")
  349. result.append("膝盖角度分析:膝盖无明显超伸")
  350. else:
  351. print("膝盖角度分析:下肢膝盖超伸角度为{}度,程度{}".format(round(knee_angle_r, 2), knee_forward_risk_level))
  352. result.append("膝盖角度分析:下肢膝盖超伸角度为{}度,程度{}".format(round(knee_angle_r, 2), knee_forward_risk_level))
  353. return result
  354. run_openpose_for_image_front(index)
  355. run_openpose_for_image_side(index)
  356. result_front = analyse_npy_front(source_npy_front)
  357. result_side = analyse_npy_side(source_npy_side)
  358. result = result_front + result_side
  359. text_save(save_path, result)