我正在使用运动检测脚本跟踪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;
}
}
答案 0 :(得分:2)
您的代码失败是因为您在findContours
上呼叫frame
,在while
循环之前未对其进行初始化。
您在查找最大轮廓时也存在问题,因为您不会在每次迭代时重置largest_area
和largest_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;
}