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来命名
阈值0的对比

当阈值为130的时候,看图像如下所示:
阈值130时候的对比

当阈值为255时候的图像:
阈值255的对比

一些极端的数值我在这里测试过了,大家可以根据图像和上面的定义做个对比来得出自己的结论,我在这里就不做总结了。 代码如下:

import cv2

img = cv2.imread("C:/Users/DELL/Desktop/img2.jpg")

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

gauss = cv2.GaussianBlur(gray, (3, 3), 1)

maxvalue = 255

def onthreshold(x):
    value = cv2.getTrackbarPos("value", "Threshold")
    a, binary = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_BINARY)
    b, binary_inv = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_BINARY_INV)
    c, trunc = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_TRUNC)
    d, to_zero = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_TOZERO)
    e, to_zero_inv = cv2.threshold(gauss, value, maxvalue, cv2.THRESH_TOZERO_INV)
    if(a):
        cv2.imshow("Binary", binary)
    if(b):
        cv2.imshow("Binary_INV", binary_inv)
    if(c):
        cv2.imshow("TRUNC", trunc)
    if(d):
        cv2.imshow("TO_ZERO", to_zero)
    if(e):
        cv2.imshow("TO_ZERO_INV", to_zero_inv)


cv2.namedWindow("Threshold")

cv2.createTrackbar("value", "Threshold", 0, 255, onthreshold)

cv2.imshow("Threshold", img)

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的值比较大的时候,就会发现,平均的这种会将整体的轮廓加深的程度大于高斯
直接看图:
高blockSize的情况分析

我图片上虽然显示的blockSize为10,不过我在程序里面做了判断,当为偶数的情况,就让它+1变成奇数。

代码如下:

import cv2

img = cv2.imread("C:/Users/DELL/Desktop/img2.jpg")

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

gauss = cv2.GaussianBlur(gray, (3, 3), 1)

maxvalue = 255

def onaptivethreshold(x):
    value = cv2.getTrackbarPos("value", "Threshold")
    if(value < 3):
        value = 3
    if(value % 2 == 0):
        value = value + 1
    args = cv2.adaptiveThreshold(gauss, maxvalue, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, value, 1)
    gaus = cv2.adaptiveThreshold(gauss, maxvalue, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, value, 1)
    cv2.imshow("Args", args)
    cv2.imshow("Gaus", gaus)

cv2.namedWindow("Threshold")

cv2.createTrackbar("value", "Threshold", 0, 10, onaptivethreshold)

cv2.imshow("Threshold", img)

cv2.waitKey(0)
  • 16
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值