2

我想从视频中数车辆。帧差分后,我得到了灰度图像或二进制图像。我已经定义了一个感兴趣的区域来处理帧的特定区域,通过感兴趣区域的车辆的像素值高于 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;
4

2 回答 2

2

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

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

您真正需要的是首先识别感兴趣的对象,将其从背景中分割出来,并使用自适应滤波器(例如卡尔曼滤波器)随时间跟踪它。看看OpenCV 视频参考。OpenCV 提供背景减法和对象分割来完成所有必需的步骤。

我建议你阅读 OpenCV - Learning OpenCV是一本很好的读物。还有关于更通用的计算机视觉算法和理论 - http://homepages.inf.ed.ac.uk/rbf/CVonline/books.htm有一个很好的列表。

于 2012-05-11T23:05:23.313 回答
0

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

于 2012-08-21T18:20:57.600 回答