//---------------------------------【头文件、命名空间包含部分】-----------------------------
// 描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include
using namespace cv;
using namespace std;//--------------------------------------【main( )函数】-----------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-------------------------------------------------------------------------------------------------
int main( )
{//【1】以灰度模式读取原始图像并显示Mat srcImage &#61; imread("/home/arthur/Documents/Project/OpenCVProject/cvdemo/11.tif", 0);if(!srcImage.data ) { printf("读取图片错误&#xff0c;请确定目录下是否有imread函数指定图片存在~&#xff01; \n"); return false; }imshow("原始图像" , srcImage);//【2】将输入图像延扩到最佳的尺寸&#xff0c;边界用0补充int m &#61; getOptimalDFTSize( srcImage.rows );int n &#61; getOptimalDFTSize( srcImage.cols );//将添加的像素初始化为0.Mat padded;copyMakeBorder(srcImage, padded, 0, m - srcImage.rows, 0, n - srcImage.cols, BORDER_CONSTANT, Scalar::all(0));cout <<"srcSize:" <(padded), Mat::zeros(padded.size(), CV_32F)};Mat complexI;merge(planes, 2, complexI);//【4】进行就地离散傅里叶变换dft(complexI, complexI);cout < log(1 &#43; sqrt(Re(DFT(I))^2 &#43; Im(DFT(I))^2))split(complexI, planes); // 将多通道数组complexI分离成几个单通道数组&#xff0c;planes[0] &#61; Re(DFT(I)), planes[1] &#61; Im(DFT(I))magnitude(planes[0], planes[1], planes[0]);// planes[0] &#61; magnitude计算二维矢量的幅值Mat magnitudeImage &#61; planes[0];//【6】进行对数尺度(logarithmic scale)缩放magnitudeImage &#43;&#61; Scalar::all(1);imshow("beforelog",magnitudeImage);log(magnitudeImage, magnitudeImage);//求自然对数normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX);imshow("afterlognor", magnitudeImage);//【7】剪切和重分布幅度图象限//若有奇数行或奇数列&#xff0c;进行频谱裁剪magnitudeImage &#61; magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));//重新排列傅立叶图像中的象限&#xff0c;使得原点位于图像中心int cx &#61; magnitudeImage.cols/2;int cy &#61; magnitudeImage.rows/2;Mat q0(magnitudeImage, Rect(0, 0, cx, cy)); // ROI区域的左上Mat q1(magnitudeImage, Rect(cx, 0, cx, cy)); // ROI区域的右上Mat q2(magnitudeImage, Rect(0, cy, cx, cy)); // ROI区域的左下Mat q3(magnitudeImage, Rect(cx, cy, cx, cy)); // ROI区域的右下//交换象限&#xff08;左上与右下进行交换&#xff09;Mat tmp;q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);//交换象限&#xff08;右上与左下进行交换&#xff09;q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//【8】归一化&#xff0c;用0到1之间的浮点值将矩阵变换为可视的图像格式//此句代码的OpenCV2版为&#xff1a;//normalize(magnitudeImage, magnitudeImage, 0, 1, CV_MINMAX);//此句代码的OpenCV3版为:normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX);//【9】显示效果图imshow("频谱幅值", magnitudeImage);waitKey();return 0;
}