算法步驟
全局二值化容易受陰影影響,所以可以局部二值化。自適應閾值分割的本質就是局部二值化。
具體操作步驟如下:
(1) 對某個像素值,原來為 \(S\),取其周圍的 \(n\times n\) 的區域,求區域均值或高斯加權值,記為 \(T\);
(2) 對 \(8\) 位圖像,如果 \(S > T\),則該像素點二值化為 \(255\), 否則為 \(0\)。
優化:
(1) 在實際操作中,通過卷積操作,即均值模糊或高斯模糊,實現求區域均值或高斯加權值;
(2) 上面步驟中,增加超參數 \(C\),\(C\) 可以為任何實數,當 \(S > T- C\) 時,把原像素二值化為 \(255\)。
(3) 也可以設置超參數 \(\alpha\in [0,1]\),當 \(S > (1-\alpha) T\) 時把原像素點二值化為 \(255\),通常取 \(\alpha=0.15\)。
效果
左圖為原始灰度圖,右圖為自適應閾值化結果。
實現
1. 調用OpenCV函數
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread(img_path, 0) # img_path 為圖像路徑
img_bin = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,
cv.THRESH_BINARY, 21, 6)
plt.imshow(np.hstack([img, img_bin]), cmap='gray')
plt.show()
2. 自己實現
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread(img_path, 0) # img_path 換為圖片路徑
C = 6
winSize = 21
img_blur = cv.blur(img, (winSize, winSize))
img_bin = np.uint8(img > img_blur.astype(np.int) - C) * 255 # 此時的 img_bin 即為最終閾值化結果
3. 自己實現(方法二)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread(img_path, 0) # img_path 換為圖片路徑
alpha = 0.05
winSize = 21
img_blur = cv.GaussianBlur(img, (winSize, winSize), 5)
img_bin = np.uint8(img > (1 - alpha) * img_blur) * 255 # 此時的 img_bin 即為最終閾值化結果
說明:
- 未經許可,謝絕轉載。
- 本教程為《數字圖像處理Python OpenCV實戰》的配套代碼相關內容。
免費視頻教程為0-6章(標題號≤6),可在此處點擊觀看。
所有課件及源代碼可在此處下載:
鏈接:https://pan.baidu.com/s/198PySe_vebO3e06idHSQ6g
提取碼:11o4
有問題可在QQ群(1079300899)指出,進群答案:數字圖像處理。在本文評論指出可能導致回復很晚。