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)
原文地址:https://www.cnblogs.com/ybqjymy/p/15702190.html