圖片處理-opencv-12.圖像傅里葉變換

傅里葉變換

傅里葉變換(Fourier Transform,簡稱FT)常用于數(shù)字信號處理央碟,它的目的是將時間域上的信號轉(zhuǎn)變?yōu)轭l率域上的信號寒波。隨著域的不同,對同一個事物的了解角度也隨之改變崇堰,因此在時域中某些不好處理的地方沃于,在頻域就可以較為簡單的處理。同時海诲,可以從頻域里發(fā)現(xiàn)一些原先不易察覺的特征繁莹。傅里葉定理指出“任何連續(xù)周期信號都可以表示成(或者無限逼近)一系列正弦信號的疊加√蒯#”

傅里葉變換可以應用于圖像處理中咨演,經(jīng)過對圖像進行變換得到其頻譜圖。從譜頻圖里頻率高低來表征圖像中灰度變化劇烈程度敬辣。圖像中的邊緣信號和噪聲信號往往是高頻信號雪标,而圖像變化頻繁的圖像輪廓及背景等信號往往是低頻信號。這時可以有針對性的對圖像進行相關操作溉跃,例如圖像除噪村刨、圖像增強和銳化等。

Numpy實現(xiàn)傅里葉變換

Numpy中的fft模塊撰茎,相關函數(shù)如下:

  • 計算一維傅里葉變換
    numpy.fft.fft(a, n=None, axis=-1, norm=None)
  • 計算二維的傅里葉變換
    numpy.fft.fft2(a, n=None, axis=-1, norm=None)
  • 計算n維的傅里葉變換
    numpy.fft.fftn()
  • 計算n維實數(shù)的傅里葉變換
    numpy.fft.rfftn()
  • 返回傅里葉變換的采樣頻率
    numpy.fft.fftfreq()
  • 將FFT輸出中的直流分量移動到頻譜中央
    numpy.fft.shift()

Numpy中的 FFT包提供了函數(shù) np.fft.fft2()可以對信號進行快速傅里葉變換嵌牺,其函數(shù)原型如下所示,該輸出結(jié)果是一個復數(shù)數(shù)組(Complex Ndarry)。

fft2(a, s=None, axes=(-2, -1), norm=None)

  • a表示輸入圖像逆粹,陣列狀的復雜數(shù)組
  • s表示整數(shù)序列募疮,可以決定輸出數(shù)組的大小。輸出可選形狀(每個轉(zhuǎn)換軸的長度)僻弹,其中s[0]表示軸0阿浓,s[1]表示軸1。對應fit(x,n)函數(shù)中的n蹋绽,沿著每個軸芭毙,如果給定的形狀小于輸入形狀,則將剪切輸入卸耘。如果大于則輸入將用零填充退敦。如果未給定’s’,則使用沿’axles’指定的軸的輸入形狀
  • axes表示整數(shù)序列蚣抗,用于計算FFT的可選軸侈百。如果未給出,則使用最后兩個軸翰铡《塾颍“axes”中的重復索引表示對該軸執(zhí)行多次轉(zhuǎn)換,一個元素序列意味著執(zhí)行一維FFT
  • norm包括None和ortho兩個選項锭魔,規(guī)范化模式(請參見numpy.fft)网梢。默認值為無

頻率分布圖譜,其中越靠近中心位置頻率越低赂毯,越亮(灰度值越高)的位置代表該頻率的信號振幅越大

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


#讀取圖像
img = cv2.imread('data/test3.jpg', 0)

#快速傅里葉變換算法得到頻率分布
f = np.fft.fft2(img)

#默認結(jié)果中心點位置是在左上角,
#調(diào)用fftshift()函數(shù)轉(zhuǎn)移到中間位置
fshift = np.fft.fftshift(f)       

#fft結(jié)果是復數(shù), 其絕對值結(jié)果是振幅
fimg = np.log(np.abs(fshift))

#展示結(jié)果
plt.figure(figsize=(10, 4))
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('Original Fourier')
plt.axis('off')
plt.subplot(122), plt.imshow(fimg, 'gray'), plt.title('Fourier Fourier')
plt.axis('off')
plt.show()
image.png

Numpy實現(xiàn)傅里葉逆變換

傅里葉逆變換,是傅里葉變換的逆操作拣宰,將頻譜圖像轉(zhuǎn)換為原始圖像的過程党涕。通過傅里葉變換將轉(zhuǎn)換為頻譜圖,并對高頻(邊界)和低頻(細節(jié))部分進行處理巡社,接著需要通過傅里葉逆變換恢復為原始效果圖膛堤。頻域上對圖像的處理會反映在逆變換圖像上,從而更好地進行圖像處理晌该。

圖像逆傅里葉變換主要使用的函數(shù)如下所示:

  • 實現(xiàn)圖像逆傅里葉變換肥荔,返回一個復數(shù)數(shù)組
    numpy.fft.ifft2(a, n=None, axis=-1, norm=None)
  • fftshit()函數(shù)的逆函數(shù),它將頻譜圖像的中心低頻部分移動至左上角
    numpy.fft.fftshift()
  • 將復數(shù)轉(zhuǎn)換為0至255范圍
    iimg = numpy.abs(逆傅里葉變換結(jié)果)
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
plt.figure(figsize=(10, 4))

#讀取圖像
img = cv.imread('data/test3.jpg', 0)

#傅里葉變換
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
res = np.log(np.abs(fshift))

#傅里葉逆變換
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)

#展示結(jié)果
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(132), plt.imshow(res, 'gray'), plt.title('Fourier Image')
plt.axis('off')
plt.subplot(133), plt.imshow(iimg, 'gray'), plt.title('Inverse Fourier Image')
plt.axis('off')
plt.show()
image.png

OpenCV實現(xiàn)傅里葉變換

OpenCV 中相應的函數(shù)是cv2.dft()和用Numpy輸出的結(jié)果一樣朝群,但是是雙通道的燕耿。第一個通道是結(jié)果的實數(shù)部分,第二個通道是結(jié)果的虛數(shù)部分姜胖,并且輸入圖像要首先轉(zhuǎn)換成 np.float32 格式誉帅。其函數(shù)原型如下所示:

dst = cv2.dft(src, dst=None, flags=None, nonzeroRows=None)

  • src表示輸入圖像,需要通過np.float32轉(zhuǎn)換格式
  • dst表示輸出圖像,包括輸出大小和尺寸
  • flags表示轉(zhuǎn)換標記蚜锨,其中DFT_INVERSE執(zhí)行反向一維或二維轉(zhuǎn)換档插,而不是默認的正向轉(zhuǎn)換;DFT_SCALE表示縮放結(jié)果亚再,由陣列元素的數(shù)量除以它郭膛;DFT_ROWS執(zhí)行正向或反向變換輸入矩陣的每個單獨的行,該標志可以同時轉(zhuǎn)換多個矢量氛悬,并可用于減少開銷以執(zhí)行3D和更高維度的轉(zhuǎn)換等则剃;DFT_COMPLEX_OUTPUT執(zhí)行1D或2D實數(shù)組的正向轉(zhuǎn)換,這是最快的選擇圆雁,默認功能忍级;DFT_REAL_OUTPUT執(zhí)行一維或二維復數(shù)陣列的逆變換,結(jié)果通常是相同大小的復數(shù)數(shù)組伪朽,但如果輸入數(shù)組具有共軛復數(shù)對稱性轴咱,則輸出為真實數(shù)組
  • nonzeroRows表示當參數(shù)不為零時,函數(shù)假定只有nonzeroRows輸入數(shù)組的第一行(未設置)或者只有輸出數(shù)組的第一個(設置)包含非零烈涮,因此函數(shù)可以處理其余的行更有效率朴肺,并節(jié)省一些時間;這種技術對計算陣列互相關或使用DFT卷積非常有用

由于輸出的頻譜結(jié)果是一個復數(shù)坚洽,需要調(diào)用cv2.magnitude()函數(shù)將傅里葉變換的雙通道結(jié)果轉(zhuǎn)換為0到255的范圍戈稿。其函數(shù)原型如下:

cv2.magnitude(x, y)

  • x表示浮點型X坐標值,即實部
  • y表示浮點型Y坐標值讶舰,即虛部
  • 最終輸出結(jié)果為幅值
import numpy as np
import cv2
from matplotlib import pyplot as plt
plt.figure(figsize=(10, 4))

#讀取圖像
img = cv.imread('data/test3.jpg', 0)

#傅里葉變換
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)

#將頻譜低頻從左上角移動至中心位置
dft_shift = np.fft.fftshift(dft)

#頻譜圖像雙通道復數(shù)轉(zhuǎn)換為0-255區(qū)間
result = 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(result, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
image.png

OpenCV實現(xiàn)傅里葉逆變換

OpenCV 中鞍盗,通過函數(shù)cv2.idft()實現(xiàn)傅里葉逆變換,其返回結(jié)果取決于原始圖像的類型和大小跳昼,原始圖像可以為實數(shù)或復數(shù)般甲。其函數(shù)原型如下所示:

dst = cv2.idft(src[, dst[, flags[, nonzeroRows]]])

  • src表示輸入圖像,包括實數(shù)或復數(shù)
  • dst表示輸出圖像
  • flags表示轉(zhuǎn)換標記
  • nonzeroRows表示要處理的dst行數(shù)
import numpy as np
import cv2
from matplotlib import pyplot as plt
plt.figure(figsize=(10, 4))

#讀取圖像
img = cv.imread('data/test3.jpg', 0)

#傅里葉變換
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
res1= 20*np.log(cv2.magnitude(dftshift[:,:,0], dftshift[:,:,1]))

#傅里葉逆變換
ishift = np.fft.ifftshift(dftshift)
iimg = cv2.idft(ishift)
res2 = cv2.magnitude(iimg[:,:,0], iimg[:,:,1])

#顯示圖像
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(132), plt.imshow(res1, 'gray'), plt.title('Fourier Image')
plt.axis('off')
plt.subplot(133), plt.imshow(res2, 'gray'), plt.title('Inverse Fourier Image')
plt.axis('off')
plt.show()
image.png

圖像濾波

傅里葉變換的目的并不是為了觀察圖像的頻率分布(至少不是最終目的)鹅颊,更多情況下是為了對頻率進行過濾敷存,通過修改頻率以達到圖像增強、圖像去噪堪伍、邊緣檢測锚烦、特征提取、壓縮加密等目的帝雇。

過濾的方法一般有三種:低通(Low-pass)涮俄、高通(High-pass)、帶通(Band-pass)摊求。

高通濾波

高通濾波器是指通過高頻的濾波器禽拔,衰減低頻而通過高頻刘离,常用于增強尖銳的細節(jié),但會導致圖像的對比度會降低睹栖。該濾波器將檢測圖像的某個區(qū)域硫惕,根據(jù)像素與周圍像素的差值來提升像素的亮度。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
plt.figure(figsize=(10, 4))

#讀取圖像
img = cv.imread('data/test3.jpg', 0)

#傅里葉變換
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)

#設置高通濾波器
rows, cols = img.shape
crow,ccol = int(rows/2), int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0

#傅里葉逆變換
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)

#顯示原始圖像和高通濾波處理圖像
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(122), plt.imshow(iimg, 'gray'), plt.title('Result Image')
plt.axis('off')
plt.show()
image.png

低通濾波

低通濾波器是指通過低頻的濾波器野来,衰減高頻而通過低頻恼除,常用于模糊圖像。低通濾波器與高通濾波器相反曼氛,當一個像素與周圍像素的插值小于一個特定值時豁辉,平滑該像素的亮度,常用于去燥和模糊化處理舀患。

import cv2
import numpy as np
from matplotlib import pyplot as plt
plt.figure(figsize=(10, 6))

#讀取圖像
img = cv.imread('data/test3.jpg', 0)


#傅里葉變換
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
fshift = 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

#掩膜圖像和頻譜圖像乘積
f = fshift * mask
# print(f.shape, fshift.shape, mask.shape)


#傅里葉逆變換
ishift = np.fft.ifftshift(f)
iimg = cv2.idft(ishift)
res = cv2.magnitude(iimg[:,:,0], iimg[:,:,1])

#顯示原始圖像和低通濾波處理圖像
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('Original Image')
plt.axis('off')
plt.subplot(122), plt.imshow(res, 'gray'), plt.title('Result Image')
plt.axis('off')
plt.show()
image.png
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末徽级,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子聊浅,更是在濱河造成了極大的恐慌餐抢,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件低匙,死亡現(xiàn)場離奇詭異旷痕,居然都是意外死亡,警方通過查閱死者的電腦和手機顽冶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門欺抗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人强重,你說我怎么就攤上這事绞呈。” “怎么了间景?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵报强,是天一觀的道長。 經(jīng)常有香客問我拱燃,道長,這世上最難降的妖魔是什么力惯? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任碗誉,我火速辦了婚禮,結(jié)果婚禮上父晶,老公的妹妹穿的比我還像新娘哮缺。我一直安慰自己,他們只是感情好甲喝,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布尝苇。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糠溜。 梳的紋絲不亂的頭發(fā)上淳玩,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音非竿,去河邊找鬼蜕着。 笑死,一個胖子當著我的面吹牛红柱,可吹牛的內(nèi)容都是我干的承匣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼锤悄,長吁一口氣:“原來是場噩夢啊……” “哼韧骗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起零聚,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤袍暴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后握牧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體容诬,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年沿腰,在試婚紗的時候發(fā)現(xiàn)自己被綠了览徒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡颂龙,死狀恐怖习蓬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情措嵌,我是刑警寧澤躲叼,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站企巢,受9級特大地震影響枫慷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜浪规,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一或听、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笋婿,春花似錦誉裆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粱腻。三九已至,卻和暖如春斩跌,著一層夾襖步出監(jiān)牢的瞬間绍些,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工遇革, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萝快。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像揪漩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吏口,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348