今天是持續寫作的第 38 / 100 天,
如果你有想要交流的想法、技術,歡迎在評論區留言,
取經之旅第 6 天
- 彩色影像的二值化
- 方法 1
- 方法 2
- 方法 3
- OpenCV 尾聲
今天學習一下彩色影像的二值化操作,

彩色影像的二值化
影像的二值化,就是讓影像的像素點矩陣中,每個像素點的灰度值設定為 0(黑色) 或者 255(白色),說白了就是讓影像呈現只有黑和白的效果,
在灰度圖中影像的灰度值的范圍是 0~255,在二值化的影像中灰度值的范圍是 0 或者 255,
一個像素點在灰度化之后的灰度值如何轉換為 0(黑色)或者 255(白色),例如灰度值是 200,那二值化之后到底是 0 還是 255,這里面衍生出來的概念叫做閾值,
有前面咱學到的像素概念,這時橡皮擦首先想到的是二值化肯定能大幅度降低影像處理的資料量,畢竟數值變少了,
那接下來就學習一下如何將影像二值化吧,
方法 1
取閾值為 127,相當于 0~255 的中數(0+255)/2 = 127,灰度值大于等于 127 的設定為 0,灰度值大于 127 的設定為 255,這種方法簡單便捷,缺點就是閾值設定的太死板了,對于不同的照片,效果肯定不同,檢索資料的時候發現,還有人把這種方法稱為 史上最弱智的二值處理方法,沒辦法,弱智方法也得學啊,
該方法會使用到一個 threshold 方法,
threshold 方法的語法格式如下:
cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dst
引數說明如下:
- src 輸入圖,中只能輸入單通道圖,一般就是灰度圖;
- thresh 閾值;
- maxval 最大值,當像素超過了閾值(或者小于閾值)時所賦予的值;
- type - 二值化操作的型別,有 5 種,在下文描述;
- dst 輸出陣列/影像(與 src 相同大小和型別以及相同通道數的陣列/影像),
回傳值 retval 閾值 thresh, dst 經過處理的影像,
二值化操作型別(閾值型別):
- 二進制閾值化 THRESH_BINARY,過門限的值為最大值,其他值為 0;
- 反二進制閾值化 THRESH_BINARY_INV,過門限的值為 0,其他值為最大值;
- 截斷閾值化 THRESH_TRUNC,過門限的值為門限值,其他值不變;
- 閾值化為 0 THRESH_TOZERO,過門限的值不變,其他設定為 0;
- 反閾值化為 0 THRESH_TOZERO_INV,過門限的值為 0,其他不變,
以上內容也叫做全域閾值,
全域閾值代碼測驗代碼如下
import cv2
def main():
img = cv2.imread("6.jpg", 0)
thresh, dst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow("dst", dst)
cv2.waitKey()
if __name__ == "__main__":
main()
得到的效果真的不怎么好看,

不斷的去調整下圖紅框中的值,查看效果,

更換最后一個個引數之后,可以對比不同效果,

方法 2
計算像素點矩陣中的所有像素點的灰度值的平均值 avg,讓每一個像素點與 avg 比較,小于等于 avg 的像素點就為 0(黑色),大于 avg 的像 素點為 255(白色),這種方法看起來靠譜了一些,
使用該方法之前需要先遍歷影像的所有灰度值,才能計算出平均值,
img = cv2.imread("6.jpg", 0)
height, width = img.shape
# 灰度值總和
px_t = 0
for i in range(height):
for j in range(width):
px_t += img[i][j]
print(px_t)
# 求像素平均值
avg_thresh = int(px_t/(height*width))
thresh, dst = cv2.threshold(img, avg_thresh, 255, cv2.THRESH_BINARY)
print("閾值:", thresh)
cv2.imshow("dst", dst)
cv2.waitKey()

方法 3
在使用方法 3 學習之前,先跑偏一點,距離今日的 1 小時學習時間又要過去了,
安裝 matplotlib 庫,然后用于圖片的展示,就不用每次都使用 imshow 方法了,
安裝比較簡單,pip install matplotlib 即可,
頭部匯入模塊之后,撰寫如下代碼:
import cv2
import matplotlib.pylab as plt
def main2():
img = cv2.imread('6.jpg', 0)
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY',
'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i+1)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
運行之后發現,這簡直是用在學習階段最棒的呈現了,一次展示所有的效果,

OpenCV 尾聲
1 個小時又過去了,對 Python OpenCV 影像寫入相關的知識點,你掌握了嗎?
空閑之余,可以訂閱橡皮擦的爬蟲百例課程學習爬蟲知識,
想學 Python 爬蟲,可以訂閱橡皮擦專欄哦~ 🈲🈲🈲🈲 點擊發現驚喜 🈲🈲🈲🈲
如果你想跟博主建立親密關系,可以關注博主,或者關注博主公眾號 “
非本科程式員”,了解一個非本科程式員是如何成長的,
博主 ID:夢想橡皮擦,希望大家點贊、評論、收藏
CSDN認證博客專家
大學老師
高級產品經理
互聯網從業者
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/242889.html
標籤:python
