如何跟踪视频中的前景并在其上绘制矩形 [英] how to track foreground in video and draw rectangle on it

查看:86
本文介绍了如何跟踪视频中的前景并在其上绘制矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

im在运动检测脚本中运行,跟踪人偶我使用了前景函数MOG2,并且我下一步要做的工作是在移动人偶中绘制一个矩形,但是运行它时出现错误 有任何解决办法吗?

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 ?

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

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

中止

那是我的代码:

#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循环才对其进行初始化.

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

在查找最大轮廓时也会遇到问题,因为每次迭代时都不会重置largest_arealargest_contour_index,因此,如果在当前帧中找不到轮廓,该操作将失败.

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.

此代码应该是您要执行的操作. 您可以在此处找到相关的答案. 这里的代码是OpenCV 3.0.0的端口,外加使用形态学开放的噪声消除功能.

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

这篇关于如何跟踪视频中的前景并在其上绘制矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆