将和分配给矩阵时,大小为4的无效写入

问题描述 投票:0回答:2

你好,我正在尝试实现二维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

}
c++ opencv computer-vision valgrind
2个回答
0
投票

您拥有“ Mat copy_output;”它正在使用默认构造函数构造Mat,该构造函数可能具有0行和0 cols。当您调用copy_output.at(y,x)= sum时。它正在尝试将不存在的内存放入内存。

Mat copy_output(input.rows,input.cols,input.type()); 

或类似上面的内容。


0
投票

该代码是为奇数大小的内核设计的,如果不对偶数大小的内核进行大的修改,它将无法正常工作。这可能是您越界读取的原因。我建议您通过根据需要添加零的行和/或列来使内核奇数大小。

您的越界写入发生是因为copy_outputcopy_input的大小不同。假设您按照其他答案中的说明进行了初始化(Mat copy_output(input.rows,input.cols,input.type()),然后

copy_output.at<float>(y,x) = sum;

由于xy变得比input.rowsinput.cols大,因此超出界限。将copy_output初始化为填充的输入图像的大小(cv::copyMakeBorder的结果),或者写入:

copy_output.at<float>(y-kernel.rows/2,x-kernel.cols/2) = sum;

请注意,代码中的round是多余的,kernel.rows/2是整数除法,产生整数。 round对整数不执行任何操作。

© www.soinside.com 2019 - 2024. All rights reserved.