image-processing - 关于使用卷积自定义高斯模糊的问题

标签 image-processing opencv gaussian

我正在编写一个函数 Conv2ByFFT() 来执行高斯模糊,这类似于 openCV api 中的 GaussianBlur()。但是当我比较 by function 和 GaussianBlur() api 之间的效果时,我发现前者没有后者那么“模糊”,我不知道为什么。

这是“正确的” this is the "correct" one

这是使用我的 Conv2ByFFT() 的结果 this is the result using my Conv2ByFFT()

这是一些代码

void Conv2ByFFT(const Mat& f,const Mat& g,Mat& result)
{
result.create(abs(f.rows-g.rows)+1,abs(f.cols-g.cols)+1,f.type());

//pad the images and get optimal FFT size
Size dftSize;
dftSize.width = getOptimalDFTSize(f.cols + g.cols - 1);
dftSize.height = getOptimalDFTSize(f.rows + g.cols - 1);

Mat tmpF(dftSize,f.type(),Scalar::all(0));
Mat tmpG(dftSize,g.type(),Scalar::all(0));

Mat roiF(tmpF, Rect(0,0,f.cols,f.rows));
f.copyTo(roiF);
Mat roiG(tmpG, Rect(0,0,g.cols,g.rows));
g.copyTo(roiG);

//perform Fourier Transform
dft(tmpF,tmpF,0,f.rows);
dft(tmpG,tmpG,0,g.rows);

//perform per-element multiplication of two Fourier spectrums
mulSpectrums(tmpF,tmpG,tmpF,0);

//perform inverse Fourier Transform
dft(tmpF,tmpF,DFT_INVERSE+DFT_SCALE,result.rows);

tmpF(Rect(0,0,result.cols,result.rows)).copyTo(result);
}

int main()
{
//read image
const char* imagename = "c:\\lena.bmp";
Mat img = imread(imagename);

//check image
if(img.empty())
{  fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
} 
if( !img.data )
    return -1;

Mat src;

//convert the rgbimage into grayimage
cvtColor(img,src,CV_BGR2GRAY);

//save the grayimage
imwrite("lenagray.bmp",src);

//convert the image into float type 
src.convertTo(src,CV_64FC1);


//******************************************************************************
//                    use GaussianBlur() in openCV
//******************************************************************************

//use Gaussian filter to blur the image
Mat dst = src.clone();
GaussianBlur(src,dst,Size(11,11),2);

//show and save the result
dst.convertTo(dst,CV_8U);
imshow("image",dst);
imwrite("lenablur.bmp",dst);

//******************************************************************************
//                    use GaussianBlur() in openCV
//******************************************************************************




//******************************************************************************
//                    use self-defining Conv2ByFFT()
//******************************************************************************

Mat result;

Mat gaussianFilter = getGaussianKernel(11,2,CV_64FC1);

//do the convolution to blur the image
Conv2ByFFT(src,gaussianFilter,result);

//show and save the result
result.convertTo(result,CV_8U);
//imshow("image1",result);
imwrite("lenablur1.bmp",result);

//******************************************************************************
//                    use self-defining Conv2ByFFT()
//******************************************************************************


cvWaitKey();
return 0;
}

最佳答案

getGaussianKernel 返回系数向量,而不是二维内核。

由于二维高斯核是可分离的,在卷积方法中,这个向量在两个方向上应用,与一次应用完整核具有相同的效果。

您的 FFT 函数只是将矢量与图像进行卷积。我想如果你仔细看,模糊只是在一个方向上。

您需要创建一个完整的二维高斯核,然后应用它。或者,我认为您可以利用可分离性并将向量应用两次。

关于image-processing - 关于使用卷积自定义高斯模糊的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7735719/

相关文章:

opencv - 如何检测大小可变的部分矩形

python - 如何使用 opencv.omnidir 模块去扭曲鱼眼图像

cuda - 从 CUDA 中的高斯分布生成随机数

c++ - 使用网络摄像头时 ffmpeg 启动太慢(与使用 OpenCV 相同)

python - 使用python对二维散点图进行高斯求和

python - 如何用 Python 生成 2D 高斯?

python - 从 PyTorch 自定义数据集的 __getitem__ 中的巨大未压缩 tar 文件读取图像的最快方法

algorithm - 使用什么算法来标准化图像上某人的脸?

php - 如何使用 ImageMagick 对图像的一部分进行像素化?

c++ - OpenCV 错误:断言失败 (buf.data && buf.isContinuous()) 在 cv::imdecode_,文件 ..\..\..\..\opencv\modules\highgui\src\loadsave.cpp