Python+OpenCV实现图像二值化:全局与局部阈值详解
本文详细介绍如何使用Python和OpenCV库实现图像二值化。重点解析cv.threshold函数的全局阈值处理,包括THRESH_OTSU和THRESH_TRIANGLE自适应算法,以及adaptiveThreshold函数的局部阈值应用。通过代码示例展示参数设置与效果差异,帮助开发者掌握黑白图像转换的核心技术。
图像二值化的核心在于将图像中每个像素点的灰度值强制设定为0或255,从而让整幅图像呈现出清晰的黑白对比效果。
普通图像二值化处理流程
具体实现代码如下:
import cv2 as cv
import numpy as np
#全局阈值
def threshold_demo(image):
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) #把输入图像灰度化
#直接阈值化是对输入的单通道矩阵逐像素进行阈值分割。
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
print("threshold value %s"%ret)
cv.namedWindow("binary0", cv.WINDOW_NORMAL)
cv.imshow("binary0", binary)
#局部阈值
def local_threshold(image):
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) #把输入图像灰度化
#自适应阈值化能够根据图像不同区域亮度分布,改变阈值
binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY, 25, 10)
cv.namedWindow("binary1", cv.WINDOW_NORMAL)
cv.imshow("binary1", binary)
#用户自己计算阈值
def custom_threshold(image):
gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) #把输入图像灰度化
h, w =gray.shape[:2]
m = np.reshape(gray, [1,w*h])
mean = m.sum()/(w*h)
print("mean:",mean)
ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
cv.namedWindow("binary2", cv.WINDOW_NORMAL)
cv.imshow("binary2", binary)
src = cv.imread('E:/imageload/kobe.jpg')
cv.namedWindow('input_image', cv.WINDOW_NORMAL) #设置为WINDOW_NORMAL可以任意缩放
cv.imshow('input_image', src)
threshold_demo(src)
local_threshold(src)
custom_threshold(src)
cv.waitKey(0)
cv.destroyAllWindows()
代码运行后的输出结果如下:

在操作过程中需注意以下关键点:
1. 全局阈值处理
OpenCV提供了threshold函数用于执行全局阈值操作,其标准函数原型为:threshold(src, thresh, maxval, type[, dst]) -> retval, dst。
src参数代表输入图像,支持多通道,数据类型为8位或32位浮点型。
thresh参数指定具体的阈值数值。
maxval参数用于配合THRESH_BINARY和THRESH_BINARY_INV类型,设定阈值判断为真时的最大像素值。
type参数定义所采用的阈值算法类型。
retval参数返回最终使用的阈值。若采用全局固定阈值算法,返回值即为输入的thresh;若采用全局自适应算法,则返回系统自动计算出的最优阈值。
dst参数指定输出图像,其尺寸、类型及通道数需与src保持一致。
关于type参数的具体阈值类型说明,可参考博客:https://blog.csdn.net/iracer/article/details/49232703,该资源讲解详尽。
具体的阈值类型分类如下:

各类阈值类型的可视化示意图:

若仅单独选择上述五种固定阈值类型之一,通常属于固定阈值算法,处理效果往往不够理想。
除此之外,OpenCV还支持自适应阈值算法:即根据图像局部特征动态计算合适的阈值,而非使用固定值。
例如,结合cv.THRESH_OTSU使用,写作cv.THRESH_BINARY | cv.THRESH_OTSU。示例代码:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)。这代表大律法(Otsu's method),属于全局自适应阈值,此时第二个参数0可替换为任意数值但实际无效。
又如,结合cv.THRESH_TRIANGLE使用,写作cv.THRESH_BINARY | cv.THRESH_TRIANGLE。示例代码:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)。这代表TRIANGLE法,属于全局自适应阈值,同样适用于单峰直方图,第二个参数0改为任意数字亦无效。
补充说明:
cv.THRESH_OTSU和cv.THRESH_TRIANGLE既可以单独使用,也可以与固定阈值标志结合使用。无论哪种写法,系统均优先执行自适应阈值算法。
独立使用的示例:ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_OTSU)(大律法);ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_TRIANGLE)(TRIANGLE法)。
2. 局部阈值处理
OpenCV使用adaptiveThreshold函数进行局部阈值处理,其函数原型为:adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst。
src参数表示输入图像,必须是8位单通道图像。
maxValue参数指定在使用THRESH_BINARY和THRESH_BINARY_INV时的最大像素值。
adaptiveMethod参数定义自适应算法,可选平均法(ADAPTIVE_THRESH_MEAN_C)或高斯加权法(ADAPTIVE_THRESH_GAUSSIAN_C)。
thresholdType参数指定阈值类型,必须为THRESH_BINARY或THRESH_BINARY_INV之一。
blockSize参数定义邻域块的大小,必须为奇数且大于1(如3、5、7等)。
C参数是一个常数,表示从平均值或加权平均值中减去的数值。通常为正数,但也允许为零或负数。
补充:在使用平均和高斯两种算法时,系统会计算每个像素周围blockSize x blockSize大小像素块的加权均值,再减去常量C得到自适应阈值。若采用平均法,周围像素权重相同;若采用高斯法,权重则依据像素到中心点的距离通过高斯方程计算得出。
参考来源:https://blog.csdn.net/guduruyu/article/details/68059450
3. numpy的reshape函数用于在不改变数据内容的前提下重塑数组,其函数原型为:reshape(a, newshape, order='C')。
a参数指代需要重新排列形状的原始数组。
newshape参数为int或int类型元组(tuple),例如(1, 3)表示生成一个1行3列的新数组结构。
order参数指定读取a中元素的索引顺序,以及将元素放置到新数组中的索引顺序。
函数返回值:若条件允许,返回新数组的视图对象;否则返回副本。
以上即为Python结合OpenCV进行图像二值化处理的完整解析,更多Python图像二值化相关技术资料,敬请关注本站后续文章。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









