[Python影象處理] 七.影象閾值化處理及演算法對比
該系列文章是講解Python OpenCV影象處理知識,前期主要講解影象入門、OpenCV基礎用法,中期講解影象處理的各種演算法,包括影象銳化運算元、影象增強技術、影象分割等,後期結合深度學習研究影象識別、影象分類應用。希望文章對您有所幫助,如果有不足之處,還請海涵~
本篇文章主要講解Python呼叫OpenCV實現影象閾值化處理操作,包括二進位制閾值化、反二進位制閾值化、截斷閾值化、反閾值化為0、閾值化為0。全文均是基礎知識,希望對您有所幫助。 1.閾值化 2.二進位制閾值化 3.反二進位制閾值化 4.截斷閾值化 5.反閾值化為0 6.閾值化為0
PS:文章參考自己以前系列影象處理文章及OpenCV庫函式,同時部分參考網易雲視訊,推薦大家去學習。同時,本篇文章涉及到《計算機圖形學》基礎知識,請大家下來補充。
一. 閾值化
(注:該部分參考作者的論文《基於苗族服飾的影象銳化和邊緣提取技術研究》)
影象的二值化或閾值化(Binarization)旨在提取影象中的目標物體,將背景以及噪聲區分開來。通常會設定一個閾值T,通過T將影象的畫素劃分為兩類:大於T的畫素群和小於T的畫素群。 灰度轉換處理後的影象中,每個畫素都只有一個灰度值,其大小表示明暗程度。二值化處理可以將影象中的畫素劃分為兩類顏色,常用的二值化演算法如公式1所示:
當灰度Gray小於閾值T時,其畫素設定為0,表示黑色;當灰度Gray大於或等於閾值T時,其Y值為255,表示白色。 Python OpenCV中提供了閾值函式threshold()實現二值化處理,其公式及引數如下圖所示: retval, dst = cv2.threshold(src, thresh, maxval, type)
二. 二進位制閾值化
該方法先要選定一個特定的閾值量,比如127。新的閾值產生規則如下: (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)。如下圖所示:
三. 反二進位制閾值化
該方法與二進位制閾值化方法相似,先要選定一個特定的灰度值作為閾值,比如127。新的閾值產生規則如下: (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()
輸出結果如下圖所示:
四. 截斷閾值化
該方法需要選定一個閾值,影象中大於該閾值的畫素點被設定為該閾值,小於該閾值的保持不變,比如127。新的閾值產生規則如下: (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()
輸出結果如下圖所示::
五. 反閾值化為0
該方法先選定一個閾值,比如127,接著對影象的灰度值進行如下處理: (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()
輸出結果如下圖所示:
六. 閾值化為0
該方法先選定一個閾值,比如127,接著對影象的灰度值進行如下處理: (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()
輸出結果如下圖所示:
完整五個演算法的對比程式碼如下所示:
#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()
#灰度影象處理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
#閾值化為0處理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO)
print r
titles = ['Source Image','Gray Image','Laplacian Image','Robert Image','Prewitt Image','Sobel Image']
images = [lenna_img, GrayImage, Laplacian, Robert, Prewitt, Sobel]
for i in np.arange(6):
plt.subplot(3,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
輸出結果如下圖所示:
希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵。最近經歷的事情太多,有喜有悲,關閉了朋友圈,希望通過不斷學習和寫文章來忘記煩勞,將憂鬱轉換為動力。哎,總感覺自己在感動這個世界,幫助所有人,而自己卻…誰有關心秀璋?晚安。 (By:Eastmount 2018-10-30 晚上10點 https://blog.csdn.net/Eastmount/)