Python+OpenCV实现图像二值化:全局与局部阈值详解

陆遥
陆遥
发布时间:2026-10-12 | 2人浏览过
原创

本文详细介绍如何使用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图像二值化相关技术资料,敬请关注本站后续文章。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表