使用OpenCV检测视频中的基本更改

时间:2018-01-10 14:58:52

标签: c++ opencv motion-detection

尝试重新创建一个基本的变化检测程序,我是从Adrian Rosebrock完成的一个很棒的博客中获得的(如果想进入python和OpenCV,请到这里)。代码是用python设计的,我试图将它转换为C ++。您可以找到博文here。我的奋斗是absdiff(firsFrame, gray, imageDifference),因为循环的每次迭代都有firstFrame和灰色相等。我认为问题出在我初始化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 个答案:

答案 0 :(得分:4)

有待改进:

  1. firstFrame = gray =&gt; gray.copyTo(firstFrame)

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

  2. 略过一些帧。

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

  3. cv :: Scalar&lt; ==&gt;元组

    在C ++中:

    cv::Scalar(b,g,r) <==> tuple(b,g,r)

    (b,g,r) ==> r

  4. 修改后的代码:

    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 );
    
        // ...
    
    
    }
    

    enter image description here