我想写一个程序,可以创建一个多边形(任意数量的边)围绕某个对象,并找到多边形的质心。为此,我选择使用凸凹和findContours函数。在下面的程序中,您会看到两个窗口。一个窗口包含用于更改过滤器的HSV和形态值的轨道栏,另一个窗口包含已过滤的图像。在过滤图像并获得二值图像后,您必须点击'c'找到轮廓,然后点'h'找到凸凹。过滤图像并执行形态学操作不是问题。主要问题是找到轮廓。Opencv 3.0.0,C++,Visual Studio 2015 - 错误发现轮廓和ConvexHull
#include<iostream>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\video\background_segm.hpp>
#include<Windows.h>
using namespace cv;
using namespace std;
//functions prototypes
void on_trackbar(int, void*);
void createTrackbars();
void showimgcontours(Mat &threshedimg, Mat &original);
void toggle(int key);
void morphit(Mat &img);
void blurthresh(Mat &img);
//function prototypes ends here
//boolean toggles
bool domorph = false;
bool doblurthresh = false;
bool showchangedframe = false;
bool showcontours = false;
bool showhull = false;
//boolean toggles end
int H_MIN = 0;
int H_MAX = 255;
int S_MIN = 0;
int S_MAX = 255;
int V_MIN = 0;
int V_MAX = 255;
int kerode = 1;
int kdilate = 1;
int kblur = 1;
int threshval = 0;
int main(void)
{
createTrackbars();
on_trackbar(0, 0);
Mat frame, hsvframe, rangeframe;
int key;
VideoCapture cap(0);
while ((key = waitKey(30)) != 27)
{
toggle(key);
cap >> frame;
flip(frame, frame, 180);
cvtColor(frame, hsvframe, COLOR_BGR2HSV);
inRange(hsvframe, Scalar(H_MIN, S_MIN, V_MIN), Scalar(H_MAX, S_MAX, V_MAX), rangeframe);
if (domorph)
morphit(rangeframe);
if (doblurthresh)
blurthresh(rangeframe);
if (showcontours)
showimgcontours(rangeframe, frame);
if (showchangedframe)
imshow("Camera", frame);
else
imshow("Camera", rangeframe);
}
}
void on_trackbar(int, void*)
{//This function gets called whenever a
// trackbar position is changed
if (kerode == 0)
kerode = 1;
if (kdilate == 0)
kdilate = 1;
if (kblur == 0)
kblur = 1;
}
void createTrackbars()
{
String trackbarWindowName = "TrackBars";
namedWindow(trackbarWindowName, WINDOW_NORMAL);
createTrackbar("H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar);
createTrackbar("H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar);
createTrackbar("S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar);
createTrackbar("S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar);
createTrackbar("V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar);
createTrackbar("V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar);
createTrackbar("Erode", trackbarWindowName, &kerode, 31, on_trackbar);
createTrackbar("Dilate", trackbarWindowName, &kdilate, 31, on_trackbar);
createTrackbar("Blur", trackbarWindowName, &kblur, 255, on_trackbar);
createTrackbar("Thresh", trackbarWindowName, &threshval, 255, on_trackbar);
}
void morphit(Mat &img)
{
erode(img, img, getStructuringElement(MORPH_RECT, Size(kerode, kerode)));
dilate(img, img, getStructuringElement(MORPH_RECT, Size(kdilate, kdilate)));
}
void blurthresh(Mat &img)
{
//medianBlur(img,img,kblur%2+3+kblur);
blur(img, img, Size(kblur, kblur), Point(-1, -1), BORDER_DEFAULT);
threshold(img, img, threshval, 255, THRESH_BINARY_INV);
}
void toggle(int key)
{
//toggle line start
if (key == 'm')
domorph = !domorph;
if (key == 'b')
doblurthresh = !doblurthresh;
if (key == 'r')
showchangedframe = !showchangedframe;
if (key == 'c')
showcontours = !showcontours;
if (key == 'h')
showhull = !showhull;
//toggle line end
}
void showimgcontours(Mat &threshedimg, Mat &original)
{
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
int largest_area = 0;
int largest_contour_index = 0;
findContours(threshedimg, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
vector<vector<Point> >hull(contours.size());
//find a hull for each contour
for (int i = 0; i < contours.size(); i++)
{
convexHull(Mat(contours[i]), hull[i], false);
}
//this will find the largest contour
for (int i = 0; i< contours.size(); i++) // iterate through each contour.
{
double a = contourArea(contours[i], false); // Find the area of each contour
if (a>largest_area)
{
largest_area = a;
largest_contour_index = i; //Store the index of the largest contour
}
}
//search for the largest contour has end
if (contours.size() > 0)
{
drawContours(original, contours, largest_contour_index, CV_RGB(0, 255, 0), 2, 8, hierarchy);
//if you want to show every contour, use the following
//drawContours(original,-1, CV_RGB(0, 255, 0), 2, 8, hierarchy);
if (showhull)
drawContours(original, hull, largest_contour_index, CV_RGB(0, 0, 255), 2, 8, hierarchy);
//if you want to show every hull(s), use the following
//drawContours(original,-1, CV_RGB(0, 255, 0), 2, 8, hierarchy);
}
}
的问题是,它总是会触发一个断点向量类模板(某处void Tidy()
)每当我尝试运行findcontours()函数。弹出一个对话框并显示以下消息:
“ConsoleApplication2.exe中的0x00007FF9374CD328(ucrtbase.dll)未处理的异常:将无效参数传递给认为无效参数致命的函数。
然后对话框重定向我到向量类模板,并显示在下面段第7行设置一个断点。
void _Tidy()
{ // free all storage
if (this->_Myfirst() != pointer())
{ // something to free, destroy and deallocate it
this->_Orphan_all();
_Destroy(this->_Myfirst(), this->_Mylast());
this->_Getal().deallocate(this->_Myfirst(),
this->_Myend() - this->_Myfirst());
this->_Myfirst() = pointer();
this->_Mylast() = pointer();
this->_Myend() = pointer();
}
}
这是与findContours功能或矢量类或完全不同的东西出了问题?
[csumike](http://stackoverflow.com/users/5572856)认为这可能是由已知的错误引起的:http://code.opencv.org/issues/4452#note-3 – cgmb
([他认为他的答案应该已经被删除](http://stackoverflow.com/review/low-quality-posts/10236232),因为它提供了一个看起来有用和有效的答案。不幸的是,作为一个新用户并开始你的帖子与'我有同样的问题'我您很可能会将您的答案删除,因为新用户对答案使用答案框是一种常见的错误。这就是评论的方式,有时候。) – cgmb