赞
踩
思路:
思路来自b站视频:
Yolov7-pose跌倒检测
关键代码:
- void DrawPred(cv::Mat& img, std::vector<OutputPose>& results,
- const std::vector<std::vector<unsigned int>> &SKELLTON,
- const std::vector<std::vector<unsigned int>> &KPS_COLORS,
- const std::vector<std::vector<unsigned int>> &LIMB_COLORS)
- {
- const int num_point =17;
- for (auto &result:results){
- int left,top,width, height;
- left = result.box.x;
- top = result.box.y;
- width = result.box.width;
- height = result.box.height;
-
-
- // printf("x: %d y:%d w:%d h%d\n",(int)left, (int)top, (int)result.box.width, (int)result.box.height);
-
- // 框出目标
- rectangle(img, result.box,Scalar(0,0,255), 2, 8);
-
- // 在目标框左上角标识目标类别以及概率
- string label = "person:" + to_string(result.confidence) ;
- int baseLine;
- Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
- top = max(top, labelSize.height);
- putText(img, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255), 2);
-
- // 连线
- auto &kps = result.kps;
- // cout << "该目标关键点:" << kps.size() << endl;
- for (int k=0; k<num_point+2; k++){// 不要设置为>0.5f ,>0.0f显示效果比较好
- // 关键点绘制
- if (k<num_point){
- int kps_x = std::round(kps[k*3]);
- int kps_y = std::round(kps[k*3 + 1]);
- float kps_s = kps[k*3 + 2];
-
- // printf("x:%d y:%d s:%f\n", kps_x, kps_y, kps_s);
-
- if (kps_s > 0.0f){
- cv::Scalar kps_color = Scalar(KPS_COLORS[k][0],KPS_COLORS[k][1],KPS_COLORS[k][2]);
- cv::circle(img, {kps_x, kps_y}, 5, kps_color, -1);
- }
- }
-
- auto &ske = SKELLTON[k];
- int pos1_x = std::round(kps[(ske[0] -1) * 3]);
- int pos1_y = std::round(kps[(ske[0] -1) * 3 + 1]);
-
- int pos2_x = std::round(kps[(ske[1] -1) * 3]);
- int pos2_y = std::round(kps[(ske[1] -1) * 3 + 1]);
-
- float pos1_s = kps[(ske[0] -1) * 3 + 2];
- float pos2_s = kps[(ske[1] -1) * 3 + 2];
-
- if (pos1_s > 0.0f && pos2_s >0.0f){// 不要设置为>0.5f ,>0.0f显示效果比较好
- cv::Scalar limb_color = cv::Scalar(LIMB_COLORS[k][0], LIMB_COLORS[k][1], LIMB_COLORS[k][3]);
- cv::line(img, {pos1_x, pos1_y}, {pos2_x, pos2_y}, limb_color);
- }
-
- // 跌倒检测
- float pt5_x = kps[5*3];
- float pt5_y = kps[5*3 + 1];
- float pt6_x = kps[6*3];
- float pt6_y = kps[6*3+1];
- float center_up_x = (pt5_x + pt6_x) /2.0f ;
- float center_up_y = (pt5_y + pt6_y) / 2.0f;
- Point center_up = Point((int)center_up_x, (int)center_up_y);
-
- float pt11_x = kps[11*3];
- float pt11_y = kps[11*3 + 1];
- float pt12_x = kps[12*3];
- float pt12_y = kps[12*3 + 1];
- float center_down_x = (pt11_x + pt12_x) / 2.0f;
- float center_down_y = (pt11_y + pt12_y) / 2.0f;
- Point center_down = Point((int)center_down_x, (int)center_down_y);
-
-
- float right_angle_point_x = center_down_x;
- float righ_angle_point_y = center_up_y;
- Point right_angl_point = Point((int)right_angle_point_x, (int)righ_angle_point_y);
-
-
- float a = abs(right_angle_point_x - center_up_x);
- float b = abs(center_down_y - righ_angle_point_y);
-
- float tan_value = a / b;
- float Pi = acos(-1);
- float angle = atan(tan_value) * 180.0f/ Pi;
- string angel_label = "angle: " + to_string(angle);
- putText(img, angel_label, Point(left, top-40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255), 2);
-
- if (angle > 60.0f || center_down_y <= center_up_y || (double)width/ height > 5.0f/3.0f) // 宽高比小于0.6为站立,大于5/3为跌倒
- {
- string fall_down_label = "person fall down!!!!";
- putText(img, fall_down_label , Point(left, top-20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,255), 2);
-
- printf("angel:%f width/height:%f\n",angle, (double)width/ height );
- }
-
-
-
-
-
-
- cv::line(img, center_up, center_down,
- Scalar(0,0,255), 2, 8);
- cv::line(img, center_up, right_angl_point,
- Scalar(0,0,255), 2, 8);
- cv::line(img, right_angl_point, center_down,
- Scalar(0,0,255), 2, 8);
-
-
-
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。