python傅里叶逆变换_OpenCV-Python系列之傅里叶变换
傅里葉變換
我們生活在時間的世界中,早上7:00起來吃早飯,8:00去擠地鐵,9:00開始上班。。。以時間為參照就是時域分析。
但是在頻域中一切都是靜止的!可能有些人無法理解,我建議大家看看這個文章,寫的真是相當好,推薦!
https://zhuanlan.zhihu.com/p/19763358
傅里葉變換經常被用來分析不同濾波器的頻率特性。我們可以使用?2D?離散傅里葉變換?(DFT)?分析圖像的頻域特性。實現?DFT?的一個快速算法被稱為快速傅里葉變換(FFT)。
對于一個正弦信號,如果它的幅度變化非常快,即f數值比較大,我們可以說他是高頻信號,如果變化非常慢,即f數值比較小,我們稱之為低頻信號。你可以把這種想法應用到圖像中,那么我們如何看待圖像的變化幅度大小呢?那就是看邊界點和噪聲,一般邊界和噪聲是圖像中的高頻分量(注意這里的高頻是指變化非???#xff0c;而非出現的次數多)。如果沒有如此大的幅度變化我們稱之為低頻分量。
那么用傅里葉變換進行濾波的優點在哪兒呢,它可以把圖像由時域轉換成頻域,由于頻域中的信息更為簡單,所以濾波起來更為方便,濾波之后再轉換到時域,那么就相當于一個濾波了。
傅里葉變換的作用
·?????????????高頻:變化劇烈的灰度分量,例如邊界
·?????????????低頻:變化緩慢的灰度分量,例如一片大海
所以一般情況下,由于圖像中的高頻分量與低頻分量都存在,我們可以用傅里葉變換進行濾波。
濾波
·?????????????低通濾波器:只保留低頻,會使得圖像模糊
·?????????????高通濾波器:只保留高頻,會使得圖像細節增強
我們來看傅里葉變換的函數原型:
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系列之傅里叶变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scrapy框架_Python:Scra
- 下一篇: python中级水平_python 初级