AI 图像傅里叶变换
傅立葉原理表明:
任何連續測量的時序或信號,都可以表示為不同頻率的正弦波信號的無限疊加。而根據該原理創立的傅立葉變換算法利用直接測量到的原始信號,以累加方式來計算該信號中不同正弦波信號的頻率、振幅和相位。
反變換從本質上說也是一種累加處理,這樣就可以將單獨改變的正弦波信號轉換成一個信號。
傅立葉變換將原來難以處理的時域信號轉換成了易于分析的頻域信號(信號的頻譜),最后還可以利用傅立葉反變換將這些頻域信號轉換成時域信號。
?
圖像傅立葉變換的物理意義
圖像的頻率是表征圖像中灰度變化劇烈程度的指標,是灰度在平面空間上的梯度。
如:大面積的沙漠在圖像中是一片灰度變化緩慢的區域,對應的頻率值很低;而對于地表屬性變換劇烈的邊緣區域在圖像中是一片灰度變化劇烈的區域,對應的頻率值較高。
傅立葉變換在實際中有非常明顯的物理意義,設f是一個能量有限的模擬信號,則其傅立葉變換就表示f的譜。從純粹的數學意義上看,傅立葉變換是將一個函數轉換為一系列周期函數來處理的。
從物理效果看,傅立葉變換是將圖像從空間域轉換到頻率域,其逆變換是將圖像從頻率域轉換到空間域。換句話說,傅立葉變換的物理意義是將圖像的灰度分布函數變換為圖像的頻率分布函數,傅立葉逆變換是將圖像的頻率分布函數變換為灰度分布函數。
?
傅立葉變換以前,圖像(未壓縮的位圖)是由對在連續空間(現實空間)上的采樣得到一系列點的集合,我們習慣用一個二維矩陣表示空間上各點,則圖像可由z=f(x,y)來表示。由于空間是三維的,圖像是二維的,因此空間中物體在另一個維度上的關系就由梯度來表示,這樣我們可以通過觀察圖像得知物體在三維空間中的對應關系。為什么要提梯度?因為實際上對圖像進行二維傅立葉變換得到頻譜圖,就是圖像梯度的分布圖,當然頻譜圖上的各點與圖像上各點并不存在一一對應的關系,即使在不移頻的情況下也是沒有。傅立葉頻譜圖上我們看到的明暗不一的亮點,實際上圖像上某一點與鄰域點差異的強弱,即梯度的大小,也即該點的頻率的大小(可以這么理解,圖像中的低頻部分指低梯度的點,高頻部分相反)。一般來講,梯度大則該點的亮度強,否則該點亮度弱。這樣通過觀察傅立葉變換后的頻譜圖,也叫功率圖,我們首先就可以看出,圖像的能量分布,如果頻譜圖中暗的點數更多,那么實際圖像是比較柔和的(因為各點與鄰域差異都不大,梯度相對較小),反之,如果頻譜圖中亮的點數多,那么實際圖像一定是尖銳的,邊界分明且邊界兩邊像素差異較大的。
?
對頻譜移頻到原點以后,可以看出圖像的頻率分布是以原點為圓心,對稱分布的。將頻譜移頻到圓心除了可以清晰地看出圖像頻率分布以外,還有一個好處,它可以分離出有周期性規律的干擾信號,比如正弦干擾,一副帶有正弦干擾,移頻到原點的頻譜圖上可以看出除了中心以外還存在以某一點為中心,對稱分布的亮點集合,這個集合就是干擾噪音產生的,這時可以很直觀的通過在該位置放置帶阻濾波器消除干擾。
?
頻率濾波?
在頻域中,頻率越大說明原始信號變化速度越快;頻率越小說明原始信號越平緩。當頻率為0時,表示直流信號,沒有變化。因此,頻率的大小反應了信號的變化快慢。高頻分量解釋信號的突變部分,而低頻分量決定信號的整體形象。
在圖像處理中,頻域反應了圖像在空域灰度變化劇烈程度,也就是圖像灰度的變化速度,也就是圖像的梯度大小。對圖像而言,圖像的邊緣部分是突變部分,變化較快,因此反應在頻域上是高頻分量;圖像的噪聲大部分情況下是高頻部分;圖像平緩變化部分則為低頻分量。也就是說,傅立葉變換提供另外一個角度來觀察圖像,可以將圖像從灰度分布轉化到頻率分布上來觀察圖像的特征。書面一點說就是,傅里葉變換提供了一條從空域到頻率自由轉換的途徑。對圖像處理而言,以下概念非常的重要:?
圖像高頻分量:圖像突變部分;在某些情況下指圖像邊緣信息,某些情況下指噪聲,更多是兩者的混合;?
低頻分量:圖像變化平緩的部分,也就是圖像輪廓信息?高通濾波器:讓圖像使低頻分量抑制,高頻分量通過?低通濾波器:與高通相反,讓圖像使高頻分量抑制,低頻分量通過?
帶通濾波器:使圖像在某一部分的頻率信息通過,其他過低或過高都抑制?模板運算與卷積定理?
在時域內做模板運算,實際上就是對圖像進行卷積。模板運算是圖像處理一個很重要的處理過程,很多圖像處理過程,比如增強/去噪(這兩個分不清楚),邊緣檢測中普遍用到。
根據卷積定理,時域卷積等價與頻域乘積。因此,在時域內對圖像做模板運算就等效于在頻域內對圖像做濾波處理。?
比如說一個均值模板,其頻域響應為一個低通濾波器;在時域內對圖像作均值濾波就等效于在頻域內對圖像用均值模板的頻域響應對圖像的頻域響應作一個低通濾波。
?
在MATLAB中
i=imread('lena2561.bmp'); figure(1); imshow(i); colorbar;j=fft2(i);%完成FFT變換 k=fftshift(j);%%實現居中%取得傅里葉頻譜 figure(2); l=log(abs(k)); imshow(l,[]); colorbar; % s=abs(j);%取得傅里葉頻譜 % s=(s-min(min(s)))/(max(max(s))-min(min(s)))*255; % imshow(s);% 實現傅里葉逆變換 n=ifft2(j)/255; figure(3); imshow(n); colorbar;?
OpenCV
#include <stdio.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> /************************************************************************** //src IPL_DEPTH_8U //dst IPL_DEPTH_64F **************************************************************************/ //傅里葉正變換 void fft2(IplImage *src, IplImage *dst) { //實部、虛部IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0;// int i, j;image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); //實部//Imaginary partimage_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); //虛部//2 channels (image_Re, image_Im)Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);// Real part conversion from u8 to 64f (double)cvConvertScale(src, image_Re, 1, 0);// Imaginary part (zeros) cvZero(image_Im);// Join real and imaginary parts and stock them in Fourier imagecvMerge(image_Re, image_Im, 0, 0, Fourier);// Application of the forward Fourier transform cvDFT(Fourier, dst, CV_DXT_FORWARD);cvReleaseImage(&image_Re);cvReleaseImage(&image_Im);cvReleaseImage(&Fourier); } /************************************************************************** //src IPL_DEPTH_64F //dst IPL_DEPTH_8U **************************************************************************/ void fft2shift(IplImage *src, IplImage *dst) { IplImage *image_Re = 0, *image_Im = 0; int nRow, nCol, i, j, cy, cx; double scale, shift, tmp13, tmp24; image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); //Imaginary part image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); cvSplit( src, image_Re, image_Im, 0, 0 );//具體原理見岡薩雷斯數字圖像處理p123// Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)//計算傅里葉譜cvPow( image_Re, image_Re, 2.0);cvPow( image_Im, image_Im, 2.0);cvAdd( image_Re, image_Im, image_Re);cvPow( image_Re, image_Re, 0.5 );//對數變換以增強灰度級細節(這種變換使以窄帶低灰度輸入圖像值映射//一寬帶輸出值,具體可見岡薩雷斯數字圖像處理p62)// Compute log(1 + Mag);cvAddS( image_Re, cvScalar(1.0), image_Re ); // 1 + MagcvLog( image_Re, image_Re ); // log(1 + Mag)//Rearrange the quadrants of Fourier image so that the origin is at the image centernRow = src->height;nCol = src->width;cy = nRow/2; // image centercx = nCol/2; //CV_IMAGE_ELEM為OpenCV定義的宏,用來讀取圖像的像素值,這一部分就是進行中心變換for( j = 0; j < cy; j++ ){for( i = 0; i < cx; i++ ){//中心化,將整體份成四塊進行對角交換tmp13 = CV_IMAGE_ELEM( image_Re, double, j, i);CV_IMAGE_ELEM( image_Re, double, j, i) = CV_IMAGE_ELEM(image_Re, double, j+cy, i+cx);CV_IMAGE_ELEM( image_Re, double, j+cy, i+cx) = tmp13;tmp24 = CV_IMAGE_ELEM( image_Re, double, j, i+cx);CV_IMAGE_ELEM( image_Re, double, j, i+cx) =CV_IMAGE_ELEM( image_Re, double, j+cy, i);CV_IMAGE_ELEM( image_Re, double, j+cy, i) = tmp24;}}//歸一化處理將矩陣的元素值歸一為[0,255]//[(f(x,y)-minVal)/(maxVal-minVal)]*255double minVal = 0, maxVal = 0;// Localize minimum and maximum valuescvMinMaxLoc( image_Re, &minVal, &maxVal );// Normalize image (0 - 255) to be observed as an u8 imagescale = 255/(maxVal - minVal);shift = -minVal * scale;cvConvertScale(image_Re, dst, scale, shift);cvReleaseImage(&image_Re);cvReleaseImage(&image_Im); } /***********************************************************************/ int main() { IplImage *src; //源圖像 IplImage *Fourier; //傅里葉系數 IplImage *dst ; IplImage *ImageRe; IplImage *ImageIm; IplImage *Image; IplImage *ImageDst; double m,M; double scale; double shift; src = cvLoadImage("D:\\main.jpg",0); //加載源圖像,第二個參數表示將輸入的圖片轉為單信道 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(10000); cvReleaseImage(&src); cvReleaseImage(&Image); cvReleaseImage(&ImageIm); cvReleaseImage(&ImageRe); cvReleaseImage(&Fourier); cvReleaseImage(&dst); cvReleaseImage(&ImageDst); return 0; }?
轉載于:https://www.cnblogs.com/Lemon-Li/p/3277025.html
總結
以上是生活随笔為你收集整理的AI 图像傅里叶变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Levenberg-Marquardt快
- 下一篇: CORE ANIMATION的学习备忘录