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

一、二值化

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

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

二、阈值法

  

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

2.1、实现过程

导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

设置  阈值  最大值

thresh=127
maxval=255

做出操作 

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

得出结果 

cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

2.2、内置函数

 导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
利用函数threshold
ret,img_thresh=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)

 得出结果 

cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

三、反阈值法

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

3.1、实现过程

导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

设置  阈值  最大值

thresh=127
maxval=255

做出操作 

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

得出结果 

cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

3.2、内置函数

 导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
利用函数threshold
ret,img_thresh=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV)

 得出结果 

cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

四、截断阈值法

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

4.1、实现过程

导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

设置  阈值  最大值

thresh=127
maxval=255

做出操作 

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

得出结果 

cv2.imshow('img_thresh',img_thresh)
cv2.waitKey(0)

4.2、内置函数

 导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
利用函数threshold
ret,img_thresh1=cv2.threshold(img_gray,127,255,cv2.THRESH_TRUNC)

 得出结果 

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、实现过程

导入模块

import numpy as np
import cv2

读取图片

image_np = cv2.imread('light.jpg')

灰度化

image_gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY)

取数组最大最小行数列数

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

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

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

# 设置最大值
maxval = 255

 生成一个二值化模板图

image_thresh = np.zeros((image_shape[0], image_shape[1]), dtype=np.uint8)

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

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 = {}

建立循环求值 

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

进行二值化操作 

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

显示结果 

cv2.imshow('image_thresh', image_thresh)
cv2.waitKey(0)

5.2、内置函数

  导入模块

import cv2
import numpy as np

读取图像 

img=cv2.imread('light.jpg')

图像灰度化 

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

 得出结果 

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_OTSU 或 THRESH_TRIANGLE 可以与上述值之一结合使用。在这些情况下,该函数使用 Otsu 或 Triangle 算法确定最佳阈值,并使用它而不是指定的阈值。

注意

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

cv.threshold(src, thresh, maxval, type[, dst]) ->retval, dst
方法描述
src输入数组 (多通道、8 位或 32 位浮点)
thresh

阈值

maxvalMaximum 值,用于 THRESH_BINARY 和 THRESH_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 算法选择最佳阈值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值