#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.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); }