跳到主要内容

OCR 文字识别【选修】

本节定位

OCR 很容易被说成一句话:

  • 把图片里的字识别出来

但真实项目里,问题会更细:

  • 字在哪里
  • 顺序是什么
  • 多栏版面怎么读
  • 倾斜和模糊怎么办

所以 OCR 更像一条流水线,而不是单个模型。

学习目标

  • 理解 OCR 中“检测”和“识别”的区别
  • 理解文档版面为什么会进一步增加复杂度
  • 通过可运行示例建立 OCR 流水线直觉
  • 理解 OCR 在表单、票据、文档场景中的特殊难点

一、OCR 通常分哪几步?

1. 文本检测

先找出文字区域在哪里。

2. 文本识别

再把每块文字区域转成字符序列。

3. 版面与结构理解

在复杂文档场景里,还要回答:

  • 哪段先读
  • 哪段属于标题
  • 哪段属于表格或正文

二、先看一个最小 OCR 流水线示例

image_blocks = [
{"box": (0, 0, 50, 20), "pixels": "INV-001"},
{"box": (0, 30, 80, 50), "pixels": "TOTAL 299"},
]


def detect_text_regions(image_blocks):
return [block["box"] for block in image_blocks]


def recognize_text(image_blocks):
return [{"box": block["box"], "text": block["pixels"]} for block in image_blocks]


regions = detect_text_regions(image_blocks)
texts = recognize_text(image_blocks)

print("regions:", regions)
print("texts:", texts)

2.1 这个例子最关键的地方是什么?

它清楚分开了:

  • 找文字在哪里
  • 把文字读出来

这正是 OCR 最基础的两阶段结构。

2.2 为什么很多 OCR 错误不在“识别字本身”?

因为如果检测阶段就把文字框切错:

  • 漏了一半
  • 顺序乱了

后面的识别再强也没法完全补救。


三、OCR 为什么经常比想象中更难?

3.1 文字不总是规则排版

可能会遇到:

  • 倾斜
  • 透视变形
  • 模糊
  • 遮挡

3.2 文档不总是单栏单行

例如:

  • 表格
  • 发票
  • 医疗单据

这时“识别文字”只是第一步,
真正难的是结构理解。

3.3 字符级别错误会影响下游业务

像编号、金额、日期这种字段,
识错一位就可能直接影响业务。


四、最容易踩的坑

4.1 只看识别准确率,不看检测质量

OCR 是多阶段流水线,前一步错会传给后一步。

4.2 只做字符识别,不做结构恢复

很多文档类项目真正要的是:

  • 字段
  • 表格结构
  • 阅读顺序

4.3 忽略图像预处理

例如:

  • 二值化
  • 去噪
  • 倾斜校正

在很多场景里非常重要。


小结

这节最重要的是建立一个流水线判断:

OCR 不是单一“识字模型”,而是一条包含文本检测、文本识别和版面理解的多阶段系统。

只要这条线清楚了,后面你做票据、表单、文档理解项目就不会只盯识别模型本身。


练习

  1. 给示例再加一个新文字块,思考阅读顺序该怎么恢复。
  2. 为什么检测阶段的错误会直接拖垮 OCR 最终效果?
  3. 想一想:表格票据和普通街景文字识别,哪一层难点差别最大?
  4. 如果金额字段总识错一位,你会先查检测、识别还是后处理?为什么?