0

我已经被这个问题困扰了好几天了;

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

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

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

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

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

这是调试器输出:

0 cv::thresh_8u(cv::Mat const&, cv::Mat&, 无符号字符, 无符号字符, int) C:\OpenCV2.4\OpenMinGw\install\bin\libopencv_imgproc240.dll 0 0x62b2c624  
1 cv::_InputArray::getMat(int) 常量 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);

    }

使用:

  • 视窗 7 x64

  • 使用 mingw 4.1.0 编译的 OpenCV 2.4.0

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

编辑:

这是我的代码的较短版本:

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显示,这意味着图像已加载。

在这里上传项目

4

3 回答 3

0

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

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

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

也改变一下:

vector<vector<Point> > contours;

to:

vector<vector<cv::Point2f> > contours;
于 2013-03-30T14:45:33.377 回答
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()can't access the specified file发生的。这使得函数返回一个空的Mat。要检查是否是这种情况,只需执行以下操作:

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

The reason why it happens is because Qt Creator builds the .exe of the project in a separate folder, so when the application runs, it tries to load the image from the directory where the .exe was launched, and it fails because the image isn't there.

When calling imread() remember to pass the FULL PATH to the file. See if that fixes the issue.

EDIT:

Remember to convert the image to binary before feeding it to 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);
于 2013-03-30T18:37:49.707 回答
0

I used function Qtconcurrent::run() and everything started working. Even though this isn't a permanent (nor a good) solution; this is all I could come up with.

I'm still open to other answers though.

于 2013-04-03T18:52:06.403 回答