车辆检测计数算法是一个经典的算法,可以使用目标跟踪+目标识别的方案来解决。
但是经过几天的调研后,我发现了一种简单的解决方案。
https://blog.csdn.net/taifyang/article/details/128264192
只需要前后两帧做一个最短路径匹配,然后利用直线与检测点是否相交,进行车辆计数。
这样的好处是显然易见的,足够简单并且依据也符合常理。
下面给出了一段我自己编写的计数函数:
void MarkNumber(vector<vector<Detection>> &new_det, vector<vector<Detection>> &old_det) { if (old_det.size() == 0) { old_det = new_det; return; } vector<vector<float>> dis_matrix; vector<Rect> new_rct; vector<Rect> old_rct; for (const auto& detection : new_det[0]) { cv::Rect temp; temp.x = (double)detection.bbox.x; temp.y = (double)detection.bbox.y;// - ori_center.y+ detection.bbox.height/2.0 temp.height = (double)detection.bbox.height; temp.width = (double)detection.bbox.width; new_rct.push_back(temp); } for (const auto& detection : old_det[0]) { cv::Rect temp; temp.x = (double)detection.bbox.x; temp.y = (double)detection.bbox.y;// - ori_center.y+ detection.bbox.height/2.0 temp.height = (double)detection.bbox.height; temp.width = (double)detection.bbox.width; old_rct.push_back(temp); } for (int i = 0; i < new_rct.size(); i++) { vector<float> dis_vec; for (int j = 0; j < old_rct.size(); j++) { Point new_center = Point(new_rct[i].x + new_rct[i].width / 2, new_rct[i].y + new_rct[i].height / 2); Point old_center = Point(old_rct[j].x + old_rct[j].width / 2, old_rct[j].y + old_rct[j].height / 2); float temp_dis = sqrt(pow(new_center.x - old_center.x, 2) + pow(new_center.y - old_center.y, 2)); dis_vec.push_back(temp_dis); } dis_matrix.push_back(dis_vec); } for (int i = 0; i < new_rct.size(); i++) { int min_index= std::min_element(dis_matrix[i].begin(), dis_matrix[i].end()) - dis_matrix[i].begin(); if (dis_matrix[i][min_index]< max_dis && dis_matrix[i][min_index] > min_dis) { Point new_center = Point(new_rct[i].x + new_rct[i].width / 2, new_rct[i].y + new_rct[i].height / 2); Point old_center = Point(old_rct[min_index].x + old_rct[min_index].width / 2, old_rct[min_index].y + old_rct[min_index].height / 2); float tx=new_center.x - old_center.x; float ty = new_center.y - old_center.y; if (vector_x * tx + vector_y * ty > 0) { cv::Mat A = cv::Mat::zeros(2,2,CV_32F); A.at<float>(0, 0) = old_center.y-new_center.y; A.at<float>(0, 1) = new_center.x - old_center.x; A.at<float>(1, 0) = line_pt[0].y - line_pt[1].y; A.at<float>(1, 1) = line_pt[1].x - line_pt[1].x; cv::Mat B = cv::Mat::zeros(2, 1, CV_32F); B.at<float>(0, 0) = old_center.y * new_center.x- old_center.x * new_center.y; B.at<float>(1, 0) = line_pt[0].y * line_pt[1].x - line_pt[0].x * line_pt[1].y; cv::Mat theta = A.inv() * B; float theta_x = theta.at<float>(0, 0); float theta_y = theta.at<float>(1, 0); if (theta_x >= min(line_pt[0].x, line_pt[1].x) && theta_y >= min(line_pt[0].y, line_pt[1].y) && theta_x <= max(line_pt[0].x, line_pt[1].x) && theta_y <= max(line_pt[0].y, line_pt[1].y)) { count++; } } } } auto tt = std::chrono::system_clock::to_time_t (std::chrono::system_clock::now()); struct tm* ptm = new tm(); localtime_s(ptm, &tt); if (ptm->tm_hour ==0 && ptm->tm_min == 0) { count = 0; } }
标签:old,center,temp,rct,检测,计数,算法,new,dis From: https://www.cnblogs.com/xmds/p/17893807.html