数字图像处理——第四章 频率域滤波
數字圖像處理——第4章 頻率域濾波
文章目錄
- 數字圖像處理——第4章 頻率域濾波
- 頻率域
- 1.傅里葉級數原理
- 1.1.一維傅里葉變換
- 1.2.二維傅里葉變換
- 2.python×傅里葉級數
- 2.1.傅里葉變換后的頻譜圖
- 3.頻率域濾波
- 3.1.低頻與高頻
- 3.2.頻率域濾波步驟
- 3.3.低通濾波器
- 3.4.高通濾波器
- 3.5.低通與高通濾波器實驗總結
頻率域
上一章學的灰度變換和空間濾波,主要目的是減少噪聲和平滑圖像,同時也是在空間域進行的圖像增強操作。而這章主要是頻率域濾波,濾波的概念在上一章節有涉及到,所以先了解下頻率域。頻率域是指從函數的頻率角度出發分析函數,和頻率域相對的是時間域。簡單說就是如果從時間域分析信號時,時間是橫坐標,振幅是縱坐標。而在頻率域分析的時候則是頻率是橫坐標,振幅是縱坐標。那么下一個問題就是為什么要在頻率域中進行圖像處理? 1). 可以利用頻率成分和圖像外表之間的對應關系。一些在空間域表述困難的增強任務,在頻率域中變得非常普通;2). 濾波在頻率域更為直觀,它可以解釋空間域濾波的某些性質; 3).可以在頻率域指定濾波器,做反變換,然后在空間域使用結果濾波器作為空間域濾波器的指導。
頻率域濾波是對圖像進行傅里葉變換,將圖像由圖像空間轉換到頻域空間,然后在頻率域中對圖像的頻譜作分析處理,以改變圖像的頻率特征。
1.傅里葉級數原理
傅里葉是18世紀法國的一位偉大的數學家。他指出任何周期函數都可以表示為不同頻率的正弦和或者余弦和的形式,每個正弦或者余弦乘以不同的系數就是傅里葉級數。無論函數有多復雜,只要它是周期性的,并且滿足一定的數學條件,就一定可以用這樣的正弦和或者余弦和的形式來表示。翻開考完研沒扔的高數,回看到傅里葉級數,公式如下:
f(x)=a02+∑n=1∞(ancos?nπlx+bnsin?nπlx)f(x)=\frac{a_{0}}{2}+\sum_{n=1}^{\infty}\left(a_{n} \cos \frac{n \pi}{l} x+b_{n} \sin \frac{n \pi}{l} x\right) f(x)=2a0??+n=1∑∞?(an?coslnπ?x+bn?sinlnπ?x)
其中:
an=1l∫?llf(x)cos?nπlxdx,n=0,1,2,?,其中a0為n=0時a_{n}=\frac{1}{l} \int_{-l}^{l} f(x) \cos \frac{n \pi}{l} x \mathrm{~d} x, n=0,1,2, \cdots,其中a_{0}為n=0時 an?=l1?∫?ll?f(x)coslnπ?x?dx,n=0,1,2,?,其中a0?為n=0時
bn=1l∫?llf(x)sin?nπlxdx,n=0,1,2,?,b_{n}=\frac{1}{l} \int_{-l}^{l} f(x) \sin \frac{n \pi}{l} x \mathrm{~d} x, n=0,1,2, \cdots, bn?=l1?∫?ll?f(x)sinlnπ?x?dx,n=0,1,2,?,
除此之外,若展開式中只有正弦函數,則稱其為正弦函數;相反,若展開式中只有余弦函數,則稱其為余弦級數。
1.1.一維傅里葉變換
傅里葉變換:
F(μ)=∫?∞+∞f(t)e?j2πμtdtF(\mu)=\int_{-\infty}^{+\infty} f(t) e^{-j 2 \pi \mu t} d t F(μ)=∫?∞+∞?f(t)e?j2πμtdt
傅里葉反變換:
f(t)=∫?∞+∞F(μ)ej2πμtdμf(t)=\int_{-\infty}^{+\infty} F(\mu) e^{j 2 \pi \mu t} d \mu f(t)=∫?∞+∞?F(μ)ej2πμtdμ
其中,2πμ代表頻率,t代表時間。其中,2 \pi \mu代表頻率,t代表時間。其中,2πμ代表頻率,t代表時間。傅里葉變換認為一個周期函數(信號)包含多個頻率分量,任意函數(信號)f(t)可通過多個周期函數(基函數)相加而合成。從物理角度理解傅里葉變換是以一組特殊的函數(三角函數)為正交基,對原函數進行線性變換,物理意義便是原函數在各組基函數的投影。
1.2.二維傅里葉變換
同樣連續的傅里葉變換為:
F(μ,v)=∫?∞+∞∫?∞+∞f(t,z)e?j2π(μt+vz)dtdzF(\mu, v)=\int_{-\infty}^{+\infty} \int_{-\infty}^{+\infty} f(t, z) e^{-j 2 \pi(\mu t+v z)} d t d z F(μ,v)=∫?∞+∞?∫?∞+∞?f(t,z)e?j2π(μt+vz)dtdz
它的反變換:
f(t,z)=∫?∞+∞∫?∞+∞F(μ,v)ej2π(μt+vz)dμdvf(t, z)=\int_{-\infty}^{+\infty} \int_{-\infty}^{+\infty} F(\mu, v) e^{j 2 \pi(\mu t+v z)} d \mu d v f(t,z)=∫?∞+∞?∫?∞+∞?F(μ,v)ej2π(μt+vz)dμdv
傅里葉逆變換是將圖像的頻率分布函數變換為灰度分布函數傅里葉變換以前,圖像(未壓縮的位圖)是由對在連續空間(現實空間)上的采樣得到一系列點的集合,通常用一個二維矩陣表示空間上各點,記為z=f(x,y)。又因空間是三維的,圖像是二維的,因此空間中物體在另一個維度上的關系就必須由梯度來表示,這樣我們才能通過觀察圖像得知物體在三維空間中的對應關系。
傅里葉頻譜圖上我們看到的明暗不一的亮點,其意義是指圖像上某一點與鄰域點差異的強弱,即梯度的大小,也即該點的頻率的大小(可以這么理解,圖像中的低頻部分指低梯度的點,高頻部分相反)。一般來講,梯度大則該點的亮度強,否則該點亮度弱。這樣通過觀察傅里葉變換后的頻譜圖,也叫功率圖,我們就可以直觀地看出圖像的能量分布:如果頻譜圖中暗的點數更多,那么實際圖像是比較柔和的(因為各點與鄰域差異都不大,梯度相對較小);反之,如果頻譜圖中亮的點數多,那么實際圖像一定是尖銳的、邊界分明且邊界兩邊像素差異較大的。
2.python×傅里葉級數
理論過于抽象,還是實實在在的用代碼折騰一下比較好理解。首先我們需要一個原函數:
f(x)={exp?(x),?π≤x<01,0≤x<πf(x)=\left\{\begin{array}{lr} \exp (x), & -\pi \leq x<0 \\ 1, & 0 \leq x<\pi \end{array}\right. f(x)={exp(x),1,??π≤x<00≤x<π?
函數圖像如下:
可以用numpy和plt畫出,代碼如下:
import os
import cv2
from pylab import *
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3,pi)# 定義x軸
cond = [True if (i>-pi and i<0) else False for i in x] #使用列表解析的方法
y=1*(x>0)+np.exp(x)*cond # y的函數
plt.plot(x,y)
plt.show()
接著算出該函數的a0,an,bn,最后自定義函數畫出傅里葉級數變換,圖像如下:
由上圖看出,這圖像就有正弦余弦內味了,周期函數都可以表示為不同頻率的正弦和或者余弦和的形式。代碼如下,建議做這種小實驗使用jupyter,方便快捷
import os
import cv2
from pylab import *
import matplotlib.pyplot as plt
import numpy as np
x = mgrid[-10:10:0.2]
n = arange(1, 1000)
def fourier_transform():a0 = (1-exp(-pi))/pi+1s = a0 / 2for i in range(1, 100, 1):s0 = ((1-(-1)**i*exp(-pi))/(pi*(1+i**2))*cos(i*x)+1/pi*( (-i*(1-(-1)**i*exp(-pi)))/(1+i**2) + (1-(-1)**i)/i ) * sin(i*x))s = s + s0 plot(x,s,'orange',linewidth=0.6)title('fourier_transform')show()
fourier_transform()
2.1.傅里葉變換后的頻譜圖
使用傅里葉變換獲得的頻譜圖。圖像的主要成分是低頻信息,它形成了圖像的基本灰度等級,對圖像結構的決定作用較小;高頻信息形成了圖像的邊緣和細節,是在中頻信息上對圖像內容的進一步強化。
如上圖所示,中間的亮點代表著圖像的低頻,其余周圍則表示圖像的高頻信息。若不將低頻信息移至中間,則低頻信息過于分散,頻譜未中心化如下圖所示:
代碼如下所示:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 讀取圖片
img = cv2.imread(' ', 0)# 進行float32形式轉換
float32_img = np.float32(img)# 使用cv2.dft進行傅里葉變化
dft_img = cv2.dft(float32_img, flags=cv2.DFT_COMPLEX_OUTPUT)# 使用np.fft.shiftfft()將變化后的圖像的低頻轉移到中心位置
dft_img_ce = np.fft.fftshift(dft_img)# 使用cv2.magnitude將實部和虛部轉換為實部,乘以20是為了使得結果更大
# img_dft = 20 * np.log(cv2.magnitude(dft_img_ce[:, :, 0], dft_img_ce[:, :, 1]))
# 頻譜未中心化
img_dft = 20 * np.log(cv2.magnitude(dft_img[:, :, 0], dft_img[:, :, 1]))
# 進行畫圖操作
plt.subplot(121) # 我是第一行第二列的第一個
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.imshow(img_dft, cmap='gray')
plt.show()
3.頻率域濾波
3.1.低頻與高頻
低頻對應圖像內變換緩慢的灰度分兩。例如在一幅大草原的圖像中,低頻對應著廣袤的顏色趨于一致的草原。總結就是低頻是圖像中平坦的,灰度變化不大的點,圖像中的大部分區域。
高頻對應圖像內變化越來越快的灰度分量,是由灰度的尖銳過度造成的,例如,還是大草原那幅圖像,若圖像中有一只獅子,則獅子的邊緣信息就是高頻。總結就是高頻是圖像中灰度變化劇烈的點,一般是圖像輪廓或者是噪聲。
根據圖像的高頻與低頻的特征,我們可以設計相應的高通與低通濾波器。通過低頻的濾波器叫做低通濾波器,通過高頻的濾波器叫做高通濾波器。高通濾波可以檢測圖像中尖銳、變化明顯的地方;低通濾波可以讓圖像變得光滑,濾除圖像中的噪聲。
3.2.頻率域濾波步驟
為了方便下述低通高通濾波器的實驗,必須先明確頻率域濾波的基本步驟。
- 首先將圖片讀取成灰度圖且轉化為np.float32()
- 使用cv2.dft函數進行傅里葉變化
- 使用np.fft.fftshift函數將低頻轉移到圖像中心
- 定義掩模:生成的掩模中間為1周圍為0
- 將掩模與傅里葉變化后圖像相乘,保留中間部分
- 使用np.fft.ifftshift將低頻移動到原來的位置
- 使用cv2.idft進行傅里葉的反變化
- 使用cv2.magnitude轉化為空間域內
- 使用plt進行繪圖展示
由上述敘述可知,濾波的關鍵取決于濾波函數,也稱為濾波器,因為它在濾波中抑制或除去了頻譜中的某些分量,而保留其他的一些頻率不受影響,從而達到濾波的目的。而下述的 低通濾波器和高通濾波器的不同點,便在于定義不同的濾波,即步驟中的掩模,不同的濾波將產生不同的效果。
3.3.低通濾波器
理想的低通濾波器模板為:
H(u,v)={1,D(u,v)≤D00,D(u,v)>D0H(u, v)=\left\{\begin{array}{ll} 1, & D(u, v) \leq D_{0} \\ 0, & D(u, v)>D_{0} \end{array}\right. H(u,v)={1,0,?D(u,v)≤D0?D(u,v)>D0??
其中,D0表示通帶半徑,D(u,v)是到頻譜中心的距離(歐式距離),計算公式如下:
D(u,v)=(u?M/2)2+(v?N/2)2\mathrm{D}(u, v)=\sqrt{(u-M / 2)^{2}+(v-N / 2)^{2}} D(u,v)=(u?M/2)2+(v?N/2)2?
M和N表示頻譜圖像的大小,(M/2,N/2)即為頻譜中心。低通濾波器代碼如下所示:
# 低通濾波器
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 第一步讀入圖片
img = cv2.imread(' ', 0)# filepath
# 使用cv2.dft進行傅里葉變化
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
# 使用np.fft.fftshift將低頻轉移到圖像中心
dft_center = np.fft.fftshift(dft)
# 定義掩模:生成的掩模中間為1周圍為0
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得圖像的中心點位置
mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1# 將掩模與傅里葉變化后圖像相乘,保留中間部分
mask_img = dft_center * mask# 使用np.fft.ifftshift(將低頻移動到原來的位置
img_idf = np.fft.ifftshift(mask_img)# 使用cv2.idft進行傅里葉的反變化
img_idf = cv2.idft(img_idf)# 使用cv2.magnitude轉化為空間域內
img_idf = cv2.magnitude(img_idf[:, :, 0], img_idf[:, :, 1])# 進行繪圖操作
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.imshow(img_idf, cmap='gray')
plt.show()
由實驗可以看出,圖片經過低通濾波器,使低頻通過而使高頻衰減 ,降低了圖像變換的幅度。平滑且模糊掉了尖銳和邊緣部分。保留了圖像的整體概貌(低頻部分),去掉了圖像的細節(高頻部分)。
3.4.高通濾波器
和低通濾波器相反,理想的高通濾波器為:
H(u,v)={0,D(u,v)≤D0)1,D(u,v)>D0)H(u, v)=\left\{\begin{array}{ll} 0, & \left.\mathrm{D}(\mathrm{u}, \mathrm{v}) \leq D_{0}\right) \\ 1, & \left.\mathrm{D}(\mathrm{u}, \mathrm{v})>D_{0}\right) \end{array}\right. H(u,v)={0,1,?D(u,v)≤D0?)D(u,v)>D0?)?
其中,D0表示通帶半徑,D(u,v)是到頻譜中心的距離(歐式距離),計算公式如下:
D(u,v)=(u?M/2)2+(v?N/2)2\mathrm{D}(u, v)=\sqrt{(u-M / 2)^{2}+(v-N / 2)^{2}} D(u,v)=(u?M/2)2+(v?N/2)2?
常見的巴特沃斯高通濾波器(BHPF)公式如下:
H(u,v)=11+[D0/D(u,v)]2nH(u, v)=\frac{1}{1+\left[D_{0} / D(u, v)\right]^{2 n}} H(u,v)=1+[D0?/D(u,v)]2n1?
還有高斯高通濾波器(GHPF):
H(u,v)=1?e?D2(u,v)/2σ2,σ=D0H(u, v)=1-e^{-D^{2}(u, v) / 2 \sigma^{2}}, \sigma=D_{0} H(u,v)=1?e?D2(u,v)/2σ2,σ=D0?
# 實現高通濾波器
import cv2
import numpy as np
from matplotlib import pyplot as plt#讀取圖像
img = cv2.imread(' ', 0) # filepath
#傅里葉變換
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.ones((rows, cols, 2), np.uint8) # 低通濾波器這是np.zeros
mask[crow-30:crow+30, ccol-30:ccol+30] = 0 # 低通濾波器這就是1
#掩膜圖像和頻譜圖像乘積
f = fshift * mask
#傅里葉逆變換
ishift = np.fft.ifftshift(f)
iimg = cv2.idft(ishift)
res = cv2.magnitude(iimg[:,:,0], iimg[:,:,1])
#顯示原始圖像和高通濾波處理圖像
plt.subplot(121), plt.imshow(img, 'gray')
plt.subplot(122), plt.imshow(res, 'gray')
plt.show()
實現效果如下圖所示:
由上述實驗可以看出:高通濾波器使高頻通過而使低頻衰減,被高通濾波的圖像比原始圖像少灰度級的平滑過渡而突出邊緣等細節部分,保留了圖像的細節,模糊了概貌。也就是邊緣信息更加突出,例如輪廓。
3.5.低通與高通濾波器實驗總結
由上述實驗可看出,低通濾波器的濾波定義為:
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得圖像的中心點位置
mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
高通濾波器的濾波為:
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得圖像的中心點位置
mask = np.ones((img.shape[0], img.shape[1], 2), np.uint8) # 低通濾波器這是np.zeros
mask[crow-30:crow+30, ccol-30:ccol+30] = 0 # 低通濾波器這就是1
相同點在于定義的掩模大小和圖片大小相同,不同點在于低通濾波器中間為1,那么經過傅里葉變換的圖像和掩模相乘之后,便只保留中間部分;相反,高通濾波器中間為0,經過傅里葉變換的圖像和掩模相乘之后,便只保留邊緣部分。
總結
以上是生活随笔為你收集整理的数字图像处理——第四章 频率域滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CornerNet代码解析——损失函数
- 下一篇: 数字图像处理——第五章 图像复原与重建