原理:
傅里叶变换原理:任一函数都可以表示成无数个正弦和余弦函数的和的形式.
所以傅里叶变换就是一个用来将函数分解的工具.
代码实现:
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
Mat I=imread("/home/dongoa/opencv-prj/3/1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
if(I.empty()) return -1;
//将图像延伸扩展到最佳尺寸
Mat padded;
int m=getOptimalDFTSize(I.rows);//返回最佳尺寸
int n=getOptimalDFTSize(I.cols);
copyMakeBorder(I,padded,0,m-I.rows,0,n-I.cols,BORDER_CONSTANT,Scalar::all(0));
//参数:输入图像,输出图形,边框的粗细程度,然后是填充参数
//为傅里叶变换的结果实部和虚部分配存储空间
Mat planes[]={Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)};//建立一个planes矩阵数组
Mat complexI;//存放结果的矩阵图像
merge(planes,2,complexI);
//进行离散傅里叶变换
dft(complexI,complexI);
//将离散傅里叶变换的转换成幅度
split(complexI,planes);
magnitude(planes[0],planes[1],planes[0]);
Mat magI=planes[0];
//对数尺度缩放
magI += Scalar::all(1);
log(magI,magI);
//剪切和重分布幅度象限
magI=magI(Rect(0,0,magI.cols&-2,magI.rows&-2));//取小于等于cols最近的偶数
int cx=magI.cols/2;
int cy=magI.rows/2;
Mat q0(magI,Rect(0,0,cx,cy));
Mat q1(magI,Rect(cx,0,cx,cy));
Mat q2(magI,Rect(0,cy,cx,cy));
Mat q3(magI,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(magI,magI,0,1,CV_MINMAX);
imshow("Input",I);
imshow("magnitude",magI);
waitKey();
return 0;
}
应用:
决定图片中物体的几何方向.