Python----计算机视觉处理(Opencv:二值化,阈值法,反阈值法,截断阈值法,OTSU阈值法)

一、二值化

二值化,顾名思义,就是将某张图像的像素改成只有两个值,其操作的图像也必须是灰度图。也就是 说,二值化的过程,就是将一张灰度图上的像素根据某种规则修改为0和maxval(maxval表示最大值, 一般为255,显示白色)两种像素值,使图像呈现黑白的效果,能够帮助我们更好地分析图像中的形 状、边缘和轮廓等特征

二值化图:就是将图像中的像素改成只有两种值,其操作的图像必须是灰度图。

二、阈值法

阈值法(THRESH_BINARY): 通过设置一个阈值,将灰度图 中的每一个像素值与该阈值进 行比较,小于等于阈值的像素 就被设置为0(黑),大于阈 值的像素就被设置为maxval。

2.1、实现过程

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

设置 阈值 最大值

python 复制代码
thresh=127
maxval=255

做出操作

python 复制代码
img_thresh=np.zeros((1067,800),np.uint8)
for i in range(1067):
    for j in range(800):
        if img_gray[i,j] > thresh:
            img_thresh[i,j]=maxval
        else:
            img_thresh[i,j]=0

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

2.2、内置函数

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

利用函数threshold

python 复制代码
ret,img_thresh=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

三、反阈值法

反阈值法(THRESH_BINARY_INV): 与阈值法相反。反阈值法是当灰度 图的像素值大于阈值时,该像素值 将会变成0(黑),当灰度图的像 素值小于等于阈值时,该像素值将 会变成maxval。

3.1、实现过程

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

设置 阈值 最大值

python 复制代码
thresh=127
maxval=255

做出操作

python 复制代码
img_thresh=np.zeros((1067,800),np.uint8)
for i in range(1067):
    for j in range(800):
        if img_gray[i,j] > thresh:
            img_thresh[i,j]=0
        else:
            img_thresh[i,j]=maxval

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

3.2、内置函数

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

利用函数threshold

python 复制代码
ret,img_thresh=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV)

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

四、截断阈值法

截断阈值法(THRESH_TRUNC): 指将灰度图中的所有像素与阈 值进行比较,像素值大于阈值 的部分将会被修改为阈值,小 于等于阈值的部分不变。换句 话说,经过截断阈值法处理过 的二值化图中的最大像素值就 是阈值。

4.1、实现过程

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

设置 阈值 最大值

python 复制代码
thresh=127
maxval=255

做出操作

python 复制代码
img_thresh=np.zeros((1067,800),np.uint8)
for i in range(1067):
    for j in range(800):
        if img_gray[i,j] > thresh:
            img_thresh[i,j]=thresh

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

4.2、内置函数

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

利用函数threshold

python 复制代码
ret,img_thresh1=cv2.threshold(img_gray,127,255,cv2.THRESH_TRUNC)

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

五、OTSU阈值法

OTSU阈值法:OTSU算法是通过一个值将这张图分前景色和背景色(也就是灰 度图中小于这个值的是一类,大于这个值的是一类),通过统计学方法(最大类 间方差)来验证该值的合理性,当根据该值进行分割时,使用最大类间方差计算 得到的值最大时,该值就是二值化算法中所需要的阈值。通常该值是从灰度图中 的最小值加1开始进行迭代计算,直到灰度图中的最大像素值减1,然后把得到的 最大类间方差值进行比较,来得到二值化的阈值。

g就是前景与背景两类之间的方差,这个值越大,说明前景和背景的差别就越大,效果就越好。OTSU算 法就是在灰度图的像素值范围内遍历阈值T,使得g最大,基本上双峰图片的阈值T在两峰之间的谷底。

通过OTSU算法得到阈值之后,就可以结合上面的方法根据该阈值进行二值化,在本实验中有 THRESH_OTSU和THRESH_INV_OTSU两种方法,就是在计算出阈值后结合了阈值法和反阈值法

注意:

使用OTSU算法计算阈值时,组件中的thresh参数将不再有任何作用。

5.1、实现过程

导入模块

python 复制代码
import numpy as np
import cv2

读取图片

python 复制代码
image_np = cv2.imread('light.jpg')

灰度化

python 复制代码
image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)

取数组最大最小行数列数

python 复制代码
# 使用np数组的min()函数去获取数组中的最小值
min_value = image_gray.min()

# 使用np数组的max()函数去获取数组中的最大值
max_value = image_gray.max()

# 使用np数组的shape属性获取灰度图的高度和宽度
image_shape = image_gray.shape

# 设置最大值
maxval = 255

生成一个二值化模板图

python 复制代码
image_thresh = np.zeros((image_shape[0], image_shape[1]), dtype=np.uint8)

定义计算最大类间方差公式中所用的变量

python 复制代码
n_0 = 0
n_1 = 0
w_0 = 0
w_1 = 0
u_0 = 0
u_1 = 0
u = 0
rows = image_shape[0]
cols = image_shape[1]


# 定义一个字典,用来存储每一个阈值所对应的最大类间方差,方便后面获取合适的阈值
var = {}

建立循环求值

python 复制代码
for t in range(min_value + 1, max_value, 1):
    # 定义一个列表用来存储前景像素点
    foreground = []

    # 定义一个列表用来存储后景像素点
    background = []

    # 定义一个变量用来存储前景的像素值的总数
    forepix = 0

    # 定义一个变量用来存储后景的像素值的总数
    backpix = 0

    # 定义一个变量用来求灰度图中所有的像素值的和
    pix = 0

    # 使用嵌套的for循环去遍历灰度图,用来区分在当前阈值下哪些点是前景点,哪些点是背景点
    for i in range(image_shape[0]):
        for j in range(image_shape[1]):
            # 将灰度图的每个像素点去和阈值进行比较,如果大于阈值就是前景像素点
            if image_gray[i, j] > t:
                # 将前景像素点放到列表,方便后续去计算个数
                foreground.append([i, j])
                # 求前景像素点的总像素值
                forepix += image_gray[i, j]
                # 将该像素点的像素值加到pix里,用来统计图像的总像素值
                pix += image_gray[i, j]
            else:
                # 将后景像素点放到列表,方便后续去计算个数
                background.append([i, j])
                # 求后景像素点的总像素值
                backpix += image_gray[i, j]
                # 将该像素点的像素值加到pix里,用来统计图像的总像素值
                pix += image_gray[i, j]
    # 获取前景像素点数
    n_0 = len(foreground)
    # 获取背景像素点数
    n_1 = len(background)
    # 通过计算获取w0
    w_0 = n_0 / (image_shape[0] * image_shape[1])
    # 通过计算获取w1
    w_1 = n_1 / (image_shape[0] * image_shape[1])
    # 通过计算获取前景的平均像素值
    u_0 = forepix / n_0
    # 通过计算获取背景的平均像素值
    u_1 = backpix / n_1
    # 通过计算获取整幅图的平均像素值
    u = pix / (image_shape[0] * image_shape[1])

    # 通过最大类间方差公式去计算当前阈值下的最大类间方差的结果
    g = w_0 * ((u_0 - u) ** 2) + w_1 * ((u_1 - u) ** 2)

    # 将获取到的最大类间方差值和对于的阈值一块存储到字典中,方便后续选出最大值
    var[t] = g

进行二值化操作

python 复制代码
thresh = max(var, key=var.get)

# 使用一个嵌套循环去进行二值化操作
for i in range(image_shape[0]):
    for j in range(image_shape[1]):
        # 使用if判断灰度图中的第i行第j列的像素点的像素值与阈值的大小关系
        # 如果灰度图的第i行第j列比阈值大,就将该像素设置为maxval
        if image_gray[i, j] > thresh:
            image_thresh[i, j] = maxval
        # 否则的话,就设置为0
        else:
            image_thresh[i, j] = 0

显示结果

python 复制代码
cv2.imshow('image_thresh', image_thresh)
cv2.waitKey(0)

5.2、内置函数

导入模块

python 复制代码
import cv2
import numpy as np

读取图像

python 复制代码
img=cv2.imread('light.jpg')

图像灰度化

python 复制代码
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

利用函数threshold

python 复制代码
# 注意:OTSU在使用时候,需要配合其他的二值化方法去进行,其模式就是 cv2.THRESH_OTSU + 要二值化的方法的参数
ret, image_thresh = cv2.threshold(image_gray, thresh, maxval, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

得出结果

python 复制代码
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

六、其余二值化方法

6.1、低阈值零处理

低阈值零处理(THRESH_TOZERO): 就是像素值小于等于阈值的部分被置 为0(也就是黑色),大于阈值的部 分不变。

6.2、超阈值零处理

超阈值零处理(THRESH_TOZERO_INV): 就是将灰度图中的每个像素与阈值进行 比较,像素值大于阈值的部分置为0 (也就是黑色),像素值小于等于阈值 的部分不变。

七、库函数

7.1、threshold()

将固定级别的阈值应用于每个数组元素。

该函数将固定级别的阈值应用于多通道数组。该函数通常用于从灰度图像中获取双层(二进制)图像( compare 也可用于此目的)或用于去除噪声,即过滤掉值太小或太大的像素。该函数支持多种类型的阈值。它们由 type parameter 确定。

此外,特殊值 THRESH_OTSUTHRESH_TRIANGLE 可以与上述值之一结合使用。在这些情况下,该函数使用 Otsu 或 Triangle 算法确定最佳阈值,并使用它而不是指定的阈值。

注意

目前,Otsu 和 Triangle 方法仅针对 8 位单通道图像实现。

python 复制代码
cv.threshold(src, thresh, maxval, type[, dst]) ->retval, dst
方法 描述
src 输入数组 (多通道、8 位或 32 位浮点)
thresh 阈值
maxval Maximum 值,用于 THRESH_BINARYTHRESH_BINARY_INV 阈值类型。
type 阈值类型

注意:

该方法有两个返回值retval、dst
阈值作的类型

|------------------------------------------------------------|----------------------------------------------------------------------------|
| THRESH_BINARY Python: cv.THRESH_BINARY 阈值法 | |
| THRESH_BINARY_INV Python: cv.THRESH_BINARY_INV 反阈值法 | |
| THRESH_TRUNC Python: cv.THRESH_TRUNC 截断阈值法 | |
| THRESH_TOZERO Python: cv.THRESH_TOZERO 低阈值零处理 | |
| THRESH_TOZERO_INV Python: cv.THRESH_TOZERO_INV 超阈值零处理 | |
| THRESH_MASK Python: cv.THRESH_MASK | |
| THRESH_OTSU Python: cv.THRESH_OTSU OTSU阈值法 | flag 中,使用 Otsu 算法选择最佳阈值 |
| THRESH_TRIANGLE Python: cv.THRESH_TRIANGLE Triangle阈值法 | 标志,使用 Triangle 算法选择最佳阈值 |

相关推荐
没有晚不了安1 小时前
第三周日志-周末看书(3)
python
喵~来学编程啦1 小时前
【Python入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】
开发语言·python
早点睡啊Y1 小时前
AI绘画笔记--基础知识
人工智能·ai作画
患得患失9492 小时前
【后端】【django drf】Django DRF API 编写规范(程序设计规则)
python·django·sqlite
愚戏师4 小时前
Python :数据模型
开发语言·python
袁袁袁袁满4 小时前
Blackbox.Ai体验:AI编程插件如何提升开发效率
人工智能·ai编程·ai插件·chatgpt-4o·deepseek-r1满血版·免费大模型·gemini pro
摸鱼仙人~5 小时前
预训练微调类型分类
人工智能·自然语言处理·分类
申耀的科技观察5 小时前
【观察】拓展大模型应用交付领域“新赛道”,亚信科技为高质量发展“加速度”...
大数据·人工智能·科技
哈喽小疯车5 小时前
Python 实现大文件的高并发下载
python