【转】源码来自csdn下载
1 #include <string> 2 #include <iostream> 3 #include <stdio.h> 4 #include <fstream> 5 #include<math.h> 6 7 #include <opencv2opencv.hpp> 8 #include <opencv2highguihighgui.hpp> 9 #include <opencv2imgprocimgproc.hpp> 10 #include <opencv2corecore.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版本!!!