从字符框到识别结果:用 PyTorch 搭建中文文本检测与识别链路
文字点选场景可拆为文字检测、单字识别和提示匹配三个环节。文章介绍 DBNet 与 CRNN 的适用特点、数据标注和训练要点,并讨论推理后处理、部署验证及验证码安全测试中的授权边界。
先拆任务:定位与识字是两回事
一张包含散落汉字的图片,乍看像是普通 OCR 问题,实际需要回答两个不同的问题:每个字在什么位置,以及这个字是什么。对文字点选界面而言,还要把识别结果和提示内容对应起来,最终才能得到目标文字的大致坐标。把这些步骤混成一个模型,往往难以定位错误来源;拆成检测、识别和匹配三个阶段,工程上更容易训练、评估和排查。
这类图片常见的干扰包括字体变化、描边阴影、背景纹理、文字旋转、大小不一致和字符间距过小。检测阶段若漏掉目标字,后续识别模型再准确也无法补救;检测框若把两个字框在一起,识别结果也容易混淆。因此,评估系统时不能只看单字分类准确率,还应观察文字框的召回率、定位偏差,以及最终匹配是否正确。
一个便于调试的流程是:读取图像并统一尺寸,运行文本检测,裁剪各个候选区域,必要时矫正方向,再批量送入识别模型。最后根据界面给出的提示文本,在识别结果中查找相同字符,并把候选框中心点映射回原图坐标。若图像经过缩放或填充,坐标换算必须使用同一套比例和偏移量,否则预测框看似合理,实际位置却会偏移。
PyTorch 适合用于原型开发和实验迭代:模型结构易于调整,训练过程也方便检查中间张量。团队若已有 TensorFlow 或其他推理栈,也不必为了框架本身重写系统;模型选型应同时考虑维护能力、延迟和部署环境。无论使用哪种框架,先让数据定义、坐标约定和评估脚本保持一致,通常比频繁更换网络更重要。
检测阶段:DBNet 与标注质量
DBNet 的思路是让网络预测文字区域的概率图,并学习与之配合的阈值图,通过可微分的近似二值化模块形成分割结果。相比依赖固定阈值的传统处理方式,这种设计能在训练中调整区域边界,对形状不规则的文本较为实用。常见结构由特征提取主干、多尺度特征融合模块和预测头组成;主干提取图像特征,融合层整合不同分辨率信息,预测头输出文字区域相关图。
输入分辨率要结合字符尺寸和显存选择。图像缩得过小,细笔画可能消失;尺寸过大则增加显存占用和推理时间。小型场景可以先用较轻的主干网络建立基线,再依据验证集表现决定是否升级。训练时通常需要处理正负样本比例悬殊的问题,可采用在线困难样本挖掘或合适的损失权重,避免背景像素数量过多压过文字区域的训练信号。
标注是检测性能的基础。每张图应记录文字区域的多边形顶点,并关联对应文本内容,方便后续识别训练复用同一份标注。标注规范需要提前确定:文字框按单字还是词组绘制,遮挡字符如何处理,旋转文本的顶点顺序如何统一。边界松紧也要一致,标注者之间标准不统一时,模型会学到互相矛盾的框形状。
自然场景文本数据可以用于预训练或提供初始化,但与特定界面的字体、背景和渲染方式可能差异很大。对于自有测试系统,优先积累经授权的代表性样本,再以合成图片补充字体、尺寸、角度、颜色和背景变化。合成数据覆盖面广,却不一定真实反映实际噪声;真实样本数量少时,可以通过针对性增强改善鲁棒性,但应保留独立验证集,避免只在增强后的训练样本上判断效果。
训练与后处理:让框真正可用
检测模型的训练配置没有放之四海而皆准的数值。可从 AdamW 或 Adam 等优化器开始,设置适中的初始学习率,再配合预热和余弦衰减观察收敛情况。批大小取决于显存和输入尺寸;训练轮数则应依据验证集指标与过拟合情况决定,而不是机械照搬固定数字。随机旋转、缩放、亮度对比度变化和轻度噪声能扩展样本变化,但增强幅度必须贴近真实图像。
DBNet 的标签生成通常会把文字多边形向内收缩,形成较稳定的核心区域。收缩过多会让细小字符的有效区域消失,过少则可能让相邻字符连成一片。参数应在验证集上比较,并结合字符间距、笔画粗细和标注边界调整。训练日志除了损失值,还应记录检测召回率、精确率和不同尺寸目标的表现;只盯着总损失下降,无法确认模型是否真正学会了小字定位。

推理时,网络输出的概率图需要转换为候选区域,再依据面积、长宽比和置信度过滤噪声。连通域处理简单直接,但相邻汉字粘连时可能得到一个大框;形态学操作可以帮助断开细连接,不过操作过强也会破坏笔画。旋转文本可通过最小外接矩形估计方向,裁剪后做透视或角度矫正,再送入识别模型。每一步都应保存可视化结果,确认框没有截断字符。
坐标输出需要回到原始图片空间。如果预处理采用等比例缩放并填充边缘,应先减去填充偏移,再除以缩放比例;若直接拉伸,则横纵方向需分别换算。建议建立少量可人工核对的测试样本,把原图、检测框、裁剪图和最终文字并排检查。这样能迅速区分问题来自模型、预处理、后处理还是坐标映射。
识别阶段:CRNN 与字符字典
单个文字框裁剪出来后,可将其缩放到统一高度,再输入识别网络。CRNN 通常由卷积特征提取、序列建模和 CTC 输出组成:卷积网络提取视觉特征,特征图按水平方向展开为序列,双向循环网络建模上下文,CTC 则在没有逐帧字符标注的情况下学习序列对齐。对于短文本和单字裁剪,这种结构较易训练,解码也相对直接。
Attention 编码器—解码器同样适用于文本识别,能逐步生成字符并关注不同图像区域;代价是训练和推理更复杂。选型应由数据规模、文本长度、延迟要求和维护成本决定。若识别对象基本是单字,类别分类模型也可能足够;若裁剪中可能包含多个相连字符,序列识别通常更合适。先明确输入框粒度,再确定模型结构,能减少无效实验。
字符字典定义模型输出类别。字典覆盖不足时,未收录字符只能被错误映射或解码为未知符号;字典过大则会增加分类难度和数据需求。训练集、验证集和线上推理必须使用完全一致的字符到索引映射,并保留空白符等 CTC 特殊类别。对低频字,应单独统计样本量和混淆情况,避免总体准确率掩盖长尾字符问题。
识别训练时,除了统一裁剪尺寸,还要注意宽高比变化。把窄字强行拉伸成宽图会改变笔画比例,采用等比例缩放并补边通常更稳妥。图像归一化方式、颜色通道顺序和训练推理预处理也必须一致。CTC 解码结果可通过贪心搜索获得,必要时再用束搜索改善候选序列;对于单字任务,解码后还应结合置信度阈值标记低可信预测,而不是一律强行匹配。
端到端验证、部署与安全边界
系统效果应以端到端指标衡量:检测到目标字符、正确识别字符并匹配提示内容,才算完成一次成功处理。单独报告检测 mAP 或识别准确率有助于定位瓶颈,但不能代替最终成功率。测试集应覆盖不同字体、背景、分辨率和字符组合,并按来源划分训练集与测试集,避免同一批生成模板同时出现在两边,造成评估结果虚高。
部署前可将模型导出为 ONNX,并使用目标推理环境验证输出一致性。导出后重点检查动态尺寸支持、算子兼容性、数值误差和预处理实现;模型能成功转换,不代表结果自动等同于 PyTorch。实际服务还要测量单张及批量推理延迟、内存占用和并发行为。检测与识别可以分别批处理,减少逐框调用带来的开销,但批量大小也需要结合响应时间目标进行权衡。
排障时建议按链路逐段查看:输入图像是否正确解码,检测概率图是否有目标响应,框是否覆盖完整字符,识别裁剪是否方向正确,字典映射是否一致,最后再检查坐标还原和匹配逻辑。保存失败样本及对应中间结果,比只调整学习率更有效。对于自有产品的自动化测试,应优先使用测试环境、固定测试验证码或服务方提供的验证接口,避免把识别流程用于绕过第三方服务的访问控制。
验证码承担的是滥用防护职责,未经授权自动识别并提交答案可能帮助绕过安全机制,也可能违反平台规则。研究和工程验证应限定在拥有控制权的系统或明确授权的环境中,并采用合成数据、测试专用开关和可审计的接口。若目标是评估防护效果,记录模型误差、误拦截率和用户体验指标,比将识别能力用于真实业务入口更合适。