how to track foreground in video and draw rectangl

2019-04-13 16:02发布

im working in motion detection script that tracking pepole i used foreground function MOG2 and it work what i want to do in the next step is draw a rectangle in moving pepole but i get a error when i run it there are any ideas how to fix it ?

the error: 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

that's my code:

#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;
  }


}

1条回答
做个烂人
2楼-- · 2019-04-13 17:00

Your code fails because you are calling findContours on frame, which is not initialized until the while loop.

You have also issues in finding the largest contour, since you don't reset largest_area and largest_contour_index at each iteration, so it will fail in case you don't find a contour in the current frame.

This code should be what you meant to do. You can find a related answer here. The code here is the port to OpenCV 3.0.0, plus noise removal using morphological open.

#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;
}
查看更多
登录 后发表回答