如何跟踪视频中的前景并在其上绘制矩形

how to track foreground in video and draw rectangle on it

我正在研究一个跟踪人的运动检测脚本。 我使用了前景功能 MOG2,它完成了我想做的事情。在下一步中,我想在移动的人周围绘制一个矩形,但是当我 运行 它时出现错误。

有什么解决办法吗?

错误:

OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/shar/opencv/modules/core/src/array.cpp, line 2494
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/shar/opencv/modules/core/src/array.cpp:2494: error: (-206) Unrecognized or unsupported array type in function cvGetMat

Aborted

这是我的代码:

    #include <opencv2/opencv.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <vector>
    #include <iostream>
    #include <sstream>
    #include <opencv2/video/background_segm.hpp>  
    #include <opencv2/video/background_segm.hpp>
    using namespace std;
    using namespace cv;
    
    
    int main()
    {
       //Openthevideofile
       cv::VideoCapture capture(0);
       cv::Mat frame;
       Mat colored;  
       //foregroundbinaryimage
       cv::Mat foreground;
       int largest_area=0;
       int largest_contour_index=0;
       Rect bounding_rect;
       cv::namedWindow("ExtractedForeground");
       vector<vector<Point> > contours; // Vector for storing contour
       vector<Vec4i> hierarchy;
       findContours( frame, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
       //checkifvideosuccessfullyopened
       if (!capture.isOpened())
         return 0;
       //currentvideoframe
    
       //TheMixtureofGaussianobject
       //used with all default parameters
       cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2 = cv::createBackgroundSubtractorMOG2();
      
       bool stop(false);
            //  testing the bounding    box 
    
       //forallframesinvideo
       while(!stop){
      //readnextframeifany
        if(!capture.read(frame))
          break;
       //updatethebackground
       //andreturntheforeground
        float learningRate = 0.01; // or whatever
        cv::Mat foreground; 
        pMOG2->apply(frame, foreground, learningRate);
      //learningrate
      //Complementtheimage
        cv::threshold(foreground,foreground,128,255,cv::THRESH_BINARY_INV);
      //showforeground
        for( int i = 0; i< contours.size(); i++ )
        {
            //  Find the area of contour
            double a=contourArea( contours[i],false); 
            if(a>largest_area){
                largest_area=a;cout<<i<<" area  "<<a<<endl;
                // Store the index of largest contour
                largest_contour_index=i;               
                // Find the bounding rectangle for biggest contour
                bounding_rect=boundingRect(contours[i]);
            }
         }
    
        Scalar color( 255,255,255);  // color of the contour in the
        //Draw the contour and rectangle
        drawContours( frame, contours,largest_contour_index, color, CV_FILLED,8,hierarchy);
        rectangle(frame, bounding_rect,  Scalar(0,255,0),2, 8,0);
    
    
        cv::imshow("ExtractedForeground",foreground);
        cv::imshow("colord",colored);
    
      //introduceadelay
      //orpresskeytostop
        if(cv::waitKey(10)>=0)
        stop=true;
      }
     
    
    }

您的代码失败,因为您在 frame 上调用 findContours,直到 while 循环才初始化。

你在寻找最大轮廓时也有问题,因为你没有在每次迭代时重置 largest_arealargest_contour_index,所以如果你没有找到轮廓就会失败当前帧。

这段代码应该是你想要做的。 你可以找到一个相关的答案here。 这里的代码是 OpenCV 3.0.0 的端口,加上使用形态学打开的噪声去除。

#include <opencv2\opencv.hpp>
#include <vector>

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
    Ptr<BackgroundSubtractorMOG2> bg = createBackgroundSubtractorMOG2(500, 16, false);
    VideoCapture cap(0);
    Mat3b frame;
    Mat1b fmask;
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3,3));

    for (;;)
    {
        // Capture frame
        cap >> frame;

        // Background subtraction
        bg->apply(frame, fmask, -1);

        // Clean foreground from noise
        morphologyEx(fmask, fmask, MORPH_OPEN, kernel);

        // Find contours
        vector<vector<Point>> contours;
        findContours(fmask.clone(), contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

        if (!contours.empty())
        {
            // Get largest contour
            int idx_largest_contour = -1;
            double area_largest_contour = 0.0;

            for (int i = 0; i < contours.size(); ++i)
            {
                double area = contourArea(contours[i]);
                if (area_largest_contour < area)
                {
                    area_largest_contour = area;
                    idx_largest_contour = i;
                }
            }

            if (area_largest_contour > 200)
            {
                // Draw
                Rect roi = boundingRect(contours[idx_largest_contour]);
                drawContours(frame, contours, idx_largest_contour, Scalar(0, 0, 255));
                rectangle(frame, roi, Scalar(0, 255, 0));
            }
        }

        imshow("frame", frame);
        imshow("mask", fmask);
        if (cv::waitKey(30) >= 0) break;
    }
    return 0;
}