opencv python 圖像二值化/簡單閾值化/大津閾值法

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()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章