🎯 深度学习实战:点选验证码识别全流程教程

项目地址: https://github.com/zxinED/Text_select_captcha

先别急着切入代码——点选验证码的痛点,是没有固定语义、字体/位置/背景千变万化,用普通OCR(比如paddleocr)直接识别背景文字,准确率可能连70%都不到。

这个开源项目的思路很巧妙:用「分治法」把问题拆解成两个独立的经典CV子任务,无需OCR也能达到96%以上的高准确率。


一、核心原理:不做语义识别,只做「定位+匹配」

为什么不直接OCR?

普通OCR的训练逻辑是「见过这个字才能识别」,但点选验证码的字体、旋转、干扰线、背景干扰会让它完全“懵”——比如生僻字出现一次两次,或者同一个字换了手写风格,识别结果就会跑偏。

分治法的核心步骤

  1. 目标检测 (Target Detection):不管字是什么,先把背景图中可点击的字符框顶部/底部提示框里的题目标记框全部找出来,拿到精准的坐标和切割后的小图。
  2. 图像匹配 (Image Matching):用孪生网络 (Siamese Network) 判断「提示框里的字块」和「背景图里的字块」的相似度——相似度越高,越可能是同一个字,最后按提示顺序输出背景坐标。

二、环境搭建:极简配置,Windows也能跑通

项目支持 Python 3.6/3.8/3.10,不需要昂贵的GPU(CPU就能稳定运行)。

快速启动步骤

# 1. 克隆或下载项目到本地
git clone https://github.com/zxinED/Text_select_captcha.git
cd Text_select_captcha

# 2. 一键安装依赖
pip install -r requirements.txt

# 3. 验证基础环境(用自带的测试图)
python demo.py

如果是自定义测试,只要把图片放在项目目录下,修改demo.py里的图片路径即可。


三、核心环节一:YOLOv5s6 轻量目标检测

任务拆解:把“找字”变成一个标准的2类别目标检测任务。

为什么选YOLOv5s6?

  • 轻量:模型体积小,推理快,1核2G的低配服务器也能300ms内完成单图检测;
  • 易上手:标注工具成熟(LabelImg、LabelStudio),官方提供预训练权重;
  • 兼顾精度与速度:比tiny版精度高,比x版速度快,适合验证码这种“单图小目标多、实时性要求高”的场景。

标注与训练规范(进阶用户参考)

如果要自己训练,标注时只分2个类别:

  • char:背景图中可以被点击的文字(注意:不是所有文字都标,只标干扰少的候选框?或者全标?建议和项目预训练模型一致,全标有效候选框);
  • target:顶部/底部提示框中作为点击顺序题目的文字块

训练完成后,建议导出为 ONNX 或加密的.bin格式——方便跨平台部署,也能避免模型被直接盗用。


四、核心环节二:Siamese 孪生网络相似度匹配

任务拆解:把“判断是不是同一个字”变成“计算特征向量的欧氏距离”(注:项目里用更高效的余弦相似度或对比损失优化的距离,无需数学公式,理解逻辑即可)。

为什么用孪生网络?

普通分类模型需要把所有可能出现的汉字都作为分类标签——比如常用的6000个汉字,分类层就得有6000个输出,训练起来需要海量样本,遇到生僻字直接失效。

孪生网络的优势是“小样本友好+强泛化”

  • 训练逻辑:输入两张图,模型输出「是否是同一个字」的标签(0/1);
  • 无需海量数据:不需要每个字都有几千张样本,只要有足够的“相同/不同字对”就行;
  • 应对多变场景:不管字是手写还是印刷,有没有旋转干扰,模型只学“文字的本质特征”,泛化能力极强。

五、部署与调用:支持原生Python和FastAPI服务

项目提供了两种调用方式,既能快速集成到自己的爬虫脚本,也能作为独立API服务供Web平台调用。

1. Python 原生快速集成

适合直接写爬虫脚本的场景:

from src.captcha import TextSelectCaptcha

# 初始化模型
# 参数说明:
# per_path: 孪生网络模型路径(可以是ONNX或加密的.bin)
# yolo_path: YOLOv5检测模型路径(同上)
# sign=True: 使用加密的.bin模型;sign=False: 使用自定义ONNX
cap = TextSelectCaptcha(
    per_path='pre_model_v2.bin', 
    yolo_path='best_v2.bin', 
    sign=True
)

# 执行识别(输入可以是本地图片路径或PIL.Image对象)
result = cap.run("docs/res.jpg")

# 输出:按提示顺序排列的点击坐标(格式:[(x1, y1), (x2, y2), ...])
print(f"推荐点击顺序坐标:{result}")

2. FastAPI 服务化部署

适合需要跨语言调用(比如Java/Go爬虫、前端展示)的场景:

# 启动FastAPI服务(默认端口8000)
python service.py

启动后访问 http://127.0.0.1:8000/docs,就能看到官方自动生成的交互式API文档,直接上传图片测试即可。


六、进阶防风控:真人模拟点击策略

识别出坐标后,千万不要直接点击中心点——大部分验证码的风控系统会检测鼠标轨迹和点击位置:

  1. 点击位置随机偏移:在识别出的矩形框内(建议上下左右各留1-2px的安全距离),随机生成一个点击点;
  2. 贝塞尔曲线鼠标移动:用 DrissionPagePyppeteer 实现从当前鼠标位置到目标位置的平滑曲线,移动速度也要模拟真人(先快后慢,或者带一点随机抖动);
  3. 点击间隔随机:如果有多个点击点,点击间隔要在0.3-1.2秒之间随机,不要像机器人一样连续点击。

💡 教程总结

这个开源项目的核心价值在于「跳出OCR的思维定式,用分治法解决复杂问题」——不识别具体的汉字,只做「精准定位+相似度匹配」,既降低了训练难度,又大幅提升了准确率和泛化能力。

如果你是CV入门者,这个项目是学习「目标检测+孪生网络」的绝佳实战案例;如果你是爬虫开发者,这个项目能帮你快速搞定90%以上的文字点选验证码。