1、为什么需要图像二值化?
| 场景 | 说明 |
|---|---|
| 文字识别(OCR) | 当需要提取图片(比如扫描的文件、发票图片、身份证)中的文字内容时,将图像二值化后,提高字符边缘清晰度,减少背景干扰,用于给OCR程序 识别 |
| 条形码 / 二维码识别 | 快速识别黑白条纹图案 |
| 医学图像处理 | 比如X光片中提取骨骼轮廓 |
| 目标检测与分割 | 定位图像中的特定区域,可用于质检环节检测缺陷区域 |
将复杂的灰度或彩色图像简化为只有黑白两种状态的图像(0 和 255)
图像二值化可达到 "化繁为简",在保留关键结构的同时去除冗余信息,在 OCR、目标分割、形态学处理等场景中非常有效。
当需要从图像中快速提取 有|没有 、在哪里 信息时,就可以尝试使用二值化处理。
2、图像二值化(Binarization)函数 cv2.threshold()
cv2.threshold() 是 OpenCV的图像二值化函数,将灰度图像转换为黑白二值图像。
通过设定一个阈值(threshold),将像素点分为两类:
- >阈值为某一个值(如 255,白色)
- ≤ 阈值为另一值(如 0,黑色)
2.1 函数定义
retval, dst = cv2.threshold(src, thresh, maxval, type)
- 返回值
dst:新的二值图像
retval: 实际使用的阈值 - 参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| src | NumPy 数组 | 必须是灰度图像 |
| thresh | float | 设定的阈值,比如128 |
| maxval | float | 当像素满足条件时,设置的最大值(通常为 255) |
| type | int | 阈值类型 |
- 阈值类型 type 说明
| 类型 | 名称 | 含义 |
|---|---|---|
| cv2.THRESH_BINARY | 二进制阈值化 | if pixel > thresh: 255 else 0 |
| cv2.THRESH_BINARY_INV | 反向二进制 | if pixel > thresh: 0 else 255 |
| cv2.THRESH_TRUNC | 截断 | if pixel > thresh: thresh else pixel |
| cv2.THRESH_TOZERO | 低于阈值清零 | if pixel <= thresh: 0 else pixel |
| cv2.THRESH_TOZERO_INV | 高于阈值清零 | if pixel > thresh: 0 else pixel |
| cv2.THRESH_OTSU | 自动计算最优阈值(基于 Otsu 算法) | 需和上述类型 按位或组合使用, 如cv2.THRESH_BINARY + cv2.THRESH_OTSU |
2.2 OTSU
OTSU(大津算法) 是一种经典的自动图像二值化方法,用于在灰度图像中自动选择最佳阈值,将图像分为前景和背景两部分。由日本学者 大津展之(Nobuyuki Otsu) 1979年提出。
算法解决的主要问题是:在不知道阈值的情况下,如何自动找出一个"最优"阈值来分割图像?
OTSU 算法的思路是:
最大化类间方差(Between-class Variance),让前景(目标)和背景之间的差异尽可能大,从而使分割最清晰。
2.3 代码示例
python
import cv2
import numpy as np
import os
# 1.读取图像
img_path = "img/dog.jpg"
if not os.path.exists(img_path):
raise FileNotFoundError(f"未找到图像文件{img_path}")
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
thresh , img1 = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)
cv2.imshow("Original", img)
cv2.imshow("threshold", img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
