OpenCv 实现高斯模糊

OpenCv Implementing Gaussian Blur

我想在 opencv 中实现高斯模糊功能,但是当我尝试时我得到了一个有噪声的图像。这是我的代码:

int main( int argc, char** argv )
{
    src = imread( "fruits.jpg", 0 );

    gauss3x3 = Mat(src.cols,src.rows,src.type()); //src.clone();

    Mat kernelX = getGaussianKernel(3, 1);
    Mat kernelY = getGaussianKernel(3, 1);
    Mat kernelXY = kernelX * kernelY.t();

    filter(src,gauss3x3,kernelXY);

    namedWindow( window_name4, WINDOW_AUTOSIZE );
    imshow(window_name4,gauss3x3);
}

void filter(Mat src, Mat dst, Mat kernel) {
    cout << "filter" << endl;

    for(int i=0; i<src.rows - 0; i++) {
        for(int j=0; j<src.cols - 0; j++) {
            float p = 0;
            for(int k=0; k<kernel.rows; k++) {
                for(int l=0; l<kernel.cols; l++) {
                    if(i+k < src.rows && j+l < src.cols) {
                        p += (src.at<uchar>(i + k,j + l) * kernel.at<uchar>(k,l));                    
                    }
                }
            }

            if(i + kernel.rows/2 < src.rows && j + kernel.cols/2 < src.cols) {
                dst.at<uchar>(i + kernel.rows/2,j + kernel.cols/2) = p / sum(kernel)[0];
            }

        }
    }
}

我对解决方案一无所知。任何帮助将不胜感激。

改变

kernel.at<uchar>(k,l)

至:

kernel.at<double>(k,l)

重点是内核默认的数据类型是CV_64F,对应double(documentation).

此外,请检查您的输入图像是否严格为灰度图像。要支持颜色,您必须在开始时检测图像类型并区分您的代码。要创建该函数的颜色版本,您必须首先使用 .at<cv::Vec3b> 代替 .at<uchar>(当然这不是唯一必要的修改)。

我还建议您将函数声明更改为:

void filter(const Mat& src, Mat& dst, const Mat& kernel) {

算法的其余部分看起来不错,除了它可能很慢之外,如果您避免使用 at 方法并限制 for 循环以便不必检查是否您将触摸图像边框,如果您将不同的 cv::Mat 大小存储在某个本地 const 变量中,并在循环中使用它们。最后,sum(kernel) 是常量,因此您也可以预先计算该值。