1. 程式人生 > >Python3+OpenCV3影象處理(十)—— 影象二值化

Python3+OpenCV3影象處理(十)—— 影象二值化

簡介:影象二值化就是將影象上的畫素點的灰度值設定為0或255,也就是將整個影象呈現出明顯的黑白效果的過程。

一、普通影象二值化

程式碼如下:

複製程式碼

import cv2 as cv
import numpy as np

#全域性閾值
def threshold_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  #把輸入影象灰度化
    #直接閾值化是對輸入的單通道矩陣逐畫素進行閾值分割。
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
    print("threshold value %s"%ret)
    cv.namedWindow("binary0", cv.WINDOW_NORMAL)
    cv.imshow("binary0", binary)

#區域性閾值
def local_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  #把輸入影象灰度化
    #自適應閾值化能夠根據影象不同區域亮度分佈,改變閾值
    binary =  cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY, 25, 10)
    cv.namedWindow("binary1", cv.WINDOW_NORMAL)
    cv.imshow("binary1", binary)

#使用者自己計算閾值
def custom_threshold(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  #把輸入影象灰度化
    h, w =gray.shape[:2]
    m = np.reshape(gray, [1,w*h])
    mean = m.sum()/(w*h)
    print("mean:",mean)
    ret, binary =  cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
    cv.namedWindow("binary2", cv.WINDOW_NORMAL)
    cv.imshow("binary2", binary)

src = cv.imread('E:/imageload/kobe.jpg')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #設定為WINDOW_NORMAL可以任意縮放
cv.imshow('input_image', src)
threshold_demo(src)
local_threshold(src)
custom_threshold(src)
cv.waitKey(0)
cv.destroyAllWindows()

複製程式碼

執行結果:

注意:

1.全域性閾值

①OpenC的threshold函式進行全域性閾值。其函式原型為:threshold(src, thresh, maxval, type[, dst]) -> retval, dst

src引數表示輸入影象(多通道,8位或32位浮點)。

thresh引數表示閾值。

maxval引數表示與THRESH_BINARY和THRESH_BINARY_INV閾值型別一起使用設定的最大值。

type引數表示閾值型別。

retval引數表示返回的閾值。若是全域性固定閾值演算法,則返回thresh引數值。若是全域性自適應閾值演算法,則返回自適應計算得出的合適閾值。

dst引數表示輸出與src相同大小和型別以及相同通道數的影象。

閾值型別:

閾值型別圖示:

③type引數單獨選擇上述五種閾值型別時,是固定閾值演算法,效果比較差。

此外還有自適應閾值演算法:(自適應計算合適的閾值,而不是固定閾值)

比如結合cv.THRESH_OTSU,寫成cv.THRESH_BINARY | cv.THRESH_OTSU。例子:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) #大律法,全域性自適應閾值,第二個引數值0可改為任意數字但不起作用。 

比如結合cv.THRESH_TRIANGLE,寫成cv.THRESH_BINARY | cv.THRESH_TRIANGLE

。例子:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE) #TRIANGLE法,全域性自適應閾值,第二個引數值0可改為任意數字但不起作用,適用於單個波峰。  

補:

cv.THRESH_OTSU和cv.THRESH_TRIANGLE也可單獨使用,不一定要寫成和固定閾值演算法結合的形式。單獨寫和結合起來寫,都是自適應閾值演算法優先。

例子:ret, binary = cv.threshold(gray, 0, 255,  cv.THRESH_OTSU) #大律法       ret, binary = cv.threshold(gray, 0, 255,  cv.THRESH_TRIANGLE) #TRIANGLE法  

2.區域性閾值

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即可得到自適應閾值。如果使用平均的方法,則所有畫素周圍的權值相同;如果使用高斯的方法,則每個畫素周圍畫素的權值則根據其到中心點的距離通過高斯方程得到。

3.numpy的reshape函式是給陣列一個新的形狀而不改變其資料,函式原型:reshape(a, newshape, order='C')

a引數表示需要重新形成的原始陣列。

newshape引數表示int或int型別元組(tuple),若為(1, 3),表示生成的新陣列是1行3列。

order引數表表示使用此索引順序讀取a的元素,並使用此索引順序將元素放置到重新形成的陣列中。

函式返回值:如果可能的話,這將是一個新的檢視物件; 否則,它會成為副本。