s1093705 作業二

線條自畫像 (二值化與邊緣偵測 Image Thresholding and Edge Detection)

題目說明:

撰寫一個程式,以灰階模式讀取一張圖像 imread(path, IMREAD_GRAYSCALE)

    (a)利用Sobel Operators 偵測並輸出邊緣成分圖

    (b)設計一個類似素描線條的自畫像圖案。

開發環境:

  • Windows 11 
  • Visual Studio Code
  • Python 3.11.2 
  • Opencv 4.7.0

實作結果:

Sobel Operators 偵測邊緣圖

邊緣圖轉換成素描風格圖

不同技術轉換成出的素描風格圖

實作Demo:


程式說明:

本題利用 cv2.createTrackbar() 和 cv2.getTrackbarPos() 來控制以下變數,來尋找邊緣偵測的最佳參數:
  • A:  cv2.threadhold() ,將圖形顏色較淡的地方,去除小於A 的值,A 以上的值維持不變。
  • B:用高斯分佈進行模糊化的計算,指定模糊區域單位 BxB。
  • C:用 cv2.threadhold() ,去除小於 C 的值,C 以上的值維持不變,以達到加強邊緣線的效果。
  • D:

(a)利用Sobel Operators 偵測並輸出邊緣成分圖

1. 先將圖形顏色較淡的地方,用 cv2.threadhold() 去除,此例是去除小於A 的值,A 以上的值維持不變,
參數介紹: (Reference)
v2.THRESH_BINARY如果大於 A 就等於 255,反之等於 0。
cv2.THRESH_BINARY_INV如果大於 A 就等於 0,反之等於 255。
cv2.THRESH_TRUNC如果大於 A 就等於 127,反之數值不變。
cv2.THRESH_TOZERO如果大於 A 數值不變,反之數值等於 0。
cv2.THRESH_TOZERO_INV如果大於 A 等於 0,反之數值不變。

    ret, image = cv2.threshold(image, A, 255, cv2.THRESH_TOZERO)




2. 使用 cv2.GaussianBlur() 方法,使用高斯分佈進行模糊化的計算,指定模糊區域單位 ( 必須是大於 1 的奇數 ) ,此範例是BxB 

    blur_image = cv2.GaussianBlur(image, (B,B), sigmaX=0, sigmaY=0)




3. 使用 cv2.Sobel() 方法,針對「灰階圖片」,使用索伯運算子進行偵測邊緣的轉換,使用方法如下: (Reference)

該算子包含兩組3x3的矩陣,分別為橫向及縱向,將之與圖像作平面
卷積,即可分別得出橫向及縱向的亮度差分近似值。

    sobel_x = cv2.Sobel(blur_image, cv2.CV_16S, 1, 0, ksize=3, scale=1, delta=0,
                        borderType=cv2.BORDER_DEFAULT)
    sobel_y = cv2.Sobel(blur_image, cv2.CV_16S, 0, 1, ksize=3, scale=1, delta=0,
                        borderType=cv2.BORDER_DEFAULT)


取其絕對值:

    abs_sobel_x = cv2.convertScaleAbs(sobel_x)
    abs_sobel_y = cv2.convertScaleAbs(sobel_y)
left: abs_sobel_x
right: abs_sobel_y


將 x軸和 y軸算出的梯度,利用各50%的權重權重相加:

    edge_image = cv2.addWeighted(abs_sobel_x, 0.5, abs_sobel_y, 0.5, 0)



4. 最後再用二值化 cv2.threadhold(),數值大於 C 就等於 255,反之等於 0,來加強邊緣線:

    ret, edge_image = cv2.threshold(edge_image, C, 255, cv2.THRESH_BINARY)



(b)設計一個類似素描線條的自畫像圖案

 方法一:利用 (a) 的邊緣偵測結果,做 cv2.bitwise_not,達到我們對於素描的印象—白底的畫布上,有著簡單的灰階線條,描述圖形簡單的線條輪廓。
    sketch_image = cv2.bitwise_not(edge_image)

 


方法二: 先用 cv2.GaussianBlur() 方法,使用高斯分佈進行模糊化的計算,指定DxD的模糊區域單位,此處D的值越大,素描圖繪越清晰

接著用 cv2.divide(),將原圖與高斯模糊圖做相除,就會有十分逼真的素描圖。

    blur_image = cv2.GaussianBlur(image, (D,D), sigmaX=0, sigmaY=0)
    sketch_image = cv2.divide(image, blur_image, scale=256)







留言

這個網誌中的熱門文章

rzwang Homework #1

s1101438 Homework #1

s1093309 作業6