在OpenCV中使用时间进行帧处理和其他任务

时间:2012-05-11 02:45:09

标签: c++ image-processing opencv computer-vision background-subtraction

我想从视频中计算车辆数量。在帧差分后,我得到了灰度图像或一种二值图像。我已经定义了一个感兴趣区域来处理帧的特定区域,通过感兴趣区域的车辆的像素值高于0或甚至高于40或50,因为它们是白色的。

我的想法是,当特定时间间隔(比如1-2秒)中的一定数量的像素是白色时,必须有车辆通过,所以我会递增计数器。

我想要的是,在1-2秒后检查是否还有白色像素出现。如果没有白色像素,则意味着车辆已经过去并且下一辆车将要到来,这样计数器必须递增。

我想到的一种方法是计算视频的帧数并将其存储在名为No_of_frames的变量中。然后使用该变量我想我可以估计时间的流逝。如果变量No_of_frames的值更大,那么假设为20,则表示如果我的视频帧速率为25-30 fps,则已经过了将近1秒。

我在Windows 7和OpenCV 2.3.1中使用Qt Creator

我的代码类似于:

             for(int i=0; i<matFrame.rows; i++)
             {
                 for(int j=0;j<matFrame.cols;j++)

                 if (matFrame.at<uchar>(i,j)>100)//values of pixels greater than 100
                                                 //will be considered as white.
                     {
                        whitePixels++;
                     }
                 if ()// here I want to use time. The 'if' statement must be like: 
                 //if (total_no._of_whitepixels>100 && no_white_pixel_came_after 2secs)
                //which means that a vehicle has just passed so increment the counter. 
                    {  
                        counter++;      
                    }
             }

计算车辆的任何其他想法,比我的更好,将是最受欢迎的。提前致谢。

对于背景分割我使用以下算法,但它很慢,我不知道为什么。整个代码如下:

// opencv2/video/background_segm.hpp OPENCV header file must be included.
IplImage*       tmp_frame = NULL;
CvCapture*      cap = NULL;
bool update_bg_model = true;

 Mat element = getStructuringElement( 0, Size( 2,2 ),Point() );
 Mat eroded_frame;
 Mat before_erode;
if( argc > 2 )
    cap = cvCaptureFromCAM(0);

else
//  cap = cvCreateFileCapture( "C:\\4.avi" );
   cap = cvCreateFileCapture( "C:\\traffic2.mp4" );

if( !cap )
{
    printf("can not open camera or video file\n");
    return -1;
}

tmp_frame = cvQueryFrame(cap);
if(!tmp_frame)
{
    printf("can not read data from the video source\n");
    return -1;
}

cvNamedWindow("BackGround", 1);
cvNamedWindow("ForeGround", 1);

CvBGStatModel* bg_model = 0;

for( int fr = 1;tmp_frame; tmp_frame = cvQueryFrame(cap), fr++ )
{
    if(!bg_model)
    {
        //create BG model
        bg_model = cvCreateGaussianBGModel( tmp_frame );
      //  bg_model = cvCreateFGDStatModel( temp );
        continue;
    }

    double t = (double)cvGetTickCount();
    cvUpdateBGStatModel( tmp_frame, bg_model, update_bg_model ? -1 : 0 );
    t = (double)cvGetTickCount() - t;
    printf( "%d. %.1f\n", fr, t/(cvGetTickFrequency()*1000.) );

    before_erode= bg_model->foreground;
    cv::erode((Mat)bg_model->background, (Mat)bg_model->foreground,  element );
    //eroded_frame=bg_model->foreground;
     //frame=(IplImage *)erode_frame.data;

     cvShowImage("BackGround", bg_model->background);
     cvShowImage("ForeGround", bg_model->foreground);
    // cvShowImage("ForeGround", bg_model->foreground);
    char k = cvWaitKey(5);
    if( k == 27 ) break;
    if( k == ' ' )
    {
        update_bg_model = !update_bg_model;
        if(update_bg_model)
            printf("Background update is on\n");
        else
            printf("Background update is off\n");
    }
}
cvReleaseBGStatModel( &bg_model );
cvReleaseCapture(&cap);
return 0;

2 个答案:

答案 0 :(得分:2)

对车辆跟踪和计数进行了大量研究。您描述的方法似乎非常脆弱,并且不太可能是健壮的或准确的。主要问题是使用高于某个阈值的像素数,而不考虑它们的空间连通性或时间关系。

如果感兴趣的对象是唯一(或最大)移动对象,则帧差异对于将移动对象与其背景分离非常有用。

您真正需要的是首先识别感兴趣的对象,从背景中对其进行分割,然后使用自适应滤波器(例如卡尔曼滤波器)随时间跟踪它。看看OpenCV video reference。 OpenCV提供背景减法和对象分割,以执行所有必需的步骤。

我建议您阅读OpenCV - Learning OpenCV是一个很好的阅读。而且对于更一般的计算机视觉算法和理论 - http://homepages.inf.ed.ac.uk/rbf/CVonline/books.htm有一个很好的列表。

答案 1 :(得分:0)

通常他们只是在路上放一个小气动管道(软管半满空气)。它附在一个简单的柜台上。经过管道的每辆车产生两个脉冲(第一前轮,后轮)。计数器以指定的时间间隔记录脉冲数,并除以2以获得大约车辆计数。