使用 OpenCV 检测视频中的基本变化

Posted

技术标签:

【中文标题】使用 OpenCV 检测视频中的基本变化【英文标题】:Detect Basic Change in Video using OpenCV 【发布时间】:2018-01-10 14:58:51 【问题描述】:

尝试重新创建一个基本的变化检测程序,我从 Adrian Rosebrock 的一篇很棒的博客中获得(如果想了解 python 和 OpenCV,请点击此处)。该代码是用 python 设计的,我正在尝试将其转换为 C++。你可以找到博文here。我的斗争是absdiff(firsFrame, gray, imageDifference),因为循环的每次迭代都有 firstFrame 和 gray 相等。我认为问题出在我初始化firstFrame = gray 的位置,但我做了cout 检查以查看它被击中了多少次,所以不确定。这是代码:

int min_area = 500; //min area of motion detectable

//get camera operational and make sure working correctly
VideoCapture camera(0);
if(!camera.isOpened())
    cout << "cannot open camera" << endl;
    return(1);


Mat firstFrame, gray, imageDifference, thresh;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;


while(true)
    Mat frame;
    camera.read(frame);
    if(frame.empty())
        cout << "frame was not captured" << endl;
        return(2);
    
    //pre processing
    //resize(frame, frame, Size (1200,900));
    cvtColor(frame, gray, COLOR_BGR2GRAY);
    GaussianBlur(gray, gray, Size( 21, 21 ), 0, 0 );

    //initrialize first frame if necessary
    if(firstFrame.empty())
        cout << "hit" << endl;
        firstFrame = gray;
        continue;
    

    //get difference
    absdiff(firstFrame, gray, imageDifference);
    threshold(imageDifference, thresh, 25, 255, THRESH_BINARY);
    //fill in holes
    dilate(thresh, thresh, Mat(), Point(-1, -1), 2, 1, 1);
    findContours(thresh, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

    //loop over contours
    for(int i = 0; i < contours.size(); i++)
        //get the boundboxes and save the ROI as an Image
        if (contourArea(contours[i]) < min_area)
            continue;
        
        Rect boundRect = boundingRect( Mat(contours[i]));
        rectangle( frame, boundRect.tl(), boundRect.br(), (0,255,0), 1, 8, 0 );

    
    //draw everything
    imshow("Security feed", frame);
    imshow("Thresh", thresh);
    imshow("Difference", imageDifference);
    if (waitKey(30) >= 0)
        break;


camera.release();
destroyAllWindows();
return(0);

【问题讨论】:

【参考方案1】:

有待改进:

    firstFrame = gray => gray.copyTo(firstFrame)

    您在同一行定义firstFramegray,然后在执行firstFrame = gray 之后,它们共享相同的数据存储器。所以每次都是一样的。

    跳过一些帧。

    由于相机刚启动,所以第一帧不是那么稳定,你应该跳过一些帧(比如10帧)。

    cv::Scalar 元组

    在 C++ 中:

    cv::Scalar(b,g,r) &lt;==&gt; tuple(b,g,r)

    (b,g,r) ==&gt; r


修改代码:

int cnt = 0;

while(true) 

    Mat frame;
    camera.read(frame);
    if(frame.empty()) 
        cout << "frame was not captured" << endl;
        return(2);
    
    //pre processing
    //resize(frame, frame, Size (1200,900));
    cvtColor(frame, gray, COLOR_BGR2GRAY);
    GaussianBlur(gray, gray, Size( 21, 21 ), 0, 0 );

    //initrialize first frame if necessary
    if(firstFrame.empty()) 
        if(cnt<10)
            ++cnt;
        else
            cout << "hit" << endl;
            gray.copyTo(firstFrame);
        
        continue;
    

    // ...

    ///  cv::Scalar(b,g,r) <==> tuple(b,g,r)
    ///  (b,g,r) ==> r
    rectangle( frame, boundRect.tl(), boundRect.br(), Scalar(0,255,0), 1, 8, 0 );

    // ...




【讨论】:

以上是关于使用 OpenCV 检测视频中的基本变化的主要内容,如果未能解决你的问题,请参考以下文章

动态背景视频流中的运动/变化检测

Opencv 3.0 加载人脸级联时出错

视频中的Opencv马赛克

opencv 提取avi视频中的帧,逐帧播放

有没有人在 OpenCV 中使用 MSER 来检测区域?

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测