我在linux终端(Linux中的c ++)中编译了以下代码,并使用的是OpenCv 2.4.3。
然而,在运行时遇到分段错误,我真的不知道为什么。我已经放置了不同的cout语句来知道程序是否处理到特定阶段但是徒劳无功。请你帮助我好吗?请解释一下这个分段错误究竟是什么。我被困在这里很长时间了。
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
{
cout<<"check"<<flush;
Mat src,src_gray,dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
char* window_name = "sharpness estimate";
int freq,rows,cols =0;
double *estimate,*min = 0;
Point *minLoc,*maxLoc = 0;
src = imread("/home/siddarth/examplescv/erez images/image53.jpg");
if( !src.data )
{
return -1;
}
namedWindow(window_name,CV_WINDOW_AUTOSIZE);
Mat abs_dst;
cvtColor(src,src_gray,CV_RGB2GRAY);
Laplacian(src_gray,dst,ddepth,kernel_size,scale,delta,BORDER_DEFAULT);
convertScaleAbs(dst, abs_dst);
minMaxLoc(dst,min,estimate,minLoc,maxLoc,noArray());
Size s = dst.size();
rows = s.height;
cols = s.width;
cout<<rows<<endl<<cols<<endl;
for(int i=0;i<=rows;i++)
{
for(int j=0;j<=cols;j++)
{
if(dst.at<double>(i,j) >= *estimate-100
&& dst.at<double>(i,j) <= *estimate+100)
{
cout<<freq++;
}
}
}
cout<<"estimate :"<<*estimate<<endl;
cout<<"frequency :"<<freq<<endl;
imshow(window_name,abs_dst);
waitKey(1000);
return 0;
}
代码不会在主函数声明之后穿过第一个“check”print语句。这是令人困惑的问题。但是,一旦我刷新了第一个print语句,它就被执行了。我仍然面临着问题。
答案 0 :(得分:4)
确保将std::endl
插入cout
,以便刷新缓冲区。这可能就是你没有看到任何输出的原因。
一个直接的问题是,您的for
循环会使用<=
检查条件,这意味着您可能会在结束时查看条件。但是,由于您使用的是at
,因此应该抛出异常(假设此Mat
类型的行为类似于标准容器)。
此外,您正在创建许多指针以作为一些函数参数传递(例如,double* estimate
)。这实际上并没有给你一个double
对象,只是一个指针。除非你传递给他们的功能是为你分配一个double
(我希望不是这样),你做错了。你应该这样做:
double estimate;
minMaxLoc(/* ... */, &estimate, /* ... */);
您需要使用输出参数获得的所有值。
需要注意的另一点是:执行int i, j = 0;
只会将j
初始化为0
,而不是i
。您需要int i = 0, j = 0;
。
好的,我将解释为什么修复初始化程序的工作原理。我不得不抬头the definition of minMaxLoc看看会发生什么。基本上,该功能类似于以下内容:
void setToFive(int* x)
{
if (x) {
*x = 5;
}
}
此函数将指向int
,然后将int
设置为值5
。但是,如果传递的指针是空指针,则不会设置该值(否则将存在未定义的行为,因为您正在解除空指针)。基本上,传递空指针说“我不关心这个值,所以不要把它给我”。
现在,当你初始化你的指针时,你正在做:
double *estimate, *min = 0;
这只将min
设置为空指针。由于estimate
未初始化,因此您不能依赖其值为null。您需要为每个声明者提供初始化器:
double *estimate = 0, *min = 0;
答案 1 :(得分:1)
感谢@sftrabbit。问题是初始化。而不是
int freq,rows,cols=0;
改变是
int freq=0,rows=0,cols=0;
这消除了分段错误。非常感谢你的帮助:)。
答案 2 :(得分:1)
由于您处于Linux环境中,因此可以使用valgrind准确找出分段错误发生的位置。只需在程序名称或执行程序的方式之前键入valgrind。例如,如果使用以下命令执行程序:
hello -print
发出以下命令:
valgrind hello -print
我看到你已经解决了这个问题,但这可能对将来有所帮助!