數字影象處理筆記(七):頻域低通濾波平滑影象
1 - 傅立葉變換
在前面我們對空間濾波做了重點的研究,現在我們來介紹一下涉及頻率域中的各種濾波技術。影象從空間域轉換到頻率域使用的是二維傅立葉變換,一個畫素為M*N的影象f(x,y)進行傅立葉變換得到F(u,v),那麼一般的公式為:
它的反變換就是
反變換就可以實現將頻域影象恢復到時域影象。
這些公式可能有些複雜,但是使用numpy包提供的函式可以直接進行影象的傅立葉變換
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('images/12.jpg',0)
f = np.fft.fft2(img)# 快速傅立葉變換演算法得到頻率分佈
fshift = np.fft.fftshift(f) # 預設結果中心點位置是在左上角,轉移到中間位置
#取絕對值:將複數變化成實數
#取對數的目的為了將資料變化到較小的範圍(比如0-255)
s1 = np.log(np.abs(f))
s2 = np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(s1,'gray'),plt.title('original')
plt.subplot(122),plt.imshow(s2,'gray'),plt.title('center')
plt.show()
(注意的是,上圖其實並沒有什麼含義,顯示出來的可以看成是頻域後圖像的振幅資訊)
Ok再來說說程式中為什麼要有一個np.fft.fftshift(f)中心化操作,整個影象是在傅立葉變換的一個週期內完成的,將其看成橫縱兩個方向的一維傅立葉變換,在每個方向上都會有高頻訊號和低頻訊號,那麼傅立葉變換將低頻訊號放在了邊緣,高頻訊號放在了中間,然而一副影象,很明顯的低頻訊號多而明顯,所以將低頻訊號採用一種方法移到中間
影象變換到頻域後就可以進行操作了,目前接觸到的頻域操作似乎也就是一些濾波操作,如同空域裡面的濾波操作一樣,不過原理不一樣了,後面再說說一些頻域濾波方法。好了一旦操作完,得到的資料還是頻域資料,那麼如何將其變換到時域呢?這裡就是傅立葉反變換了,公式表示就如同前面那樣。這個頻域變換到時域的操作就是逆向傅立葉變換再走一遍(比如先反中心化,在逆變換)。一個例項如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('images/12.jpg',0) #直接讀為灰度影象
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
#取絕對值:將複數變化成實數
#取對數的目的為了將資料變化到0-255
s1 = np.log(np.abs(fshift))
plt.subplot(131),plt.imshow(img,'gray'),plt.title('original')
plt.subplot(132),plt.imshow(s1,'gray'),plt.title('center')
# 逆變換
f1shift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f1shift)
#出來的是複數,無法顯示
img_back = np.abs(img_back)
plt.subplot(133),plt.imshow(img_back,'gray'),plt.title('img back')
plt.show()
好了,瞭解基本的傅立葉變換操作後,我們就可以對影象先進行傅立葉變換,然後在頻率域上進行濾波操作後,再利用傅立葉逆變換得到處理之後的影象。下面就介紹頻率域濾波器的作用。
2 - 使用頻率域濾波器平滑影象
2.1 - 理想低通濾波器
以原點為圓心,以
為半徑的院內,無衰減地通過所有頻率,而在圓外“切斷”所有頻率的二維低通濾波器,稱為理想低通濾波器(ILPF),其函式表示式為:
其中,
是一個正常數,
是頻率域中點
與頻率域矩形中心的距離,即
python構建理想低通濾波器
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('images/12.jpg',0) #直接讀為灰度影象
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
#取絕對值:將複數變化成實數
#取對數的目的為了將資料變化到0-255
s1 = np.log(np.abs(fshift))
def make_transform_matrix(d,image):
"""
構建理想低通濾波器
:param d: 濾波器半徑
:param image: 影象的傅立葉變換
:return:
"""
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
if dis <= d:
transfor_matrix[i,j]=1
else:
transfor_matrix[i,j]=0
return transfor_matrix
d_1 = make_transform_matrix(10,fshift)
d_2 = make_transform_matrix(30,fshift)
d_3 = make_transform_matrix(50,fshift)
plt.subplot(131)
plt.axis("off")
plt.imshow(d_1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(d_2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(d_3,cmap="gray")
plt.show()
之後進行濾波處理
#頻率域經過理想低通濾波器變換後再進行逆變換還原到時域影象
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_1)))
img_d2 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_2)))
img_d3 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_3)))
plt.subplot(131)
plt.axis("off")
plt.imshow(img_d1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(img_d2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(img_d3,cmap="gray")
plt.show()
2.2 - 布特沃斯低通濾波器
截止頻率位於距原點
處的n階布特沃斯低通濾波器(BLPF)的傳遞函式定義為
其與ILPF的不同,BLPF傳遞函式在通過頻率和截止頻率的選擇上並沒有選擇使用尖銳、不連續的區分,而是採用更加的平滑傳遞函式的濾波器。
python構建BLPF濾波器:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('images/12.jpg',0) #直接讀為灰度影象
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
s1 = np.log(np.abs(fshift))
def butterworthPassFilter(image, d, n):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa, pb):
from math import sqrt
dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
return dis
dis = cal_distance(center_point, (i, j))
transfor_matrix[i, j] = 1 / ((1 + (dis / d)) ** n)
return transfor_matrix
d_matrix = make_transform_matrix(d)
plt.imshow(d_matrix, cmap="gray")
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
return new_img
butter_5_1 = butterworthPassFilter(img,5,1)
plt.subplot(121)
plt.imshow(img,cmap="gray")
plt.title("img")
plt.axis("off")
plt.subplot(122)
plt.imshow(butter_5_1,cmap="gray")
plt.title("d=5,n=3")
plt.axis("off")
plt.show()
2.3 - 高斯低通濾波器
高斯低通濾波(GLPF)函式表示式:
其中,D(u,v)是距頻率矩形中心的距離,
是關於中心的擴充套件度的度量。通過令
我們可以在本節中使用其他濾波器的表示法來表示該濾波器
其中,
是截止頻率,當
時,GLPF下降到其最大值的0.607處
python實現高斯低通濾波器平滑影象
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('images/12.jpg',0) #直接讀為灰度影象
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
s1 = np.log(np.abs(fshift))
def GaussianLowFilter(image,d):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
transfor_matrix[i,j] = np.exp(-(dis**2)/(2*(d**2)))
return transfor_matrix
d_matrix = make_transform_matrix(d)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img
img_d1 = GaussianLowFilter(img,10)
img_d2 = GaussianLowFilter(img,30)
img_d3 = GaussianLowFilter(img,50)
plt.subplot(131)
plt.axis("off")
plt.imshow(img_d1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(img_d2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(img_d3,cmap="gray")
plt.show()
3 - 總結
總結一下,我們學習瞭如何將圖片進行傅立葉變換到頻率域,通過在頻域率的低通濾波來進行影象的平滑處理,然後我們主要介紹了理想低通濾波器(ILPF)、布特沃斯低通濾波器(BLPF)和高斯低通濾波器(GLPF)的原理和具體的在python環境下對圖片處理的實驗。