https://m.toutiao.com/is/6trAYu3/?=傅里葉變換有什么應用場景
文章目錄 傅里葉基礎 傅里葉基礎numpy實現 逆傅里葉numpy實現 頻域的高通濾波 傅里葉OpenCV實現 傅里葉OpenCV逆變換實現 頻域的低通濾波 傅里葉變換有什么應用場景 傅里葉變換matlab實現
傅里葉基礎法國數學家吉恩·巴普提斯特·約瑟夫·傅里葉被世人銘記的最大的貢獻是:他指出任何周期函數都可以表示為不同頻率的正弦和/或余弦之和的形式,每個正弦項和/或余弦項乘以不同的系數(現在稱該和為傅里葉級數)。無論函數多么復雜,只要它是周期的,并且滿足某些適度的數學條件,都可以用這樣的和來表示。即一個復雜的函數可以表示為簡單的正弦和余弦之和。甚至非周期函數(單該曲線下的面積是有限的)也可以用正弦和/或許·余弦乘以加權函數的積分來表示。在這種情況下的公式就是傅里葉公式。 比如說我們以制作一個飲料的過程,使用時域的角度來看就是這樣: 這里是什么意思呢,就是說一個飲料的制作需要在18點整放1個單位冰糖、3個單位紅豆、2個單位的綠豆、4個單位的西紅柿,還有1個單位的純凈水。然后再18:01分只需要假如一個單位的純凈水。后面也是一致。 而頻域是怎么描述這件事的呢?
具體來說就是說他發現了一個規律,就是說這個制作過程,每分鐘都要加入冰糖,每兩分鐘都要加入紅豆,每三分鐘都要加入一次綠豆…。 對于時域角度我們這樣描述。
對于頻域角度我們這樣描述這件事,用直方圖表示就是:
如果要考慮更精準的時間精度,我們就要引入相位這個概念。他是一個和時間差有關的一個表述。
這里我們說明一下就是時域和頻域的表述是互逆的,對于時域我們是時間為橫坐標,振幅為縱坐標。對于頻域我們以頻率為橫坐標,振幅為縱坐標。但是可以看得出來頻域的表述更加簡單,但是比較抽象,不容易理解。 傅里葉說:任何連續周期信號,可以由一組適當的正弦曲線組合而成。 注意這里是一組而不是一個。比如對于這樣的一個圖像: f(x)=3np.sin(0.8x)+7np.sin(1/3x)+2np.sin(0.2x)
看上去是毫無規律可言吧,但是它也可以由一組正弦函數組成。
他們是可逆的,想不到吧,亂七八糟的東西也有規律了。但是他們就是這樣組合而成的嗎?不可能吧,所以這里就是不是同時開始的一組余弦函數,在疊加時要體現開始的時間。也就說組合的函數他們的開始時間是不一樣的。在這里分別對應0,2,3.看公式就看出來啦。 這里多說一嘴就是說傅里葉變換從時域角度來看,這個世界是動態的!從頻域角度來看這個世界是靜止的。 從數學角度來講:傅里葉變換將一個任意的周期函數分解成為無窮個正弦函數的和的形式。 從物理角度來講:傅里葉變換實現了將信號從空間域到頻率域的轉換。
傅里葉基礎numpy實現python是可以實現傅里葉變換的,這里就要說到三劍客的numpy了。對應的函數是:numpy.fft.fft2返回一個復數數組(complex ndarray)。numpy.fft.fftshift這個函數時表示把將零頻率分量移到頻譜中心。 還要設置頻譜的范圍20*np.log(np.abs(fshift)),對于圖像來說就是255了。
import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread('image\\lena.bmp',0)f = np.fft.fft2(img)fshift = np.fft.fftshift(f)result = 20*np.log(np.abs(fshift))plt.subplot(121)plt.imshow(img, cmap = 'gray')plt.title('original')plt.axis('off')plt.subplot(122)plt.imshow(result, cmap = 'gray')plt.title('result')plt.axis('off')plt.show()12345678910111213141516
結果是: 原圖和頻譜圖像。
- 傅里葉得到低頻、高頻信息,針對低頻、高頻處理能夠實現不同的 目的。
- 傅里葉過程是可逆的,圖像經過傅里葉變換、逆傅里葉變換后,能 夠恢復到原始圖像
- 在頻域對圖像進行處理,在頻域的處理會反映在逆變換圖像上
逆傅里葉numpy實現對于傅里葉的逆操作這里沒有什么可說的,就是把頻域圖像轉回原圖像。 函數是:numpy.fft.ifft2,那么還有一個操作就是把中間移動回去對啊。numpy.fft.ifftshift。iimg = np.abs(逆傅里葉變換結果)而第二個圖就表示低頻部分,邊緣就表示為高頻部分。
import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread('image\\boat.bmp',0)f = np.fft.fft2(img)fshift = np.fft.fftshift(f)ishift = np.fft.ifftshift(fshift)iimg = np.fft.ifft2(ishift)iimg = np.abs(iimg)plt.subplot(121),plt.imshow(img, cmap = 'gray')plt.title('original'),plt.axis('off')plt.subplot(122),plt.imshow(iimg, cmap = 'gray')plt.title('iimg'),plt.axis('off')plt.show()1234567891011121314
首先我們要進行傅里葉變換吧,才可以進行逆操作。結果是: 完全一致!!!
頻域的高通濾波首先我們來看看到底什么是高頻,什么是低頻在圖像中如何理解。 低頻對應圖像內變化緩慢的灰度分量。例如,在一幅大草原的圖像中,低頻對應著廣袤的顏色趨于一致的草原。 高頻對應圖像內變化越來越快的灰度分量,是由灰度的尖銳過渡造成的。例如,在一幅大草原的圖像中,其中獅子的邊緣等信息。 對于濾波我們之前也了解過了,就是說過濾掉不需要的部分唄。 通過低頻的濾波器稱為低通濾波器。 通過高頻的濾波器稱為高通濾波器 修改傅里葉變換以達到特殊目的,然后計算IDFT返回到圖像域。比如我們可以利用傅里葉變換進行,圖像增強、圖像去噪、邊緣檢測、特征提取、圖像壓縮、圖像加密等。 衰減高頻而通過低頻,低通濾波器,將模糊一幅圖像。 衰減低頻而通過高頻,高通濾波器,將增強尖銳的細節,但是會導致圖像 的對比度降低 那么我們只需要再濾波中來一個掩膜操作,具體看下面: 對于這個掩膜我們這樣做:
rows, cols = img.shapecrow,ccol = int(rows/2) , int(cols/2)fshift[crow-30:crow+30, ccol-30:ccol+30] = 0123
具體代碼是: import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread('image\\boat.bmp',0)f = np.fft.fft2(img)fshift = np.fft.fftshift(f)rows, cols = img.shapecrow,ccol = int(rows/2) , int(cols/2)fshift[crow-30:crow+30, ccol-30:ccol+30] = 0ishift = np.fft.ifftshift(fshift)iimg = np.fft.ifft2(ishift)iimg = np.abs(iimg)plt.subplot(121),plt.imshow(img, cmap = 'gray')plt.title('original'),plt.axis('off')plt.subplot(122),plt.imshow(iimg, cmap = 'gray')plt.title('iimg'),plt.axis('off')plt.show()1234567891011121314151617
得到后的圖象是這樣的: 可以出來把邊緣描繪的非常完整,但是圖像的對比度降低了。
傅里葉OpenCV實現對于OpenCV中的傅里葉變換函數是:返回結果=cv2.dft(原始圖像,轉換標識) 返回結果是雙通道的,第一個是實數部分,第二個通道是虛數部分。 輸入圖像要首先轉換成np.float32 格式, np.float32(img) flags = cv2.DFT_COMPLEX_OUTPUT,輸出一個復數陣列 移動頻譜部分和numpy一致,是這樣的,numpy.fft.fftshift,然后進行返回值=cv2.magnitude(參數1,參數2)這里參數1就是實數部分,參數2就是虛數部分,并且進行 = 根號()2 + ()2操作。 import numpy as npimport cv2import matplotlib.pyplot as pltimg = cv2.imread('image\\lena.bmp',0)dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)dftShift = np.fft.fftshift(dft)result = 20*np.log(cv2.magnitude(dftShift[:,:,0],dftShift[:,:,1]))plt.subplot(121),plt.imshow(img, cmap = 'gray')plt.title('original'),plt.axis('off')plt.subplot(122),plt.imshow(result, cmap = 'gray')plt.title('result'), plt.axis('off')plt.show()123456789101112
得到的圖像和numpy一致。
傅里葉OpenCV逆變換實現對于傅里葉變換的逆操作,使用OpenCV的函數就是返回結果=cv2.idft(原始數據),然后計算幅度函數仍然是返回值=cv2.magnitude(參數1,參數2),numpy.fft.ifftshift import numpy as npimport cv2import matplotlib.pyplot as pltimg = cv2.imread('image\\lena.bmp',0)dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)dftShift = np.fft.fftshift(dft)ishift = np.fft.ifftshift(dftShift)iImg = cv2.idft(ishift)iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])plt.subplot(121),plt.imshow(img, cmap = 'gray')plt.title('original'), plt.axis('off')plt.subplot(122),plt.imshow(iImg, cmap = 'gray')plt.title('inverse'), plt.axis('off')plt.show()1234567891011121314
頻域的低通濾波我們這里的想法就是: 自己構建一個低通濾波器,把中間位置設置成255,其余部分為0.那么我們做一個與操作,就可以把高頻過濾了。
rows, cols = img.shapecrow,ccol = int(rows/2) , int(cols/2)mask = np.zeros((rows,cols,2),np.uint8)mask[crow-30:crow+30, ccol-30:ccol+30] = 11234
低通濾波器構建代碼。 然后我們完整代碼就是: import numpy as npimport cv2import matplotlib.pyplot as pltimg = cv2.imread('image\\lena.bmp',0)dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)dftShift = np.fft.fftshift(dft)rows, cols = img.shapecrow,ccol = int(rows/2) , int(cols/2)mask = np.zeros((rows,cols,2),np.uint8)mask[crow-30:crow+30, ccol-30:ccol+30] = 1fShift = dftShift*maskishift = np.fft.ifftshift(fShift)iImg = cv2.idft(ishift)iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])plt.subplot(121),plt.imshow(img, cmap = 'gray')plt.title('original'), plt.axis('off')plt.subplot(122),plt.imshow(iImg, cmap = 'gray')plt.title('inverse'), plt.axis('off')plt.show()12345678910111213141516171819
結果是: 傅里葉變換有什么應用場景傅里葉變換可以將一個時域信號轉換成在不同頻率下對應的振幅及相位,其頻譜就是時域信號在頻域下的表現,而反傅里葉變換可以將頻譜再轉換回時域的信號。最簡單最直接的應用就是時頻域轉換,比如在移動通信的LTE系統中,要把接收的信號從時域變成頻域,就需要使用FFT(快速傅里葉變換)。又例如對一個采集到的聲音做傅立葉變化就能分出好幾個頻率的信號。比如南非世界杯時,南非人吹的嗚嗚主拉的聲音太吵了,那么對現場的音頻做傅立葉變化(當然是對聲音的數據做),會得到一個展開式,然后找出嗚嗚主拉的特征頻率,去掉展開式中的那個頻率的sin函數,再還原數據,就得到了沒有嗚嗚主拉的嗡嗡聲的現場聲音。而對圖片的數據做傅立葉,然后增大高頻信號的系數就可以提高圖像的對比度。同樣,相機自動對焦就是通過找圖像的高頻分量最大的時候,就是對好了。 傅里葉變換matlab實現[i,lcmp]=imread('F:/123.jpg');%=======讀取圖像 顯示圖像subplot(2,2,1),imshow(i,lcmp);title('original');ii=im2double(i); %=====將圖像矩陣類型轉換為double(圖像計算很多是不能用整型的),沒有這個會報錯!! ,如果不用這個就必須轉化為灰度圖!i1 = fft2(ii); %======傅里葉變換i2 =fftshift(i1); %======將變換的頻率圖像四角移動到中心(原來良的部分在四角 現在移動中心,便于后面的處理)i3=log(abs(i2)); %=====顯示中心低頻部分,加對數是為了更好的顯示subplot(2,2,2),imshow(i3,[]);title('Fourier');map=colormap(lcmp); %===取色譜imwrite(i3,map,'f:/ffttank.bmp'); %===將上面i3輸入到ffttank文件中i5 = real(ifft2(ifftshift(i2))); %===頻域的圖反變換到空域 并取實部i6 = im2uint8(mat2gray(i5)); %===取其灰度圖imwrite(i6,map,'f:/tank2.bmp','bmp'); %===利用灰度圖和原來取得顏色模板 還原圖像subplot(2,2,3),imshow(i6);title('anti-Fourier');i7=rgb2gray(i);i8=fft2(i7);%===對灰色圖才能歸一化。因為那是2維矩陣,彩色圖是3維矩陣,需要轉化為2維灰圖m=fftshift(i8); %直流分量移到頻譜中心%RR=real(m); %取傅立葉變換的實部%II=imag(m); %取傅立葉變換的虛部A=abs(m);%計算頻譜幅值%A=sqrt(RR.^2+II.^2);A=(A-min(min(A)))/(max(max(A))-min(min(A)))*225; %歸一化subplot(2,2,4),imshow(A); %顯示原圖像colorbar; %顯示圖像的顏色條title('FFT spectrum'); %圖像命名123456789101112131415161718192021222324252627
結果是:
|