快速傅里叶变换python_【原创】OpenCV-Python系列之傅里叶变换(三十八)
OpenCV-Python系列之傅里葉變換
傅里葉變換
我們生活在時間的世界中,早上7:00起來吃早飯,8:00去擠地鐵,9:00開始上班。。。以時間為參照就是時域分析。
但是在頻域中一切都是靜止的!可能有些人無法理解,我建議大家看看這個文章,寫的真是相當好,推薦!
傅里葉變換經常被用來分析不同濾波器的頻率特性。我們可以使用 2D 離散傅里葉變換 (DFT) 分析圖像的頻域特性。實現 DFT 的一個快速算法被稱為快速傅里葉變換(FFT)。
對于一個正弦信號,如果它的幅度變化非常快,即f數值比較大,我們可以說他是高頻信號,如果變化非常慢,即f數值比較小,我們稱之為低頻信號。你可以把這種想法應用到圖像中,那么我們如何看待圖像的變化幅度大小呢?那就是看邊界點和噪聲,一般邊界和噪聲是圖像中的高頻分量(注意這里的高頻是指變化非常快,而非出現的次數多)。如果沒有如此大的幅度變化我們稱之為低頻分量。
那么用傅里葉變換進行濾波的優點在哪兒呢,它可以把圖像由時域轉換成頻域,由于頻域中的信息更為簡單,所以濾波起來更為方便,濾波之后再轉換到時域,那么就相當于一個濾波了。
傅里葉變換的作用
·高頻:變化劇烈的灰度分量,例如邊界
·低頻:變化緩慢的灰度分量,例如一片大海
所以一般情況下,由于圖像中的高頻分量與低頻分量都存在,我們可以用傅里葉變換進行濾波。
濾波
·低通濾波器:只保留低頻,會使得圖像模糊
·高通濾波器:只保留高頻,會使得圖像細節增強
我們來看傅里葉變換的函數原型:
dst=cv2.dft(src, dst=None, flags=None, nonzeroRows=None)
第一個參數src為輸入圖像
dst是輸出圖像,包括輸出圖像的大小和尺寸
flags有五種,為轉換標志:
1、DFT _INVERSE:執行的是反向的一維或者二維的轉換。
2、DFT _SCALE:矩陣的元素數量除以它,產生縮放效果。
3、DFT _COMPLEX_OUTPUT:執行正向轉換。
4、DFT _REAL_OUTPUT:執行一維或二維復數陣列的逆變換,結果通常是相同大小的復數數組,但如果輸入數組具有共軛復數對稱性,則輸出為真實數組。
5、DFT _ROWS:執行正向或者反向變換輸入矩陣的每個單獨的行,該標志可以同時轉換多個矢量,并可用于減少開銷以執行3D和更高維度的轉換等。
nonzeroRows:表示當參數不為零時,函數假定只有nonzeroRows輸入數組的第一行(未設置)或者只有輸出數組的第一個(設置)包含非零,因此函數可以處理其余的行更有效率,并節省一些時間;這種技術對計算陣列互相關或使用DFT卷積非常有用。
繼續來分析傅里葉逆變換函數:
dst = cv2.idft(src[, dst[, flags[, nonzeroRows]]])
src: 表示輸入圖像,包括實數或復數。
dst: 表示輸出圖像。
flags: 表示轉換標記。
nonzeroRows: 表示要處理的dst行數,其余行的內容未定義。
得到的結果中頻率為零的部分會在左上角,通常要轉換到中心位置,可以通過np.fft.fftshift()和np.fft.ifftshift()變換來實現,前者是傅里葉變換,后者是傅里葉逆變換。
cv2.dft()返回的結果是雙通道(實部、虛部),通常需要轉換成圖像格式才能展示(0,255),讓我們看一下代碼:def dft():
img = cv2.imread('min.jpg', 0) # 將圖像轉換成灰度圖
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT) # 進行傅里葉變換
dft_shift = np.fft.fftshift(dft) # 將頻率為零的部分轉移到中心位置
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) # 公式
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
可以看到,中心部分比較亮,越靠近中間位置低頻信息越多,而高頻信息則都在邊界部分。
接下來要想對其進行濾波,應該怎么辦呢?
顯而易見,既然我們要去除低頻分量,那就定一個范圍,比如30*30的正方形范圍,以圖像中心為正方形中心點,將這個范圍以內的高亮度的像素點去掉,就完成了濾波,然后我們再使用傅里葉逆變換將圖像還原就可以看到。
代碼:def filter():
img = cv2.imread('min.jpg', 0)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2) # 中心位置
# 低通濾波
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
# 高通濾波器
# mask = np.ones((rows, cols, 2), np.uint8)
# mask[crow-30:crow+30, ccol-30:ccol+30] = 0
# IDFT
fshift = dft_shift * mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])
plt.show()
低通結果:
也可以設計高通濾波器將低頻部分去除,代碼在上面也有,只需修改掩模即可,構建一個掩模,與低頻區域對應的地方設置為 0, 與高頻區域對應的地方設置為 1。下圖為效果圖,高通結果:
可以看到,高通濾波相當于保留了圖像的邊緣部分,因為邊緣部分屬于高頻信息。
總結
以上是生活随笔為你收集整理的快速傅里叶变换python_【原创】OpenCV-Python系列之傅里叶变换(三十八)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本田中国与东风汽车合作:在商用车领域开启
- 下一篇: pythonrandrange_Pyth