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
this is the result using my Conv2ByFFT()
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.
精彩评论