一、二值化
二值化,顾名思义,就是将某张图像的像素改成只有两个值,其操作的图像也必须是灰度图。也就是 说,二值化的过程,就是将一张灰度图上的像素根据某种规则修改为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_OTSU 或 THRESH_TRIANGLE 可以与上述值之一结合使用。在这些情况下,该函数使用 Otsu 或 Triangle 算法确定最佳阈值,并使用它而不是指定的阈值。
注意
目前,Otsu 和 Triangle 方法仅针对 8 位单通道图像实现。
python
cv.threshold(src, thresh, maxval, type[, dst]) ->retval, dst
方法 | 描述 |
---|---|
src | 输入数组 (多通道、8 位或 32 位浮点) |
thresh | 阈值 |
maxval | Maximum 值,用于 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 算法选择最佳阈值 |