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 算法选择最佳阈值 |

相关推荐
wwlsm_zql2 分钟前
京津冀工业智能体赋能:重构产业链升级新篇章
人工智能·重构
lzjava202414 分钟前
Spring AI实现一个智能客服
java·人工智能·spring
hweiyu0023 分钟前
数据挖掘 miRNA调节网络的构建(视频教程)
人工智能·数据挖掘
wshlp12345636 分钟前
deepseek api 灵活使用
python
飞哥数智坊37 分钟前
AI Coding 新手常见的3大误区
人工智能·ai编程
3Bronze1Pyramid37 分钟前
深度学习参数优化
人工智能·深度学习
笨笨没好名字43 分钟前
自然语言处理(NLP)之文本预处理:词元化——以《时间机器》文本数据集为例
人工智能·自然语言处理
skywalk816344 分钟前
简单、高效且低成本的预训练、微调与服务,惠及大众基于 Ray 架构设计的覆盖大语言模型(LLM)完整生命周期的解决方案byzer-llm
人工智能·语言模型·自然语言处理
urkay-1 小时前
Android Cursor AI代码编辑器
android·人工智能·编辑器·iphone·androidx
AI视觉网奇1 小时前
coco json 分类标注工具源代码
开发语言·python