OpenCV - HoughCircles导致程序崩溃

3
我希望使用OpenCV和C++在图像中检测圆。我可以参考官方文档并调整由OpenCV团队编写的代码片段的参数来实现这一点。
因此,我正在使用以下代码(已经调整了参数):
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    #include <stdio.h>

    using namespace cv;

    int main(int, char** argv)
    {
       Mat src, src_gray;

       /// Read the image
       src = imread( argv[1], 1 );

       if( !src.data )
         { return -1; }

       /// Convert it to gray
        cvtColor( src, src_gray, CV_BGR2GRAY );

       /// Reduce the noise so we avoid false circle detection
        GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );

        vector<Vec3f> circles;

       /// Apply the Hough Transform to find the circles
        HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 6.0, 5, 110, 70, 3, 20 );

       /// Draw the circles detected
        for( size_t i = 0; i < circles.size(); i++ )
        {
             Point center(cvRound(circles[i][0]), cvRound(circles[i][2]));
             int radius = cvRound(circles[i][3]);
             // circle center
             circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
             // circle outline
             circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
        }

       /// Show your results
        namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
        imshow( "Hough Circle Transform Demo", src );

        waitKey(0);

        src.release();
        src_gray.release();

        return 0;
    }

我想检测的图像是以下的圆形图案:测试图片

这实际上是通过使用cvBlobsLib获得的两个斑点的轮廓,并重新绘制成一个新图像。

该算法能够识别每个圆的中心,但是,当我按任意键关闭程序时,它就会崩溃... :( 我不得不强制关闭它。

我需要将该算法适应于在相机中运行,因此在出现崩溃问题时无法继续实现。

那么,有人知道可能导致这个问题的原因吗? 我正在使用Visual Studio 2012和OpenCV版本2.4.2进行开发。

如果有人能给我建议或尝试运行该算法,我将非常感激!

4个回答

1

我有四个建议给你。

第一:要判断一个Mat是否为空,可以使用

if( src.empty() ) // instead of !src.data.

如果一个空的Mat,那么src.data很可能具有随机(过时)的值。

第二点:请像这样更正索引:

Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);

(实际上你不必使用cvRound,但随便怎么样都可以)。

第三点:值得检查的是,通过检查读入图像的通道数是否正确来确认imread是否理解你想要以彩色模式加载图像:

src.channels()==3
//or
src.type()==CV_8UC3; // that is what you are counting for, really.

否则,在灰度图像上使用类似CV_BGR2GRAY的行可能会导致奇怪的行为。
第四点:您不需要释放Mat。这就是创建Mat类的原因,以便它们自动处理释放。

谢谢您的建议!就像我说的,我是OpenCV的新手,对此感到抱歉... - Saph

0

除了您超出 Vec3f 边界之外,我没有看到任何明显的问题:

         Point center(cvRound(circles[i][0]), cvRound(circles[i][2]));
         int radius = cvRound(circles[i][3]);

我认为你想说的是1和2,而不是2和3。

这并不一定会导致崩溃(通过破坏堆栈或堆),但另一方面它是未定义的行为...

我建议的另一件事是删除在waitKey调用之后的两行:

    src.release();
    src_gray.release();

这些由对象中的析构函数自动处理,所以我不明白为什么你需要手动处理。当然,这可能不会改变任何事情。

从那里开始,如果你仍然遇到崩溃问题,你应该开始省略代码的部分,直到你可以确定导致崩溃的那一部分。


谢谢你的回答!我已经更正了你指出的索引,并且还删除了我放置在那里以释放内存的行...但是什么也没有改变 :(然后,我尝试注释掉代码的一些部分,唯一导致我的代码崩溃的是对HoughCircles的调用...有趣的是,它不会在调用后立即崩溃——崩溃只发生在return 0;行之后... 在调用HoughCircles之后,我放置了一个std::cin.get();,程序实际上等待输入... - Saph
是的,当堆栈或堆被破坏时,您可能会看到这种行为。通常情况下,资源清理之前,事情可以继续工作。在这种情况下,从 main 返回。因此,似乎 HoughCirclesGaussianBlurcvtColor 中的一个正在做一些不好的事情。 - paddy

0

我开始对环境感到怀疑,于是找了一个已经安装好OpenCV的朋友来尝试我的代码,他可以顺利运行它...

所以我重新安装了一切,但这次我选择了Microsoft Visual Studio 2010 SP1和OpenCV 2.4.3,然后它就正常工作了。

如果有人遇到同样的问题,我建议降级到VS2010。此外,当我设置环境时,这个视频安装指南真的很有帮助!

谢谢 :)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接