影象二值化(python+opencv)

weixin_34353714發表於2018-12-04

定義:影象的二值化,就是將影象上的畫素點的灰度值設定為0或255,也就是將整個影象呈現出明顯的只有黑和白的視覺效果。

一幅影象包括目標物體、背景還有噪聲,要想從多值的數字影象中直接提取出目標物體,常用的方法就是設定一個閾值T,用T將影象的資料分成兩部分:大於T的畫素群和小於T的畫素群。這是研究灰度變換的最特殊的方法,稱為影象的二值化(Binarization)。

全域性閾值:

Python-OpenCV中提供了閾值(threshold)函式:cv2.threshold(src, threshold, maxValue, method)

8777072-e560341634e68b3b.png

src原圖:破折線為將被閾值化的值;虛線為閾值

8777072-957a1c3520962a7c.png

cv2.THRESH_BINARY:大於閾值的畫素點的灰度值設定為maxValue(如8位灰度值最大為255),灰度值小於閾值的畫素點的灰度值設定為0。

8777072-1aa2b243f84e555d.png

cv2.THRESH_BINARY_INV :大於閾值的畫素點的灰度值設定為0,而小於該閾值的設定為maxValue。

8777072-04afe0f3ab648bbf.png

cv2.THRESH_TRUNC:畫素點的灰度值小於閾值不改變,大於閾值的灰度值的畫素點就設定為該閾值。

8777072-68235e14f63cd7cb.png

cv2.THRESH_TOZERO:畫素點的灰度值小於該閾值的不進行任何改變,而大於該閾值的部分,其灰度值全部變為0。

8777072-ab05d16c1da87890.png

cv2.THRESH_TOZERO_INV:畫素點的灰度值大於該閾值的不進行任何改變,畫素點的灰度值小於該閾值的,其灰度值全部變為0。

Python+opencv程式碼:

def getPicMinRect(pic):

    GrayImage = np.array(pic).reshape(40,40).astype(np.uint8)

    ret,thresh1=cv2.threshold(GrayImage,10,255,cv2.THRESH_BINARY) 

    ret,thresh2=cv2.threshold(GrayImage,10,255,cv2.THRESH_BINARY_INV) 

    ret,thresh3=cv2.threshold(GrayImage,10,255,cv2.THRESH_TRUNC) 

    ret,thresh4=cv2.threshold(GrayImage,10,255,cv2.THRESH_TOZERO) 

    ret,thresh5=cv2.threshold(GrayImage,10,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()


8777072-847b21543310dbbd.png

自適應閾值:

當同一幅影象上的不同部分的具有不同亮度時。這種情況下我們需要採用自適應閾值。此時的閾值是根據影象上的每一個小區域計算與其對應的閾值。因此在同一幅影象上的不同區域採用的是不同的閾值,從而使我們能在亮度不同的情況下得到更好的結果。

Python-OpenCV中提供了閾值(threshold)函式:cv2.adaptiveThreshold(src, maxValue, adaptive_method, threshold_type, block_size, param1)

好吧,這玩意的threshold_type其實就兩種:CV_THRESH_BINARY, CV_THRESH_BINARY_INV

adaptive_method也有兩種: CV_ADAPTIVE_THRESH_MEAN_C, CV_ADAPTIVE_THRESH_GAUSSIAN_C

函式 cvAdaptiveThreshold 將灰度影象變換到二值影象,採用下面公式:

switch(threshold_type):

    case CV_THRESH_BINARY:

        if src(x,y)>T(x,y):

            dst(x,y) = maxValue

        else:

            dsy(x,y) = 0

    case CV_THRESH_BINARY_INV:

        if src(x,y)>T(x,y):

            dst(x,y) = 0

        else:

            dsy(x,y) = maxValue

其中 T(x,y)為當前畫素點單獨計算的閾值

對方法 CV_ADAPTIVE_THRESH_MEAN_C,先求出block中的均值,再減掉param1。

對方法 CV_ADAPTIVE_THRESH_GAUSSIAN_C ,先求出block中的加權和(gaussian), 再減掉param1。

Python+opencv程式碼:

def getPic(pic):

    GrayImage = np.array(pic).reshape(40,40).astype(np.uint8)

    th1 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,3,5)

    th2 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,3,50)

    th3 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,3,5)

    th4 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,3,50)

    titles = ['Gray Image', 'Adaptive Mean prama1=5', 

    'Adaptive Mean prama1=50', 'Adaptive Gaussian prama1=5','Adaptive Gaussian prama1=50'] 

    images = [GrayImage, th1, th2, th3, th4] 

    for i in xrange(5): 

      plt.subplot(2,3,i+1),plt.imshow(images[i]) 

      plt.title(titles[i]) 

      plt.xticks([]),plt.yticks([]) 

    plt.show()


8777072-9448e8a282e0fcd6.png

相關文章