iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
自我挑戰組

數位影像處理系列 第 10

[Day 10] 影像梯度與銳化

  • 分享至 

  • xImage
  •  

今天我們先討論影像梯度的定義以及影像銳化,有了前面兩個基礎知識後,再介紹中值濾波和雙邊濾波。


1.影像梯度

影像梯度(Image Gradiant)是指在數位影像中,像素強度或色彩的變化量,通常具有方向性。定義如下:

https://ithelp.ithome.com.tw/upload/images/20220917/201523709pSnGrBGXP.png

最右邊的矩陣上方為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輸出。結果如下:
https://ithelp.ithome.com.tw/upload/images/20220917/20152370pNxdUodAkq.png
Gradient_x 和 Gradient_y方別用來擷取x與y方向的邊緣資訊,最後第四張圖則是用來擷取兩個方向的邊緣資訊。


2.影像銳化

影像銳化(Image Sharpening)可用來強化影像的邊緣資訊,主要是利用二階導函數實作,定義如下:

https://ithelp.ithome.com.tw/upload/images/20220917/20152370BDpEiiIeNs.png
這個式子看起來很恐怖,不過其實就是將函數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,以調整數位影像。結果如下:
https://ithelp.ithome.com.tw/upload/images/20220917/20152370xqhU9OUlQq.png
房屋的邊緣細節變得清楚,可是怎麼好像怪怪的? 其他的細節都丟失了。

我們可以使用混和拉普拉斯算子來解決這個問題,程式碼如下:

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()

結果如下圖:
https://ithelp.ithome.com.tw/upload/images/20220917/20152370SPDoO1ShbP.png

可以發現既能保留背景細節,也成加強影像邊緣資訊,這些知識我們將用在未來的非銳化遮罩、中值濾波等等

Github:https://github.com/Damien-Chen/Image_Processing


上一篇
[Day 9]影像濾波(2)-平均濾波與高斯濾波
下一篇
[Day 11] 影像濾波(3)-非銳化遮罩、中值濾波與雙邊濾波
系列文
數位影像處理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言