当我尝试使用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,所以我想知道我的堆是否溢出了?
所以基本上崩溃追溯到findContours
,这就是XCode给我的全部内容:
答案 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(...),因为你想要在碎片边缘周围轮廓化什么?如果我的猜测是正确的,那么您正试图找到图像中对象周围的轮廓。如果是这种情况,那么您应该尝试使用分段方法(例如grabCut或floodfill(分水岭,均值分割)等获取图像中对象的二进制遮罩,运行一些基本的image morphology运算符清理掩码,然后在此掩码上运行findContours(...)。
希望这有帮助。