當圖像各局部亮度不同時,全局閾值就很難將背景和目標分割。因此提出了自適應閾值,即在圖像的不同區域採用不同的閾值進行分割。利用函數cv2.adaptiveThreshold()進行分割。
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
參數:
1. src:原圖像
2. maxValue:當閾值類型(thresholdType)採用cv2.THRESH_BINARY和cv2.THRESH_BINARY_INV時像素點被賦予的新值
3. adaptiveMethod:自適應閾值的計算方法,包括兩種:
- cv2.ADPTIVE_THRESH_MEAN_C:閾值取自相鄰區域的平均值
- cv2.ADPTIVE_THRESH_GAUSSIAN_C:閾值取值相鄰區域的加權和,權重爲一個高斯窗口。
4. thresholdType:閾值分割類型,共5種,同cv2.threshold()的閾值分割類型參數,詳情見https://blog.csdn.net/weixin_42216109/article/details/89553383
5. blockSize:用來計算閾值的鄰域大小
6. C:常數,adaptiveMethod方法計算出的數值減去這個常數C就爲閾值
返回值:
1. 閾值分割後的圖像
e.g.
通過如下代碼對比全局閾值分割和自適應閾值分割的區別
import cv2
import matplotlib.pyplot as plt
#載入原圖
img_original=cv2.imread('E:\ShannonT\\notebook workspace\\images\\4.26.6.jpg',0)
#全局閾值分割
retval,img_global=cv2.threshold(img_original,130,255,cv2.THRESH_BINARY)
#自適應閾值分割
img_ada_mean=cv2.adaptiveThreshold(img_original,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,15,3)
img_ada_gaussian=cv2.adaptiveThreshold(img_original,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3)
imgs=[img_original,img_global,img_ada_mean,img_ada_gaussian]
titles=['Original Image','Global Thresholding(130)','Adaptive Mean','Adaptive Guassian',]
#顯示圖片
for i in range(4):
plt.subplot(2,2,i+1)
plt.imshow(imgs[i],'gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
結果顯示如下:
補充:從自適應閾值分割的結果來看,圖像中存在較多的噪聲,於是我們可以先通過函數cv2.GaussianBlur()進行噪聲去除,詳情參考https://blog.csdn.net/duwangthefirst/article/details/79971338
import cv2
import matplotlib.pyplot as plt
#載入原圖
img_original=cv2.imread('E:\ShannonT\\notebook workspace\\images\\4.26.6.jpg',0)
#高斯濾波
img_blur=cv2.GaussianBlur(img_original,(5,5),5)
#自適應閾值分割
img_thresh=cv2.adaptiveThreshold(img_original,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3)
img_thresh_blur=cv2.adaptiveThreshold(img_blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3)
#顯示圖像
imgs=[img_thresh,img_thresh_blur]
titles=['img_thresh','img_thresh_blur']
for i in range(2):
plt.subplot(1,2,i+1)
plt.imshow(imgs[i],'gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
結果如下所示,可以發現噪聲數量明顯減少。