您現在的位置是:首頁 > 綜合

簡單易懂的傅立葉變換原理和程式碼實現

  • 由 深度人工智慧學院 發表于 綜合
  • 2022-01-28
簡介shape)#兩個通道# 2

逆z變換怎麼理解

按照某度的解釋,傅立葉變換,是表示能將滿足一定條件的某個函式表示成三角函式(正弦和/或餘弦函式)或者它們的積分的線性組合。在不同的研究領域,傅立葉變換具有多種不同的變體形式,如連續傅立葉變換和離散傅立葉變換。最初傅立葉分析是作為熱過程的解析分析的工具被提出的。其公式是一個連續積分函式:

簡單易懂的傅立葉變換原理和程式碼實現

公式描述:公式中F(ω)為f(t)的像函式,f(t)為F(ω)的像原函式。

原理解析

拋開復雜的公式推導簡單來說,傅立葉變換的實際意義就是對一個指定的訊號曲線,可以使用傅立葉變換的方法對其進行分解重組,其目的就是將複雜問題簡單化處理,再將處理後的結果綜合起來考慮。

簡單易懂的傅立葉變換原理和程式碼實現

具體操作就是將一個訊號曲線分解成若干個正弦曲線,這些正弦的頻率代表了原訊號曲線的頻率變化情況,總的來說就是對原來訊號曲線上的不同頻率的訊號進行分門別類,同一頻率下的訊號被分到了一個正弦曲線上,這樣就有了若干個不同頻率的正弦曲線了,而這些正弦曲線中,有些是我們需要的資訊,而有些是不需要的資訊。

簡單易懂的傅立葉變換原理和程式碼實現

相對原始的訊號,分解後的若干正弦曲線的訊號是非常容易處理的,比如我們需要去除指定頻段的訊號,在原訊號曲線上是比較難實現的,但是在分解後的若干正弦曲線中就變得非常容易,我們要做的只需要對這些正弦曲線按照頻率大小進行排序,然後刪除掉不需要的頻段曲線即可,當然,操作完之後要記得將分解處理完後剩下的正弦曲線訊號合併成原始的訊號,這種操作被稱為傅立葉逆變換或者逆傅立葉變換。

以語音訊號為例,一般我們接觸到的訊號是一幅基於時間序列的音訊聲波圖,也稱為時域圖。聲音是介質振動在聽覺系統中產生的反應。聲音總可以被分解為不同頻率不同強度正弦波的疊加(傅立葉變換)。聲音有兩個基本的物理屬性:

頻率

振幅

。聲音的振幅就是音量,頻率的高低就是指音調,頻率用赫茲(Hz)作單位。人耳只能聽到20Hz到20khz範圍的聲音。

簡單易懂的傅立葉變換原理和程式碼實現

音訊圖上波峰的高低象徵著聲音的振幅大小,從物理角度解釋,振幅就是聲帶偏離原來位置的大小,聲帶偏離原來的位置越大,則聲音越大,波峰越高的地方意味著音訊的振幅越高,也就是音量越大。而頻率就是聲帶在單位時間內振動的次數,在音訊圖上可以看作是一個週期,頻率越高,就意味著聲帶振動的次數越多,也就是音調越高。

簡單易懂的傅立葉變換原理和程式碼實現

直接時域上的音訊圖進行處理比較麻煩,所以一般會先將時域圖按照不同的頻率振幅分解成若干個音訊和振幅不同的音訊訊號圖。再將這些不同的訊號圖按照不同的振幅對映到一個平面圖上,就是我們所說的頻域圖。

簡單易懂的傅立葉變換原理和程式碼實現

傅立葉變換對於訊號的處理主要作用是將訊號從時域影象轉換到頻域影象,其完整步驟如下:傅立葉變換(時域圖→頻域圖)→頻域圖排序→去除指定頻率的訊號→頻域圖順序還原→逆傅立葉變換(頻域圖→時域圖)→時域圖取模還原。

簡單易懂的傅立葉變換原理和程式碼實現

那麼我們如此大費周章的去除訊號中指定頻段的訊號目的是什麼呢?當然是基於實際問題的處理,最常見的就是訊號去噪,一般來說。訊號中都會存在一些干擾的噪聲訊號,不利於訊號的處理,而這些噪聲訊號的頻段往往都是固定的,只要我們對訊號進行傅立葉變換的操作,就很容易去除掉這些干擾的噪聲訊號了。

舉個例子,我們在戶外街道上錄製一段語音,這段語音的訊號中,實際是上包含了我們正常發出的聲音和街道背景的噪聲訊號的。這個時候我們如果想要讓錄製的語音變得清晰一些,就需要對這段語音進行傅立葉變換的操作,目的就是去除噪聲干擾。當然處理語音訊號噪聲的方法有很多,而傅立葉變換是必將經典的一種方法。

簡單易懂的傅立葉變換原理和程式碼實現

大多數情況下,噪聲屬於高頻訊號,去除掉噪聲的音訊圖和原始音訊圖相比,差異不大,整體來看,由於有一部分的高頻訊號被去除了,去噪後的訊號圖比原圖會更平滑一些。

說完傅立葉變換在訊號領域的應用,接下來說說傅立葉變換在影象視覺領域的應用。我們一般所說的訊號是一個一維資料,資料前後是由順序的,而影象是一個二維(灰度圖)或三維(RGB圖)的資料(在程式碼實現中,會統一轉成二維灰度圖),但是無論資料是多少個維度,他們的處理步驟都是一樣的,只不過具體操作細節有所變換而已,但是要明白,不管是一維資料也好,還是二維三維資料也罷,它們之間其實都是可以互相轉換的。

那麼傅立葉變換在影象視覺領域的具體實現方法是怎麼樣的呢?實際上只需要把在一維訊號中處理流程的時域訊號換成空域訊號即可,其他步驟不做任何變化。其實也很好理解,一維訊號資料是具有先後時序的,而二維或者三維資料之間的關係就不像一維訊號那麼,只是基於時序的關係了,它們之間的關係是基於空間的關係。

程式碼演示

接下來,我們就傅立葉變換在影象領域的應用進行程式碼實際操作演示,我們先透過傅立葉變換對影象進行去噪操作的演示,也就是去掉一部分高頻訊號的操作,由於是去高頻訊號,留低頻訊號,這個操作也被稱為低通濾波。

下面以成都深度智谷科技的教學機構“深度人工智慧學院”的教學練習題為例演示傅立葉變換的結果

,在opencv中以離散傅立葉變換(DFT)來實現影象低通濾波操作:

import numpyimport cv2import matplotlib。pyplot as plt ‘DFT:離散傅立葉變換’# OpenCV中的 DFT(Discrete Fourier Transform) 離散傅立葉變換img = cv2。imread(“。。/images/1。jpg”)# 轉化為灰度圖gray = cv2。cvtColor(img, cv2。COLOR_BGR2GRAY)rows, cols = gray。shape# 1。DFT離散傅立葉變換: 空域——>頻域dft = cv2。dft(alt="簡單易懂的傅立葉變換原理和程式碼實現" data-isLoading="0" src="/static/img/blank.gif" data-src=numpy。float32(gray), flags=cv2。DFT_COMPLEX_OUTPUT) # src為灰度圖,並且是numpy。float32型別print(dft。shape)#兩個通道# 2。中心化: 將低頻移動到影象中心fftshift = numpy。fft。fftshift(dft)# 獲取振幅譜(展示圖片用): numpy。log()是為了將值限制在[0, 255]magnitude_spectrum = numpy。log(cv2。magnitude(fftshift[:, :, 0], fftshift[:, :, 1]))# 3。濾波操作之低通濾波(去高頻,保低頻)mask = numpy。zeros((rows, cols,2), dtype=numpy。uint8)mask[(rows // 2 - 30): (rows // 2 + 30), (cols // 2 - 30): (cols // 2 + 30)] = 1fftshift = fftshift * mask# 4。去中心化: 將低頻和高頻的位置還原ifftshift = numpy。fft。ifftshift(fftshift)# 5。逆傅立葉變換: 頻域——>空域idft = cv2。idft(ifftshift)# 6。二維向量取模(幅值)img_back = cv2。magnitude(idft[:, :, 0], idft[:, :, 1])# 結合matplotlib展示多張圖片plt。figure(figsize=(10, 10))plt。subplot(221),plt。imshow(gray,cmap=“gray”),plt。title(“Input Gray Image”),plt。xticks([]),plt。yticks([])plt。subplot(222),plt。imshow(magnitude_spectrum,cmap=“gray”),plt。title(“Magnitude Spectrum”),plt。xticks([]), plt。yticks([])plt。subplot(223), plt。imshow(img_back, cmap=“gray”), plt。title(“Image after LPF”),plt。xticks([]), plt。yticks([])plt。subplot(224),plt。imshow(img_back), plt。title(“Result in JET”),plt。xticks([]), plt。yticks([])plt。show()

程式碼展現效果:

簡單易懂的傅立葉變換原理和程式碼實現

透過上面案例,我們直觀地感受到了傅立葉變換在影象去噪方面的實際效果,去掉了高頻訊號後,無論是灰度圖,還是預設色彩圖,影象的輪廓都會被軟化,界限變得模糊,這是由於影象的噪聲以及邊緣部位往往梯度變化較大,而梯度較大的地方屬於高頻訊號,所以在去噪的同時會軟化影象邊緣。

接下來我們進行一個反向操作,也就是影象高通濾波操作,即去低頻訊號,留高頻訊號,看看處理後的影象最終有什麼變化。我們這次以numpy中的快速傅立葉變換為例來實現影象高通濾波操作:

import numpyimport cv2import matplotlib。pyplot as plt img = cv2。imread(“。。/images/1。jpg”)# 轉化為灰度圖gray = cv2。cvtColor(img, cv2。COLOR_BGR2GRAY)rows, cols = gray。shapeprint(gray。shape)# 1。FFT快速傅立葉變換: 空域——>頻域fft = numpy。fft。fft2(gray) # 傅立葉變換,引數為灰度圖print(fft。shape)# 2。中心化: 將低頻訊號移動到影象中心fftshift = numpy。fft。fftshift(fft)print(numpy。min(numpy。abs(fftshift)))#絕對最低頻率訊號print(numpy。max(fftshift),numpy。min(fftshift))#最高頻率訊號,最低頻率訊號# 獲取振幅譜(展示圖片用): numpy。log()是為了將值壓縮在[0, 255]附近magnitude_spectrum = numpy。log(numpy。abs(fftshift))print(numpy。max(magnitude_spectrum),numpy。min(magnitude_spectrum))# 3。濾波操作之高通濾波(去低頻,保高頻)fftshift[rows // 2 - 50:rows // 2 + 50, cols // 2 - 50: cols // 2 + 50] = 0# print(fftshift。shape)# 4。去中心化: 將剩餘的低頻和高頻的位置還原ifftshift = numpy。fft。ifftshift(fftshift)# 5。逆傅立葉變換: 頻域——>空域ifft = numpy。fft。ifft2(ifftshift)# print(ifft)# 6。二維向量取模(幅值)img_back = numpy。abs(ifft)# 結合matplotlib展示多張圖片plt。figure(figsize=(10, 10))plt。subplot(221), plt。imshow(gray, cmap=“gray”), plt。title(“Input Gray Image”)plt。xticks([]), plt。yticks([])plt。subplot(222), plt。imshow(magnitude_spectrum, cmap=“gray”), plt。title(“Magnitude Spectrum”)plt。xticks([]), plt。yticks([])plt。subplot(223), plt。imshow(img_back, cmap=“gray”), plt。title(“Image after HPF”)plt。xticks([]), plt。yticks([])plt。subplot(224), plt。imshow(img_back), plt。title(“Result in JET”) # 預設cmap=‘jet’plt。xticks([]), plt。yticks([])plt。show()

程式碼展現效果:

簡單易懂的傅立葉變換原理和程式碼實現

影象高通濾波的效果和低通濾波效果剛好相反,從上面案例的結果來看,高通濾波的操作會使影象失去更多的背景細節部分,只保留了影象相應的輪廓介面。這是因為背景部分的影象梯度變化相對輪廓部分的梯度變化較小,影象梯度變化較小的這部分屬於低頻訊號,去除掉這部分低頻訊號,會使得影象缺少過渡,邊緣顯得生硬,當去除過多的低頻訊號時,甚至會讓影象變成一副邊緣輪廓圖。

既然我們能夠透過傅立葉變換對影象進行高通濾波或低通濾波的操作,那麼同樣也能對影象進行指定任意頻段的濾波操作,比如中通濾波就是保留影象中間指定頻段的資料,去除高頻資料和低頻資料的操作,而阻滯濾波剛好是去除影象中間指定頻段的資料,保留高頻和低頻資料。

後記:

關於普通傅立葉變換和離散傅立葉變換、快速傅立葉變換之間的概念關係如下:

DTFT是離散時間傅立葉變換,用來表達連續的訊號的頻譜。

DFT是離散傅立葉變換,針對的是離散的訊號和頻譜DFT是DTFT變化而來,其實就是將連續時間t變成了nT。為什麼要這樣做呢,因為計算機是在數字環境下工作的,它不可能看見或者處理現實中連續的訊號,只能夠進行離散計算,在真實性上儘可能地逼近連續訊號。所以DFT是為了我們能夠去用工具分析訊號而創造出來的,通常我們直接用DTFT的機會很少。

FFT(Fast Fourier Transformation),即為快速傅氏變換,是離散傅氏變換的快速演算法,

它是根據離散傅氏變換的奇、偶、虛、實等特性,對離散傅立葉變換的演算法進行改進獲得的。

它對傅氏變換的理論並沒有新的發現,但是對於在計算機系統或者說數字系統中應用離散傅立葉變換,可以說是進了一大步。在FFT中,利用WN的週期性和對稱性,把一個N項序列(設N=2k,k為正整數),分為兩個N/2項的子序列,每個N/2點DFT變換需要(N/2)2次運算,再用N次運算把兩個N/2點的DFT變換組合成一個N點的DFT變換。這樣變換以後,總的運算次數就變成N+2*(N/2)^2=N+N^2/2。FFT提高了運算速度,但是,也對參與運算的樣本序列作出了限制,即要求樣本數為2^N點。離散傅立葉變換DFT則無上述限制。

小結:FFT快,DFT靈活,各有優點,如果滿足分析要求,兩者準確度相同。

關注深度人工智慧學院,我們長期致力於人工智慧職業教育培訓領域的發展,

傳播AI教育,培養AI人才”

是我們的長期願景。

文末附上一張傅立葉變換的動態圖,理論上任何圖形都能被分解成若干個正弦波,也就可以被若干個圓組合的運動軌跡擬合:

簡單易懂的傅立葉變換原理和程式碼實現

作者:智谷煉藥協會學徒

Top