2

我试图在二值化图像中找到最大的轮廓。从这个问题本教程来看,你会认为这是微不足道的,我同意。但是,当我在下图中运行我的代码时,它会产生错误。注意左上角的 2x2 点,它应该算作一个轮廓。

问题.png

Mat img = imread("problem.png", CV_LOAD_IMAGE_GRAYSCALE);
vector<vector<Point>> ContourVector;
findContours(img, ContourVector, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
//findContours(img, ContourVector, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);    // Alternative mode

int biggest = 0;
double BiggestContourArea = contourArea(ContourVector[biggest]);
for (int i = 1; i != ContourVector.size(); ++i){
if ( (contourArea(ContourVector[i])) > BiggestContourArea) {
    biggest = i;
    BiggestContourArea = contourArea(ContourVector[biggest]);
}
}
img = Scalar(0,0,0);
drawContours(img, ContourVector, biggest, Scalar(255,255,255), CV_FILLED );
imshow("Largest contour", img);
waitKey(0);

如果使用模式 CV_RETR_LIST,我会在 i = 3 时收到此错误,尽管 ContourVector 的大小为 4。但是为什么向量会大于轮廓数?

"Assertion failed: (0 <= contourIdx && contourIdx < (int)last) in unknown function, file ..[..]contours.cpp, line 1810"

如果使用 CV_RETR_EXTERNAL 模式(这会更有意义),我会收到此错误。为什么会发生这种情况

OpenCV Error: Bad argument (input array is not a valid matrix)  in unknown function, file ..[..]utils.cpp, line 54

如果有人能解释这些错误,我将不胜感激。

我还想知道为什么由于某种原因,循环内的 contourArea 的结果为 0,而 ContourVector[i].size() 给出了一个大得离谱的数字(大约 40 亿)。

4

3 回答 3

0

我无法判断 CV_EXTERNAL 案例。但是在第一种情况下,问题似乎很简单。

for (int i = 1; i != ContourVector.size(); ++i){
    if ( (contourArea(ContourVector[i])) > BiggestContourArea) {
        biggest = i;
        BiggestContourArea = contourArea(ContourVector[biggest]);
    }
}

在 C++ 中,数组和向量从零开始索引。所以向量中的第一项有索引0,最后一项有ContourVector.size() - 1

要修复您的代码,只需将 for 循环更改为:

for (int i = 1; i < ContourVector.size(); ++i)    ....
于 2013-08-08T07:13:55.120 回答
0

这似乎是与 Visual Studio 2012 和 OpenCV 提供的预构建库的兼容性问题。在我安装并使用 Visual Studio 2010 运行代码后,问题就消失了。

我假设您也可以通过使用 VS 2012 从源代码构建 OpenCV 来解决此问题,但我没有管理。这里有一本手册,但它已经过时了(git 中没有“源”目录)。

我在 VS 2012 中的这个项目还有其他奇怪的问题,这与一些库问题一致。编译代码在调试和发布模式下工作正常,但在调试模式下执行它会出错。在发布模式下,它似乎可以工作,但它产生了引发这个问题的错误。

对于协议,我将“/build/x86/vc10/lib”链接为 VS 2012 中的附加库目录,并且错误是由 OpenCV 版本 2.4.4 到 2.4.6 产生的。

于 2013-08-27T17:16:39.803 回答
0

为了回应您的上一篇文章(这似乎是一个兼容性问题......),您是否尝试在 VS 2012 中使用“/build/x86/vc11/lib”而不是 vc10?我绝不是专家,但这可能是图书馆的不匹配。(vc11肯定是2.4.6 openCV的,之前不确定)

唐 祝你有美好的一天

于 2013-10-08T05:08:15.630 回答