2D卷积边界处理:零填充不起作用?

时间:2019-11-06 22:06:51

标签: c++ opencv convolution

我正在做一个家庭作业,我们需要编写一个获取图像和内核的函数,并且我们必须计算2d空间卷积。 使用高斯内核,可以得到预期的结果(图像模糊),但是如果我改用例如边缘检测内核(taken from here),则会发现某些功能无法正常工作(图像变灰)。

我想问题可能是边界处理(应为零填充),但我不确定完全正确实施还是最后归一化。 有没有一种方法可以显示浮动图片(例如,浮动图片的一个像素的值为25000),因为如果我不使用规范化,我认为它总是以255(白色)为上限。

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

int main(int argc, char *argv[])
{
    cv::Mat img = cv::imread("orig.jpg",0);             // load image as grayscale
    img.convertTo(img,CV_32FC1);                        // convert to float
    cv::Mat_<float> output(img.rows,img.cols);          // create new mat with same size as source image
    output = 0;   
    // creating a kernel (here Gaussian blur)
    cv::Mat_<float> kernel(5,5);
    kernel << 1,4,6,4,1,4,16,24,16,4,6,24,36,24,6,4,16,24,16,4,1,4,6,4,1;

    int kCenterX = kernel.cols/2;
    int kCenterY = kernel.rows/2;

    for (int i = 0; i < img.rows; i++){                 // for every row in image
        for (int j = 0; j < img.cols; j++){             // for every column in image
            for (int m = 0; m < kernel.rows; m++){      // for every row of kernel
                int mm = kernel.rows - 1 -m;            // row index of flipped kernel
                for (int n = 0; n < kernel.cols; n++){  // for every column of kernel
                    int nn = kernel.cols - 1 -n;        // column index of flipped kernel
                    // index for border handling
                    int ii = i + (m - kCenterY);
                    int jj = j + (n - kCenterX);
                    // checking if sample is still in bound of input image
                    // and if not, treat those pixels as 0 (because they won't get added to sum)
                    if (ii >= 0 && ii < img.rows && jj >= 0 && jj < img.cols)
                        output.at<float>(i,j) += img.at<float>(ii,jj) * kernel.at<float>(mm,nn);
                }
            }
        }
    }
    // normalize input and output image (might be wrong, but I don't know how else I can see float images
    cv::normalize(output, output, 0, 1, cv::NORM_MINMAX);
    cv::normalize(img, img, 0, 1, cv::NORM_MINMAX);
    // display images
    cv::imshow("Original", img);
    cv::imshow("Convolution", output);
    cv::waitKey(0);
    return 0;
}

0 个答案:

没有答案