我已经坚持这个问题好几天了;
我创建了一个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
答案 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(),一切都开始工作了。 即使这不是永久性(也不是好的)解决方案;这就是我能想到的。
我仍然愿意接受其他答案。