什麼是圖像二值化
彩色圖像: 有blue,green,red三個通道,取值範圍均爲0-255
灰度圖:只有一個通道0-255,所以一共有256種顏色
二值圖像:只有兩種顏色,黑色和白色
圖像二值化
圖像二值化的步驟
- 獲取閾值
- 根據閾值去二值化圖像
Opencv二值化的方法及代碼
全局閾值
OpenCv的threshold函數進行全局閾值。
其函數原型爲:cv.threshold(src, thresh, maxval, type[, dst]) -> retval, dst
src:表示輸入圖像(多通道,8位或32位浮點)。
thresh:表示閾值。
maxval:與THRESH_BINARY和THRESH_BINARY_INV閾值類型一起使用設置的最大值。
type: 閾值類型。
retval: 返回的閾值。若是全局固定閾值算法,則返回thresh參數值。若是全局自適應閾值算法,則返回自適應計算得出的合適閾值。
dst: 輸出與src相同大小和類型以及相同通道數的圖像。
閾值的類型
原灰度圖像的像素值(其中紅色的線表示閾值,折線表示像素值)
- THRESH_BINARY:超過閾值的值爲最大值,其他值是0
- THRESH_BINARY_INV:超過閾值的值爲0,其他值爲最大值
- THRESH_TRUNC: 超過閾值的值等於閾值,其他值不變
- THRESH_TOZERO: 超過閾值的值不變,其他值爲0
- THRESH_TOZERO_INV:超過閾值的值爲0,其他值不變
代碼實現
- 全局閾值使用THRESH_OTSU大津法
def threshold_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) ##要二值化圖像,必須先將圖像轉爲灰度圖
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
print("threshold value %s" % ret) #打印閾值,超過閾值顯示爲白色,低於該閾值顯示爲黑色
cv.imshow("threshold", binary) #顯示二值化圖像
threshold value 137.0 #獲取閾值爲137
- 全局閾值使用THRESH_TRIANGLE 三角形算法
def threshold_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY|cv.THRESH_TRIANGLE)
print("threshold value %s" % ret)
cv.imshow("threshold", binary)
threshold value 105.0
知識補充:
cv.THRESH_OTSU和cv.THRESH_TRAINGLE都是自動獲取閾值
THRESH_OTSU:適用於雙波峯
THRESH_TRIANGLE:適用於單個波峯,最開始用於醫學分割細胞等
- 全局閾值 自己手動設定閾值
(1)THRESH_BINARY_INV大於閾值的都爲0
ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
(2)THRESH_TRUNC截斷大於127的值都爲127,其他值不變
ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TRUNC)
(3)THRESH_TOZERO 超過閾值的值不變,小於閾值的爲0
ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TOZERO)
局部閾值
可以使圖片更加清晰
OpenCV的adaptiveThreshold函數進行局部閾值。函數原型爲:adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
src:輸入圖像(8位單通道圖像)。
maxValue:使用 THRESH_BINARY 和 THRESH_BINARY_INV 的最大值.
adaptiveMethod參數表示自適應閾值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)。
thresholdType:閾值類型,必須爲THRESH_BINARY或THRESH_BINARY_INV的閾值類型。
blockSize: 塊大小(奇數且大於1,比如3,5,7........ )。
C: 常數,表示從平均值或加權平均值中減去的數。 通常情況下,這是正值,但也可能爲零或負值
在使用平均和高斯兩種算法情況下,通過計算每個像素周圍blockSize x blockSize大小像素塊的加權均值並減去常量C即可得到自適應閾值。
如果使用平均的方法,則所有像素周圍的權值相同;
如果使用高斯的方法,則每個像素周圍像素的權值則根據其到中心點的距離通過高斯方程得到
def adaptive_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 25, 10)
cv.imshow("binary", binary)
binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
全局和局部閾值比較
自己計算閾值
def custom_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
h, w = gray.shape[:2]
m = np.reshape(gray, [1, h*w]) #將圖像轉爲1行h*w列
mean = m.sum() / (h*w) #計算圖像的均值,用均值作爲閾值,來分割圖像
ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
print("threshold value %s" % ret)
cv.imshow("cudtom_binary", binary)
threshold value 107.0
知識補充:
np.reshpe是給數組一個新的形狀而不改變其數據,
函數原型:reshape(a, newshape, order=‘C’)
a參數表示需要重新形成的原始數組。
newshape參數表示int或int類型元組(tuple),若爲(1, 3),表示生成的新數組是1行3列。
order參數表表示使用此索引順序讀取a的元素,並使用此索引順序將元素放置到重新形成的數組中。
函數返回值:如果可能的話,這將是一個新的視圖對象; 否則,它會成爲副本。
注意:將圖像轉一維數組,轉換維度要保證圖像的size不變,newshape=[行,列]