圖像閾值_有cv2.threshold,cv2.adaptiveThreshold 等。


1.簡單閾值

使用的函數:cv2.threshold (src, thresh, maxval, type)

注釋:

與名字一樣,這種方法非常簡單。但像素值高於閾值時,我們給這個像素賦予一個新值(可能是白色),否則我們給它賦予另外一種顏色(也許是黑色)。這個函數就是cv2.threshhold()。這個函數的第一個參數就是原圖像,原圖像應該是灰度圖。第二個參數就是用來對像素值進行分類的閾值。第三個參數就是當像素值高於(有時是小於)閾值時應該被賦予的新的像素值。OpenCV提供了多種不同的閾值方法,這是有第四個參數來決定的。這些方法包括:
• cv2.THRESH_BINARY
• cv2.THRESH_BINARY_INV
• cv2.THRESH_TRUNC
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV

 

 

 代碼:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('test.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.自適應閾值

使用的函數:dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)

注釋:

在前面的部分我們使用是全局閾值,整幅圖像采用同一個數作為閾值。當時這種方法並不適應與所有情況,尤其是當同一幅圖像上的不同部分的具有不同亮度時。這種情況下我們需要采用自適應閾值。此時的閾值是根據圖像上的每一個小區域計算與其對應的閾值。因此在同一幅圖像上的不同區域采用的是不同的閾值,從而使我們能在亮度不同的情況下得到更好的結果。這種方法需要我們指定三個參數,返回值只有一個。
• Adaptive Method- 指定計算閾值的方法。
– cv2.ADPTIVE_THRESH_MEAN_C:閾值取自相鄰區域的平
均值
– cv2.ADPTIVE_THRESH_GAUSSIAN_C:閾值取值相鄰區域
的加權和,權重為一個高斯窗口。
• Block Size - 鄰域大小(用來計算閾值的區域大小)。
• C - 這就是是一個常數,閾值就等於的平均值或者加權平均值減去這個常
數。

代碼:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('test.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_GAUSSIAN_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', 'Adaptivw 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.Otsu’s 二值化

在第一部分中我們提到過retVal,當我們使用Otsu 二值化時會用到它。那么它到底是什么呢?在使用全局閾值時,我們就是隨便給了一個數來做閾值,那我們怎么知道我們選取的這個數的好壞呢?答案就是不停的嘗試。如果是一副雙峰圖像(簡單來說雙峰圖像是指圖像直方圖中存在兩個峰)呢?我們豈不是應該在兩個峰之間的峰谷選一個值作為閾值?這就是Otsu 二值化要做的。簡單來說就是對一副雙峰圖像自動根據其直方圖計算出一個閾值。(對於非雙峰圖像,這種方法得到的結果可能會不理想)。這里用到到的函數還是cv2.threshold(),但是需要多傳入一個參數(flag):cv2.THRESH_OTSU。這時要把閾值設為0。然后算法會找到最優閾值,這個最優閾值就是返回值retVal。如果不使用Otsu 二值化,返回的retVal 值與設定的閾值相等。

下面的例子中,輸入圖像是一副帶有噪聲的圖像。第一種方法,我們設127 為全局閾值。第二種方法,我們直接使用Otsu 二值化。第三種方法,我們首先使用一個5x5 的高斯核除去噪音,然后再使用Otsu 二值化。看看噪音去除對結果的影響有多大吧。

代碼:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('test.jpg', 0)

ret,th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
ret,th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

blur = cv2.GaussianBlur(img, (5,5), 0)
#閾值一定要設為0
ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

images = [img, 0, th1,
        img, 0, th2,
        blur, 0, th3]

titles = ['Original Noisy Images', '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()

結果如圖所示:

 使用的原圖如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM