当前位置:   article > 正文

YOLOv8 人体姿态估计 跌倒检测_摔倒姿态估计

摔倒姿态估计

思路:

  1. pt5与pt6取中间点,记为center_up; pt11 与 pt12取中间点记为center_down,作直角三角形,直角为right_angle_point。
  2. center_up与center_down连线,right_angle_point与center_down连线,计算这线夹角的tan值,然后用tan的反函数求出夹角值。
  3. 当夹角>60度,或center_up_y <= center_down_y , 或检测框宽高比大于5/3,则为跌倒

思路来自b站视频:

Yolov7-pose跌倒检测

关键代码:

  1. void DrawPred(cv::Mat& img, std::vector<OutputPose>& results,
  2. const std::vector<std::vector<unsigned int>> &SKELLTON,
  3. const std::vector<std::vector<unsigned int>> &KPS_COLORS,
  4. const std::vector<std::vector<unsigned int>> &LIMB_COLORS)
  5. {
  6. const int num_point =17;
  7. for (auto &result:results){
  8. int left,top,width, height;
  9. left = result.box.x;
  10. top = result.box.y;
  11. width = result.box.width;
  12. height = result.box.height;
  13. // printf("x: %d y:%d w:%d h%d\n",(int)left, (int)top, (int)result.box.width, (int)result.box.height);
  14. // 框出目标
  15. rectangle(img, result.box,Scalar(0,0,255), 2, 8);
  16. // 在目标框左上角标识目标类别以及概率
  17. string label = "person:" + to_string(result.confidence) ;
  18. int baseLine;
  19. Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
  20. top = max(top, labelSize.height);
  21. putText(img, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255), 2);
  22. // 连线
  23. auto &kps = result.kps;
  24. // cout << "该目标关键点:" << kps.size() << endl;
  25. for (int k=0; k<num_point+2; k++){// 不要设置为>0.5f ,>0.0f显示效果比较好
  26. // 关键点绘制
  27. if (k<num_point){
  28. int kps_x = std::round(kps[k*3]);
  29. int kps_y = std::round(kps[k*3 + 1]);
  30. float kps_s = kps[k*3 + 2];
  31. // printf("x:%d y:%d s:%f\n", kps_x, kps_y, kps_s);
  32. if (kps_s > 0.0f){
  33. cv::Scalar kps_color = Scalar(KPS_COLORS[k][0],KPS_COLORS[k][1],KPS_COLORS[k][2]);
  34. cv::circle(img, {kps_x, kps_y}, 5, kps_color, -1);
  35. }
  36. }
  37. auto &ske = SKELLTON[k];
  38. int pos1_x = std::round(kps[(ske[0] -1) * 3]);
  39. int pos1_y = std::round(kps[(ske[0] -1) * 3 + 1]);
  40. int pos2_x = std::round(kps[(ske[1] -1) * 3]);
  41. int pos2_y = std::round(kps[(ske[1] -1) * 3 + 1]);
  42. float pos1_s = kps[(ske[0] -1) * 3 + 2];
  43. float pos2_s = kps[(ske[1] -1) * 3 + 2];
  44. if (pos1_s > 0.0f && pos2_s >0.0f){// 不要设置为>0.5f ,>0.0f显示效果比较好
  45. cv::Scalar limb_color = cv::Scalar(LIMB_COLORS[k][0], LIMB_COLORS[k][1], LIMB_COLORS[k][3]);
  46. cv::line(img, {pos1_x, pos1_y}, {pos2_x, pos2_y}, limb_color);
  47. }
  48. // 跌倒检测
  49. float pt5_x = kps[5*3];
  50. float pt5_y = kps[5*3 + 1];
  51. float pt6_x = kps[6*3];
  52. float pt6_y = kps[6*3+1];
  53. float center_up_x = (pt5_x + pt6_x) /2.0f ;
  54. float center_up_y = (pt5_y + pt6_y) / 2.0f;
  55. Point center_up = Point((int)center_up_x, (int)center_up_y);
  56. float pt11_x = kps[11*3];
  57. float pt11_y = kps[11*3 + 1];
  58. float pt12_x = kps[12*3];
  59. float pt12_y = kps[12*3 + 1];
  60. float center_down_x = (pt11_x + pt12_x) / 2.0f;
  61. float center_down_y = (pt11_y + pt12_y) / 2.0f;
  62. Point center_down = Point((int)center_down_x, (int)center_down_y);
  63. float right_angle_point_x = center_down_x;
  64. float righ_angle_point_y = center_up_y;
  65. Point right_angl_point = Point((int)right_angle_point_x, (int)righ_angle_point_y);
  66. float a = abs(right_angle_point_x - center_up_x);
  67. float b = abs(center_down_y - righ_angle_point_y);
  68. float tan_value = a / b;
  69. float Pi = acos(-1);
  70. float angle = atan(tan_value) * 180.0f/ Pi;
  71. string angel_label = "angle: " + to_string(angle);
  72. putText(img, angel_label, Point(left, top-40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255), 2);
  73. if (angle > 60.0f || center_down_y <= center_up_y || (double)width/ height > 5.0f/3.0f) // 宽高比小于0.6为站立,大于5/3为跌倒
  74. {
  75. string fall_down_label = "person fall down!!!!";
  76. putText(img, fall_down_label , Point(left, top-20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255), 2);
  77. printf("angel:%f width/height:%f\n",angle, (double)width/ height );
  78. }
  79. cv::line(img, center_up, center_down,
  80. Scalar(0,0,255), 2, 8);
  81. cv::line(img, center_up, right_angl_point,
  82. Scalar(0,0,255), 2, 8);
  83. cv::line(img, right_angl_point, center_down,
  84. Scalar(0,0,255), 2, 8);
  85. }
  86. }
  87. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/133613
推荐阅读
相关标签
  

闽ICP备14008679号