使用带有Qt Gui的cv :: findContours时程序崩溃

时间:2013-03-30 14:26:09

标签: c++ qt opencv

我已经坚持这个问题好几天了;

我创建了一个Qt控制台项目,将它与OpenCV连接起来,一切正常;

我创建了一个Qt Gui项目,添加了一个按钮并从按钮插槽中的上一个项目复制了相同的代码,我得到了一个windows segFault,程序退出了代码-1073741819。

所以我使用调试器来检测问题,结果证明是使用函数cv::threshold

我更改了它,而是使用cv::Canny,但后来我遇到cv::findContours同样的问题!

奇怪的是,当我调用按钮的'MainWindow :: on_pushButton_clicked()'时 在windows的构造函数中它工作!!!

这是调试器输出:

0   cv::thresh_8u(cv::Mat const&, cv::Mat&, unsigned char, unsigned char, int)  C:\OpenCV2.4\OpenMinGw\install\bin\libopencv_imgproc240.dll 0   0x62b2c624  
1   cv::_InputArray::getMat(int) const  C:\OpenCV2.4\OpenMinGw\install\bin\libopencv_core240.dll    0   0x65c1a838  
2   ??      0   0x00000000  

这是我得到错误的函数(我从OpenCV教程得到的):

void MainWindow::on_pushButton_clicked(){

    Mat src; Mat src_gray;
    int thresh = 100;
    RNG rng(12345);
    Mat canny_output;

    vector<vector<Point> > contours;

    /// Load source image and convert it to gray
    src = imread( "hat-10.bmp", 1 );

    cvtColor( src, src_gray, CV_BGR2GRAY );
    blur( src_gray, src_gray, Size(3,3) );

    /// Detect edges using canny
    Canny( src_gray, canny_output, thresh, thresh*2, 3 );
    qDebug("Ok 1");

    /// Find contours
    if(cv::sum(src_gray).val[0] > 0.0){

        qDebug("Ok 2");
        cv::findContours( src_gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
        /// Draw contours
        Mat drawing = Mat::zeros( src_gray.size(), CV_8UC3 );
        for( int i = 0; i< contours.size(); i++ )
        {
            Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
            drawContours( drawing, contours, i, color, 2);//, 8, hierarchy, 0, Point() );
        }
        /// Show in a window
        imshow( "Contours", drawing);

    }

使用:

  • Windows 7 x64

  • 使用mingw 4.1.0编译的OpenCV 2.4.0

  • 基于Qt 4.7.0(32位)的Qt Creator 2.0.0

修改:

这是我的代码的缩写版本:

void MainWindow::on_toolButton_clicked(){
 std::vector<std::vector<cv::Point> > contours;

/// Load source image and convert it to gray
Mat src = imread( "C:/Users/poste/L3 ISIL/PFE Licence/new bmp/hat-10.bmp", 1);
// my image is already a binary one
Mat canny_output(src.size(), src.type());

Canny(src,canny_output,100,200,3);

imshow("Source",  canny_output); // here image is displayed before crash
waitKey(500);

/// Find contours
findContours(canny_output, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );

}

在控制台模式下,没有问题。从GUI应用程序构造函数调用时,也没有问题。 实际点击按钮时它只会崩溃。

编辑: 我拍了一张截图![这里] http://i.stack.imgur.com/1LyeF.png 显示canny_output,表示已加载图片。

上传的项目here

3 个答案:

答案 0 :(得分:0)

首先确保要阈值的图像实际上是灰度图像。在阈值处理后在另一个窗口中显示它。

在cv :: FindContours之前执行此操作:

cvThreshold(originalImage,resultingImage,100,100,CV_THRESH_BINARY) 

也改变了:

vector<vector<Point> > contours;

to:

vector<vector<cv::Point2f> > contours;

答案 1 :(得分:0)

试试这个:

/// Load source image and convert it to gray
Mat src = imread( "hat-10.bmp", 1 );

Mat src_gray(src.size(), CV_8U);
cvtColor( src, src_gray, CV_BGR2GRAY );

blur( src_gray, src_gray, Size(3,3) );

//Apply threshold
cv::Mat thres_output(src_gray.size(), src_gray.type());
cv::threshold(src_gray, thres_output, 100, 255, cv::THRESH_BINARY);
qDebug("Ok 1");

OpenCV文档在Basic Thresholding Operations上有完整的演示。

修改

仔细检查您的代码和评论后,我想我知道发生了什么:这些问题可能会发生,因为 imread()无法访问指定的文件。这使得函数返回空Mat。要检查是否是这种情况,只需执行以下操作:

Mat src = imread( "hat-10.bmp", 1 );
if (src.empty())
{
    std::cout << "!!! imread failed to open image\n";
    return;
}

之所以发生这种情况,是因为Qt Creator在单独的文件夹中构建项目的 .exe ,因此当应用程序运行时,它会尝试从.exe目录中加载图像已经启动了,因为图像不存在而失败。

调用imread()时,请记住将FULL PATH传递给文件。看看是否能解决问题。

修改

请记住将图像转换为二进制文件,然后再将其转换为findContours()

// Convert from 32F to 8U
cv::Mat binary_img;
canny_output.convertTo(binary_img, CV_8U);

std::vector<std::vector<cv::Point> > contours;
cv::findContours(binary_img, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

答案 2 :(得分:0)

我使用了函数Qtconcurrent :: run(),一切都开始工作了。 即使这不是永久性(也不是好的)解决方案;这就是我能想到的。

我仍然愿意接受其他答案。