在講閾值操作方法之前,肯定是先講下閾值分割的作用
閾值分割其實就是圖像分離,對於閾值內的你想如何操作,一個最簡單的例子就是二值圖像。
接下來我們看下方法吧:
threshold —— 簡單的閾值操作
adaptiveThreshold —— 自適應閾值操作
threshold參數說明:
def threshold(src, thresh, maxval, type, dst=None)
thresh:Double類型的,具體的閾值。
maxval:Double類型的,閾值的最大值
type:
THRESH_BINARY 二進制閾值化 -> 大於閾值為1 小於閾值為0
THRESH_BINARY_INV 反二進制閾值化 -> 大於閾值為0 小於閾值為1
THRESH_TRUNC 截斷閾值化 -> 大於閾值為閾值,小於閾值不變
THRESH_TOZERO 閾值化為0 -> 大於閾值的不變,小於閾值的全為0
THRESH_TOZERO_INV 反閾值化為0 -> 大於閾值為0,小於閾值不變
在本實驗中,我還是采用了使用進度條來調節當前閾值的操作,最大閾值設定為255,得到的實驗結果如下:
當閾值為0的時候 看下圖像,可以對比上面的總結,窗口名稱我用type較少Thresh來命名
當閾值為130的時候,看圖像如下所示:

當閾值為255時候的圖像:

一些極端的數值我在這里測試過了,大家可以根據圖像和上面的定義做個對比來得出自己的結論,我在這里就不做總結了。 代碼如下:
1 import cv2 2
3 img = cv2.imread("C:/Users/DELL/Desktop/img2.jpg") 4
5 gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) 6
7 gauss = cv2.GaussianBlur(gray, (3, 3), 1) 8
9 maxvalue = 255
10
11 def onthreshold(x): 12 value = cv2.getTrackbarPos("value", "Threshold") 13 a, binary = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_BINARY) 14 b, binary_inv = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_BINARY_INV) 15 c, trunc = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_TRUNC) 16 d, to_zero = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_TOZERO) 17 e, to_zero_inv = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_TOZERO_INV) 18 if(a): 19 cv2.imshow("Binary", binary) 20 if(b): 21 cv2.imshow("Binary_INV", binary_inv) 22 if(c): 23 cv2.imshow("TRUNC", trunc) 24 if(d): 25 cv2.imshow("TO_ZERO", to_zero) 26 if(e): 27 cv2.imshow("TO_ZERO_INV", to_zero_inv) 28
29
30 cv2.namedWindow("Threshold") 31
32 cv2.createTrackbar("value", "Threshold", 0, 255, onthreshold) 33
34 cv2.imshow("Threshold", img) 35
36 cv2.waitKey(0)
在這個方法里我要講下,你會發現方法前面有兩個參數,原因是當你進入Pycharm的方法聲明中,里面是這樣給你實列的:
threshold(src, thresh, maxval, type[, dst]) -> retval, dst
第一個retval是你的方法是否執行成功,dst是目標圖像,上面懶得起名字,所以用a,b,c,d,e來代表的對應方法的Bool值。
接下來講下adaptiveThreshold的參數:
def adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C,dst=None)
maxval:Double類型的,閾值的最大值
adaptiveMethod:Int類型的,這里有兩種選擇
1 —— ADAPTIVE_THRESH_MEAN_C(通過平均的方法取得平均值)
2 —— ADAPTIVE_THRESH_GAUSSIAN_C(通過高斯取得高斯值)
不過這兩種方法最后得到的結果要減掉參數里面的C值
thresholdType:Int類型的,方法如下:
THRESH_BINARY 二進制閾值化 -> 大於閾值為1 小於閾值為0
THRESH_BINARY_INV 反二進制閾值化 -> 大於閾值為0 小於閾值為1
THRESH_TRUNC 截斷閾值化 -> 大於閾值為閾值,小於閾值不變
THRESH_TOZERO 閾值化為0 -> 大於閾值的不變,小於閾值的全為0
THRESH_TOZERO_INV 反閾值化為0 -> 大於閾值為0,小於閾值不變
blockSize:Int類型的,這個值來決定像素的鄰域塊有多大。
注意:這里的blockSize的值要為奇數,否則會給出這樣的提示:
Assertion failed (blockSize % 2 == 1 && blockSize > 1) in cv::adaptiveThreshold
C:偏移值調整量,計算adaptiveMethod用到的參數。
實驗中,我閾值的type選擇第一種,來演示這兩種方式得出的結果
當blockSize的值比較小的時候,兩種方法得到的結果的差異不是很大

當blockSize的值比較大的時候,就會發現,平均的這種會將整體的輪廓加深的程度大於高斯
直接看圖:

我圖片上雖然顯示的blockSize為10,不過我在程序里面做了判斷,當為偶數的情況,就讓它+1變成奇數。
代碼如下:
1 import cv2 2
3 img = cv2.imread("C:/Users/DELL/Desktop/img2.jpg") 4
5 gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) 6
7 gauss = cv2.GaussianBlur(gray, (3, 3), 1) 8
9 maxvalue = 255
10
11 def onaptivethreshold(x): 12 value = cv2.getTrackbarPos("value", "Threshold") 13 if(value < 3): 14 value = 3
15 if(value % 2 == 0): 16 value = value + 1
17 args = cv2.adaptiveThreshold(gauss, maxvalue, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, value, 1) 18 gaus = cv2.adaptiveThreshold(gauss, maxvalue, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, value, 1) 19 cv2.imshow("Args", args) 20 cv2.imshow("Gaus", gaus) 21
22 cv2.namedWindow("Threshold") 23
24 cv2.createTrackbar("value", "Threshold", 0, 10, onaptivethreshold) 25
26 cv2.imshow("Threshold", img) 27
28 cv2.waitKey(0)
