opencv显示图像的傅里叶谱图像(频谱)源代码详解

来源:互联网 发布:小说哪个软件好 编辑:程序博客网 时间:2024/05/24 05:26

1. 频率域

通过傅里叶变换连接空间域和频率域,其是频率域滤波的基础。这里将结合opencv中的sample文档(\source\sample目录下的dft.cpp),对一副灰度图像进行傅里叶变换,并显示其傅里叶谱图像。


2. 傅里叶谱显示

#include<opencv.hpp>#include<iostream>int main(void){//加载一副灰度图像cv::Mat src=cv::imread("D:/Opencv Picture/Lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);if (!src.data){std::cout << "Image Load Fail!!!" << "\n";return 1;}cv::imshow("SRC", src);//扩充图像尺寸到最佳尺寸,边界用0填充int r = cv::getOptimalDFTSize(src.rows);int c = cv::getOptimalDFTSize(src.cols);cv::Mat padded;cv::copyMakeBorder(src, padded, 0, r - src.rows, 0, c - src.cols, cv::BORDER_CONSTANT,cv::Scalar::all(0));//为傅里叶变换的结果(复数,包含实部和虚部,所以需要创建一个二维的数组)分配存储空间,//需要用至少float型来存储//最后将二维数组合并为二通道--傅里叶变换需要cv::Mat dst1[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) };cv::Mat dst2;cv::merge(dst1,2, dst2);//傅里叶变换,结果依旧存储在dst2中cv::dft(dst2, dst2);//将复数换算成幅值cv::split(dst2, dst1);//把二通道图像分解为二维数组,保存到dst1中,dst1[0]中存放的为实部cv::magnitude(dst1[0], dst1[1], dst1[0]);//结果存放在dst1[0]中cv::Mat magnitudeImage = dst1[0];//对数尺度缩放以便于显示//计算log(1 + sqrt(Re(DFT(dst2))**2 + Im(DFT(dst2))**2))magnitudeImage += cv::Scalar::all(1);cv::log(magnitudeImage, magnitudeImage);//剪切和重分布幅度图象限//若有奇数行或奇数列,进行频谱裁剪magnitudeImage = magnitudeImage(cv::Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));//任何一个数&-2的结果一定是偶数//重新排列傅里叶图像的象限,使原点位于图像中心int cx = magnitudeImage.cols / 2;int cy = magnitudeImage.rows / 2;cv::Mat q0(magnitudeImage(cv::Rect(0, 0, cx, cy)));cv::Mat q1(magnitudeImage(cv::Rect(cx, 0, cx, cy)));cv::Mat q2(magnitudeImage(cv::Rect(0, cy, cx, cy)));cv::Mat q3(magnitudeImage(cv::Rect(cy, cy, cx, cy)));cv::Mat tmp;q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//将幅度值归一化到0~1之间,这是因为magnitudeImage中的数据类型是浮点型,这时用imshow()来显示函数,会将像素值乘于255,因此需要归一化到0~1之间cv:normalize(magnitudeImage, magnitudeImage, 0, 1, cv::NORM_MINMAX);//显示最后的频谱cv::imshow("spectrum magnitude", magnitudeImage);cv::waitKey();return 0;}

3. 显示结果

运行结果如下。


下面来一步步看看,各个步骤的作用。如果不进行归一化处理的结果如下图所示,整个画面发白,根本看不到任何信息。


如果不进行象限调整,结果如下,低频出现在图片的四个角(四角发亮),而通过调整之后将低频调整到了原点附近。



如果不进行尺度调整,可以发现对比度不高,仅仅能看到中心一个亮点,说明尺度调整后,能显示更多细节。