离散傅里叶变换

前言

本节学习离散傅里叶变换,好难啊~分两天学习

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <time.h>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

int main(){
Mat srcIamge = imread("3.jpg",0);
if(!srcIamge.data){
printf("Failed!");
return 0;
}
imshow("srcImage",srcIamge);

int m = getOptimalDFTSize(srcIamge.rows);
int n = getOptimalDFTSize(srcIamge.cols);

Mat padded;
copyMakeBorder(srcIamge,padded,0,m - srcIamge.rows,0,n - srcIamge.cols,BORDER_CONSTANT,Scalar::all(0));

Mat planes[] = {Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)};
Mat complexI;
merge(planes,2,complexI);

dft(complexI,complexI);

split(complexI,planes);
magnitude(planes[0],planes[1],planes[0]);
Mat magnitudeImage = planes[0];

magnitudeImage = magnitudeImage(Rect(0,0,magnitudeImage.cols & -2,magnitudeImage.rows & -2));
int cx = magnitudeImage.cols / 2;
int cy = magnitudeImage.rows / 2;
Mat q0(magnitudeImage, Rect(0,0,cx,cy));
Mat q1(magnitudeImage, Rect(cx,0,cx,cy));
Mat q2(magnitudeImage, Rect(0,cy,cx,cy));
Mat q3(magnitudeImage, Rect(cx,cy,cx,cy));

Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);

normalize(magnitudeImage,magnitudeImage,0,1,NORM_MINMAX);

imshow("dstImage",magnitudeImage);
waitKey();

return 0;
}

一:dft()函数

参数解释:
第一个参数为输入图像,可以是实数或虚数
第二个参数为输出图像,其大小和类型取决于第三个参数flags
第三个参数为转换的标识符,有默认值0.其可取的值如下所示:
DFT_INVERSE: 用一维或二维逆变换取代默认的正向变换
DFT_SCALE: 缩放比例标识符,根据数据元素个数平均求出其缩放结果,如有N个元素,则输出结果以1/N缩放输出,常与DFT_INVERSE搭配使用。
DFT_ROWS: 对输入矩阵的每行进行正向或反向的傅里叶变换;此标识符可在处理多种适量的的时候用于减小资源的开销,这些处理常常是三维或高维变换等复杂操作。
DFT_COMPLEX_OUTPUT: 对一维或二维的实数数组进行正向变换,这样的结果虽然是复数阵列,但拥有复数的共轭对称性(CCS),可以以一个和原数组尺寸大小相同的实数数组进行填充,这是最快的选择也是函数默认的方法。你可能想要得到一个全尺寸的复数数组(像简单光谱分析等等),通过设置标志位可以使函数生成一个全尺寸的复数输出数组。
DFT_REAL_OUTPUT: 对一维二维复数数组进行逆向变换,这样的结果通常是一个尺寸相同的复数矩阵,但是如果输入矩阵有复数的共轭对称性(比如是一个带有DFT_COMPLEX_OUTPUT标识符的正变换结果),便会输出实数矩阵。
int nonzeroRows = 0: 当这个参数不为0,函数会假设只有输入数组(没有设置DFT_INVERSE)的第一行或第一个输出数组(设置了DFT_INVERSE)包含非零值。这样的话函数就可以对其他的行进行更高效的处理节省一些时间,这项技术尤其是在采用DFT计算矩阵卷积时非常有效。