开发者

questions about self-defined Gaussian blur using convolution

I am writing a function Conv2ByFFT() to do the Gaussian blur which is similar to the GaussianBlur() in openCV api. But as i compare the effects between by function and GaussianBlur() api, i find that the former is not as "blurred" as the latter and i don't know why.

this is the "correct" one

questions about self-defined Gaussian blur using convolution

this is the result using my Conv2ByFFT()

questions about self-defined Gaussian blur using convolution

here's some code

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 returns a vector of coefficients, not a 2-d kernel.

As the 2-d Gaussian kernel is separable, in the convolution method, this vector is applied in both directions which has the same effect as applying the full kernel all at once.

Your FFT function merely convolves the vector with the image. I think if you look carefully, the blur is only in one direction.

You need to create a full 2-d gaussian kernel, and apply that. Alternatively, I think you can make use of the separability and apply the vector twice.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜