1 #include<opencv2/opencv.hpp>
2 #include<iostream>
3
4 using namespace std;
5 using namespace cv;
6
7 int main() {
8 //以灰度图读取原始图像并显示
9 Mat srcImage = imread("C:\\Users\\Nelsoner\\Desktop\\Camera Roll\\05.jpg", 0);
10
11 if (!srcImage.data) {
12 cout << "读取图片出错!" << endl;
13 return false;
14 }
15 imshow("原始图像", srcImage);
16
17 //ShowHelpText();
18
19 //将输入图像延扩到最佳的尺寸,边界用0补充
20 int m = getOptimalDFTSize(srcImage.rows);
21 int n = getOptimalDFTSize(srcImage.cols);
22
23 //将添加的像素初始化为0
24 Mat padded;
25 copyMakeBorder(srcImage, padded, 0, m - srcImage.rows, 0, n - srcImage.cols, BORDER_CONSTANT, Scalar::all(0));
26
27 //为傅里叶变换的结果(实部和虚部)分配存储空间
28 //将planes数组组合合并成一个多通道的数组complexI
29 Mat planes[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };
30 Mat complexI;
31 merge(planes, 2, complexI);
32
33 //进行就地离散傅里叶变换
34 dft(complexI, complexI);
35
36 //将复数转换为幅值,即=>log(1+sqrt(Re(DFT(I))^2+Im(DFT(I))^2))
37 split(complexI, planes); //将多通道数组complexI分离成几个单通道数组,planes[0] = Re(DFT(I),planes[1] = Im(DFT(I)))
38 magnitude(planes[0], planes[1], planes[0]);
39 Mat magnitudeImage = planes[0];
40
41 //进行对数尺度(logarithmic scale)缩放
42 magnitudeImage += Scalar::all(1);
43 log(magnitudeImage, magnitudeImage); //求自然对数
44
45 //剪切和重分布幅度图象限
46 //若有奇数行或奇数列,进行频谱裁剪
47 magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols &-2, magnitudeImage.rows&-2));
48
49 //重新排列傅里叶图像中的象限,使得原点位于图像中心
50 int cx = magnitudeImage.cols / 2;
51 int cy = magnitudeImage.rows / 2;
52 Mat q0(magnitudeImage, Rect(0, 0, cx, cy)); //ROI区域的左上
53 Mat q1(magnitudeImage, Rect(cx, 0, cx, cy)); //ROI区域的右上
54 Mat q2(magnitudeImage, Rect(0, cy, cx, cy)); //ROI区域的左下
55 Mat q3(magnitudeImage, Rect(cx, cy, cx, cy)); //ROI区域的右下
56
57 //交换象限(左上与右下进行交换)
58 Mat tmp;
59 q0.copyTo(tmp);
60 q3.copyTo(q0);
61 tmp.copyTo(q3);
62
63 //交换象限(右上与左下进行交换) Mat tmp;
64 q1.copyTo(tmp);
65 q2.copyTo(q1);
66 tmp.copyTo(q2);
67
68 //归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
69 normalize(magnitudeImage, magnitudeImage, 0, 1, CV_MINMAX);
70
71 //显示效果图
72 imshow("频谱赋值", magnitudeImage);
73 waitKey();
74
75 return 0;
76 }
