一、什么是OCR
OCR,全称 Optical Character Recognition,中文常译为光学字符识别。
- 定义:OCR 是指让计算机从图像中识别出文字,并把文字转换为可编辑、可搜索的机器可读文本的技术。
二、OCR是怎么进行识别的
“识别”可以拆分为“文字识别”和“字符识别”。 传统OCR和深度学习OCR对于这两个方面的处理方式完全不同。
1.传统OCR的识别原理
核心思路:先切分,再分类
1.1 预处理
输入图像先经过灰度化、二值化、去噪、倾斜校正。二值化后,文字变成黑色前景,背景变成白色。这一步的目标是让文字区域和背景尽可能分离干净。
Note灰度化:把彩色图像每个像素的 RGB 三个通道值合成为一个亮度值,使图像从三通道彩色图变成单通道灰度图。
二值化:设定一个阈值,把灰度图中每个像素按阈值分成黑、白两类,只保留两个值(通常 0 和 255),得到黑白图像。
去噪:去除图像中的随机噪点、孤立干扰像素或杂斑,使图像更干净、文字边缘更清晰。
1.2 行分割与字符分割
用投影法找文字行和字符的边界:
- 水平投影:把每一行像素的黑色数量累加,得到一条曲线。文字行所在区域黑色像素多,行与行之间的空白区域黑色像素少,曲线出现低谷(行边界)。
- 垂直投影:对每一行文字再做垂直投影,字符之间的空白处出现低谷(字符边界)。
分割完成后,每个字符被切成一个独立的小图像块。
1.3 特征提取
对每个字符图像块提取特征。 传统方法手工设计特征,常见的有:
- 笔画方向特征:统计不同方向上笔画的分布。
- 轮廓特征:字符外轮廓的形状描述。
- 网格特征:把字符区域划分成网格,统计每个格子里的前景像素比例。
- 投影特征:字符在水平和垂直方向上的投影分布。
- HOG 特征:梯度方向直方图,描述局部形状。
这些特征被拼接成一个数值向量,作为分类器的输入。
Note分类器:一种根据输入特征判断样本属于哪个类别的模型或算法。OCR 中就是把字符区域提取出的特征向量映射成具体字符类别(如“A”“中”),通常输出类别和置信度。后文中KNN、SVM 都是分类器。
1.4 分类识别
用分类器判断这个特征向量属于哪个字符类别。常见方法:
- 模板匹配:把待识别字符和标准字符模板逐一比对,计算相似度,取最相似者。简单直观,但对字体变化和噪声敏感。
- KNN:找特征空间中最近的 K 个训练样本,投票决定类别。
- SVM:在特征空间中找一个超平面,把不同字符类别分开。
- 决策树/随机森林:用一系列规则对特征做判断。
分类器输出字符类别,同时给出置信度。
1.5 后处理
用词典或语言模型纠错。 比如识别出“H3LLO”,语言模型根据上下文修正为“HELLO”。
传统 OCR 的根本局限:分割一错,后面全错。字符粘连、字体变化、背景复杂时,分割质量急剧下降,识别率随之崩溃。
2.深度学习OCR的识别原理
深度学习不再依赖显式字符分割,而是用神经网络直接从图像中学习“图像→字符序列”的映射。
2.1 文字检测:先找到文字在哪
检测模型输入整张图,输出文字区域的位置框或多边形。以 DBNet 为例:
- 用 CNN 提取图像特征。
- 预测每个像素属于文字区域的概率,得到一张概率图。
- 对概率图做阈值化,得到文字区域。
- 用可微二值化让阈值本身也参与训练,使模型能自适应不同图像。
- 从二值图中提取连通域,得到文字框。
检测模型通常输出一组文字框坐标和置信度。
NoteDBNet(Differentiable Binarization Network,可微分二值化网络):一种基于图像分割的文本检测算法。
CNN(卷积神经网络):一种专门处理图像等网格数据的神经网络。它用卷积核在图像上滑动,提取局部特征(边缘、笔画、纹理等),再逐层组合成更高级的特征。
2.2 字符识别:把文字框变成字符序列
这是“识别”的核心。主流架构是 CRNN + CTC。
NoteCRNN(卷积循环神经网络):一种用于文字行识别的神经网络架构。CNN 提取图像特征序列,RNN(常用 LSTM)建模字符间上下文关系,CTC 负责把序列输出解码成不定长字符序列。
CTC(Connectionist Temporal Classification,连接时序分类):一种用于序列识别的损失函数和解码方法,解决输入序列与输出字符序列长度不一致、且无需逐字符对齐标注的问题。
CRNN 的结构:
- CNN 部分:把文字框图像缩放到固定高度,宽度按比例缩放。CNN 提取特征图。特征图的高度被压到 1,宽度保留,相当于把图像变成一条“特征序列”。每一列对应原图中的一个水平片段。
- RNN 部分:对特征序列做序列建模。常用双向 LSTM,让每个位置的特征都能看到左右上下文。
- 输出层:每个时间步输出一个概率分布,表示该位置对应哪个字符(包括一个特殊的“空白”类别)。
CTC 解决什么问题:
假设图像宽度对应 20 个时间步,但真实文字只有 5 个字符。模型输出 20 个时间步的概率分布,CTC 负责把这 20 个输出映射到 5 个字符。
CTC 的规则:
- 每个时间步取概率最大的字符。
- 合并连续重复的字符。
- 删除所有空白符。
例如模型输出:
--H--E-LL-L-O--
合并重复并删除空白后得到:
HELLO
CTC 的关键优势是:不需要知道每个字符具体对应图像中的哪一列。训练时只需要整行文字的标注,不需要逐字符的位置标注。
Attention 解码器:
另一种识别架构是编码器-解码器 + 注意力机制。编码器把图像编码成特征序列,解码器逐步生成字符,每一步通过注意力机制“看”图像的不同区域。适合不规则排版和长文本。
Transformer 类模型:
用自注意力同时建模图像特征和文本序列关系,近年来在精度上表现突出。
2.3 端到端 OCR
把检测和识别放在一个模型里,输入图像直接输出文本和位置。优点是联合优化、减少误差传递;缺点是训练数据要求更高、模型更复杂。
你的笔记目前完成了**“原理层”**:是什么、怎么识别(传统 + 深度学习)。后面的逻辑应该沿着 “评估 → 分类 → 挑战 → 实践 → 工程 → 总结” 往下走,形成一条从理论到落地的完整链路。
三、OCR 的主要分类
按场景分:印刷体、手写体、自然场景、文档、票据/证件。 按输出粒度分:单字识别、文字行识别、整页文档识别。 按技术路线分:传统 OCR、深度学习 OCR、端到端 OCR。
四、OCR 的评估指标
- CER(字符错误率):字符级编辑距离 / 真实字符总数,越低越好。
- WER(词错误率):以词为单位计算编辑距离比例,适合英文等有空格分隔的语言。
- 检测指标:Precision、Recall、F1、IoU,用于评价文字框质量。
Note1. Precision(精确率 / 查准率)
公式:
- TP(True Positive):预测是文字,实际也是文字。
- FP(False Positive):预测是文字,实际不是文字(误检)。
2. Recall(召回率 / 查全率)
公式:
- FN(False Negative):实际是文字,但模型没检测出来(漏检)。
3. F1(F1 分数)
名称含义:Precision 和 Recall 的 调和平均,用一个数综合衡量两者。
公式:
为什么用调和平均而不是算术平均 调和平均对“偏科”更敏感。如果 Precision 很高但 Recall 很低,F1 会被拉低,不会因为一个高就掩盖另一个低。
4. IoU(Intersection over Union,交并比)
两个框的 交集面积除以并集面积,衡量两个框重合程度。
公式:
取值 0–1。完全重合为 1,完全不重合为 0。
五、OCR 的主要技术挑战
图像模糊、低分辨率、噪声;光照不均;倾斜、透视、弯曲文字;复杂背景;字体多样性;手写体变化;中英混排、竖排;字符粘连或断裂;表格、多栏、图文混排;输出序列与图像位置对齐困难。
六、OCR 在编程中的基本用法(Python)
基本结构:选库 → 初始化 → 预处理 → 调用识别 → 解析结果。
三个主流库对比:
| 库 | 定位 | 中文精度 | 安装特点 |
|---|---|---|---|
| pytesseract | Tesseract 封装 | 中等 | 需先装引擎本体 |
| PaddleOCR | 中文场景优化 | 高 | pip 安装即用,自带模型 |
| EasyOCR | 深度学习多语言 | 中等 | pip 安装,开箱即用 |
最小示例(pytesseract):
import pytesseract
from PIL import Image
text = pytesseract.image_to_string(Image.open("input.png"), lang="chi_sim+eng")
要坐标和置信度用 image_to_data,返回字典。
七、OCR 在软件开发中的工程化用法
核心认知:OCR 很少被当成孤立函数,而是封装成独立服务或能力层。
典型链路:前端 → 业务后端 → OCR 服务 → 数据库/存储
生产级 OCR 服务的内部层次:
- 预处理层(二值化、校正、去噪)
- 调度与容错层(多 Provider、限流、熔断、重试)
- 核心识别层(检测 + 识别 Pipeline)
- 后处理层(纠错、格式化)
部署模式选型:
| 模式 | 特点 | 适用 |
|---|---|---|
| 公有云 API | 接入快、免运维 | 快速原型、通用场景 |
| 私有化部署 | 数据不出域、可定制 | 金融、政务、医疗 |
| 混合云 | 敏感数据本地、非敏感上云 | 平衡安全与弹性 |