網(wǎng)站域名地址查詢網(wǎng)站創(chuàng)建
目錄
一、傅里葉變換
1.1 傅里葉變換概念
1.2?opencv中傅里葉變換
二、實驗代碼
一、環(huán)境
本文使用環(huán)境為:
- Windows10
- Python 3.9.17
- opencv-python 4.8.0.74
二、傅里葉變換
2.1 傅里葉變換概念
傅里葉變換(Fourier Transform)是一種在數(shù)學、物理和工程領域廣泛應用的算法,用于分析信號或數(shù)據(jù)的頻率成分。它是由法國數(shù)學家約瑟夫·傅里葉(Joseph Fourier)于19世紀初提出的,因此得名。傅里葉變換的基本思想是將一個時域信號轉(zhuǎn)換為頻域信號,或者將一個頻域信號轉(zhuǎn)換回時域信號。這種轉(zhuǎn)換可以幫助我們更好地理解和分析信號的特性,例如幅度、頻率和相位等。
傅里葉變換可以分為連續(xù)傅里葉變換(Continuous Fourier Transform,CFT)和離散傅里葉變換(Discrete Fourier Transform,DFT)。連續(xù)傅里葉變換用于處理連續(xù)時間信號,而離散傅里葉變換用于處理離散時間信號。在實際應用中,由于計算機處理的是離散數(shù)據(jù),因此離散傅里葉變換更為常用。
離散傅里葉變換(DFT)的基本步驟如下:
-
對輸入信號進行采樣,得到離散時間信號。采樣頻率通常為原始信號頻率的整數(shù)倍,以滿足奈奎斯特采樣定理。
-
對離散時間信號進行窗函數(shù)處理。窗函數(shù)的作用是減小信號截斷引起的頻譜泄漏,同時減小頻譜旁瓣的影響。常用的窗函數(shù)有矩形窗、漢寧窗和海寧窗等。
-
計算離散時間信號的離散傅里葉變換。這可以通過快速傅里葉變換(Fast Fourier Transform,FFT)算法來實現(xiàn),以提高計算效率。快速傅里葉變換是一種基于蝶形運算的高效算法,其計算復雜度為O(nlogn),其中n為信號長度。
-
對離散傅里葉變換的結(jié)果進行分析。通過觀察頻譜圖,可以了解信號的頻率分布、幅值和相位等信息。此外,還可以利用傅里葉變換的性質(zhì)進行信號處理,例如濾波、降噪和壓縮等。
傅里葉變換具有以下重要性質(zhì):
-
線性性質(zhì):傅里葉變換滿足線性疊加原理,即兩個信號的傅里葉變換之和等于這兩個信號分別進行傅里葉變換后再相加的結(jié)果。
-
共軛對稱性:對于實數(shù)信號,其傅里葉變換的共軛復數(shù)表示了信號的頻譜。這意味著實數(shù)信號的頻譜是以原點為中心的對稱分布。
-
時移性質(zhì):對于任意實數(shù)τ,信號x(t)與其自身延時τ的信號x(t-τ)的傅里葉變換之比等于e^(j2πτ),其中j為虛數(shù)單位。這表明時移操作可以通過乘以復指數(shù)因子來實現(xiàn)。
-
頻移性質(zhì):對于任意實數(shù)ω,信號x(t)與其頻率為ω的信號cos(2πωt)的乘積的傅里葉變換等于X(f)與δ(f-ω)的卷積,其中δ(f)表示狄拉克δ函數(shù)。這表明頻率調(diào)制可以通過乘以復指數(shù)因子和濾波操作來實現(xiàn)。
-
能量守恒:離散傅里葉變換的能量守恒性質(zhì)表明,信號的總能量在時域和頻域之間是平衡的。這意味著在頻域中去除某些頻率分量后,信號的總能量會相應地轉(zhuǎn)移到其他頻率分量上。
總之,傅里葉變換是一種強大的數(shù)學工具,廣泛應用于通信、圖像處理、音頻處理、生物信息學等領域。通過傅里葉變換,我們可以更好地理解和分析信號的特性,從而實現(xiàn)信號的濾波、降噪、壓縮等功能。
2.2?opencv中傅里葉變換
在數(shù)字圖像處理中,空間域濾波和頻域濾波都是常見的方法,但它們之間存在一些關鍵的區(qū)別。
-
空間域濾波:這種方法直接對圖像進行操作,通常使用各種模板與圖像進行卷積運算來實現(xiàn)圖像的處理。由于其直接在圖像空間上操作,這種方法的實現(xiàn)相對簡單和直觀。
-
頻域濾波:頻域濾波首先將圖像從空間域轉(zhuǎn)換到頻域,然后對頻率域中的圖像數(shù)據(jù)進行處理,最后再將其轉(zhuǎn)換回空間域。這種處理方法的優(yōu)點在于,某些圖像處理任務在頻域中比在空間域中更為簡單。例如,根據(jù)卷積定理,可以通過傅立葉變換將空域卷積濾波變換為頻域濾波。此外,頻域濾波允許設計者使用復雜的濾波器設計,這可能在空間域中難以實現(xiàn)。然而,需要注意的是,如果選用的頻域濾波器具有陡峭的變化,可能會導致輸出圖像產(chǎn)生“振鈴”現(xiàn)象,這是由于灰度劇烈變化處產(chǎn)生的。
在OpenCV庫中,傅里葉變換和逆傅里葉變換的實現(xiàn)主要依賴于**cv2.dft()和cv2.idft()**兩個函數(shù)。在進行傅里葉變換時,你需要將原始圖像轉(zhuǎn)換為np.float32格式。
具體來說,cv2.dft()函數(shù)的定義是:cv2.dft(原始圖像,轉(zhuǎn)換標識)
。其中,原始圖像必須是np.float32格式,轉(zhuǎn)換標識用于說明是傅里葉變換還是傅里葉逆變換。此函數(shù)返回與前一個相同的結(jié)果,但是有兩個通道。第一個通道是結(jié)果的實部,第二個通道是結(jié)果的虛部。
另一方面,cv2.idft()函數(shù)被用來執(zhí)行逆傅里葉變換。例如,如果你有一個通過傅里葉變換得到的復數(shù)矩陣,你可以使用這個函數(shù)來恢復原始圖像。
需要注意的是,OpenCV提供的這兩個函數(shù)的效率較高(比OpenCV自帶的函數(shù)快3倍)。這是因為它們實現(xiàn)了一種稱為快速傅立葉變換(FFT)的快速算法。
三、實驗代碼
from __future__ import print_function
import sysimport cv2 as cv
import numpy as npdef print_help():print('''代碼演示離散傅里葉變換,同時也顯示幅度譜''')def main(argv):print_help()I = cv.imread("d:/Data/1.jpg", cv.IMREAD_GRAYSCALE)if I is None:print('Error opening image')return -1## [expand]rows, cols = I.shapem = cv.getOptimalDFTSize( rows )n = cv.getOptimalDFTSize( cols )# 把圖像邊界拓展下padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0])## [complex_and_real]planes = [np.float32(padded), np.zeros(padded.shape, np.float32)]complexI = cv.merge(planes) # Add to the expanded another plane with zeros## [complex_and_real]## [dft]cv.dft(complexI, complexI) # this way the result may fit in the source matrix## [dft]# compute the magnitude and switch to logarithmic scale# = > log(1 + sqrt(Re(DFT(I)) ^ 2 + Im(DFT(I)) ^ 2))## [magnitude]cv.split(complexI, planes) # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))cv.magnitude(planes[0], planes[1], planes[0])# planes[0] = magnitudemagI = planes[0]## [magnitude]## [log]matOfOnes = np.ones(magI.shape, dtype=magI.dtype)cv.add(matOfOnes, magI, magI) # switch to logarithmic scale# 取log是為了拉伸值cv.log(magI, magI)## [log]## [crop_rearrange]magI_rows, magI_cols = magI.shape# crop the spectrum, if it has an odd number of rows or columnsmagI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)]cx = int(magI_rows/2)cy = int(magI_cols/2)q0 = magI[0:cx, 0:cy] # Top-Left - Create a ROI per quadrantq1 = magI[cx:cx+cx, 0:cy] # Top-Rightq2 = magI[0:cx, cy:cy+cy] # Bottom-Leftq3 = magI[cx:cx+cx, cy:cy+cy] # Bottom-Righttmp = np.copy(q0) # 交換象限(左上和右下交換)magI[0:cx, 0:cy] = q3magI[cx:cx + cx, cy:cy + cy] = tmptmp = np.copy(q1) # 交換象限(右上和左下交換)magI[cx:cx + cx, 0:cy] = q2magI[0:cx, cy:cy + cy] = tmp# 歸一化到 [0, 1]范圍內(nèi)cv.normalize(magI, magI, 0, 1, cv.NORM_MINMAX)# 原圖得灰度圖cv.imshow("Input Image" , I )# 幅度譜,也叫頻譜cv.imshow("spectrum magnitude", magI)cv.waitKey()if __name__ == "__main__":main(sys.argv[1:])
原圖:
灰度圖:
幅度譜如下:中間是高頻區(qū)域、邊界是低頻區(qū)域、幅度譜是關于圖像中心對稱的。