影像處理小白(二):影像邊緣偵測
本系列將紀錄影像處理小白從 0 開始學習 Python x OpenCV 的過程。
透過選修課一次次的作業把影像處理的基礎知識建立起來。
本次作業是將圖片轉換成灰階模式並使用 Sobel operator 繪製一張素描圖。
入門者可以參照上一篇: 影像處理小白(一):建立滑桿以旋轉圖片、裁切圖片
若好奇其他的作業可以參照 影像處理分類
功課要求
撰寫一個程式,以灰階模式讀取一張圖像 imread(path, IMREAD_GRAYSCALE)
- 利用 Sobel Operators 偵測並輸出邊緣成分圖
- 設計一個類似素描線條的自畫像圖案。
成果
開發環境
OS | Editor | Language | OpenCV |
---|---|---|---|
Windows 10 | Visual Studio Code | Python 3.9.16 | OpenCV 4.5.4 |
實作
使用的 library 如下:
1
2
3
import cv2
import matplotlib.pyplot as plt
import numpy as np
1/ 讀取灰階圖片
colored_img
用以展示彩色的原圖,而 cv2.imread(file_name, cv2.IMREAD_GRAYSCALE)
會以灰階模式讀入一張圖。
1
2
3
file_name = ".\\fig.jpg"
colored_img = cv2.imread(file_name)
gray_img = cv2.imread(file_name, cv2.IMREAD_GRAYSCALE)
和上一個程式不同,這次的圖片輸出如下:
使用 result_img
儲存所有要顯示的圖片,一個個將他們貼到 plt
中,這裡帶入了 plt.axis("off")
隱藏 matplotlib 預設的 x 軸和 y 軸的刻度。
1
2
3
4
5
6
7
8
9
10
11
result_img = [colored_img]
fig = plt.figure()
def show_img():
for i in range(0, len(result_img)):
image_rgb = cv2.cvtColor(result_img[i], cv2.COLOR_BGR2RGB)
fig.add_subplot(2, 2, i + 1)
plt.imshow(image_rgb)
plt.axis("off")
plt.show()
2/ 邊緣成分圖
首先利用高斯模糊 (Gaussian blur) 去除雜訊(噪聲),使邊界更好檢測:
1
2
3
# 高斯模糊協助過濾雜訊
gray_img = cv2.GaussianBlur(gray_img,(3, 3), 0)
result_img.append(gray_img)
再利用索伯算子 (Sobel operaters) 提取 x 方向和 y 方向的邊界,之後將兩者的絕對值相加,獲得完整的邊緣成分圖。
1
2
3
4
5
6
7
8
9
# 提取 x 方向和 y 方向的邊緣
edge_x = cv2.Sobel(gray_img, cv2.CV_16S, 1, 0, 3)
edge_Y = cv2.Sobel(gray_img, cv2.CV_16S, 0, 1, 3)
# 轉換為 unit8 (提取絕對值)
abs_x = cv2.convertScaleAbs(edge_x)
abs_y = cv2.convertScaleAbs(edge_Y)
# 將兩者取絕對值相加,獲得完整影像
edge_all = cv2.addWeighted(abs_x, 0.5, abs_y, 0.5, 0)
result_img.append(edge_all)
關於高斯模糊和索伯算子,日後我想寫篇文章給他們。
3/ 素描線條畫像
這裡簡單的使用 bitwise_not()
將邊緣成分圖黑白相反,使其看起來像素描:
1
2
sketch_img = cv2.bitwise_not(edge_all)
result_img.append(sketch_img)
最後使用 show_img()
展示成果。
總結
本篇使用高斯模糊去除雜訊、索伯算子提取邊界、bitwise_not()
進行黑白反轉。
邊界提取是很實用的東西,例如分辨一張圖畫是寶可夢還是數碼寶貝 等。
參考資料
This post is licensed under CC BY 4.0 by the author.