使用copymakeborder函数实现2D卷积滤波器

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

我正在尝试实现2D卷积滤波器。我首先使用copymakeborder来创建图像的边框,然后再遍历图像并适当地过滤。然后,我使用colRange和rowRange删除填充,然后将格式化的图片复制到输出矩阵中。

但是图片显示不正确。我一直陷在这个问题上,我找不到错误。我想我已经忽略了一些东西,但是我不确定在哪里。

有人可以帮我吗?

void algorithms::manual_filter_2d(const Mat & input, Mat & output, const Mat & kernel) {

    Mat temp_image(input.rows, input.cols, input.type());
    cv::copyMakeBorder(input, temp_image, (kernel.cols) / 2, (kernel.cols) / 2, (kernel.rows) / 2, (kernel.rows) / 2, cv::BORDER_REPLICATE);

    Mat temp_output(temp_image.rows, temp_image.cols, input.type());

    for (int y = (kernel.rows - 1) / 2; y < temp_image.rows - ((kernel.rows) / 2); y++) {
        for (int x = (kernel.cols - 1) / 2; x < temp_image.cols - ((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 += temp_image.at < float > (y + ky - ((kernel.rows - 1) / 2), x + kx - ((kernel.cols - 1) / 2)) * kernel.at < float > (ky, kx);
                }
            }
            temp_output.at < float > (y - kernel.rows / 2, x - kernel.cols / 2) = sum;
        }
    }
    temp_output.rowRange((kernel.rows - 1) / 2, temp_image.rows - ((kernel.rows) / 2)).colRange((kernel.cols - 1) / 2, temp_image.cols - ((kernel.cols) / 2)).copyTo(output);
}
c++ opencv convolution
1个回答
0
投票

设置卷积结果的坐标是错误的

    // copy input image using a tmp one
    Mat temp_image(input.rows, input.cols, input.type());
    // pad image using border duplication
    cv::copyMakeBorder(input, temp_image, (kernel.cols)/2, (kernel.cols)/2, (kernel.rows)/2, (kernel.rows)/2, cv::BORDER_REPLICATE);
    // output image
    Mat temp_output(temp_image.rows, temp_image.cols, input.type());

    // move over the image
    for(int y=(kernel.rows-1)/2; y<temp_image.rows-((kernel.rows)/2); y++) {
        for(int x=(kernel.cols-1)/2; x<temp_image.cols-((kernel.cols)/2); x++) {

            float sum = 0.0f;
            // loop inside the kernel
            for (int ky=0; ky<kernel.rows; ky++) {
                for (int kx=0; kx<kernel.cols; kx++) {
                    sum += temp_image.at<float>(y + ky - ((kernel.rows - 1) / 2), x + kx - ((kernel.cols - 1) / 2)) *kernel.at<float>(ky, kx);
                }
            }
            // center inside the image respect to the kernel
            temp_output.at<float>(y,x) = sum;
        }
    }
    // copy convolution result into output image
    temp_output.rowRange((kernel.rows-1)/2, temp_image.rows-((kernel.rows)/2)).colRange((kernel.cols-1)/2, temp_image.cols-((kernel.cols)/2)).copyTo(output);
}
© www.soinside.com 2019 - 2024. All rights reserved.