本文适合OpenCV图像处理入门,讲解
cv2.threshold()固定阈值二值化API,包含参数解析、5种阈值模式、示例代码、Otsu自动阈值,可直接复制到CSDN发布。
一、函数简介
阈值处理是图像处理非常基础的操作,常用于图像分割、前景背景分离、形态学预处理。 把灰度图像像素和设定阈值比较,按照不同规则重新赋值像素。
函数原型:
ret, dst = cv2.threshold(src, thresh, maxval, type)
返回值
ret:实际生效的阈值。普通阈值就是传入的thresh;使用Otsu算法时为算法自动计算出最优阈值。dst:阈值处理完成之后的输出图像(单通道)。
参数详解
| 参数 | 说明 |
|---|---|
| src | 输入图像,必须为单通道灰度图,彩色图像需要先转为灰度,否则报错 |
| thresh | 手动设定的阈值,取值范围 0~255 |
| maxval | 满足判定条件时,像素被赋予的最大值,一般填255(代表白色) |
| type | 阈值处理模式,共5种基础模式,还可以叠加Otsu自动阈值算法 |
二、五种基础阈值模式
以 thresh=127,maxval=255 作为例子,对比5种模式处理逻辑。
| 阈值类型 | 处理逻辑 |
|---|---|
cv2.THRESH_BINARY |
像素>阈值 → maxval(255白色);像素≤阈值 → 0(黑色) |
cv2.THRESH_BINARY_INV |
BINARY反转。像素>阈值 → 0(黑色);像素≤阈值 → maxval(255白色) |
cv2.THRESH_TRUNC |
截断模式。像素>阈值 → 设置为阈值;小于等于阈值像素保持原始灰度不变 |
cv2.THRESH_TOZERO |
置零模式。像素>阈值,像素保持原值;像素≤阈值,置为0黑色 |
cv2.THRESH_TOZERO_INV |
TOZERO反转。像素>阈值置0黑色;像素≤阈值,像素保持原值 |
💡注意:
- BINARY / BINARY_INV:输出只有0和maxval,真正二值黑白图。
- TRUNC / TOZERO系列:保留中间灰度信息,不是纯二值图像。
_INV后缀代表逻辑取反。
三、完整可运行代码
import cv2
import matplotlib.pyplot as plt
# 解决matplotlib中文乱码
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 读取图片并转为灰度图
img = cv2.imread("./imgs/lena.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 5种阈值操作
ret1, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret2, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret3, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret4, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret5, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ["原始灰度图","THRESH_BINARY","THRESH_BINARY_INV","THRESH_TRUNC","THRESH_TOZERO","THRESH_TOZERO_INV"]
images = [img_gray, thresh1, thresh2, thresh3, thresh4, thresh5]
plt.figure(figsize=(12,7))
for i in range(6):
plt.subplot(2, 3, i + 1)
plt.imshow(images[i], cmap="gray")
plt.title(titles[i])
plt.axis("off")
plt.tight_layout()
plt.show()
四、Otsu大津自动阈值
手动设置固定阈值127,对光照差异大的图片效果很差。Otsu算法可以自动计算全局最优阈值,不需要人工指定。
使用方式:
-
基础阈值填
0,算法内部自动覆盖。 -
使用
+叠加cv2.THRESH_OTSU。Otsu自动阈值
ret_otsu, dst_otsu = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(f"Otsu算法自动计算的阈值:{ret_otsu}")
五、应用场景
- 目标分割:分割前景物体和背景。
- 形态学预处理:腐蚀、膨胀、开闭运算之前,经常先做阈值二值化。
- 遥感图像、文档扫描图像预处理,Otsu适合光照不均匀图像。
六、常见踩坑总结
- ❌不能直接传入BGR彩色图,threshold只接收单通道灰度图像。
_INV代表逻辑反转,黑白结果颠倒。- TRUNC、TOZERO输出依旧保留灰度,不是只有纯黑纯白。
- Otsu算法适合灰度分布双峰的图像,单峰图像效果一般。
如果你需要,我可以继续帮你写自适应阈值adaptiveThreshold的CSDN版本,专门处理明暗分布不均匀图像。