欢迎光临
我们一直在努力

人工智能之视觉领域 计算机视觉 第五章 图像阈值处理

人工智能之视觉领域 计算机视觉

第五章 图像阈值处理


文章目录

  • 人工智能之视觉领域 计算机视觉
  • 前言:图像阈值处理(二值化)
    • 1. 通俗理解:什么是图像二值化?
    • 2. 为什么需要二值化?
    • 3. 三大阈值方法详解
      • 3.1 简单阈值(Simple Thresholding)
        • 🔧 核心函数:`cv2.threshold()`
        • 📋 常用阈值类型:
        • ✅ 示例代码:
      • 3.2 自适应阈值(Adaptive Thresholding)
        • 🔧 核心函数:`cv2.adaptiveThreshold()`
        • ✅ 示例代码:
      • 3.3 OTSU 阈值(自动最优阈值)
        • 🔧 使用方式:在 `cv2.threshold()` 中添加 `cv2.THRESH_OTSU` 标志
        • 📊 直观理解 OTSU:
        • ✅ 示例代码:
    • 4. 三种方法对比流程图(Mermaid)
    • 5. 完整实战:文档图像二值化对比
    • 6. 补充技巧与注意事项
      • 🔍 技巧1:先去噪再二值化
      • 🔍 技巧2:反转黑白(如果文字是白底黑字)
      • ⚠️ 注意事项:
    • 7. 应用延伸:为 OCR 预处理
    • ✅ 本章总结
  • 资料关注

前言:图像阈值处理(二值化)

学习目标:理解“二值化”的核心思想,掌握三种主流阈值方法(简单、自适应、OTSU),能根据实际图像选择合适策略,为后续轮廓检测、OCR 等任务打下基础。


1. 通俗理解:什么是图像二值化?

想象你有一张手写笔记的照片,背景是米黄色,字迹是深灰色。 你想把这张图变成 纯黑字 + 纯白背景,方便打印或识别。

✅ 二值化 = 把图像变成只有“黑”和“白”两种颜色的图

  • 黑色(0):表示“前景”(如文字、物体)
  • 白色(255):表示“背景”

这种操作在计算机视觉中叫 阈值处理(Thresholding),是预处理的关键一步。


2. 为什么需要二值化?

原始图像问题二值化后优势
背景杂乱、光照不均 只保留目标结构,去除纹理/噪声
颜色复杂、通道多 简化为单通道,计算量大幅下降
边缘模糊 强化前景与背景的边界

🎯 典型应用场景:

  • 扫描文档去底纹(如发票、试卷)
  • 车牌/文字识别(OCR)前处理
  • 工业零件缺陷检测
  • 轮廓提取(需先二值化)

3. 三大阈值方法详解

3.1 简单阈值(Simple Thresholding)

原理:设定一个全局阈值 T,所有像素按统一标准判断:

  • 若 pixel > T → 设为白色(255)
  • 否则 → 设为黑色(0)
🔧 核心函数:cv2.threshold()

retval, dst = cv2.threshold(src, thresh, maxval, type)

参数说明
src 输入图像(必须是灰度图)
thresh 阈值(如 127)
maxval 最大值(通常为 255)
type 阈值类型(见下表)
📋 常用阈值类型:
类型效果公式
cv2.THRESH_BINARY 标准二值化 dst = 255 if src > thresh else 0
cv2.THRESH_BINARY_INV 反向二值化 dst = 0 if src > thresh else 255
cv2.THRESH_TRUNC 截断 dst = thresh if src > thresh else src
cv2.THRESH_TOZERO 低于阈值归零 dst = src if src > thresh else 0

💡 初学者只需掌握 THRESH_BINARY 和 THRESH_BINARY_INV

✅ 示例代码:

import cv2

# 读取并转灰度
img = cv2.imread('document.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 简单阈值(手动设阈值=127)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 显示对比
cv2.imshow('Original', gray)
cv2.imshow('Binary (Simple)', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()

⚠️ 缺点:光照不均时,全局阈值失效(部分区域过曝/欠曝)


3.2 自适应阈值(Adaptive Thresholding)

原理:不再用全局阈值,而是对每个小区域计算局部阈值,适合光照不均的图像。

🔧 核心函数:cv2.adaptiveThreshold()

dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)

参数说明
src 灰度图
maxValue 输出最大值(255)
adaptiveMethod 计算方法:ADAPTIVE_THRESH_MEAN_C(均值)ADAPTIVE_THRESH_GAUSSIAN_C(高斯加权)
thresholdType 通常为 THRESH_BINARY 或 THRESH_BINARY_INV
blockSize 邻域大小(必须为奇数,如 11, 21)
C 从均值/高斯值中减去的常数(用于微调)
✅ 示例代码:

# 自适应阈值(均值法)
adaptive_mean = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
blockSize=11, C=2
)

# 自适应阈值(高斯法)
adaptive_gauss = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
blockSize=11, C=2
)

# 显示
cv2.imshow('Adaptive Mean', adaptive_mean)
cv2.imshow('Adaptive Gauss', adaptive_gauss)
cv2.waitKey(0)
cv2.destroyAllWindows()

✅ 优点:能处理阴影、渐变背景 ❌ 缺点:计算量稍大,blockSize 需调参


3.3 OTSU 阈值(自动最优阈值)

原理:由 Nobuyuki Otsu 提出,自动搜索使类间方差最大的阈值,适合双峰直方图(前景/背景区分明显)。

🔧 使用方式:在 cv2.threshold() 中添加 cv2.THRESH_OTSU 标志

# OTSU 会忽略你传入的 thresh 值(设为 0 即可)
_, otsu_binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

📊 直观理解 OTSU:
  • 图像直方图有两个“山峰”(一个代表背景,一个代表文字)
  • OTSU 找到两峰之间的“山谷”作为最佳分割点
✅ 示例代码:

# OTSU 二值化
_, otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

print(f"✅ OTSU 自动计算的最优阈值: {_}")

cv2.imshow('OTSU Binary', otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()

✅ 适用场景:文档、印章、高对比度图像 ❌ 不适用:低对比度、多灰度级图像(如自然风景)


4. 三种方法对比流程图(Mermaid)

#mermaid-svg-b3Czn3RZr56MJ0sS{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-b3Czn3RZr56MJ0sS .error-icon{fill:#552222;}#mermaid-svg-b3Czn3RZr56MJ0sS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-b3Czn3RZr56MJ0sS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-b3Czn3RZr56MJ0sS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-b3Czn3RZr56MJ0sS .marker.cross{stroke:#333333;}#mermaid-svg-b3Czn3RZr56MJ0sS svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-b3Czn3RZr56MJ0sS p{margin:0;}#mermaid-svg-b3Czn3RZr56MJ0sS .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS .cluster-label text{fill:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS .cluster-label span{color:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS .cluster-label span p{background-color:transparent;}#mermaid-svg-b3Czn3RZr56MJ0sS .label text,#mermaid-svg-b3Czn3RZr56MJ0sS span{fill:#333;color:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS .node rect,#mermaid-svg-b3Czn3RZr56MJ0sS .node circle,#mermaid-svg-b3Czn3RZr56MJ0sS .node ellipse,#mermaid-svg-b3Czn3RZr56MJ0sS .node polygon,#mermaid-svg-b3Czn3RZr56MJ0sS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-b3Czn3RZr56MJ0sS .rough-node .label text,#mermaid-svg-b3Czn3RZr56MJ0sS .node .label text,#mermaid-svg-b3Czn3RZr56MJ0sS .image-shape .label,#mermaid-svg-b3Czn3RZr56MJ0sS .icon-shape .label{text-anchor:middle;}#mermaid-svg-b3Czn3RZr56MJ0sS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-b3Czn3RZr56MJ0sS .rough-node .label,#mermaid-svg-b3Czn3RZr56MJ0sS .node .label,#mermaid-svg-b3Czn3RZr56MJ0sS .image-shape .label,#mermaid-svg-b3Czn3RZr56MJ0sS .icon-shape .label{text-align:center;}#mermaid-svg-b3Czn3RZr56MJ0sS .node.clickable{cursor:pointer;}#mermaid-svg-b3Czn3RZr56MJ0sS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-b3Czn3RZr56MJ0sS .arrowheadPath{fill:#333333;}#mermaid-svg-b3Czn3RZr56MJ0sS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-b3Czn3RZr56MJ0sS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-b3Czn3RZr56MJ0sS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-b3Czn3RZr56MJ0sS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-b3Czn3RZr56MJ0sS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-b3Czn3RZr56MJ0sS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-b3Czn3RZr56MJ0sS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-b3Czn3RZr56MJ0sS .cluster text{fill:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS .cluster span{color:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-b3Czn3RZr56MJ0sS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-b3Czn3RZr56MJ0sS rect.text{fill:none;stroke-width:0;}#mermaid-svg-b3Czn3RZr56MJ0sS .icon-shape,#mermaid-svg-b3Czn3RZr56MJ0sS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-b3Czn3RZr56MJ0sS .icon-shape p,#mermaid-svg-b3Czn3RZr56MJ0sS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-b3Czn3RZr56MJ0sS .icon-shape rect,#mermaid-svg-b3Czn3RZr56MJ0sS .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-b3Czn3RZr56MJ0sS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-b3Czn3RZr56MJ0sS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-b3Czn3RZr56MJ0sS :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

输入灰度图像

图像光照是否均匀?

前景/背景是否双峰分布?

使用自适应阈值

使用 OTSU 阈值

尝试简单阈值 + 调参

输出二值图


5. 完整实战:文档图像二值化对比

import cv2
import matplotlib.pyplot as plt

# 读取图像(建议用带阴影的文档图测试)
img = cv2.imread('receipt.jpg')
if img is None:
# 创建模拟图像
img = cv2.imread('example_doc.jpg') or np.ones((400, 600, 3), dtype=np.uint8) * 200
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 1. 简单阈值
_, simple = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 2. 自适应阈值(高斯)
adaptive = cv2.adaptiveThreshold(
gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, blockSize=15, C=5
)

# 3. OTSU
_, otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# 使用 matplotlib 显示(避免 BGR 问题)
images = [gray, simple, adaptive, otsu]
titles = ['Gray', 'Simple Threshold', 'Adaptive Gaussian', 'OTSU']

plt.figure(figsize=(12, 8))
for i in range(4):
plt.subplot(2, 2, i+1)
plt.imshow(images[i], cmap='gray')
plt.title(titles[i])
plt.axis('off')
plt.tight_layout()
plt.show()

# 保存结果
cv2.imwrite('binary_simple.jpg', simple)
cv2.imwrite('binary_adaptive.jpg', adaptive)
cv2.imwrite('binary_otsu.jpg', otsu)


6. 补充技巧与注意事项

🔍 技巧1:先去噪再二值化

# 高斯模糊降噪(减少椒盐噪声)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
_, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

🔍 技巧2:反转黑白(如果文字是白底黑字)

# 使用 THRESH_BINARY_INV
_, binary_inv = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

⚠️ 注意事项:

  • 必须先转灰度图!彩色图不能直接做阈值
  • OTSU 对噪声敏感,建议先平滑
  • 自适应阈值的 blockSize 越大,越接近全局阈值;越小,细节越多但可能噪点多

7. 应用延伸:为 OCR 预处理

# 文字识别前的标准流程
def preprocess_for_ocr(image_path):
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
binary = cv2.adaptiveThreshold(
blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, blockSize=11, C=2
)
return binary

# binary_img = preprocess_for_ocr('text.jpg')
# 可直接送入 pytesseract 等 OCR 引擎


✅ 本章总结

方法适用场景优点缺点
简单阈值 光照均匀、高对比度 快速、简单 对光照敏感
自适应阈值 光照不均(阴影、渐变) 局部自适应 需调参,稍慢
OTSU 双峰直方图(文档、印章) 全自动、效果好 对噪声敏感

🌟 你现在可以:

  • 把一张模糊的发票变成清晰的黑白图
  • 为后续的“找轮廓”、“识文字”做好准备
  • 根据图像特点,选择最合适的二值化策略!

下一章,我们将学习 形态学操作 —— 用“膨胀”和“腐蚀”清理二值图中的噪点与空洞!

资料关注

公众号:咚咚王 gitee:https://gitee.com/wy18585051844/ai_learning

《Python编程:从入门到实践》 《利用Python进行数据分析》 《算法导论中文第三版》 《概率论与数理统计(第四版) (盛骤) 》 《程序员的数学》 《线性代数应该这样学第3版》 《微积分和数学分析引论》 《(西瓜书)周志华-机器学习》 《TensorFlow机器学习实战指南》 《Sklearn与TensorFlow机器学习实用指南》 《模式识别(第四版)》 《深度学习 deep learning》伊恩·古德费洛著 花书 《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》 《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》 《自然语言处理综论 第2版》 《Natural-Language-Processing-with-PyTorch》 《计算机视觉-算法与应用(中文版)》 《Learning OpenCV 4》 《AIGC:智能创作时代》杜雨+&+张孜铭 《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》 《从零构建大语言模型(中文版)》 《实战AI大模型》 《AI 3.0》

赞(0)
未经允许不得转载:171主机测评 » 人工智能之视觉领域 计算机视觉 第五章 图像阈值处理
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址