1.图像的傅里叶频谱的意义
之前的博文其实已经归纳过这方面的内容了。我们常用的图像平滑处理,其实就是一个低通滤波,一定程度上去除高频信号,可以使得图像变得柔和(也就是平滑)。但是,在去除周期性噪声时候,空间域内的滤波(卷积)就不是那么好操作了。所以,这里时候,无论是理解起来方便,还是其他原因,都需要在频域内进行滤波。
详细的叙述还是在下面的博文里面啦!!!!
[数字图像处理]频域滤波(1)–基础与低通滤波器
[数字图像处理]频域滤波(2)–高通滤波器,带阻滤波器与陷波滤波器
2. 傅里叶频谱的计算
这部分的内容,主要就是使用openCV自带的函数
void cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows=0 )
去求取图像的傅里叶变换。这里,输出结果CvArr* dst由两个通道组成,分别代表了实部与虚部。我们再根据如下算式,就可以得到傅里叶频谱了。
|F(u,v)|=R2(u,v)+F2(u,v)−−−−−−−−−−−−−−−√2
我自己也参考了很多人的代码,然后实现的代码如下。
IplImage* fft2(IplImage* image_input)
{
int dftWidth = getOptimalDFTSize(image_input->width);
int dftHeight = getOptimalDFTSize(image_input->height);
//cout<< " Width" << image_input->width << " " << dftWidth << "\n";
//cout<< "Height" << image_input->height << " " << dftHeight << "\n";
IplImage* image_padded = cvCreateImage(cvSize(dftWidth,dftHeight),
IPL_DEPTH_8U,
1);
cvCopyMakeBorder( image_input, image_padded, cvPoint(0,0), IPL_BORDER_CONSTANT,cvScalarAll(0));
IplImage *image_Re =0 , *image_Im = 0, *image_Fourier = 0;
image_Re = cvCreateImage(cvSize(dftWidth,dftHeight),IPL_DEPTH_64F,1);
image_Im = cvCreateImage(cvSize(dftWidth,dftHeight),IPL_DEPTH_64F,1);
image_Fourier = cvCreateImage(cvSize(dftWidth,dftHeight),IPL_DEPTH_64F,2);
//image_Re <--- image_padded
cvConvertScale(image_padded,image_Re);
//image_Im <--- 0
cvZero(image_Im);
//image_Fourier[0] <--- image_Re
//image_Fourier[1] <--- image_Im
cvMerge(image_Re,image_Im,0,0,image_Fourier);
cvDFT(image_Fourier,image_Fourier,CV_DXT_FORWARD);
//image_Fourier[0] ---> image_Re
//image_Fourier[1] ---> image_Im
cvSplit(image_Fourier,image_Re,image_Im,0,0);
//Mag = sqrt(Re^2 + Im^2)
cvPow(image_Re,image_Re,2.0);
cvPow(image_Im,image_Im,2.0);
cvAdd(image_Re,image_Im,image_Re);
cvPow(image_Re,image_Re,0.5);
// log (1 + Mag)
cvAddS(image_Re,cvScalar(1),image_Re );
cvLog (image_Re,image_Re);
// |-----|-----| |-----|-----|
// | 1 | 3 | | 4 | 2 |