二維圖像的離散傅立葉變換處理

儘管離第一次接觸傅立葉變換已經好幾年了,但是至今還是不理解,想想數學課和小波課都白上了哭。今天又重溫傅立葉變換,又寫了代碼。

我的習慣先上代碼,再講原理:

代碼:

#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的初始化構造函數,與其他類型進行轉換等等的問題。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章