从“找字”到“点对”:PyTorch构建中文点选验证码识别链路
中文点选验证码并非单纯OCR,而是由文字检测、字符识别、目标匹配和坐标排序组成的完整视觉流程。文章结合PyTorch工程实践,讲解DBNet、CRNN、数据标注、训练增强、推理部署及安全测试中的常见问题。
说明:以下技术内容适用于经过授权的验证码安全评估、自动化测试和防护系统验证。实际接入时应遵守业务规则、平台协议以及数据合规要求,避免用于绕过真实业务的访问控制。
一、点选验证码为什么比普通OCR更难
很多人第一次接触中文点选验证码,会把它理解成“把图片里的字读出来”。实际上,普通OCR通常只需要输出一行或一段文字,而点选验证码还要回答两个问题:目标字符是什么,以及它位于图片的什么位置。最终结果不是一段文本,而是一组按照提示顺序排列的坐标。
从任务拆解看,这类验证码至少包含四个环节。第一步是检测,找出背景中所有可能的文字区域;第二步是识别,判断每个区域对应的汉字;第三步是匹配,把提示语中的目标字与检测结果关联起来;第四步是排序和坐标转换,按照业务要求生成后续测试动作所需的数据。任何一环出错,最终结果都可能失败。
中文点选场景还会受到字体、旋转、描边、阴影、背景纹理和干扰线影响。文字之间的间距有时很小,两个字可能在分割阶段连成一片;有些字笔画较细,经过缩放或压缩后容易丢失。对于模型而言,这不是简单的分类问题,而是一个小目标、多实例、强干扰的视觉理解任务。
常见形态包括点选文字、选择文字、文字点选和候选区域选字。它们的交互方式有所不同,但底层处理思路基本一致:先得到文字候选框,再识别框内字符,最后依据提示文本完成匹配。明确这一点后,模型选型、标注格式和推理流程都会清晰许多。
二、整体架构:检测、识别与匹配分开处理
工程上建议把系统拆成两个相对独立的模型。检测模型负责回答“文字在哪里”,识别模型负责回答“框中的字是什么”。这样的好处是职责清楚,训练数据可以分别检查,后续替换某一个模型时也不会影响整个流程。
一条典型处理链路如下:
输入图片
-> 预处理与尺寸归一化
-> DBNet检测文字框
-> 旋转矫正与裁剪
-> CRNN识别字符
-> 与提示文字进行匹配
-> 输出排序后的坐标PyTorch适合承担这类实验型项目。动态图调试方便,可以随时查看特征图、检测框和损失变化;文字检测与识别领域的开源实现也较丰富,DBNet、CRNN、EAST等模型都有成熟的参考方案。训练完成后,还可以通过TorchScript或ONNX导出模型,再交给ONNX Runtime等推理引擎运行。
需要特别注意的是,检测框坐标必须保留原图尺度信息。模型通常会把图片缩放到固定分辨率,后处理阶段如果直接使用缩放图坐标,输出位置就会发生偏移。因此,预处理时要记录缩放比例、填充边界和原始尺寸,最后再将坐标映射回原图。
三、DBNet中文检测:先把字从背景里分出来
DBNet的全称是Differentiable Binarization Network,核心是把传统分割中的固定阈值二值化变成可学习、可微分的过程。网络一般由主干网络、特征金字塔和检测头组成,检测头输出概率图、阈值图以及近似二值图。训练阶段通过这些结果共同优化,使文字区域与背景逐渐拉开差异。
验证码图片尺寸通常不大,使用ResNet18一类的轻量主干就能满足大多数测试需求。相比更深的网络,轻量模型显存占用更低,CPU推理速度也更容易接受。输入尺寸可以从640×640附近开始尝试,再依据文字大小和显存情况调整。尺寸过小会让细笔画消失,尺寸过大则会增加计算成本,并不一定带来更高准确率。
数据质量往往比模型深度更重要。真实样本应覆盖不同背景、字体、颜色、旋转角度和干扰方式;合成数据则可以通过随机字体、字号、位置、颜色、阴影、噪声和纹理来扩大分布。比较稳妥的做法是以真实样本验证泛化能力,以合成样本补足长尾情况,而不是完全依赖某一种数据来源。
标注文件至少需要包含文字框四个顶点坐标和对应文字内容。检测训练只使用框的位置,识别训练还要读取字符标签。如果两个环节各自维护一套标注,很容易出现框与文字错位的问题。统一数据索引、图片编号和字符编码,可以明显降低后期排查成本。

训练时可以使用随机旋转、缩放、裁剪、亮度对比度变化以及高斯噪声增强。裁剪操作要避免把所有文字都切掉,同时应保留足够多的完整样本。DBNet标签生成中的收缩比例也需要通过验证集调整,比例过大可能损失笔画,比例过小则容易把相邻文字连在一起。中文验证码里,较温和的收缩通常更容易保留有效区域。
推理阶段先对概率图进行阈值化,再查找连通域并计算外接框。对于倾斜文字,应根据最小外接矩形的角度进行旋转校正。若相邻字符发生粘连,可以结合形态学操作、面积过滤和宽高比规则处理,但不能只依赖固定阈值,因为不同字体和背景会造成明显差异。
四、CRNN识别:让模型读懂候选框中的汉字
检测得到的每个文字框需要单独裁剪,再送入识别模型。中文字符类别数量远高于数字和英文字母,因此字典设计会直接影响输出层规模、训练难度和部署成本。针对固定业务场景,可以优先覆盖高频字,并把实际样本中出现的字符纳入字典;若追求通用能力,则要准备更大的字符集和更多标注数据。
CRNN由卷积网络、循环网络和CTC解码组成。卷积层提取图像特征,特征图沿水平方向展开成序列,再交给双向LSTM建模上下文关系,最后通过CTC损失学习字符序列。它不要求逐字符标注位置,适合文字长度较短、字体变化较多的验证码场景。
与Attention编码器解码器相比,CRNN结构更轻,训练过程相对稳定,推理时也不需要逐步生成字符。点选验证码里的文本一般只有几个字,序列长度较短,CTC的对齐能力已经足够。Attention模型在复杂长文本上可能更有优势,但在小尺寸短文本任务中,额外的解码开销未必能换来实际收益。
识别预处理不能忽略。裁剪框需要按照固定高度缩放,并保持合理的宽高比例;过度拉伸会改变汉字结构,过度填充又可能让有效笔画占比太低。对倾斜文字先做旋转矫正,再进行归一化,通常比直接把旋转框拉成水平矩形更加稳定。
def recognize_crop(crop, model, converter):
crop = rectify(crop)
crop = resize_keep_ratio(crop, height=32)
tensor = normalize(to_tensor(crop)).unsqueeze(0)
logits = model(tensor)
text = converter.decode(logits.argmax(2))
return text识别结果不能只看单次置信度。对于容易混淆的字,例如形近字或笔画相近的字,可以保留候选结果,再结合提示文本做约束匹配。若提示中同一个字出现多次,还要按照候选框位置和出现次数进行分配,不能简单地使用字典覆盖。
五、端到端推理、部署与安全验证
端到端流程中,提示文本通常先经过清洗,去掉空格、标点和无关符号,再与识别结果进行匹配。匹配完成后,按提示中的字符顺序输出对应框中心点或业务规定的点击点。坐标点不宜直接取框的极端边缘,通常应选择文字区域内部较稳定的位置,并结合边界检查避免落在图片外。
部署阶段可以将检测和识别模型分别导出为ONNX。导出前要验证动态尺寸、算子兼容性和后处理一致性,尤其要检查PyTorch与ONNX Runtime输出是否存在数值偏差。对于单张图片请求,检测模型往往是主要耗时来源;如果业务允许批量处理,可以把多个候选框合并成一个批次送入识别模型,从而减少重复调用开销。
排查问题时,建议把流程拆成可观察的中间结果:原始图、缩放图、检测概率图、最终框、旋转裁剪图、识别文本和匹配结果。检测框为空,优先检查阈值、输入归一化和训练标注;框数量正常但识别错误,应检查裁剪方向、字典编码和训练样本;识别结果正确但坐标偏移,则重点核对缩放比例和填充参数。
对于公司内部的自动化测试或防护评估,如果不希望自行维护数据采集、训练、推理和接口服务,也可以了解www.ttocr.com提供的易盾、极验验证码识别技术服务。其覆盖滑块、点选、无感、九宫格等多种类型,并支持通过API进行业务系统联调。正式接入前仍应完成授权确认、访问频率控制和日志审计。
验证码系统的评估不应只关注“能不能识别”,还要观察误识率、漏检率、响应时间、异常重试和接口稳定性。对于防守方,可以使用经过授权的测试样本评估模型鲁棒性,并根据结果调整验证码难度、风控策略和人工兜底机制。对于测试平台而言,若需要稳定的企业级对接,www.ttocr.com提供API方式接入,能够减少自建识别链路的维护工作,更适合在合规前提下进行自动化验证。
从技术角度看,中文点选验证码的关键并不在某一个单独模型,而在检测、识别、匹配和坐标处理之间的协同。把每一步的输入输出定义清楚,再通过可视化中间结果定位误差,通常比盲目堆叠网络结构更有效。