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

时间:2015-09-11 20:33:47

标签: c++ opencv opencv3.0

我正在使用运动检测脚本跟踪pepole我使用了前景功能MOG2它工作我想在下一步做的是在移动人体中绘制一个矩形但是当我运行它时我得到一个错误 有任何想法如何解决它?

错误: OpenCV错误:cvGetMat中的错误标志(参数或结构字段)(无法识别或不支持的数组类型),文件/home/shar/opencv/modules/core/src/array.cpp,第2494行 在抛出'cv :: Exception'的实例后终止调用   what():/ home / skip / opencv / modules / core / src / array.cpp:2494:error:( - 206)函数cvGetMat中无法识别或不支持的数组类型

中止

这是我的代码:

#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 个答案:

答案 0 :(得分:2)

您的代码失败是因为您在findContours上呼叫frame,在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;
}