Advertisement

二维图像的离散傅立叶变换处理

阅读量:

尽管离第一次接触傅立叶变换已经好几年了,但是至今还是不理解,想想数学课和小波课都白上了哭。今天又重温傅立叶变换,又写了代码。

我的习惯先上代码,再讲原理:

代码:

复制代码
 #include <opencv/cv.h>

    
 #include <opencv2/contrib/contrib.hpp>
    
 #include <opencv/highgui.h>
    
 #include "opencv2/core/core.hpp"
    
 #include "opencv2/imgproc/imgproc.hpp"
    
 #include "opencv2/highgui/highgui.hpp"
    
 #include <iostream>
    
 using namespace cv;
    
  
    
 int main(int argc,char** argv)
    
 {
    
 	Mat img = imread("D:\ 1.jpg");//原图为彩图
    
 	Mat gray_img(img.size(),CV_32F);//
    
 	if(img.empty())
    
 	{
    
 		return false;
    
 	}
    
 	if(img.channels()!=1)
    
 	{
    
 		cvtColor(img,gray_img,CV_BGR2GRAY);//将原图转换为灰度图
    
 	}
    
 	Mat expanded;
    
 	int height = getOptimalDFTSize(gray_img.rows);//DFT变换找到最合适的图像的长宽,下面会介绍原理
    
 	int width = getOptimalDFTSize(gray_img.cols);
    
 	expanded.create(height,width,CV_32F);
    
 	copyMakeBorder(gray_img,expanded,0,height-gray_img.rows,0,width-gray_img.cols,BORDER_CONSTANT,Scalar::all(0));//将原图像扩充
    
  
    
 	Mat plural[]={Mat_<float>(expanded),Mat::zeros(expanded.size(),CV_32F)};//注意Mat_为模板,下面会介绍
    
 	Mat complex;
    
 	merge(plural,2,complex);//merge(Mat* input,size_t count,Mat* output)//merge根据参数不同,意义不同
    
  
    
 	dft(complex,complex);//dft变换
    
 	split(complex,plural);
    
 	magnitude(plural[0],plural[1],plural[0]);//dft转换后的图像只有转换为幅度图才能显示出来
    
 	Mat Image = plural[0];
    
  
    
 	Image += Scalar::all(1);//将幅度图进行尺度变换,主要的原因是幅度图太大,频率低为白点,频率高为黑点,有兴趣的可以输出图像看看效果
    
 	log(Image,Image);
    
  
    
 	Image = Image(Rect(0,0,Image.cols&-2,Image.rows&-2));//以下操作等价为将图像进行顺时针90度,为了将原点移至图像的中心
    
 	int x =Image.cols/2;
    
 	int y =Image.rows/2;
    
  
    
 	Mat C0(Image,Rect(0,0,x,y));
    
 	Mat C1(Image,Rect(x,0,x,y));
    
 	Mat C2(Image,Rect(0,y,x,y));
    
 	Mat C3(Image,Rect(x,y,x,y));
    
  
    
 	Mat temp;
    
 	C0.copyTo(temp);
    
 	C3.copyTo(C0);
    
 	temp.copyTo(C3);
    
  
    
 	C1.copyTo(temp);
    
 	C2.copyTo(C1);
    
 	temp.copyTo(C2);
    
 	normalize(Image, Image, 0, 1, CV_MINMAX);//归一化也为了能够显示图像,不然图像还是太大
    
  
    
 	imshow("src",img);
    
 	imshow("dst",Image);
    
 	waitKey(0);
    
 }

原图及结果:

本文原理:

相关知识:

Mat_<>为模板,这个应该注意,说实话平时用模板比较少,这一次用到了算又对Mat了解了一下,另外也可以多注意总结Mat的初始化构造函数,与其他类型进行转换等等的问题。

全部评论 (0)

还没有任何评论哟~