基于背景差分的流量监测

初学opencv,这是我做的第一个小项目,其实原理很简单,我就贴出来与大家分享下,希望能对新手有些帮助,但是这个小项目还不是很成熟,希望大神们可以踊跃的提出建议。

 

 

这个项目其实和运动物体的检测很相似,只是在其基础上做了一些改进,具体的步骤:

 

一。取第一帧图像作为背景图

二.取后来的每一帧与第一帧进行差值运算得到差分图,对差值图进行阈值处理,

三。调用求二值图像轮廓的函数对差值图求轮廓,如果轮廓数大于1,则有物体进入,计数加一,但是在程序中要进入一个循环,避免物体进入后还没离开造成的不断计数

 

具体的程序实现:

/************************************************************
        定义窗口
**************************************************************/
 
    cvNamedWindow("haiyingyang" , 1);

 /*******************************************88
    声明定义程序中所需要的数据结构以及一些函数所需要的参数
    ****************************************************************/

 CvCapture *capture = 0;
 IplImage *pbkimage = 0;
 int flow = 0; 
 int number = 1;
 int contour_number;
 capture = cvCaptureFromCAM(0);
 IplImage * image = 0;
 IplImage *pfrimage = 0;
 CvMat *pfrmat;
 CvMat *pframemat;
 CvMemStorage *storage = cvCreateMemStorage(0);
 CvSeq *cont = 0;
 CvMat *pbkmat;

 
 /**************************************************************
               程序主体部分,完成计数功能
      ******************************************************/

  capture = cvCaptureFromCAM(0);
    

     
 /********************************************************************************
 用以后的帧不断的减去前一帧,对得到的差值图进行轮廓提取,如果有轮廓则有物体进入
 ************************************************************************************/
     for(; ;)
     {
      image= cvQueryFrame(capture);
      int n =1;
      if(number == 1)
      {
         /************************************************************
           下面的if语句取首帧图像作为背景图
  ***************************************************************/
     pfrimage = cvCreateImage(cvGetSize(image) , IPL_DEPTH_8U , 1);
     pbkimage = cvCreateImage(cvGetSize(image) , IPL_DEPTH_8U , 1);
     pfrmat = cvCreateMat(image->height  , image->width  , CV_32FC1);
     pbkmat = cvCreateMat(image->height  , image->width  , CV_32FC1);
     pframemat = cvCreateMat(image->height  , image->width  , CV_32FC1);
     cvCvtColor(image , pfrimage , CV_BGR2GRAY);
     cvCvtColor(image , pbkimage , CV_BGR2GRAY);
     cvConvert(pbkimage , pbkmat);
     number = 0;
      }
 else 
 {
    CvMemStorage *storage = cvCreateMemStorage(0);
       CvSeq *cont = 0;
    image = cvQueryFrame(capture);
    cvShowImage("haiyingyang" , image);
          cvCvtColor(image , pfrimage , CV_BGR2GRAY);
          cvConvert(pfrimage , pframemat);
    cvAbsDiff(pframemat , pbkmat , pfrmat);
    cvThreshold(pfrmat , pfrimage ,180 , 255 , CV_THRESH_BINARY);
    contour_number = cvFindContours(pfrimage , storage , &cont , sizeof(CvContour) , CV_RETR_CCOMP , CV_CHAIN_APPROX_SIMPLE);
    while(contour_number)
   {
                if(n == 1)
    {
     flow++;
     printf("current flow number:%d/n" , flow);
     n = 0;
    }

    image = cvQueryFrame(capture);
    cvShowImage("haiyingyang" , image);
    cvCvtColor(image , pfrimage , CV_BGR2GRAY);
                cvConvert(pfrimage , pframemat);
       cvAbsDiff(pframemat , pbkmat , pfrmat);
       cvThreshold(pfrmat , pfrimage , 180 , 255 , CV_THRESH_BINARY);
    contour_number = cvFindContours(pfrimage , storage , &cont , sizeof(CvContour) , CV_RETR_CCOMP , CV_CHAIN_APPROX_SIMPLE);
   }

      }
   

  if(cvWaitKey(2) >= 0)
  {
   cvReleaseMemStorage(&storage);
   cvReleaseImage(&image);
   cvReleaseImage(&pfrimage);
   cvReleaseImage(&pbkimage);
   break;
  }
     }
          

 return 0;


 

 演示效果网址:http://v.youku.com/v_show/id_XMjkxMDAyOTc2.html

显示窗口的显示可能有些卡,视屏中没闪一次就是手进入一次后离开

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值