想象你是一位考古学家,在一块布满苔藓与裂纹的古石碑前驻足。石碑上刻着密密麻麻的文字,但风化让它们断断续续,苔藓又遮住了半边。你下意识地做了两件事:先用手电筒扫过碑面,判断“哪里有字”;然后凑近每个区域,逐个辨认“这写的是什么字”。第一件事叫文字检测,第二件事叫文字识别,两者合在一起,就是计算机视觉里大名鼎鼎的 OCR(光学字符识别)。几十年来,人类一直想把考古学家这套“找字—认字”的本领教给计算机,让机器能直接从照片里读出文字。这篇文章就用这趟考古之旅,带你从零看懂 OCR 的全流程。
掌握 OCR 是进入文档智能化、自动驾驶路牌识别、仓储票据数字化等真实业务的基础技能。对 AI 从业者而言,OCR 是最容易被量产需求调用的视觉技术之一,学懂它就能快速落地一批有商业价值的应用。
可视化演示
展示OCR全流程:输入图像→文字检测(CTPN/DBNet)→文字识别(CRNN+CTC)→后处理→文本输出。
本节配有交互动效(进入视口后自动加载,约 3KB)。
OCR流水线 输入→检测(DBNet)→识别(CRNN)→后处理→文本输出,五阶段流水线 Loss = L_det + L_rec + L_ctc 端到端OCR系统,DBNet实时检测+CRNN高精度识别
OCR 初识
考古队第一次进遗址,不会急着逐字认读,而是先围着石碑转一圈,判断“碑上有没有字、字大概分布在哪些区域”。这个“先打量全局”的步骤,对应到计算机视觉里,正是 OCR 的第一个大动作——文字检测。等确认了文字的位置,专家们才会蹲下身来逐字辨认。这一整套“先定位、后认读”的流程,几千年来都是人类解读文字的自然方式,如今也成了机器识字的行动纲领。
OCR 的全称是 Optical Character Recognition,中文叫光学字符识别。它要做的事情很简单:输入一张包含文字的图像,输出一段可编辑、可搜索的文字。整条流水线通常被拆成两大步:第一步找到文字在哪里,也就是文字检测;第二步读出文字是什么,也就是文字识别。这两步就像考古队的“圈地”与“释读”,缺一不可。
OCR 的应用比想象中更普遍:扫描仪把纸质合同变成 Word 文档,停车场摄像头读出车牌号,财务软件自动抽出报销单上的金额与日期,手机相册里的“复制图片文字”功能也是它的功劳。它的发展大致经历了三个阶段:早期用模板匹配和投影分析,属于“死记硬背”印刷体;后来引入统计学习和手工特征,增强了抗干扰能力;如今深度学习让模型从海量数据中自动学出“看字”的能力。无论技术如何演进,核心挑战始终没变:现实图像中字体五花八门、光线忽明忽暗、背景繁杂凌乱,机器得像考古学家一样,在种种干扰中稳定地锁定并读懂每一个字。
翻开 OCR 的入门地图,你会发现它和考古流程惊人地相似:先定位、再解读、最后反复校验。理解了这张地图,后面每一步都是顺着它往下展开的故事。
图像预处理
考古学家不会直接趴在长满苔藓的石碑上认字,而是先用软毛刷清理表面、调整灯光角度,让字迹从背景里“浮”出来。OCR 里的图像预处理,扮演的正是这个“清理与打光”的角色:它不负责认字,却决定了字能不能被看清。
照片里的干扰五花八门:光照不均造成局部过暗或过亮,灰尘颗粒形成噪点,拍摄角度让文字歪斜。预处理的目的就是把这些干扰压下去,让文字与背景的对比足够清晰。最常用的手段是二值化:设定一个阈值 T,像素灰度超过 T 的当作文字前景,记为 1;低于 T 的当作背景,记为 0。这样一张千变万化的灰度图,就被压缩成一张简洁明了的黑白两色图,后续找字、切字都会轻松很多。
除了二值化,预处理还包括灰度化(把彩色照片变成单通道灰度图)、去噪(用中值滤波等方法抹掉小颗粒)、倾斜校正(通过检测文字行的角度把图旋转摆正)。每一步都像考古学家拂去浮土、摆正手电筒,看似琐碎,却为后续工作铺平了道路。
石头没刷干净,再厉害的眼睛也会看走眼。预处理做不好,后面检测和识别的精度都会直接打折扣。
- 灰度值函数$f(x,y)$ 表示图像在坐标 $(x,y)$ 处的灰度值,也就是这个像素的明暗程度,比如 0 代表纯黑、255 代表纯白。
- 阈值判定$f(x,y) \ge T$ 把每个像素的灰度值与一个“分界线” $T$ 作比较,T 选得好不好,直接决定“字”和“背景”能不能被干净分开。
- 二值输出$g(x,y)$ 输出 1 表示该像素被当作前景文字,输出 0 表示背景;最终整张图的所有像素都被打上“是字”或“不是字”的标签。
文字检测
清理完石碑,考古学家接下来会用粉笔沿着字迹轮廓画线,把整片碑文划分成一个个规整的“版面区块”。在 OCR 里,这一步叫作文字检测,它的任务是回答一个朴素的问题:文字到底在哪里?
文字检测的输出是一串矩形框(bounding box),每个框恰好围住一行或一块文字。有了这些框,识别器才知道该把注意力放在图像的哪些区域,而不是把整张图囫囵吞下。如果检测框画歪了,把背景纹理圈进来,把真字漏在外头,后面的识别再强也无从发挥。
早期做法是滑窗扫描:用一个固定大小的窗口在图上从左到右、从上到下地滑动,每到一处就问一句“这里有没有字”。窗口越细,定位越精确,但计算开销也成倍上涨。后来的深度学习方法改走“回归”路线,直接在特征图上预测文字框的中心、宽高和旋转角度,速度快了一个量级。无论哪种方法,都需要一把尺子来衡量“框得准不准”,这把尺子就是 IoU(交并比):
在 OCR 评测中,IoU 超过某个阈值(比如 0.5)就算检测成功。这个“及格线”设得越高,对框的精度要求就越苛刻。
检测框就像考古地图上的标注——标注越精准,后续的逐字认读就越省力;如果标注张冠李戴,所有后续工作都会功亏一篑。
- 交集面积$A \cap B$ 表示预测框 $A$ 与真实文字框 $B$ 重叠的矩形区域,$|A \cap B|$ 是这个重叠区域的面积。
- 并集面积$A \cup B$ 表示两个框覆盖的总范围,$|A \cup B|$ 是总面积,重叠部分只算一次。
- 比值计算$\text{IoU}$ 是重叠面积占总面积的比重,取值范围在 0 到 1 之间,越接近 1 说明预测框与真实框越贴合。
文字识别
粉笔框画好了,考古学家终于可以蹲下身来,对着每个框里的字逐个辨认:这一笔缺了,那一撇多了,最终连成一句完整的话。OCR 中的文字识别就承担了这份“逐字释读”的精细工作。
文字识别接收的是检测框裁出的文字行图像,输出一串字符序列。对于整齐的印刷体,可以先沿着字符间隙把每个字切出来,再逐个分类;但手写体字符常常粘连、变形,“切”这个动作本身就很难。因此现代 OCR 更倾向于用“序列到序列”的思路:让模型直接输入一整行文字图像,输出整串字符,省去显式切分的麻烦。
深度学习时代最经典的方案是 CRNN,名字拆开看就懂了:用 CNN 把图像压成一条特征序列,再用 RNN 按从左到右的顺序建模字符之间的依赖关系,最后用 CTC(Connectionist Temporal Classification)把逐帧预测对齐成最终文本。CTC 的巧妙之处在于允许模型在每一帧输出一个“空白”符号,再通过“合并重复字符、删除空白”把一长串帧级预测压缩成短小的文本。它在训练时并不是只挑一条最可能的路径,而是把能还原成同一文本的所有路径概率全部加起来:
CTC 就像考古队的“通假字对照表”:同一个字的多种写法、模糊笔画造成的多种歧义,只要最终能还原成同一个正确句子,都算作有效证据加在一起,这让模型对模糊字迹格外宽容。
- 路径概率$P(\pi|X)$ 是模型对一条具体预测路径 $\pi$ 给出的概率,$\pi$ 是一串由字符和空白组成的帧级输出。
- 路径集合$\mathcal{B}^{-1}(Y)$ 是所有经过“合并重复字符、去掉空白”后恰好等于目标文本 $Y$ 的路径的集合。
- 求和取总把集合内所有路径的概率相加,得到模型把图像 $X$ 识别成文本 $Y$ 的总概率,训练时就是让这个总概率尽量变大。
传统方法
在没有深度学习之前,考古学家靠的是一本厚厚的《碑文字形手册》,把看到的字形和手册里的标准字形重叠比对,像极了用透明纸描红。这就是传统 OCR 的核心思路:模板匹配——拿标准模板和待识别区域做像素级对照,长得最像的那个就是答案。
模板匹配看起来很直接,但真实字符会被噪声、粗细、倾斜干扰得“不那么标准”。于是工程上发展出一整套辅助手段:先做二值化,再用投影分析切分字符。投影法的诀窍很朴素:把二值图像按列累加像素值,有字的列累加值大,没字的列累加值为 0,那么连续的非零列区间就对应一个字符的左右边界;对每一行做同样操作,还能进一步切出上下边界。字符切出后,再把它翻译成一组数字特征,比如笔画密度、水平和垂直投影值,然后与各类别的“标准特征”比较。
每一类字符的标准特征通常用该类样本的平均向量表示。识别时,只需计算待测字符特征向量与各类标准向量的欧氏距离,距离最小的类别就是识别结果:
传统方法像老派考古学家的“手册比对法”,规则透明、结果可解释、算力需求低,但遇到不按手册出牌的潦草字体就很容易失手。它没有消失,而是以组件的形式活在现代系统里。
- 特征向量$\mathbf{x}$ 是待识别字符的特征向量,每一维 $x_k$ 是某个量化特征,比如字符第 $k$ 个位置的笔画有无或投影密度。
- 类别中心$\mathbf{c}$ 是某个字符类别(如字母 A)所有样本特征的平均向量,代表这一类的“标准长相”。
- 距离计算逐维求差后平方、累加、开根号,得到的 $d$ 表示待测字符与标准类别的距离;距离越小,长得越像。
深度学习方法
如今考古队里来了一位“AI 学徒”,他不再死记手册,而是看了一万块石碑后自己总结出“什么形状像哪个字”。深度学习 OCR 正是这个套路:不靠人工定规则,而是从海量数据中自动学习“该看哪里、该怎么认”。
这种数据驱动思路用CNN(卷积神经网络)替代手工特征:卷积核就是自动学出来的特征模板,模板一层层叠加,从边缘、笔画一直抽象到字符部件;再用RNN(循环神经网络)记住字符之间的搭配习惯,组成 CRNN 后直接端到端训练——输入一张文字行图片,输出一串文本,中间不需要任何人设计规则。
CNN 的本质是一种可学习的卷积运算:一个小窗口在图上滑动,窗口内的每个像素与一组权重相乘后累加,得到一个特征值。每层堆叠都会扩大模型的“视野”,使它从只看一个点,到能看见一个笔画,再到看全一个字符。它的数学形式如下:
AI 学徒的高明之处不在于定的规矩更多,而在于“看过的碑够多、总结的规律够全”。这也是深度学习 OCR 能驾驭草书、行书和复杂背景的根本原因。
- 邻域取值$x_{i+m, j+n}$ 是输入图像在窗口内第 $(m,n)$ 个位置的像素值,窗口大小是 $M \times N$,它决定了这一层看多大的局部区域。
- 卷积核加权$W_{m,n,k}$ 是第 $k$ 个卷积核在位置 $(m,n)$ 上的权重,窗口内每个像素与对应权重相乘,相当于在按模板给这一小块区域打分。
- 偏置累加把所有乘积求和后加偏置 $b_k$,得到输出特征图第 $k$ 个通道在位置 $(i,j)$ 的值;不同 k 代表不同学到的特征模板。
评估与优化
考古队的翻译初稿交上来,领队不会直接采信,而是会抽查几段、统计哪句译对了、哪些字认错了,再决定下一步怎么改进。评估与优化就是 OCR 的“质检环节”,没有它,系统做得好不好只能靠感觉。
评估 OCR 最常用的指标是精确率和召回率。精确率回答“模型报出来的文字,有多少是真的”,要求宁缺毋滥;召回率回答“真正存在的文字,有多少被找到”,要求一个都不能少。两者像跷跷板的两端:放宽阈值,召回率上去、误报也变多;收紧阈值,精确率变高、漏报却增加。精确率的定义如下:
优化策略通常从三方面入手:一是数据,扩充更多不同字体、光照、背景的样本,并做旋转、加噪、透视变形等数据增强;二是预处理,针对具体场景调阈值、做去噪和倾斜校正;三是模型,换更强的骨干网络、加注意力机制,或做剪枝量化以部署到手机等端侧设备。
就像考古队通过抽样质检不断修订《碑文解读规范》,OCR 工程师围绕“漏报、误报、效率”三个指标持续打磨,让系统在真实业务里越用越稳。
- 真阳性$TP$(True Positive)是模型识别为文字且实际确实是文字的目标数,相当于“真金不怕火炼”的那部分。
- 假阳性$FP$(False Positive)是模型识别为文字但实际并非文字的目标数,比如把石头的裂纹当成了笔画。
- 精确率计算$TP + FP$ 是所有被模型报为“文字”的数量,$P$ 就是这些报告里真正正确占的比例,越接近 1 说明误报越少。
应用实战
考古队把同一套技术搬到不同遗址时,装备也会跟着变:在沙漠残碑前要防风沙,在潮湿洞窟里要防潮气。OCR 应用也一样——“找字—认字—校验”的主干不变,但每个具体场景都会在某个环节上提出特殊要求。
把整套链路落到业务中,最常见的三个方向是文档数字化、车牌识别和票据识别。文档数字化面对印刷体,版面相对规整,难点在于长文档的分栏、标题、正文结构分析,识别之后往往还要接排版还原;车牌识别面对户外强光、夜间低照度和车辆快速移动,要求检测模块足够快、识别模块对倾斜和模糊足够鲁棒;票据识别则需要抽取金额、日期、单号等关键字段,通常要在 OCR 之后再接一层信息抽取模型。
工程部署时还有一些通用的“战术问题”要考虑:图片太大时先做等比缩放,避免超出模型输入尺寸;推理平台选 GPU 还是 CPU,取决于实时性和成本预算;识别置信度太低时,业务系统要能提醒用户重新拍摄而不是强行返回结果。这些问题在实验室里常常被忽略,却往往是项目能否落地成功的关键。
考古技术再厉害,到了现场也还得先观察遗址环境。OCR 工程师接到新业务时,也总是先问三句话:图像从哪来?文字长什么样?算力够不够?把这三句话答清楚,OCR 项目就已经成功了一大半。
AI 应用场景
合同文档数字化
阶段:推理部署阶段(应用端)
解决的问题:传统方式靠人工把纸质合同逐字录入系统,一份 20 页的合同常常要花掉一个小时,且容易疲劳出错。OCR 系统把扫描件转成可编辑文本,录入时间缩短到分钟级,还能直接接入全文检索和关键词定位。
具体案例:某银行把历史信贷合同批量数字化:先做图像预处理增强清晰度,再用文字检测模型定位每一段落,接着用识别模型转成文本,最后存入知识库。客户经理搜索“担保条款”时,秒级就能定位到原文所在页。
停车场车牌识别
阶段:模型训练与优化阶段
解决的问题:传统地感线圈只能感知有没有车,却无法知道是哪一辆。车牌识别用“检测+识别”两段式流程,在视频流中实时锁定车牌框并读出车牌号,用于无感支付和安全管理。
具体案例:某智慧停车场出入口的摄像头每一帧都会经过三次接力:车辆检测、车牌检测、字符识别。夜间光照不足时,预处理模块先做亮度均衡,再用训练好的 CRNN 识别字符,平均准确率保持在 98% 以上。
财务票据关键信息抽取
阶段:数据标注与预处理阶段、模型微调
解决的问题:传统报销靠财务人员逐张核对发票、手动录入金额和税号,耗时费力且容易出错。OCR 先将整张票据转成文本,再配合规则或信息抽取模型取出关键字段,自动填入财务系统。
具体案例:某企业费控系统接入 OCR 后,员工拍照上传发票,系统几秒内完成验真、抽字段和报销单预填写,财务审核从原本的 5 分钟缩短到 30 秒。
Python 演示
# -*- coding: utf-8 -*-"""极简 OCR 演示:七段数码管模板匹配识别数字串对应正文"传统方法"一节:模板匹配 + 垂直投影分割"""import random DIGITS = "0123456789"SEGMENTS = { '0': {'a', 'b', 'c', 'd', 'e', 'f'}, '1': {'b', 'c'}, '2': {'a', 'b', 'g', 'e', 'd'}, '3': {'a', 'b', 'g', 'c', 'd'}, '4': {'f', 'g', 'b', 'c'}, '5': {'a', 'f', 'g', 'c', 'd'}, '6': {'a', 'f', 'g', 'e', 'c', 'd'}, '7': {'a', 'b', 'c'}, '8': {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, '9': {'a', 'b', 'c', 'd', 'f', 'g'},} class TemplateOCR: def __init__(self): self.templates = {ch: self._render(ch) for ch in DIGITS} self._width = len(self.templates['0'][0]) self._height = len(self.templates['0']) @staticmethod def _render(ch): """把七段数码管编码渲染成 5x7 二值模板""" seg = SEGMENTS[ch] grid = [[0] * 5 for _ in range(7)] for i in range(7): for j in range(5): is_h = (i in (0, 3, 6)) and (1 <= j <= 3) and ( (i == 0 and 'a' in seg) or (i == 3 and 'g' in seg) or (i == 6 and 'd' in seg) ) is_vl = (j == 0) and (i in (1, 2, 4, 5)) and ( (i <= 2 and 'f' in seg) or (i >= 4 and 'e' in seg) ) is_vr = (j == 4) and (i in (1, 2, 4, 5)) and ( (i <= 2 and 'b' in seg) or (i >= 4 and 'c' in seg) ) if is_h or is_vl or is_vr: grid[i][j] = 1 return grid def make_test_image(self, text, gap=2, noise_ratio=0.05): """把一串数字拼成带噪声的二值测试图像""" h = self._height single_w = self._width width = len(text) * single_w + gap * (len(text) - 1) image = [[0] * width for _ in range(h)] for idx, ch in enumerate(text): offset = idx * (single_w + gap) tpl = self.templates[ch] for i in range(h): for j in range(single_w): if tpl[i][j]: image[i][offset + j] = 255 for i in range(h): for j in range(width): if random.random() < noise_ratio: image[i][j] = 255 - image[i][j] return image def project_segment(self, binary_img): """垂直投影:按列统计有文字的像素,切出每个字符的列区间""" col_hit = [any(row[j] == 255 for row in binary_img) for j in range(len(binary_img[0]))] col_hit.append(False) segments = [] start = None for j, hit in enumerate(col_hit): if hit and start is None: start = j elif not hit and start is not None: segments.append((start, j - 1)) start = None return segments def _similarity(self, cell, tpl): """把切出的小图缩放到模板尺寸,逐像素比对相似度""" cell_h, cell_w = len(cell), len(cell[0]) if cell_w == 0: return -1 hit = 0 for i in range(self._height): for j in range(self._width): ci = min(int((i + 0.5) * cell_h / self._height), cell_h - 1) cj = min(int((j + 0.5) * cell_w / self._width), cell_w - 1) cell_val = 1 if cell[ci][cj] == 255 else 0 if cell_val == tpl[i][j]: hit += 1 return hit / (self._height * self._width) def recognize_cell(self, cell): """与所有模板比对,返回相似度最高的字符""" best_ch, best_score = None, -1 for ch, tpl in self.templates.items(): score = self._similarity(cell, tpl) if score > best_score: best_ch, best_score = ch, score return best_ch, best_score def recognize(self, image): """完整识别流程:投影切分 + 模板匹配""" segments = self.project_segment(image) out = [] for a, b in segments: cell = [row[a:b + 1] for row in image] ch, score = self.recognize_cell(cell) out.append(ch) return ''.join(out) def main(): random.seed(42) ocr = TemplateOCR() text = "314159" image = ocr.make_test_image(text, gap=2, noise_ratio=0.05) result = ocr.recognize(image) print("原图内容:", text) print("识别结果:", result) print("识别一致:", result == text) if __name__ == "__main__": main()
self.templates = {ch: self._render(ch) for ch in DIGITS}预先生成 10 个数字的“标准字模样板”,相当于考古手册里的标准字形。image[i][offset + j] = 255把字符模板的笔画像素渲染成白色,拼出整张测试图像。if random.random() < noise_ratio随机把一些像素黑白反转,模拟石碑上的噪点干扰。col_hit = [any(row[j] == 255 for row in binary_img) for j in range(...)]垂直投影:统计每一列是否含有文字像素,用于后续切分字符。if hit and start is None: start = j遇到连续有字的列开头,记下字符区间的左边界。elif not hit and start is not None: segments.append((start, j - 1))遇到空白列,切出一个完整的字符区间,类似考古队按间隙划分文字块。score = self._similarity(cell, tpl)把切出的字符小图和每个数字模板逐像素比对,计算相似度。ch, score = self.recognize_cell(cell)选出相似度最高的模板作为识别结果,即“距离最小者胜出”。
常见误区
误区很多初学者以为 OCR 就是把图片扔给模型,让它一个字一个字往外吐,检测这个步骤是多余的。我自己刚开始也用接口直接传整张图,以为识别模型内部会自动处理所有定位问题。
正解实际上 OCR 通常由“文字检测+文字识别”两个分工明确的环节组成。检测负责回答“文字在哪里”,输出文本框;识别负责回答“这是什么字”,只在框内工作。如果跳过检测直接对整图识别,模型很容易把背景纹理、桌子花纹误认成文字,计算量也大得离谱。即便是端到端模型,内部也隐含有定位机制。理解了检测与识别的分工,才能解释“为什么有些图识别效果差”。
为何常见:因为成熟 OCR SDK 把两阶段封装成了黑盒 API,用户只看到输入图片、输出文字,自然察觉不到中间还有一次“圈地”动作。
误区预处理不就是把图片变黑白吗?阈值设大点小点都无所谓,反正后面还有深度学习模型在兜底。
正解阈值直接决定文字和背景能否干净分离。阈值太高,浅色文字的笔画会被抹掉;阈值太低,阴影和噪点会糊成一大团黑块,把字符粘连在一起。实际工程中常用 Otsu 等方法自动选取阈值,让前景与背景的类间方差最大,效果远好于拍脑袋定一个数。这就像考古灯光,光照角度差一点,字迹就可能完全藏在阴影里。
为何常见:因为二值化看起来太简单,像是一行 if 判断,让人忽略了它对后续步骤的放大效应。
误区深度学习这么强,模板匹配、投影分析这些老古董还有什么用?考试不考,面试不问,干脆跳过。
正解传统方法并没有消失,它们以组件的形式活在现代系统里:投影法仍是很多印刷体识别器的切分手段,模板匹配思想演化成了卷积核,手工特征被可学习特征替代但分类思路保留了下来。理解传统方法等于理解 OCR 的“第一性原理”,排查问题、做轻量部署、给客户解释原理时都能派上大用场。
为何常见:因为课程和论文都在追逐 SOTA 模型,给人一种“旧方法已死”的错觉。
误区OCR 模型效果不好就加数据,把网上能爬到的图片全塞进去训练,认为数量到了质量自然到位。
正解数据质量比数量更关键。如果标注框不准、文字标签有误,模型学到的也是错误映射;如果训练集全是印刷体,部署到车牌场景照样崩。正确做法是让数据分布贴近目标场景,做清洗和人工抽检,再通过数据增强(旋转、加噪、透视变换)扩大覆盖面。这好比让考古学徒临摹字帖:临摹一万遍错别字,只会把错的记得更牢。
为何常见:深度学习“大力出奇迹”的形象深入人心,让人误以为数据量是唯一决定因素。
误区一提到 OCR 就想到几亿参数的 Transformer,认为离线跑不动、部署成本高,小团队根本玩不起。
正解OCR 场景里“模型大小”是弹性的。对清晰印刷体,一个轻量 CRNN 在 CPU 上也能实时推理;对复杂场景再上大模型或云端 API。工程上更多是在精度和延迟之间找平衡:先量化、剪枝,再考虑知识蒸馏,把大模型浓缩成小模型,端侧照样能跑。就像考古队会根据遗址规模决定带多少人,而不是每次都拉一支千人大队。
为何常见:因为论文和新闻总在报道大模型,让人忽略了工业界大量部署的是轻量模型。
面试题
Q1. OCR(光学字符识别)的两个核心步骤是什么?
- A.图像压缩和格式转换
- B.文字检测和文字识别← 正确答案
- C.目标跟踪和目标分类
- D.灰度化和彩色化
答案:B。OCR 的本质是“先找字、再认字”,对应文字检测和文字识别。A 属于图像处理但不是 OCR 核心,C 是视觉的其他任务,D 只是预处理中的一小步,不构成完整流程。
Q2. 二值化处理后的输出是什么?
- A.三通道 RGB 彩色图像
- B.只有黑白的二值图像← 正确答案
- C.灰度值连续的灰度图
- D.带透明通道的 PNG 图
答案:B。二值化把每个像素和阈值比较后标成 0 或 1(黑或白),输出的是只有两种颜色的图像。A 仍包含三通道颜色,C 还保留 0-255 的灰度级,D 涉及透明通道,都与二值化无关。
Q3. 下列哪些属于 OCR 的典型应用场景?
- A.文档数字化← 正确答案
- B.车牌识别← 正确答案
- C.人脸解锁
- D.票据识别← 正确答案
答案:ABD。文档数字化、车牌识别、票据识别都涉及“从图像中读出文字”,属于 OCR 范畴。人脸解锁依赖人脸关键点而非文字,属于人脸识别任务,和 OCR 无关。
Q4. IoU(交并比)在文字检测中的作用是?
- A.衡量预测框与真实框重叠程度← 正确答案
- B.计算图像像素总数量
- C.判断文字是否发生倾斜
- D.衡量不同字符间的相似度
答案:A。IoU 计算预测框与真实框的交集面积除以并集面积,数值越接近 1 说明框定得越准。B 是分辨率问题,C 是倾斜校正的目标,D 是字符识别中的相似度度量,都与检测框评估无关。
Q5. 垂直投影法在 OCR 传统流程中主要用于什么?
- A.切分字符的左右边界← 正确答案
- B.去除图像噪声
- C.增强文字与背景对比度
- D.训练神经网络参数
答案:A。垂直投影按列累加像素值,空白列累加为 0,连续非零列的区间就是字符的左右边界,因此常用来切分字符。B、C 属于预处理手段,D 是模型训练阶段的任务。
Q6. 关于 CRNN 架构,下列说法正确的是?
- A.用 CNN 提取图像特征← 正确答案
- B.用 RNN 建模字符序列← 正确答案
- C.训练过程不需要任何数据
- D.可以实现端到端学习← 正确答案
答案:ABD。CRNN 由 CNN 提取视觉特征、RNN 建模序列关系,输入图像直接输出文本,属于端到端模型。但它和所有深度学习模型一样,必须有标注数据训练,所以 C 错误。
Q7. 精确率(Precision)的计算公式是?
- A.TP / (TP + FP)← 正确答案
- B.TP / (TP + FN)
- C.FP / (FP + TN)
- D.TN / (TN + FP)
答案:A。精确率 = 真阳性除以所有预测为阳性的数量,即 TP/(TP+FP),衡量模型报出的结果里有多少是真字。B 是召回率,C、D 与错误率相关,都不符合定义。
Q8. CTC 解码时,把帧级路径还原为目标文本的规则是?
- A.合并重复字符并删除空白符← 正确答案
- B.按字典顺序重排所有字符
- C.随机丢弃概率偏低的帧
- D.仅保留每帧预测的末位字符
答案:A。CTC 通过“合并连续重复字符、删除空白符号”把一长串逐帧预测压缩成文本。比如路径 “A_AA_B“ 会被还原成 ”AB”。B、C、D 都不会产生有意义的目标文本。
Q9. 相比深度学习方法,传统 OCR 的劣势有哪些?
- A.对字体变化鲁棒性较弱← 正确答案
- B.需要大量手工特征工程← 正确答案
- C.完全没有实用价值可言
- D.对复杂背景适应能力差← 正确答案
答案:ABD。传统方法依赖人工设计的模板与特征,遇到新字体或复杂背景容易失效,因此 A、D 正确;特征工程全靠手工完成,B 也正确。但它计算量小、可解释性强,仍适用于点阵字符等固定场景,不能说完全没有实用价值,C 错误。
Q10. 图像预处理中倾斜校正的根本目的是什么?
- A.让文字区域接近水平以提高后续识别稳定度← 正确答案
- B.让图片颜色更鲜艳
- C.缩小图片体积以加快传输
- D.彻底消除所有噪声使图像绝对干净
答案:A。拍摄角度会让文字行倾斜,检测和识别模型对水平文字最稳,因此倾斜校正通过旋转把文字摆正。B、C 与颜色和体积无关,D 不切实际——预处理只能降低噪声,无法做到“绝对干净”。