findContours在OpenCV中崩溃编译器

时间:2012-12-08 20:36:42

标签: c++ xcode opencv vector

当我尝试使用findContours时,我已经尝试了几个小时来弄清楚XCode出了什么问题。基本上这是我的代码:

#include <opencv2/opencv.hpp>
int main()
{
    Mat img = imread(helper::getImageSequence(3, image_value_temp));
    Mat img_gray = Mat(Size(img.cols, img.rows), CV_8UC1);
    Mat img_canny;

    cvtColor(img, img_gray, CV_BGR2GRAY);    

    Canny(img_gray, img_canny, someLow, someHigh);

    vector<vector<cv::Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(img_canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
}

当我打印轮廓时,我得到7905747460161236409,所以我想知道我的堆是否溢出了?

  • XCode版本:4.5.2
  • 编译器:Apple LLVM 4.1

所以基本上崩溃追溯到findContours,这就是XCode给我的全部内容:

enter image description here

2 个答案:

答案 0 :(得分:3)

如果要提供完整的源代码和为您生成此错误的图像,则更容易重新创建错误。当我完成你的代码时,我就可以使用它了:

#include <opencv2/opencv.hpp>
int main()
{
    using namespace cv;
    Mat img = imread("test.png");
    Mat img_gray = Mat(Size(img.cols, img.rows), CV_8UC1);
    Mat img_canny;

    cvtColor(img, img_gray, CV_BGR2GRAY);    

    Canny(img_gray, img_canny, 80, 120);

    vector<vector<cv::Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(img_canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
}

它在我的系统上正常运行。我不明白为什么不应该这样做。 您在屏幕截图中发布的错误不是编译器崩溃。您的调试器显示您的程序在执行期间崩溃。 你有一个自己编写的函数circle_fitting_callback,它会在破坏cv :: points的向量时产生错误。您的问题不在您发布的代码中,而在于您未向我们展示的内容。 最好的方法是学会使用调试器。我不知道你的IDE,但是如果你单击调用堆栈中的相应行(你向我们展示的那些东西),我猜你的函数直接导致崩溃。 如果您对此感到困惑,请发布完整的代码以重现错误。

答案 1 :(得分:1)

首先,我认为您不应该直接在Canny边缘检测器的输出上运行findContours(...)。原因是对于某些图像,对于某些值输入参数到边缘检测器(在您的情况下它们是“someLow”和“someHigh”),输出图像将具有许多小的碎片边缘。因此,使用CV_RETR_TREE选项(返回嵌套轮廓的完整层次结构)调用findContours(...)将导致它找到许多轮廓,从而增加了构建层次结构的额外开销。

要对此进行测试,您可以尝试在简单的测试图像上运行代码,例如带有纯色背景的实心圆圈。 canny边缘检测器应该给出单个“边缘”,即圆圈。然后调用findContour(...)应该给你这个圈子。

另一个测试是使用CV_RETR_LIST而不是CV_RETR_TREE,因为CV_RETR_LIST只返回轮廓而不构建层次结构。

另一个测试是运行你的代码,输入到canny边缘检测器集,以返回极少数边缘。

如果这些案例没有导致程序崩溃,那么我们大致走上正轨。

最后,根据我从事图像处理/计算机视觉工作的经验,你几乎不想在边缘地图上调用findContours(...),因为你想要在碎片边缘周围轮廓化什么?如果我的猜测是正确的,那么您正试图找到图像中对象周围的轮廓。如果是这种情况,那么您应该尝试使用分段方法(例如grabCutfloodfill(分水岭,均值分割)等获取图像中对象的二进制遮罩,运行一些基本的image morphology运算符清理掩码,然后在此掩码上运行findContours(...)。

希望这有帮助。