1. 程式人生 > >《數字影象處理》學習筆記(五)--傅立葉變換

《數字影象處理》學習筆記(五)--傅立葉變換

一、一維傅立葉變換及其反變換

單變數離散函式f(x)(其中x=0,1,2,....,M-1)的傅立葉變換F(u)定義為等式:

同樣給出F(u),能用逆DFT來獲得原函式:

從尤拉公式中得到:

得出:

一個恰當的比喻是將傅立葉變換比做一個玻璃稜鏡。稜鏡是可以將光分成不同顏色成分的物理儀器,每個成分的顏色由波長(或頻率)決定。傅立葉變換可看做“數學的稜鏡”,將函式基於頻率分成不同的成分。當我們考慮光時,討論它的光譜或頻率譜線。同樣,傅立葉變換使我們能夠通過頻率成分來分析一個函式。這是屬於線型濾波核心的重要概念。

  而在複數的分析下,我們發現有時在極座標下表示F(u)很方便:

上式稱為傅立葉變換的幅度或頻率譜,同時

上式稱為變換的相角或相位譜。

這裡還有個概念叫做功率譜:

二、二維傅立葉變換

  這裡主要說下二維傅立葉影象處理的步驟:

  (1)分別定義兩個單通道浮點型影象,表示實部和虛部,對實部賦值,虛部置0,

  (2)合併上面定義的兩個單通道影象,並做二維傅立葉變換

  (3)對二維傅立葉變換處理後的影象拆分成兩個單通道浮點型影象,表示處理後的實部與虛部

  (4)求頻譜的傅立葉譜值,首先進行對數變換,以將窄帶低灰度輸入影象對映到寬頻高灰度輸出影象上

(5)然後對影象進行中心化處理

 

  (6)對影象進行歸一化處理-->8u(0-255),通過公式:255*(Xk-Xmin)/(Xmax-Xmin)

  (7)對影象做帶收縮的逆傅立葉變換

  (8)同(6)歸一化處理得到原圖

#include "dipHeader.h"

void fft2(IplImage* timg,IplImage* fimg)
{
	IplImage* img_re;
	IplImage* img_im;
	IplImage* fourier;

	img_re = cvCreateImage(cvGetSize(timg),IPL_DEPTH_64F,1);  //實部
	img_im = cvCreateImage(cvGetSize(timg),IPL_DEPTH_64F,1);  //虛部

	fourier = cvCreateImage(cvGetSize(timg),IPL_DEPTH_64F,2); 

	cvConvertScale(timg, img_re);
	cvZero(img_im); 
	cvMerge(img_re,img_im,0,0,fourier);

	cvDFT(fourier,fimg,CV_DXT_FORWARD);
	cvReleaseImage(&img_im);
	cvReleaseImage(&img_re);
	cvReleaseImage(&fourier);
	
}
//分別對換I III和II IV象限
void fft2shift(IplImage*fimg, IplImage* shiftimg)
{
	IplImage* img_re;
	IplImage* img_im;
	IplImage* fourier;
	
	img_re = cvCreateImage(cvGetSize(fimg),IPL_DEPTH_64F,1);  //實部
	img_im = cvCreateImage(cvGetSize(fimg),IPL_DEPTH_64F,1);  //虛部

	cvSplit(fimg,img_re,img_im,0,0);

	//compute the Fourier magtitude
	cvPow(img_re,img_re,2.0);
	cvPow(img_im,img_im,2.0);
	cvAdd(img_re,img_im,img_re);
	cvPow(img_re,img_re,0.5);

	//對數變換以加寬窄帶低灰度輸入影象
	cvAddS(img_re,cvScalar(1.0),img_re);
	cvLog(img_re,img_re);

	int row,col,colwidth;
	row = fimg->height;
	col = fimg->width;

	int xCenter, yCenter;
	xCenter = col/2;
	yCenter = row/2;
	double tmp13,tmp24;

	for (int x=0;x<xCenter;x++)
	{
		for(int y=0;y<yCenter;y++)
		{
			tmp13= CV_IMAGE_ELEM(img_re,double, x, y);
			CV_IMAGE_ELEM(img_re,double,x,y) = CV_IMAGE_ELEM(img_re,double,x+xCenter,y+yCenter);
			CV_IMAGE_ELEM(img_re,double,x+xCenter,y+yCenter)= tmp13;

			tmp24= CV_IMAGE_ELEM(img_re,double,x,y+yCenter);
			CV_IMAGE_ELEM(img_re,double,x,y+yCenter)=CV_IMAGE_ELEM(img_re,double,x+xCenter,y);
			CV_IMAGE_ELEM(img_re,double,x+xCenter,y)=tmp24;
		}
	}
	//歸一化為 8u 
	double minVal,maxVal;
	double scale,shift;
	cvMinMaxLoc(img_re,&minVal, &maxVal);
	scale = 255/(maxVal-minVal);
	shift = -minVal*scale;
	cvConvertScale(img_re,shiftimg,scale,shift);
	cvReleaseImage(&img_re);
	cvReleaseImage(&img_im);

}

void main()
{
	IplImage *src;
    IplImage *Fourier;   //傅立葉係數   
    IplImage *dst ;  
    IplImage *ImageRe;  
    IplImage *ImageIm;  
    IplImage *Image;  
    IplImage *ImageDst;  
    double m,M;  
    double scale;  
    double shift;  
	IplImage* workImg = cvLoadImage("fft.tif",0);  
    //src = workImg;   
    //if(workImg->nChannels==3)  
	//  OnColorToGray();  
    src=cvCreateImage(cvGetSize(workImg),IPL_DEPTH_64F,workImg->nChannels);  //源影象   
    //cvCloneImage(workImg,&src);  
	src = cvCloneImage(workImg);
    cvFlip(src);  
	
    Fourier = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);  
    dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);  
    ImageRe = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);  
    ImageIm = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);  
    Image = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);  
    ImageDst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);  
    fft2(src,Fourier);                  //傅立葉變換   
    fft2shift(Fourier, Image);          //中心化   
    cvDFT(Fourier,dst,CV_DXT_INV_SCALE);//實現傅立葉逆變換,並對結果進行縮放   
    cvSplit(dst,ImageRe,ImageIm,0,0);  
	
    cvNamedWindow("源影象",0);  
    cvShowImage("源影象",src);               
    //對陣列每個元素平方並存儲在第二個引數中   
    cvPow(ImageRe,ImageRe,2);                 
    cvPow(ImageIm,ImageIm,2);  
    cvAdd(ImageRe,ImageIm,ImageRe,NULL);  
    cvPow(ImageRe,ImageRe,0.5);  
    cvMinMaxLoc(ImageRe,&m,&M,NULL,NULL);  
    scale = 255/(M - m);  
    shift = -m * scale;  
    //將shift加在ImageRe各元素按比例縮放的結果上,儲存為ImageDst   
    cvConvertScale(ImageRe,ImageDst,scale,shift);  
	
    cvNamedWindow("傅立葉譜",0);  
    cvShowImage("傅立葉譜",Image);  
    cvNamedWindow("傅立葉逆變換",0);  
    cvShowImage("傅立葉逆變換",ImageDst);  
    //釋放影象   
    cvWaitKey(0);  
    cvReleaseImage(&src);  
    cvReleaseImage(&Image);  
    cvReleaseImage(&ImageIm);  
    cvReleaseImage(&ImageRe);  
    cvReleaseImage(&Fourier);  
    cvReleaseImage(&dst);  
    cvReleaseImage(&ImageDst);  
}


相關推薦

數字影象處理學習筆記()--變換

一、一維傅立葉變換及其反變換 單變數離散函式f(x)(其中x=0,1,2,....,M-1)的傅立葉變換F(u)定義為等式: 同樣給出F(u),能用逆DFT來獲得原函式: 從尤拉公式中得到: 得出: 一個恰當的比喻是將傅立葉變換比做一個玻璃稜鏡。稜鏡是可以將光分成不

影象處理:如何理解變換影象處理中的應用

宣告:               這篇文章的主要目的是通過建立一維傅立葉變換與影象傅立葉變換中相關概念的對應關係來幫助讀者理解影象處理中的離散傅立葉變換,因此,理解影象中離散傅立葉變換的前提條件是讀者需要了解一維傅立葉變換的基本知識,詳情可參考:https://zhuan

數字影象處理學習筆記(1)——變換影象處理中的應用

1.理解二維傅立葉變換的定義 1.1二維傅立葉變換 二維Fourier變換: 逆變換: 1.2二維離散傅立葉變換 一個影象尺寸為M×N的 函式的離散傅立葉變換由以下等式給出: 其中 和。其中變數u和v用於確定它們的頻率,頻域系統是由所張成的座標系,其

第三章-數字影象處理學習筆記

3.5平滑空間濾波器 3.5.1平滑線形濾波器(均值濾波器):其輸出是包含在濾波器模板鄰域內的畫素的簡單平均值,其結果降低了影象灰度的“尖銳”變化;由於典型的隨機噪聲由灰度級的急劇變化組成,因此常見的平滑處理應用就是降低噪聲; 其缺點:由於影

MATLAB數字影象處理學習筆記之一——讀取、顯示、儲存影象

最近學習岡薩雷斯的數字影象處理(MATLAB),隨手寫個學習筆記,以備以後複習~ 1、讀取影象 imread('filename'); %filename是一個含有影象檔案全名的字串(包含任何可用副檔名)   插一句:filename也可以是一個包含相對路徑或者是絕對路

Python下opencv使用筆記(十)(影象頻域濾波與變換

前面曾經介紹過空間域濾波,空間域濾波就是用各種模板直接與影象進行卷積運算,實現對影象的處理,這種方法直接對影象空間操作,操作簡單,所以也是空間域濾波。 頻域濾波說到底最終可能是和空間域濾波實現相同的功能,比如實現影象的輪廓提取,在空間域濾波中我們使用一個拉普拉

Python下opencv使用筆記影象頻域濾波與變換

本文轉載自  https://blog.csdn.net/on2way/article/details/46981825首先謝謝原創博主了,這篇文章對我幫助很大,記錄下方便再次閱讀。前面曾經介紹過空間域濾波,空間域濾波就是用各種模板直接與影象進行卷積運算,實現對影象的處理,這

OpenCV中對影象進行二維離散變換

#include<opencv2/opencv.hpp> #include <highgui.h> #include <iostream> #include <cv.h> #include <opencv2/core/c

影象頻域濾波與變換

1、頻率濾波 影象的空間域濾波:用各種模板直接與影象進行卷積運算,實現對影象的處理,這種方法直接對影象空間操作,操作簡單。影象處理不僅可以在空間域進行還可以在頻率域進行,把空間域的影象開窗卷積形式,變換得到頻率域的矩陣點乘形式得到比較好的效果。影象頻域濾波,先把影象轉換到頻域空間,然後對不同的頻率點進行濾波,

數字影象處理筆記——二維離散變換(2D Discrete Fourier Transform)

二維傅立葉變換 我們先來看看一維情況的傅立葉變換。在訊號系統中講過連續時間的傅立葉變換和離散時間的傅立葉變換,連續時間傅立葉變換在頻譜上時非週期的,離散時間傅立葉變換(DTFT)在頻譜上是週期的。在DSP中講了離散傅立葉變換,它的思想是將時域週期化,反映在頻域上就是對連續的週期頻譜進行抽樣

c語言數字影象處理(六):二維離散變換

基礎知識 複數表示 C = R + jI 極座標:C = |C|(cosθ + jsinθ) 尤拉公式:C = |C|ejθ 有關更多的時域與複頻域的知識可以學習複變函式與積分變換,本篇文章只給出DFT公式,性質,以及實現方法 二維離散傅立葉變換(DFT) 其中f(x,y)為原影象,F(u,

離散變換影象處理中的應用_學習

1、為什麼要進行傅立葉變換,其物理意義是什麼? 傅立葉原理表明:任何連續測量的時序或訊號,都可以表示為不同頻率的正弦波訊號的無限疊加。而根據該原理創立的傅立葉變換演算法利用直接測量到的原始訊號,以累加方式來計算該訊號中不同正弦波訊號的頻率、振幅和相位。 和傅立葉

數字影象處理,讀懂頻域處理的“變換

轉載自:https://blog.csdn.net/ebowtang/article/details/39004979 以下部分文字資料整合於網路,本文僅供自己學習用! 這是一幅很絕的一維傅立葉變換動態圖 一,讀懂傅立葉變換 一個訊號能表示成傅立葉級數

數字影象處理:11.變換

Fourier變換 對於二維訊號,二維Fourier變換定義為: 二維離散傅立葉變換為: 圖象的傅立葉變換與一維訊號的傅立葉變換變換一樣,有快速演算法,具體參見教材。有關傅立葉變換的快速演算法的程式不難找到。實際上,現在有實現傅立葉變換的晶片,可以實時實

頻率域濾波基礎之(讀數字影象處理學習halcon)

選擇性濾波 在很多應用中,其中感興趣是處理指定的頻段或頻率矩形。第一類濾波器分別稱為帶阻濾波器或帶通濾波器。第二類濾波器稱為陷波濾波器。 1、帶阻濾波和帶通濾波 D(u,v)是距離頻率矩形中心的距離,D0是頻寬的徑向中心,W是頻寬。一個帶同濾波器可以用從低通濾波器得到高通

影象處理-離散變換-數字影象處理第三版第四章內容

  影象傅立葉變換方法有很多,可以通過空間光調製器輸入影象後在通過平行光照明經過傅立葉變換透鏡進行傅立葉變換,另一個方法就是利用計算機進行傅立葉變換,其中傅立葉變換有兩種演算法一種是DFT還有一種是FFT(快速傅立葉變換)。   首先我介紹一下影象的定義,影象是怎麼去得到的

數字影象處理-離散變換(opencv3+C++顯示)

參考: http://daily.zhihu.com/story/3935067 http://blog.csdn.net/keith_bb/article/details/53389819 在學習訊號與系統或通訊原理等課程裡面可能對傅立葉變換有了一定的瞭解。我們知道傅立葉變換是把一個訊號從時域變換

opencv學習(十)之影象變換dft

在學習訊號與系統或通訊原理等課程裡面可能對傅立葉變換有了一定的瞭解。我們知道傅立葉變換是把一個訊號從時域變換到其對應的頻域進行分析。如果有小夥伴還對傅立葉變換處於很迷糊的狀態,請戳這裡,非常通俗易懂。而在影象處理中也有傅立葉分析的概念,我這裡給出在其官方指導檔案

數字影象處理成長之路4: C語言與離散變換(DFT)

這幾天一直學習傅立葉變換,看了很多國內外資料,網上講原理的很多,到了程式實現這塊大多是Matlab,opencv等,這些軟體的api對於我們理解DFT在計算機中的實現並沒有多大幫助。於是想用C/C++實現DFT,經過不斷的閱讀與程式設計實驗,最終程式有了還算滿意

python OpenCV學習筆記(二十):變換(Fourier Transform )

傅立葉變換用於分析各種濾波器的頻率特性。對於影象,二維離散傅立葉變換(2D Discrete Fourier Transform/DFT)用於尋找頻域。快速傅立葉變換(Fast Fourier Transform/FFT)的快速演算法用於計算DFT。