基於背景差分的流量監測

初學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

顯示窗口的顯示可能有些卡,視屏中沒閃一次就是手進入一次後離開

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章