這篇隨筆介紹使用OpenCV進行圖像處理的第五章 閾值處理。
5 閾值處理
閾值是指像素到達某臨界值。閾值處理表示像素到達某臨界值后,對該像素點進行操作和處理。
例如:設定一幅圖像素閾值為200,則圖片中所有大於200的像素點設置為255,圖片中所有小於或等於200的像素點設置為0。
5.1 處理類型
OpenCV中提供了cv2.threshold()函數進行閾值處理。
該函數中,要設定閾值處理的類型,常見類型如下:
cv2.THRESH_BINARY 二值化閾值處理
cv2.THRESH_BINARY _INV 反二值化閾值處理
cv2.THRESH_TRUNC 截斷閾值處理
cv2.THRESH_TOZERO_INV 超閾值零處理
cv2.THRESH_TOZERO 低閾值零處理
cv2.THRESH_MASK 掩碼處理
cv2.THRESH_OTSU Otsu算法閾值處理
此外,OpenCV還提供了cv2.adaptiveThreshold()函數進行自適應閾值處理。
5.2 二值化閾值處理(cv2.THRESH_BINARY)
該方法表示:對於像素值大於閾值thresh的像素點,將其設置為最大值;對於像素值小於閾值thresh的像素點,將其設置為0。
使用函數cv2.threshold()對圖像進行二值化閾值操作代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg') 3 t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY) #類型設置為cv2.THRESH_BINARY,閾值設置為127
4 cv2.imshow('img',img) 5 cv2.imshow('rst',rst) 6 cv2.waitKey() 7 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,右為二值化閾值處理結果。
5.3 反二值化閾值處理(cv2.THRESH_BINARY_INV)
該方法表示:對於像素值大於閾值thresh的像素點,將其設置為0;對於像素值小於閾值thresh的像素點,將其設置為最大值。
使用函數cv2.threshold()對圖像進行二值化閾值操作代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg') 3 t,rst=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) #類型設置為cv2.THRESH_BINARY_INV,閾值設置為127
4 cv2.imshow('img',img) 5 cv2.imshow('rst',rst) 6 cv2.waitKey() 7 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,右為反二值化閾值處理結果。
5.4 截斷閾值化處理(cv2.THRESH_TRUNC)
該方法表示:對於像素值大於閾值thresh的像素點,將其設置為閾值;對於像素值小於閾值thresh的像素點,保持不變。
使用函數cv2.threshold()對圖像進行截斷閾值化處理代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg') 3 t,rst=cv2.threshold(img,127,255,cv2.THRESH_TRUNC) #類型設置為cv2.THRESH_TRUNC,閾值設置為127
4 cv2.imshow('img',img) 5 cv2.imshow('rst',rst) 6 cv2.waitKey() 7 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,右為截斷閾值化處理結果。
5.5 超閾值零處理(cv2.THRESH_TOZERO_INV)
該方法表示:對於像素值大於閾值thresh的像素點,將其設置為0;對於像素值小於閾值thresh的像素點,保持不變。
使用函數cv2.threshold()對圖像進行超閾值零處理代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg') 3 t,rst=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV) #類型設置為cv2.THRESH_TOZERO_INV,閾值設置為127
4 cv2.imshow('img',img) 5 cv2.imshow('rst',rst) 6 cv2.waitKey() 7 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,右為超閾值零處理結果。
5.6 低閾值零處理(cv2.THRESH_TOZERO)
該方法表示:對於像素值小於或等於閾值thresh的像素點,將其設置為0;對於像素值大於閾值thresh的像素點,保持不變。
使用函數cv2.threshold()對圖像進行低閾值零處理代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg') 3 t,rst=cv2.threshold(img,127,255,cv2.THRESH_TOZERO) #類型設置為cv2.THRESH_TOZERO,閾值設置為127
4 cv2.imshow('img',img) 5 cv2.imshow('rst',rst) 6 cv2.waitKey() 7 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,右為低閾值零處理結果。
5.7 自適應閾值處理
一般情況下,圖像中只是用一個閾值,就會造成輪廓與內容分割不均衡,無法得到清晰有效的閾值處理圖像。
OpenCV中提供了cv2.adaptiveThreshold()函數用於實現自適應閾值處理。自適應閾值處理的原理,是通過計算每個像素點的鄰域像素進行加權平均而獲得閾值,能夠較好地處理色彩不均衡的圖像。
cv2.adaptiveThreshold()函數中,有兩個參數類型:
cv2.ADAPTIVE_THRESH_MEAN_C 鄰域內所有像素點的權重都相同
cv2.ADAPTIVE_THRESH_GAUSSIAN_C 通過高斯方程得到各個像素點的權重值,與鄰域內像素點到中心的距離有關
使用二值化閾值函數cv2.threshold()對圖像進行自適應閾值處理代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg',0) 3 #類型設置為cv2.ADAPTIVE_THRESH_MEAN_C,后面必須加cv2.THRESH_BINARY或cv2.THRESH_BINARY_INV,鄰域大小設置為5×5,最后的3是常量
4 athdMEAN=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,3) 5 #類型設置為cv2.ADAPTIVE_THRESH_GAUSSIAN_C,后面必須加cv2.THRESH_BINARY或cv2.THRESH_BINARY_INV,鄰域大小設置為5×5,最后的3是常量
6 athdGAUS=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3) 7 cv2.imshow('img',img) 8 cv2.imshow('athdMEAN',athdMEAN) 9 cv2.imshow('athdGAUS',athdGAUS) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,中為像素權重平均處理結果,右為高斯權重值處理結果。可以看到,自適應閾值處理保留了更多的細節信息。
5.8 Otsu方法(cv2.THRESH_OTSU)
Otsu方法能夠根據當前圖像生成最佳的類間分割閾值,原理是遍歷所有可能的閾值,從而找到最合適的閾值。
通過函數cv2.threshold()中傳遞類型參數:cv2.THRESH_OTSU,來實現Otsu算法。
需要注意的是,在使用Otsu方法時,要把閾值設置為0,語句為:
# t是Otsu方法得到並使用的最合適閾值,參數中閾值設置為0,傳遞兩種類型
t,otsu=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
使用Otsu方法對圖像進行自適應閾值處理代碼如下:
1 import cv2 2 img=cv2.imread('E:\python_opencv/tupian.jpg',0) 3 #類型設置為cv2.THRESH_BINARY+cv2.THRESH_OTSU,閾值設置為0
4 t,otsu=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 5 cv2.imshow('img',img) 6 cv2.imshow('otsu',otsu) 7 cv2.waitKey() 8 cv2.destroyAllWindows()
運行結果如下圖,左為原圖像,右為Otsu方法處理結果。
這次內容就分享到這里了,下次繼續更新第6章 圖像平滑處理,希望與各位老師和小伙伴們交流學習~