你好,我正在尝试实现二维ryconvolution,我相信我所有的计算和for循环都是正确的。但是,当我尝试将sum分配给copy_output.at(y,x)时,我得到一个错误的大小写使用valgrind调试时出现4错误。我已经检查了所有可能导致此问题的方法。我还初始化了copy_output。
Valgrind错误:
Process terminating with default action of signal 11 (SIGSEGV)
==30604== Access not within mapped region at address 0x10
==30604== at 0x413594: algorithms::manual_filter_2d(cv::Mat const&, cv::Mat&, cv::Mat const&) (algorithms.cpp:137)
代码:
void algorithms::manual_filter_2d(const Mat &input, Mat &output, const Mat &kernel) {
int top;
int bottom;
top = round(kernel.cols/2);
bottom = top;
int left;
int right;
left = round(kernel.rows/2);
right = left;
Mat copy_output;
Mat copy_input(input.rows,input.cols,input.type());
cv::copyMakeBorder(input, copy_input, top, bottom,left,right, cv::BORDER_REPLICATE);
for(int y=round(kernel.rows/2); y<copy_input.rows-round(kernel.rows/2); y++)
{
for(int x=round(kernel.cols/2); x<copy_input.cols-round(kernel.cols/2); x++)
{
float sum = 0.0f;
for(int ky=0;ky<kernel.rows;ky++)
{
for(int kx=0;kx<kernel.cols;kx++)
{
sum += input.at<float>(y+ky-((kernel.rows-1)/2) , x+kx-((kernel.cols-1)/2))*kernel.at<float>(ky,kx);
}
}
copy_output.at<float>(y,x) = sum; //line 137 that causes the segfault
}
}
copy_output.copyTo(output);
// TODO put your code here
}
您拥有“ Mat copy_output;”它正在使用默认构造函数构造Mat,该构造函数可能具有0行和0 cols。当您调用copy_output.at(y,x)= sum时。它正在尝试将不存在的内存放入内存。
Mat copy_output(input.rows,input.cols,input.type());
或类似上面的内容。
该代码是为奇数大小的内核设计的,如果不对偶数大小的内核进行大的修改,它将无法正常工作。这可能是您越界读取的原因。我建议您通过根据需要添加零的行和/或列来使内核奇数大小。
您的越界写入发生是因为copy_output
与copy_input
的大小不同。假设您按照其他答案中的说明进行了初始化(Mat copy_output(input.rows,input.cols,input.type())
,然后
copy_output.at<float>(y,x) = sum;
由于x
和y
变得比input.rows
和input.cols
大,因此超出界限。将copy_output
初始化为填充的输入图像的大小(cv::copyMakeBorder
的结果),或者写入:
copy_output.at<float>(y-kernel.rows/2,x-kernel.cols/2) = sum;
请注意,代码中的round
是多余的,kernel.rows/2
是整数除法,产生整数。 round
对整数不执行任何操作。