• 运动车辆检测


    【转】源码来自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版本!!!

  • 相关阅读:
    FunctionGraph无缝集成Express应用
    三分钟迁移Spring boot工程到Serverless
    分布式数据库中间件使用经验分享
    基于OAS设计可扩展OpenAPI
    从一次小哥哥与小姐姐的转账开始, 浅谈分布式事务从理论到实践
    分布式数据库DDM Sidecar模式负载均衡
    Redis缓存数据库安全加固指导(二)
    数据存储课后作业
    GrideVlew提供点击按钮添加新数据,单击项目修改,长按删除功能
    AutoCompleteTextView,Spinner,消息提示
  • 原文地址:https://www.cnblogs.com/beihaidao/p/5675769.html
Copyright © 2020-2023  润新知