analyse_by_npy.py 17 KB

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