600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 车辆的检测 跟踪和计数

车辆的检测 跟踪和计数

时间:2021-12-04 02:29:14

相关推荐

车辆的检测 跟踪和计数

【算法的步骤】

1、首先画出感兴趣区域

2、对进入感兴趣区域的车辆进行前灯的检测,跟踪和计数

感兴趣区域的划分,在视频处理中有着重要应用,在视频中标注感兴趣区域的方法:

暂停视频或者在视频流的第一帧中,画出感兴趣区域

#include<opencv2\core\core.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> using namespace cv; #include<iostream> #include<vector> using namespace std; /*----定义鼠标事件--画矩形区域:作用当两个车灯----*/ //第一步:全局变量 bool drawing_box = false; bool gotBox = false; Rect box; Point downPoint; /*void mouseRectHandler(int event, int x, int y, int flags, void *param){switch (event){case CV_EVENT_MOUSEMOVE:if (drawing_box){box.width = x - box.x;box.height = y - box.y;}break;case CV_EVENT_LBUTTONDOWN:drawing_box = true;box = Rect(x, y, 0, 0);break;case CV_EVENT_LBUTTONUP:drawing_box = false;gotBox = true;if (box.width < 0){box.x += box.width;box.width *= -1;}if( box.height < 0 ){box.y += box.height;box.height *= -1;}break;default:break;}}*/ void mouseRectHandler(int event, int x, int y, int flags, void *param) { switch (event) { case CV_EVENT_MOUSEMOVE: if (drawing_box) { //鼠标的移动到downPoint的右下角 if( x >=downPoint.x && y >= downPoint.y) { box.x = downPoint.x; box.y = downPoint.y; box.width = x - downPoint.x; box.height = y - downPoint.y; } //鼠标的移动到downPoint的右上角 if( x >= downPoint.x && y <= downPoint.y) { box.x = downPoint.x; box.y = y; box.width = x - downPoint.x; box.height = downPoint.y - y; } //鼠标的移动到downPoint的左上角 if( x <= downPoint.x && y <= downPoint.y) { box.x = x; box.y = y; box.width = downPoint.x - x; box.height = downPoint.y - y; } //鼠标的移动到downPoint的左下角 if( x <= downPoint.x && y >= downPoint.y) { box.x = x; box.y = downPoint.y; box.width = downPoint.x -x; box.height = y - downPoint.y; } } break; case CV_EVENT_LBUTTONDOWN: //按下鼠标,代表可以可以开始画矩形 drawing_box = true; //记录起点 downPoint = Point(x,y); break; case CV_EVENT_LBUTTONUP: //松开鼠标,代表结束画矩形 drawing_box = false; gotBox = true; break; default: break; } } int main(int argc,char*argv[]) { //读取视频 VideoCapture video(argv[1]); //判断视频是否打开 if( !video.isOpened()) return 0; //视频中的第一帧 Mat firstFrame; Mat frame; //读取视频的第一帧 video>>frame; //复制到firstFrame中 frame.copyTo(firstFrame); //registernamedWindow("video",1); setMouseCallback("video",mouseRectHandler,NULL); //画感兴趣区域 while(!gotBox) { firstFrame.copyTo(frame); rectangle(frame,box,Scalar(255,0,0),2);//画出感兴趣区域 imshow("video",frame); if(waitKey(50) == 'q')//---------很重要 break; } //remove callback setMouseCallback("video",NULL,NULL); //视频继续 for(;;) { //读取视频 video>>frame; //判断是否有当前帧 if(!frame.data) break; //画出感兴趣区域 rectangle(frame,box,Scalar(255,255,0),2); imshow("video",frame); if(waitKey(33) == 'q') break; } return 0; }

框定感兴趣区域之后开始检测,计数,完整代码如下:

#include<iostream>using namespace std;#include<string>#include<opencv2/core/core.hpp>#include<opencv2/highgui/highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>using namespace cv;//Trackbar控制的变量及该值的最大值int thresh = 200;const int MAX_THRESH = 255;//Trackbar控制的函数void thresh_callback(int,void*);int w_h = 25;const int MAX_W_H = 100;int vehicleFrequency = 2;//这个值不能过于大,否则拍到的车辆里,没有车牌const int MAX_VEHICLEFREQUENCY = 15;//全局标量Mat frame;//原视频流的帧Mat grayFrame;//颜色空间转化Mat binaryFrame;//二值化Mat kernel;//进行形态学处理的核函数Rect box_vehicle;bool vehicleBool;//判断是否有车辆//存储边缘vector<vector<Point> > contours;vector<Vec4i> hierarchy;Rect vehicleRect;//通过前灯检测,定位出来的车辆/*----定义鼠标事件--画矩形区域:作用当两个车灯----*///第一步:全局变量bool drawing_box = false;bool gotBox = false;Rect box;Point downPoint;void mouseRectHandler(int event, int x, int y, int flags, void *param){switch (event){case CV_EVENT_MOUSEMOVE:if (drawing_box){//鼠标的移动到downPoint的右下角if( x >=downPoint.x && y >= downPoint.y){box.x = downPoint.x;box.y = downPoint.y;box.width = x - downPoint.x;box.height = y - downPoint.y;}//鼠标的移动到downPoint的右上角if( x >= downPoint.x && y <= downPoint.y){box.x = downPoint.x;box.y = y;box.width = x - downPoint.x;box.height = downPoint.y - y;}//鼠标的移动到downPoint的左上角if( x <= downPoint.x && y <= downPoint.y){box.x = x;box.y = y;box.width = downPoint.x - x;box.height = downPoint.y - y;}//鼠标的移动到downPoint的左下角if( x <= downPoint.x && y >= downPoint.y){box.x = x;box.y = downPoint.y;box.width = downPoint.x -x;box.height = y - downPoint.y;}}break;case CV_EVENT_LBUTTONDOWN://按下鼠标,代表可以可以开始画矩形drawing_box = true;//记录起点downPoint = Point(x,y);break;case CV_EVENT_LBUTTONUP://松开鼠标,代表结束画矩形drawing_box = false;gotBox = true;break;default:break;}}int main(){//视频流的输入VideoCapture video("1.avi");if( !video.isOpened())return -1;//得到形态学处理的kernelkernel = getStructuringElement(MORPH_CROSS,Size(3,3),Point(-1,-1));//register,注册鼠标事件namedWindow("video",CV_WINDOW_AUTOSIZE);setMouseCallback("video",mouseRectHandler,NULL);//输出视频流,并同时画出感兴趣区域for(;;){video>>frame;if(!frame.data)break;//控制阈值createTrackbar("前灯检测:","video",&thresh,MAX_THRESH,thresh_callback);thresh_callback( 0, 0 );//这一行很重要//去除面积过小的createTrackbar("面积:","video",&w_h,MAX_W_H,thresh_callback);thresh_callback( 0, 0 );//代表一辆车,如果出现的频数大于createTrackbar("频数:","video",&vehicleFrequency,MAX_VEHICLEFREQUENCY,NULL);//当得到box时,去除setMouseCallbackif(gotBox){setMouseCallback("video",NULL,NULL);break;}rectangle(frame,box,Scalar(255,0,0),2);//画出感兴趣区域imshow("video",frame);if(waitKey(33) == 'q')break;}//用于跟踪算法和计数bool currentVehicleBool = false;bool previousVehicleBool = false;int numberVehicle = 0;//用于记录每一辆车的的帧数,避免是一闪而过的,可能不是车辆int numberVehicleFrame = 1;int currentVehicleNumber = 0;int previousVehicleNumber = 0;//以上画出感兴趣区域,以下可以判断是否为车辆for(;;){vehicleRect.width = 0;vehicleRect.height = 0;video >> frame;if(!frame.data)break;//颜色空间转换CV_Assert(frame.channels() == 3);cvtColor(frame,grayFrame,COLOR_BGR2GRAY);//控制阈值createTrackbar("前灯检测:","video",&thresh,MAX_THRESH,thresh_callback);thresh_callback( 0, 0 );//这一行很重要//去除面积过小的createTrackbar("面积:","video",&w_h,MAX_W_H,thresh_callback);thresh_callback( 0, 0 );createTrackbar("频数:","video",&vehicleFrequency,MAX_VEHICLEFREQUENCY,NULL);//画出感兴趣区域rectangle(frame,box,Scalar(255,255,0),2);//画出检测到的前灯rectangle(frame,vehicleRect,Scalar(0,255,0),2);//判断vehicleRect和box是否相交,来判断是否有车辆box_vehicle = box & vehicleRect;//显示二值化imshow("二值化",binaryFrame);if(box_vehicle.width >0 && vehicleRect.height > 0){currentVehicleBool = true;if( previousVehicleBool ==false ){//代表这是第几辆车numberVehicle++;//记录当前帧的车辆的标号currentVehicleNumber = numberVehicle;}//用于计数,该辆车出现的帧数if( currentVehicleNumber == previousVehicleNumber ){numberVehicleFrame ++;if( numberVehicleFrame == vehicleFrequency+1){cout << "抓拍" << endl;//imshow("抓拍",frame);//保存图片}}}else{currentVehicleBool = false;//将归为1,重新计数numberVehicleFrame = 1;}//记录上一帧的是否有车辆previousVehicleBool = currentVehicleBool;//记录上一帧,车辆的标号(number)previousVehicleNumber = currentVehicleNumber;//显示图片imshow("video",frame);cout<<currentVehicleNumber;if(waitKey(33) == 'q')break;}return 0;}void thresh_callback(int,void*)//得到新的vehicleRect{if(!grayFrame.data)return;//阈值处理threshold(grayFrame,binaryFrame,double(thresh),255.0,THRESH_BINARY);//均值滤波medianBlur(binaryFrame,binaryFrame,5);//形态学处理morphologyEx(binaryFrame,binaryFrame,MORPH_OPEN,kernel,Point(-1,-1),7,BORDER_REPLICATE);//存储边缘vector<vector<Point> > contours;vector<Vec4i> hierarchy;//找到边缘,注意为什么先把binaryFrame克隆一遍Mat tempBinaryFrame = binaryFrame.clone();findContours( tempBinaryFrame,contours,hierarchy, CV_RETR_TREE , CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );//注意这个findContours中binaryImage既是输入又是输出vector<vector<Point> > contours_poly( contours.size() );//存储vector<Rect> boundRect;boundRect.clear();for(int index = 0;index < contours.size(); index++){approxPolyDP( Mat(contours[index]), contours_poly[index], 3, true );Rect rect = boundingRect( Mat(contours_poly[index]) );//做筛选(去除较小的w_h)continue;boundRect.push_back(rect);}//得到整个汽车前灯轮廓for(int index = 0;index < boundRect.size() ;index++){if(index ==0)vehicleRect = boundRect[0];elsevehicleRect = vehicleRect | boundRect[index];//得到最大的矩形}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。