OpenCV 閾值操作(Threshold,AdaptiveThreshold)


在講閾值操作方法之前,肯定是先講下閾值分割的作用
閾值分割其實就是圖像分離,對於閾值內的你想如何操作,一個最簡單的例子就是二值圖像。

接下來我們看下方法吧:
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)

 


免責聲明!

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



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