今天我們先討論影像梯度的定義以及影像銳化,有了前面兩個基礎知識後,再介紹中值濾波和雙邊濾波。
影像梯度(Image Gradiant)是指在數位影像中,像素強度或色彩的變化量,通常具有方向性。定義如下:
最右邊的矩陣上方為x的一階導函數,下方為y的一階導函數。分別代表影像在水平與垂直方向的強度或灰階變化量。
那麼影像梯度可以做什麼?讓我們來看一個例子:Sobel濾波器
程式碼如下:
import numpy as np
import cv2
def Sobel_gradiant(f, direction = 1):
soble_x = np.array([[1, -2, -1], [0, 0, 0], [1, 2, 1]])
soble_y = np.array([[-1, 0, 1,], [-2, 0, 2], [-1, 0, 1]])
if direction == 1:
grad_x = cv2.filter2D(f, cv2.CV_32F, soble_x)
gx = abs(grad_x)
g = np.uint8(np.clip(gx, 0, 255))
elif direction == 2:
grad_y = cv2.filter2D(f, cv2.CV_32F, soble_y)
gy = abs(grad_y)
g = np.uint8(np.clip(gy, 0, 255))
else:
grad_x = cv2.filter2D(f, cv2.CV_32F, soble_x)
grad_y = cv2.filter2D(f, cv2.CV_32F, soble_y)
magnitude = abs(grad_x) + abs(grad_y)
g = np.uint8(np.clip(magnitude, 0, 255))
return g
def main():
img = cv2.imread("D:\Desktop\IThome\house.jpg", 0)
gx = Sobel_gradiant(img, 1)
gy = Sobel_gradiant(img, 2)
g = Sobel_gradiant(img, 3)
cv2.imshow("Original", img)
cv2.imshow("Gradient in x", gx)
cv2.imshow("Gradient in y", gy)
cv2.imshow("Gradient", g)
cv2.waitKey()
main()
此程式主要建立函式Sobel_gradient,用來回傳數位影像在不同方向經過Sobel梯度運算子的結果。由於數位影像的梯度可能會超過0~255的數值間,因此改用浮點數儲存,取完絕對值後將數值控制在0~255的數值範圍內,並用8-bits輸出。結果如下:
Gradient_x 和 Gradient_y方別用來擷取x與y方向的邊緣資訊,最後第四張圖則是用來擷取兩個方向的邊緣資訊。
影像銳化(Image Sharpening)可用來強化影像的邊緣資訊,主要是利用二階導函數實作,定義如下:
這個式子看起來很恐怖,不過其實就是將函數f(x,y)分別對x和y做二次微分後再相加。左邊的倒三角形平方稱為拉普拉斯運算子。
拉普拉斯運算子可用來處理影像銳化,程式碼如下:
import numpy as np
import cv2
def laplacian(f):
temp = cv2.Laplacian(f, cv2.CV_32F) + 128
g = np.uint8(np.clip(temp, 0, 255))
return g
def main():
img1 = cv2.imread("D:\Desktop\IThome\house.jpg", 0)
img2 = laplacian(img1)
cv2.imshow("Orignial", img1)
cv2.imshow("After", img2)
cv2.waitKey()
main()
在此範例中,使用拉普拉斯算子,結果值可能有正有負,因此另外補上數值128,以調整數位影像。結果如下:
房屋的邊緣細節變得清楚,可是怎麼好像怪怪的? 其他的細節都丟失了。
我們可以使用混和拉普拉斯算子來解決這個問題,程式碼如下:
import numpy as np
import cv2
def composite_laplacian(f):
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
temp = cv2.filter2D(f, cv2.CV_32F, kernel)
g = np.uint8(np.clip(temp, 0, 255))
return g
def main():
img1 = cv2.imread("D:\Desktop\IThome\house.jpg", 0)
img2 = composite_laplacian(img1)
cv2.imshow("Orignial", img1)
cv2.imshow("After", img2)
cv2.waitKey()
main()
結果如下圖:
可以發現既能保留背景細節,也成加強影像邊緣資訊,這些知識我們將用在未來的非銳化遮罩、中值濾波等等
Github:https://github.com/Damien-Chen/Image_Processing