#include <opencv2corecore.hpp>
#include <opencv2highguihighgui.hpp>
#include <opencv2imgprocimgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
string path = "1.png";
Mat src = imread(path, 0);
//【1】创建一个复数矩阵,储存傅里叶变换后的矩阵
int r = getOptimalDFTSize(src.rows);
int c = getOptimalDFTSize(src.cols);//得到最优尺寸
Mat padded;
//扩充src的边缘,将图像变大( 0, r - src.rows, 0, c - src.cols)分别表示上下左右;
copyMakeBorder(src, padded, 0, r - src.rows, 0, c - src.cols, BORDER_CONSTANT, ::Scalar::all(0));
//创建一个复数矩阵,实部为plane[0],虚部plane[1]填充0
Mat plane[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };
//【2】傅里叶变换
Mat complexImg;
merge(plane, 2, complexImg); //可以理解为组合成2通道(实部+虚部)图像
dft(complexImg, complexImg); //DFT变换后的数据复制到原处,没有另外开辟内存, complexImg是个复数矩阵
int cx = complexImg.cols / 2;
int cy = complexImg.rows / 2;
Mat m1(complexImg, cv::Rect(0, 0, cx, cy)); //左上部分
Mat m2(complexImg, cv::Rect(cx, 0, cx, cy)); //右上部分
Mat m3(complexImg, cv::Rect(0, cy, cx, cy)); //左下部分
Mat m4(complexImg, cv::Rect(cx, cy, cx, cy)); //右下部分
Mat temp;
m1.copyTo(temp);
m4.copyTo(m1);
temp.copyTo(m4);
m2.copyTo(temp);
m3.copyTo(m2);
temp.copyTo(m3);
Mat partFrequencyImg;
complexImg.copyTo(partFrequencyImg);
//变换频率
int nx1 = int(0.5f*padded.cols);
int nx2 = int(0.5f*padded.cols);
int ny1 = int(0.5f*padded.rows);
int ny2 = int(0.5f*padded.rows);
//逆变换
partFrequencyImg.colRange(nx1, nx2+1).setTo(Scalar::all(0));
partFrequencyImg.rowRange(ny1, ny2+1).setTo(Scalar::all(0));
Mat iPartDft[] = { Mat::zeros(padded.size(),CV_32F),Mat::zeros(padded.size(),CV_32F) };
idft(partFrequencyImg, partFrequencyImg);
split(partFrequencyImg, iPartDft);
magnitude(iPartDft[0], iPartDft[1], iPartDft[0]);
cv::normalize(iPartDft[0], iPartDft[0], 1, 0, CV_MINMAX);
Mat l = iPartDft[0];
imshow("l", l);
waitKey(0);
}