1 - 引言
在筆記(七)中,我們通過衰減圖像的傅里葉變換的高頻成分來平滑對象,因爲邊緣和其他灰度的急劇變化與高頻分量有關,所以圖像的銳化可在頻域通過高通濾波來實現。
一個高通濾波器是從給定的低通濾波器用下式得到:
其中,是低通濾波器的傳遞函數,也就是說之前介紹的三種低通濾波器:理想、布特沃斯、高斯低通濾波器可以通過上面的式子快速的轉變爲高通濾波器。接下來,我們介紹其他的高通濾波器
2 - 頻率域的拉普拉斯算子
拉普拉斯算子可使用如下濾波器在頻率域中實現:
在關於頻率矩形的中心,使用如下濾波器:
其中,D(u,v)是距離函數。
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 LaplaceFilter(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] = -4*(np.pi**2)*(dis**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 = LaplaceFilter(img,10)
plt.title('D_1 10')
plt.imshow(img_d1,cmap="gray")
plt.show()
3 - 高頻強調濾波
使用頻率域方法,模板由下式:
和
其中,是一個低通濾波器,是f(x,y)的傅里葉變換。是平滑後的圖像,類似於f(x,y)。然後又
該表達式定義了k=1時的鈍化模板和k>1時的高提升濾波器。
由得
方括號中的表達式,即成爲高頻強調濾波器。
高頻強調濾波器更一般的公式爲
其中, 給出了控制距原點的偏移量,控制高頻的貢獻。
import cv2
import numpy as np
import matplotlib.pyplot as plt
#解決中文顯示問題
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
img = cv2.imread('images/test_5.jpg',0) #直接讀爲灰度圖像
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
s1 = np.log(np.abs(fshift))
def GaussianLowFilter(image,d,flag=None):
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))
if flag == 0:
transfor_matrix[i,j] =0.5+0.75*(1-np.exp(-(dis**2)/(2*(d**2))))
else:
transfor_matrix[i, j] = 1 - 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
plt.subplot(221)
plt.imshow(img,cmap="gray")
plt.title("原始圖像")
plt.subplot(222)
img_d1 = GaussianLowFilter(img,40,1)
plt.imshow(img_d1,cmap="gray")
plt.title('使用高斯高通濾波')
plt.subplot(223)
img_d2 = GaussianLowFilter(img,40,0)
plt.imshow(img_d2,cmap="gray")
plt.title('使用高頻強調濾波')
"""
因爲進過傅里葉變換圖像的像素變成了浮點型,但是直方圖均衡
函數的輸入數據爲整形,所以需要進行數據類型轉換
"""
plt.subplot(224)
img_d3 = GaussianLowFilter(img,40,0)
img_d3 = img_d3.astype(np.uint8)
img_d3=cv2.equalizeHist(img_d3)
plt.imshow(img_d3,cmap="gray")
plt.title('直方圖均衡')
plt.show()
4 - 同態濾波
在生活中會得到這樣的圖像,動態範圍很大,感興趣的部分的灰度卻很暗,範圍很小,灰度層次和細節沒有辦法辨認,用一般的灰度線性變換法是不行的,因爲擴展灰度級雖可以提高物體圖像的 因爲擴展灰度級雖可以提高物體圖像的反差,但會使動態範圍變大。而壓縮灰 反差,但會使動態範圍變大。而壓縮灰度級,雖可以減少動態範圍,但物體灰 度級,雖可以減少動態範圍,但物體灰
度層次和細節就會更看不清。 度層次和細節就會更看不.這時我們需要採用同態濾波。同態濾波是一種在頻域中同時將圖像亮度範圍進行壓縮和將圖像對比度進行增強的方法。
同態濾波
節選自百度百科裏的一段話:同態濾波的基本原理是:將像元灰度值看作是照度和反射率兩個組份的產物。由於照度相對變化很小,可以看作是圖像的低頻成份,而反射率則是高頻成份。通過分別處理照度和反射率對像元灰度值的影響,達到揭示陰影區細節特徵的目的。同態濾波處理的基本流程如下:
其中f(x,y)爲原始圖像,ln爲對數變換,DFT爲傅里葉變換,H(u,v)爲頻域濾波,爲傅里葉逆變換,exp爲指數運算,g(x,y)爲輸出圖像。
圖片的照射分量通常由慢的空間變化來表徵,而反射分量往往引起突變,特變是在不同物體的連接部分。這些特性導致圖像取對數後的傅里葉變換的低頻成分與照射相聯繫,而高頻成分與反射相聯繫。雖然這些聯繫知識粗略的近似,但它們用在圖像濾波中是有益的。
使用同態濾波器可更好地控制照射分量和反射分量,這種控制需要指定一個濾波器函數H(u,v),它可用不同的可控方法影響傅里葉變換的低頻和高頻分量。
這個函數形狀可以用高通濾波器的基本形式來近似。
import cv2
import numpy as np
import matplotlib.pyplot as plt
#解決中文顯示問題
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
img = cv2.imread('images/12.jpg',0) #直接讀爲灰度圖像
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
s1 = np.log(np.abs(fshift))
def Homomorphic(image,d,L,H,c):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
def make_transform_matrix(d,L,H,c):
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] = (H-L)*(1-np.exp(-c*(dis**2/d**2)))+L
return transfor_matrix
d_matrix = make_transform_matrix(d,L,H,c)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img
plt.subplot(211)
plt.title('原始圖像')
plt.imshow(img,cmap="gray")
plt.subplot(212)
img_d1 = Homomorphic(img,80,0.25,2,1)
plt.title('同態濾波')
plt.imshow(img_d1,cmap="gray")
plt.show()
5 - 小結
本文主要介紹了各種頻域的高通濾波器來對圖像進行處理,可以看到高通濾波器主要是將圖片中的邊緣提取出來,讓圖片的細節更加清晰。高通和低通濾波器的相互轉換也十分方便,通過靈活的集合各種濾波器可以幫助我們清除圖像的噪音並且把我們感興趣的細節提取出來。