OpenCv实现高斯模糊

时间:2015-04-02 18:23:40

标签: c++ opencv filtering

我想在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];
            }

        }
    }
}

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

1 个答案:

答案 0 :(得分:1)

更改

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循环所以不必检查你是否是要触摸图像边框,如果你在一些局部const变量中存储了不同的cv::Mat尺寸,并在循环中使用它们。最后,sum(kernel)是常量,因此您也可以预先计算该值。