有这样一段话,刚开始不好理解:根据傅里叶变换理论,频域中的频谱值都是由整幅图像计算出来的,因此,整个频谱范围内,低频分量集中在四个角,且其它地方的值只可能比这个值小。
冈萨雷斯版<图像处理>里面的解释非常形象:一个恰当的比喻是将傅里叶变换比作一个玻璃棱镜。棱镜是可以将光分解为不同颜色的物理仪器,每个成分的颜色由波长(或频率)来决定。就我的理解,傅里叶变换使数学上的棱镜,将某个函数(本文指图像)基于频率分解成不同部分。在物理中,研究光是通过研究光谱,而傅里叶变换使通过研究频谱。
如上一篇博客所述:图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度。而傅立叶变换的物理意义是:将图像的灰度分布函数变换为图像的频率分布函数,傅立叶逆变换是将图像的频率分布函数变换为灰度分布函数。
为什么需要傅里叶变换呢?我们知道,傅里叶变换是将时域信号分解为不同频率的正弦信号和余弦信号之和。而时域信号只能反映信号的幅值随时间的变化情况,除了单频率分量的简谐波外,很难对信息频率的组成及频率分量的大小进行详细分析。而信号频谱显然提供了更丰富的信息。在实际的图像处理中,我们仅仅使用了图像的幅度信息,因为幅度信息基本包含了所有的几何信息。但是!!但是!!如果你想通过修改幅度或者相位的方法,来间接修改原空间图像,你需要使用逆傅里叶变换来得到修改后的空间图像,这样,你就必须同时保留幅度图像和相位图像。
从傅里叶的频谱谱中可以看到敏感不一的亮点,反映的就是某点与邻域间的差异程度,即图像梯度。低频部分指的是低梯度的点,高频部分指的是高梯度的点。一般而言,梯度大的点,则该点的亮度强,梯度小的点亮度弱。我们知道,通过傅里叶变换得到的频谱图,也叫做功率图,从功率图中可以看出图像的能量分布。如果频谱中暗色调的点比较多,说明大多数点与其邻域的差异不大,那么图像就比较柔和。反之,图像一定是很尖锐的、边界分明的。
将频谱移频到原点以后,可以看出图像的频率分布是以原点为圆心,对称分布的。将频谱移频到圆心除了可以清晰地看出图像频率分布以外,还有一个好处,它可以分离出有周期性规律的干扰信号,比如正弦干扰,一副带有正弦干扰,移频到原点的频谱图上可以看出除了中心以外还存在以某一点为中心,对称分布的亮点集合,这个集合就是干扰噪音产生的,这时可以很直观的通过在该位置放置带阻滤波器消除干扰。
离散傅里叶变换的代码如下:
# include <opencv2/core/core.hpp> # include <opencv2/highgui/highgui.hpp> # include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; cv::Mat DFT(cv::Mat srcImage) { cv::Mat srcGray; cvtColor(srcImage,srcGray,CV_RGB2GRAY); // 将输入图像延扩到最佳的尺寸 int nRows = getOptimalDFTSize(srcGray.rows); int nCols = getOptimalDFTSize(srcGray.cols); cv::Mat resultImage; // 把灰度图像放在左上角,在右边和下边扩展图像, // 添加的像素初始化为0 copyMakeBorder(srcGray, resultImage, 0, nRows - srcGray.rows, 0, nCols - srcGray.cols, BORDER_CONSTANT, Scalar::all(0)); // 为傅立叶变换的结果(实部和虚部)分配存储空间 cv::Mat planes[] = { cv::Mat_<float>(resultImage), cv::Mat::zeros(resultImage.size(), CV_32F)}; Mat completeI; // 为延扩后的图像增添一个初始化为0的通道 merge(planes,2,completeI); // 进行离散傅立叶变换 dft(completeI,completeI); // 将复数转换为幅度 split(completeI,planes); magnitude(planes[0],planes[1],planes[0]); cv::Mat dftResultImage = planes[0]; // 对数尺度(logarithmic scale)缩放 dftResultImage += 1; log(dftResultImage,dftResultImage); // 剪切和重分布幅度图象限 dftResultImage= dftResultImage(Rect(0, 0,srcGray.cols,srcGray.rows)); // 归一化图像 normalize(dftResultImage,dftResultImage, 0,1,CV_MINMAX); int cx = dftResultImage.cols/2; int cy = dftResultImage.rows/2; Mat tmp; // Top-Left - 为每一个象限创建ROI Mat q0(dftResultImage,Rect(0,0,cx,cy)); // Top-Right Mat q1(dftResultImage,Rect(cx,0,cx,cy)); // Bottom-Left Mat q2(dftResultImage,Rect(0,cy,cx,cy)); // Bottom-Right Mat q3(dftResultImage,Rect(cx,cy,cx,cy)); // 交换象限 (Top-Left with Bottom-Right) q0.copyTo(tmp); q3.copyTo(q0); tmp.copyTo(q3); // 交换象限 (Top-Right with Bottom-Left) q1.copyTo(tmp); q2.copyTo(q1); tmp.copyTo(q2); return dftResultImage; } int main() { cv::Mat srcImage = imread("1.jpg"); if(srcImage.empty()) return-1; imshow("srcImage", srcImage); cv::Mat resultImage = DFT(srcImage); imshow("resultImage", resultImage); cv::waitKey(0); return 0; }结果:
分析:
1、图像经过二维傅立叶变换后,其变换系数矩阵表明:若变换矩阵Fn原点设在中心,其频谱能量集中分布在变换系数短阵的中心附近(图中阴影区)。若所用的二维傅立叶变换矩阵Fn的原点设在左上角,那么图像信号能量将集中在系数矩阵的四个角上。这是由二维傅立叶变换本身性质决定的。同时也表明一股图像能量集中低频区域。 2 、变换之后的图像在原点平移之前四角是低频,最亮,平移之后中间部分是低频,最亮,亮度大说明低频的能量大(幅角比较大)