opencv python 圖像二值化/簡單閾值化/大津閾值法
參考:https://segmentfault.com/a/1190000015647247
1簡單的閾值化
cv2.threshold
第一個參數是源圖像,它應該是灰度圖像. 第二個參數是用於對像素值進行分類的閾值, 第三個參數是maxVal,它表示如果像素值大於(有時小於)閾值則要給出的值. OpenCV提供不同類型的閾值,它由函數的第四個參數決定. 不同的類型是:
cv2.THRESH_BINARY | 如果 src(x,y)>threshold ,dst(x,y) = max_value; 否則,dst(x,y)=0 |
cv.THRESH_BINARY_INV | 如果 src(x,y)>threshold,dst(x,y) = 0; 否則,dst(x,y) = max_value |
cv.THRESH_TRUNC | 如果 src(x,y)>threshold,dst(x,y) = max_value; 否則dst(x,y) = src(x,y) |
cv.THRESH_TOZERO | 如果src(x,y)>threshold,dst(x,y) = src(x,y) ; 否則 dst(x,y) = 0 |
cv.THRESH_TOZERO_INV | 如果 src(x,y)>threshold,dst(x,y) = 0 ; 否則dst(x,y) = src(x,y) |
import cv2
import numpy as np
import matplotlib.pylab as plt
img = cv2.imread('img.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()
2自適應閾值化
圖像在不同區域具有不同照明條件時,應進行自適應閾值處理.因此,我們爲同一圖像的不同區域獲得不同的閾值,並且它爲具有不同照明的圖像提供了更好的結果.cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])
adaptiveMethod:決定如何計算閾值
- cv2.ADAPTIVE_THRESH_MEAN_C:閾值是鄰域的平均值
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C:閾值是鄰域值的加權和,其中權重是高斯窗口
blockSize:決定了鄰域的大小
C:從計算的平均值或加權平均值中減去的常數
import cv2
import numpy as np
import matplotlib.pylab as plt
img = cv2.imread('img.jpg',0)
img = cv2.medianBlur(img,5)
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in range(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
3 大津閾值法
根據雙峯圖像的圖像直方圖自動計算閾值。 (對於非雙峯圖像,二值化不準確。)
使用cv.threshold()
但是傳遞了一個額外的標誌v.THRESH_OTSU
.對於閾值,只需傳遞零.然後算法找到最佳閾值並返回爲第二個輸出retVal。如果未使用Otsu閾值法,則retVal與之前使用的閾值相同.
在第一種情況下,將全局閾值應用爲值127.在第二種情況下,直接應用了Otsu的閾值.在第三種情況下,使用5x5高斯內核過濾圖像以消除噪聲,然後應用Otsu閾值處理.
import cv2
import numpy as np
import matplotlib.pylab as plt
img = cv2.imread('img.jpg',0)
# global thresholding
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# Otsu's thresholding
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# plot all the images and their histograms
images = [img, 0, th1,
img, 0, th2,
blur, 0, th3]
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
'Original Noisy Image','Histogram',"Otsu's Thresholding",
'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]
for i in range(3):
plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()