将总和分配给矩阵时大小为 4 的无效写入
invalid write of size 4 when assigning sum to a matrix
您好,我正在尝试实现 2d 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
}
你有“垫子 copy_output;”它正在使用可能具有 0 行和 0 列的默认构造函数构造 Mat。当您致电 copy_output.at(y,x) = sum 时。它正在尝试放入不存在的内存。
Mat copy_output(input.rows,input.cols,input.type());
或与上面类似的内容。
该代码是为奇数内核设计的,如果不对偶数内核进行大的修改将无法运行。这可能是您越界读取的原因。我建议您根据需要添加一行 and/or 列零来使内核大小为奇数。
发生越界写入是因为 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
对整数不执行任何操作。
您好,我正在尝试实现 2d 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
}
你有“垫子 copy_output;”它正在使用可能具有 0 行和 0 列的默认构造函数构造 Mat。当您致电 copy_output.at(y,x) = sum 时。它正在尝试放入不存在的内存。
Mat copy_output(input.rows,input.cols,input.type());
或与上面类似的内容。
该代码是为奇数内核设计的,如果不对偶数内核进行大的修改将无法运行。这可能是您越界读取的原因。我建议您根据需要添加一行 and/or 列零来使内核大小为奇数。
发生越界写入是因为 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
对整数不执行任何操作。