首页 > 代码库 > 离散傅里叶变换

离散傅里叶变换

 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 }

技术分享

 

离散傅里叶变换