/*傅里叶变换*/
#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main() {
Mat img = imread("D://图片//5.jpg");
if (img.empty())
return -1;
cvtColor(img, img, CV_BGR2GRAY);
Mat tempic = img.clone();
int r = getOptimalDFTSize(img.rows); //尺寸是2,3,5的倍数时处理速度最快,得到合适的尺寸
int c = getOptimalDFTSize(img.cols);
Mat padded;
copyMakeBorder(tempic, padded, 0, r - img.rows, 0, c - img.cols, BORDER_CONSTANT, Scalar::all(0)); //填充,填充纯色对结果影响不大
Mat planes[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) }; //dft要分别计算实部和虚部,把要处理的图像作为输入的实部、一个全零的图像作为输入的虚部
Mat complex;
merge(planes, 2, complex); //dft()输入和输出应该分别为单张图像,所以要先用merge()把实虚部图像合并,分别处于图像complex的两个通道内,计算得到的实虚部仍然保存在complex的两个通道内
dft(complex, complex);
split(complex, planes);
magnitude(planes[0], planes[1], planes[0]); //magnitude = sqrt(Re(DFT)^2 + Im(DFT)^2)
Mat result = planes[0];
result += Scalar::all(1);
log(result, result); //幅度的变化范围很大,容易造成一大片漆黑,只有几个点很亮。所以要用log函数把数值的范围缩小,但是仍然不能保证在[0,255]之间
result = result(Rect(0, 0, result.cols & -2, result.rows & -2));
int center_x = result.cols / 2;
int center_y = result.rows / 2;
Mat q0(result, Rect(0, 0, center_x, center_y)); // dft()直接获得的结果低频部分位于四角,高频部分位于中间,把图像做四等份,互相对调,让频域原点位于中心
Mat q1(result, Rect(center_x, 0, center_x, center_y));
Mat q2(result, Rect(0, center_y, center_x, center_y));
Mat q3(result, Rect(center_x, center_y, center_x, center_y));
Mat temp;
q0.copyTo(temp);
q3.copyTo(q0);
temp.copyTo(q3);
q1.copyTo(temp);
q2.copyTo(q1);
temp.copyTo(q2);
normalize(result, result, 0, 1, CV_MINMAX); //投射到[0,1],再通过convertTo转到[0,255]
Mat res;
result.convertTo(res, CV_8U);
imshow("result", result);
destroyAllWindows;
waitKey(0);
return 0;
}
傅里叶变换
最新推荐文章于 2024-01-17 16:50:08 发布