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

标签 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;

最佳答案

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

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

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

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

关于c++ - 在 OpenCV 中使用时间进行帧处理和其他任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10544747/

相关文章:

image-processing - 如何在 3D 中进行高斯滤波

image-processing - 两个开放轮廓的比较度量

python-2.7 - OpenCV 3.2.0-dev - 3.2.0 版本缺少 RTrees,无法找到开发版本

c++ - 与 CAM 的距离无关的人脸识别

C++删除动态数组的最后一个元素

c++ - Boost:在单独的加载/保存函数中非侵入式地序列化一个类

在 Applet 中上传图像时 Java 堆大小问题

c++ - OpenCV中基于光流的四边形点跟踪

c++ - 将一个类分离成cpp和头文件(C++)

c++ - 不推荐使用 auto_ptr 吗?