неверная запись размера 4 при назначении суммы матрице - PullRequest
0 голосов
/ 21 апреля 2020

Здравствуйте, я пытаюсь реализовать 2d ryconvolution и считаю, что все мои вычисления и циклы for верны. Однако, когда я пытаюсь присвоить sum для copy_output.at (y, x), я получаю сообщение об ошибке записи размера 4 при отладке с помощью valgrind. Я проверил все, что могло вызвать это. Я также инициализировал 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

}

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Код разработан для ядра нечетного размера и не будет работать без больших модификаций для ядер четного размера. Скорее всего, это причина ваших прочтений. Я рекомендую сделать ядро ​​нечетного размера, добавив при необходимости строку и / или столбец нулей.

Ваши записи за пределами допустимого размера происходят из-за того, что 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 ничего не делает с целым числом.

0 голосов
/ 21 апреля 2020

у вас есть "Mat copy_output;" это конструирование Mat с использованием конструктора по умолчанию, который, вероятно, имеет 0 строк и 0 столбцов. Когда вы вызываете copy_output.at (y, x) = sum. Он пытается поместить в память, которой нет.

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

или что-то похожее на выше.

...