运动车辆检测

【转】源码来自csdn下载

  1 #include <string>
  2 #include <iostream>
  3 #include <stdio.h>
  4 #include <fstream>
  5 #include<math.h>
  6 
  7 #include <opencv2\opencv.hpp>
  8 #include <opencv2\highgui\highgui.hpp>
  9 #include <opencv2\imgproc\imgproc.hpp>
 10 #include <opencv2\core\core.hpp>
 11 
 12 using namespace std;
 13 using namespace cv;
 14 void main()
 15 {
 16     // TODO: Add your control notification handler code here
 17 
 18 
 19     //定义
 20     IplImage* pFrame = NULL;
 21     IplImage* pFrImg = NULL;
 22     IplImage* pBkImg = NULL;
 23     IplImage* pFrImg1 = NULL;
 24 
 25     CvMat* pFrameMat = NULL;
 26     CvMat* pFrMat = NULL;
 27     CvMat* pBkMat = NULL;
 28     CvMat* pFrMat1 = NULL;
 29 
 30     CvMemStorage * storage = cvCreateMemStorage(0);//轮廓边缘提取时的参数
 31     CvSeq * contour = 0;//轮廓边缘提取时的参数
 32     int mode = CV_RETR_EXTERNAL;//轮廓边缘提取时的参数
 33     //形态学处理时内核的大小
 34     IplConvKernel* Element = cvCreateStructuringElementEx(13, 13, 1, 1, CV_SHAPE_RECT, NULL);
 35     
 36     //在视频中画出感兴趣的区域,怎么样才能沿车道画线???????
 37     CvPoint pt1, pt2, pt3, pt4, pt5;
 38 
 39     pt1.x = 292;//(视频中左下点)
 40     pt1.y = 100;
 41     pt2.x = 412;//(视频中右上点)
 42     pt2.y = 280;
 43 
 44     CvRect bndRect = cvRect(0, 0, 0, 0);//用cvBoundingRect画出外接矩形时需要的矩形
 45     int avgX = 0;//The midpoint X position of the rectangle surrounding the moving objects
 46     int avgY = 0;//The midpoint Y position of the rectangle surrounding the moving objects
 47     int avgX1 = 0;//用来合并相近的车辆
 48     int avgY1 = 0;
 49 
 50     CvCapture* pCapture = NULL;
 51     int nFrmNum = 0;//表示图像的帧数
 52 
 53     //创建窗口
 54     cvNamedWindow("video", 1);
 55     cvNamedWindow("foreground", 1);
 56     cvMoveWindow("video", 30, 0);
 57     cvMoveWindow("foreground", 690, 0);
 58 
 59 
 60     pCapture = cvCaptureFromFile("a.avi");
 61     pFrame = cvQueryFrame(pCapture);
 62 
 63     int widthT, heightT;
 64     widthT = pFrame->width;
 65     heightT = pFrame->height;
 66 
 67 
 68 
 69     IplImage* pFrameTemp = cvQueryFrame(pCapture);
 70     pFrame = cvCreateImage(cvGetSize(pFrameTemp), 8, 3);
 71     cvCopy(pFrameTemp, pFrame);
 72 
 73     //逐帧读取视频,cvQueryFrame从摄像头或者文件中抓取并返回一帧
 74     while (pFrameTemp = cvQueryFrame(pCapture))
 75     {
 76         //cvFlip(pFrameTemp);
 77 
 78         cvCopy(pFrameTemp, pFrame);
 79         nFrmNum++;
 80 
 81 
 82 
 83         //如果是第一帧,需要申请内存,并初始化
 84         if (nFrmNum == 1)
 85         {
 86             pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
 87             pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
 88 
 89             pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
 90             pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
 91             pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
 92             cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
 93             cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
 94             cvConvert(pFrImg, pFrameMat);
 95             cvConvert(pFrImg, pFrMat);
 96             cvConvert(pFrImg, pBkMat);
 97         }
 98 
 99         else if (nFrmNum == 3)
100         {
101             cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
102             cvConvert(pFrImg, pFrameMat);
103             //高斯滤波先,以平滑图像
104             cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
105 
106             //在视频中设置并画出感兴趣的区域
107             cvRectangle(pFrame, pt1, pt2, CV_RGB(255, 0, 0), 2, 8, 0);
108 
109             //当前帧跟背景图相减,cvAbsDiff计算两个数组差的绝对值
110             cvAbsDiff(pFrameMat, pBkMat, pFrMat);
111 
112             //二值化前景图
113             cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
114 
115             //通过查找边界找出ROI矩形区域内的运动车辆,建立完全目标档案
116 
117             cvDilate(pFrImg, pBkImg, Element, 1);
118             cvFindContours(pBkImg, storage, &contour, sizeof(CvContour), mode, CV_CHAIN_APPROX_SIMPLE);
119             //process each moving contour in the current frame用函数cvBoundingRect
120             for (; contour != 0; contour = contour->h_next)
121             {
122                 //Get a bounding rectangle around the moving object.
123                 bndRect = cvBoundingRect(contour, 0);
124 
125                 //Get an average X position of the moving contour.
126                 avgX = (bndRect.x + bndRect.x + bndRect.width) / 2;
127                 avgY = (bndRect.y + bndRect.y + bndRect.height) / 2;
128                 pt5.x = bndRect.x;//写字的左下角点
129                 pt5.y = avgY;
130 
131                 //If the center of contour is within ROI than show it
132                 if (avgX>300 && avgX<400 && avgY<300 && avgY>80)
133                 {
134                     pt3.x = bndRect.x;
135                     pt3.y = bndRect.y;
136                     pt4.x = bndRect.x + bndRect.width;
137                     pt4.y = bndRect.y + bndRect.height;
138                     if (bndRect.height>35) //把长度小于某个阀值的干扰矩形去掉
139                     {
140                         cvRectangle(pFrame, pt3, pt4, CV_RGB(255, 0, 0), 1, 8, 0);
141 
142                     }
143                 }
144             }/////查找边界的for 循环结束        
145 
146             //更新背景///////////////////////////////////////////////////
147             cvRunningAvg(pFrameMat, pBkMat, 0.005, 0);
148             //将背景转化为图像格式,用以显示
149             cvConvert(pBkMat, pBkImg);
150 
151             //显示图像////////////////////////////////////////////////////
152             cvShowImage("video", pFrameTemp);
153             cvShowImage("background", pBkImg);
154             cvShowImage("foreground", pFrImg);
155 
156             //如果有按键事件,则跳出循环,此等待也为cvShowImage函数提供时间完成显示,等待时间可以根据CPU速度调整
157             if (cvWaitKey(2) >= 0)
158                 break;
159         }
160 
161         else if (nFrmNum > 3)//从第三帧开始,根据完全目标档案来新增或删除运动车辆档案。
162         {
163             cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
164             cvConvert(pFrImg, pFrameMat);
165             //高斯滤波先,以平滑图像
166             cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
167 
168             //在视频中设置并画出感兴趣的区域
169             //cvSetImageROI(pFrame,rect1);
170             cvRectangle(pFrame, pt1, pt2, CV_RGB(255, 0, 0), 2, 8, 0);
171 
172             //当前帧跟背景图相减,cvAbsDiff计算两个数组差的绝对值
173             cvAbsDiff(pFrameMat, pBkMat, pFrMat);
174 
175             //二值化前景图,void cvThreshold( const CvArr* src, CvArr* dst, double threshold,
176             //double max_value, int threshold_type );
177             cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
178 
179             //通过查找边界找出ROI矩形区域内的运动车辆,建立完全目标档案
180             //cvCanny(pFrImg, pBkImg, 50, 150, 3);
181             cvDilate(pFrImg, pBkImg, Element, 1);
182             cvFindContours(pBkImg, storage, &contour, sizeof(CvContour),
183                 mode, CV_CHAIN_APPROX_SIMPLE);
184             //process each moving contour in the current frame用函数cvBoundingRect
185             for (; contour != 0; contour = contour->h_next)
186             {
187                 //Get a bounding rectangle around the moving object.
188                 bndRect = cvBoundingRect(contour, 0);
189 
190                 //Get an average X position of the moving contour.
191                 avgX = (bndRect.x + bndRect.x + bndRect.width) / 2;
192                 avgY = (bndRect.y + bndRect.y + bndRect.height) / 2;
193                 pt5.x = bndRect.x;//写字的左下角点
194                 pt5.y = avgY;
195 
196                 //If the center of contour is within ROI than show it
197                 if (avgX > 300 && avgX < 400 && avgY < 280 && avgY > 100)
198                 {
199                     pt3.x = bndRect.x;
200                     pt3.y = bndRect.y;
201                     pt4.x = bndRect.x + bndRect.width;
202                     pt4.y = bndRect.y + bndRect.height;
203                     if (bndRect.height>35) //把长度小于某个阀值的干扰矩形去掉
204                     {
205                         cvRectangle(pFrame, pt3, pt4, CV_RGB(225, 0, 0), 1, 8, 0);
206                     }
207                 }
208             }//轮廓分for循环结束
209 
210 
211             //更新背景///////////////////////////////////////////////////
212             cvRunningAvg(pFrameMat, pBkMat, 0.005, 0);
213             //将背景转化为图像格式,用以显示
214             cvConvert(pBkMat, pBkImg);
215 
216             //显示图像////////////////////////////////////////////////////
217             cvShowImage("video", pFrame);
218             cvShowImage("background", pBkImg);
219             cvShowImage("foreground", pFrImg);
220 
221             /*if(nFrmNum/2 ==0)
222             pBkMat=pFrameMat;*/
223             //如果有按键事件,则跳出循环,此等待也为cvShowImage函数提供时间完成显示,等待时间可以根据CPU速度调整
224             if (cvWaitKey(2) >= 0)
225                 break;
226         }//
227     }//while循环结束
228 
229     cvReleaseStructuringElement(&Element);//删除结构元素
230     //销毁窗口
231     cvDestroyWindow("video");
232     cvDestroyWindow("background");
233     cvDestroyWindow("foreground");
234 
235     //释放图像和矩阵
236     cvReleaseImage(&pFrImg);
237     cvReleaseImage(&pBkImg);
238 
239     cvReleaseMat(&pFrameMat);
240     cvReleaseMat(&pFrMat);
241     cvReleaseMat(&pBkMat);
242 }

效果如下:

代码还是比较旧的。。。c版本!!!

posted on 2016-07-16 10:46  北海盗  阅读(652)  评论(0编辑  收藏  举报