[Python影象處理] 七.影象閾值化處理及演算法對比

Eastmount發表於2018-10-30

該系列文章是講解Python OpenCV影象處理知識,前期主要講解影象入門、OpenCV基礎用法,中期講解影象處理的各種演算法,包括影象銳化運算元、影象增強技術、影象分割等,後期結合深度學習研究影象識別、影象分類應用。希望文章對您有所幫助,如果有不足之處,還請海涵~

同時推薦作者的C++影象系列知識:
[數字影象處理] 一.MFC詳解顯示BMP格式圖片
[數字影象處理] 二.MFC單文件分割視窗顯示圖片
[數字影象處理] 三.MFC實現影象灰度、取樣和量化功能詳解
[數字影象處理] 四.MFC對話方塊繪製灰度直方圖
[數字影象處理] 五.MFC影象點運算之灰度線性變化、灰度非線性變化、閾值化和均衡化處理詳解
[數字影象處理] 六.MFC空間幾何變換之影象平移、映象、旋轉、縮放詳解
[數字影象處理] 七.MFC影象增強之影象普通平滑、高斯平滑、Laplacian、Sobel、Prewitt銳化詳解

前文參考:
[Python影象處理] 一.影象處理基礎知識及OpenCV入門函式
[Python影象處理] 二.OpenCV+Numpy庫讀取與修改畫素
[Python影象處理] 三.獲取影象屬性、興趣ROI區域及通道處理
[Python影象處理] 四.影象平滑之均值濾波、方框濾波、高斯濾波及中值濾波
[Python影象處理] 五.影象融合、加法運算及影象型別轉換
[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移

本篇文章主要講解Python呼叫OpenCV實現影象閾值化處理操作,包括二進位制閾值化、反二進位制閾值化、截斷閾值化、反閾值化為0、閾值化為0。全文均是基礎知識,希望對您有所幫助。
1.閾值化
2.二進位制閾值化
3.反二進位制閾值化
4.截斷閾值化
5.反閾值化為0
6.閾值化為0

PS:文章參考自己以前系列影象處理文章及OpenCV庫函式,同時部分參考網易雲視訊,推薦大家去學習。同時,本篇文章涉及到《計算機圖形學》基礎知識,請大家下來補充。

PSS:2019年1~2月作者參加了CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

[Python影象處理] 七.影象閾值化處理及演算法對比
五年來寫了314篇部落格,12個專欄,是真的熱愛分享,熱愛CSDN這個平臺,也想幫助更多的人,專欄包括Python、資料探勘、網路爬蟲、影象處理、C#、Android等。現在也當了兩年老師,更是覺得有義務教好每一個學生,讓貴州學子好好寫點程式碼,學點技術,"師者,傳到授業解惑也",提前祝大家新年快樂。2019我們攜手共進,為愛而生。

一. 閾值化

(注:該部分參考作者的論文《基於苗族服飾的影象銳化和邊緣提取技術研究》)

影象的二值化或閾值化(Binarization)旨在提取影象中的目標物體,將背景以及噪聲區分開來。通常會設定一個閾值T,通過T將影象的畫素劃分為兩類:大於T的畫素群和小於T的畫素群。
灰度轉換處理後的影象中,每個畫素都只有一個灰度值,其大小表示明暗程度。二值化處理可以將影象中的畫素劃分為兩類顏色,常用的二值化演算法如公式1所示:

{Y=0gray<TY=255gray>=T\begin{cases} Y=0,gray<T\\ Y=255,gray>=T\\ \end{cases}
當灰度Gray小於閾值T時,其畫素設定為0,表示黑色;當灰度Gray大於或等於閾值T時,其Y值為255,表示白色。
Python OpenCV中提供了閾值函式threshold()實現二值化處理,其公式及引數如下圖所示:
retval, dst = cv2.threshold(src, thresh, maxval, type)

[Python影象處理] 七.影象閾值化處理及演算法對比
常用的方法如下表所示,其中函式中的引數Gray表示灰度圖,引數127表示對畫素值進行分類的閾值,引數255表示畫素值高於閾值時應該被賦予的新畫素值,最後一個引數對應不同的閾值處理方法。
[Python影象處理] 七.影象閾值化處理及演算法對比
對應OpenCV提供的五張圖如下所示,第一張為原圖,後面依次為:二進位制閾值化、反二進位制閾值化、截斷閾值化、反閾值化為0、閾值化為0。
[Python影象處理] 七.影象閾值化處理及演算法對比
二值化處理廣泛應用於各行各業,比如生物學中的細胞圖分割、交通領域的車牌設別等。在文化應用領域中,通過二值化處理將所需民族文物影象轉換為黑白兩色圖,從而為後面的影象識別提供更好的支撐作用。下圖表示影象經過各種二值化處理演算法後的結果,其中“BINARY”是最常見的黑白兩色處理。
[Python影象處理] 七.影象閾值化處理及演算法對比


二. 二進位制閾值化

該方法先要選定一個特定的閾值量,比如127。新的閾值產生規則如下:
dst(x,y)={maxValifsrc(x,y)>thresh0otherwise dst(x,y) = \begin{cases} maxVal, if src(x,y)>thresh\\ 0,otherwise\\ \end{cases}
(1) 大於等於127的畫素點的灰度值設定為最大值(如8位灰度值最大為255)
(2) 灰度值小於127的畫素點的灰度值設定為0
例如,163->255,86->0,102->0,201->255。

關鍵字為 cv2.THRESH_BINARY,完整程式碼如下:

#encoding:utf-8
import cv2  
import numpy as np  

#讀取圖片
src = cv2.imread('test.jpg')

#灰度影象處理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#二進位制閾值化處理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY)
print r

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出為兩個返回值,r為127,b為處理結果(大於127設定為255,小於設定為0)。如下圖所示:

[Python影象處理] 七.影象閾值化處理及演算法對比


三. 反二進位制閾值化

該方法與二進位制閾值化方法相似,先要選定一個特定的灰度值作為閾值,比如127。新的閾值產生規則如下:
dst(x,y)={0ifsrc(x,y)>threshmaxValotherwise dst(x,y) = \begin{cases} 0, if src(x,y)>thresh\\ maxVal,otherwise\\ \end{cases}
(1) 大於127的畫素點的灰度值設定為0(以8位灰度圖為例)
(2) 小於該閾值的灰度值設定為255
例如,163->0,86->255,102->255,201->0。

關鍵字為 cv2.THRESH_BINARY_INV,完整程式碼如下:

#encoding:utf-8
import cv2  
import numpy as np  

#讀取圖片
src = cv2.imread('test.jpg')

#灰度影象處理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#反二進位制閾值化處理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY_INV)
print r

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示:

[Python影象處理] 七.影象閾值化處理及演算法對比
該方法得到的結果正好與二進位制閾值化方法相反,亮色元素反而處理為黑色,暗色處理為白色。

四. 截斷閾值化

該方法需要選定一個閾值,影象中大於該閾值的畫素點被設定為該閾值,小於該閾值的保持不變,比如127。新的閾值產生規則如下:
dst(x,y)={thresholdifsrc(x,y)>threshsrc(x,y)otherwise dst(x,y) = \begin{cases} threshold, if src(x,y)>thresh\\ src(x,y),otherwise\\ \end{cases}
(1) 大於等於127的畫素點的灰度值設定為該閾值127
(2) 小於該閾值的灰度值不改變
例如,163->127,86->86,102->102,201->127。

關鍵字為 cv2.THRESH_TRUNC,完整程式碼如下:

#encoding:utf-8
import cv2  
import numpy as np  

#讀取圖片
src = cv2.imread('test.jpg')

#灰度影象處理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#截斷閾值化處理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TRUNC)
print r

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示::

[Python影象處理] 七.影象閾值化處理及演算法對比
該處理方法相當於把影象中比較亮(大於127,偏向於白色)的畫素值處理為閾值。

五. 反閾值化為0

該方法先選定一個閾值,比如127,接著對影象的灰度值進行如下處理:
dst(x,y)={0ifsrc(x,y)>threshsrc(x,y)otherwise dst(x,y) = \begin{cases} 0, if src(x,y)>thresh\\ src(x,y),otherwise\\ \end{cases}
(1) 大於等於閾值127的畫素點變為0
(2) 小於該閾值的畫素點值保持不變
例如,163->0,86->86,102->102,201->0。

關鍵字為 cv2.THRESH_TOZERO_INV,完整程式碼如下:

#encoding:utf-8
import cv2  
import numpy as np  

#讀取圖片
src = cv2.imread('test.jpg')

#灰度影象處理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#反閾值化為0處理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO_INV)
print r

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示:

[Python影象處理] 七.影象閾值化處理及演算法對比


六. 閾值化為0

該方法先選定一個閾值,比如127,接著對影象的灰度值進行如下處理:
dst(x,y)={src(x,y)ifsrc(x,y)>thresh0otherwise dst(x,y) = \begin{cases} src(x,y), if src(x,y)>thresh\\ 0,otherwise\\ \end{cases}
(1) 大於等於閾值127的畫素點,值保持不變
(2) 小於該閾值的畫素點值設定為0
例如,163->163,86->0,102->0,201->201。

關鍵字為 cv2.THRESH_TOZERO,完整程式碼如下:

#encoding:utf-8
import cv2  
import numpy as np  

#讀取圖片
src = cv2.imread('test.jpg')

#灰度影象處理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#閾值化為0處理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO)
print r

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示:

[Python影象處理] 七.影象閾值化處理及演算法對比
該演算法把比較亮的部分不變,比較暗的部分處理為0。

完整五個演算法的對比程式碼如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#讀取影象
img=cv2.imread('test.jpg')
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  

#閾值化處理
ret,thresh1=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY)  
ret,thresh2=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY_INV)  
ret,thresh3=cv2.threshold(GrayImage,127,255,cv2.THRESH_TRUNC)  
ret,thresh4=cv2.threshold(GrayImage,127,255,cv2.THRESH_TOZERO)  
ret,thresh5=cv2.threshold(GrayImage,127,255,cv2.THRESH_TOZERO_INV)

#顯示結果
titles = ['Gray Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']  
images = [GrayImage, thresh1, thresh2, thresh3, thresh4, thresh5]  
for i in xrange(6):  
   plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()

輸出結果如下圖所示:

[Python影象處理] 七.影象閾值化處理及演算法對比

希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵。最近經歷的事情太多,有喜有悲,關閉了朋友圈,希望通過不斷學習和寫文章來忘記煩勞,將憂鬱轉換為動力。哎,總感覺自己在感動這個世界,幫助所有人,而自己卻…誰有關心秀璋?晚安。
(By:Eastmount 2018-10-30 晚上10點 https://blog.csdn.net/Eastmount/)

相關文章