YOLO11图标点选验证码识别实战

发布时间:2026/10/3 12:53:26
YOLO11图标点选验证码识别实战 保姆级实战YOLO11 训练图标点选验证码识别模型附数据集与模型图标点选验证码靠传统图像处理很难做稳背景纹理复杂、图标带旋转缩放、还会不时换一批新图标。本文带你用YOLO11m训练一个单类别图标检测模型yolo11m.pt→best.pt再配合剪影模板匹配跑通检测图标 → 匹配目标 → 输出点击坐标的完整链路。适合有 Python 基础、想入门验证码识别/目标检测实战的同学。资源下载数据集 yolo11m.pt预训练权重 训练好的best.pt 测试图通过网盘分享的知识验证码链接: https://pan.baidu.com/s/5iKcZQL-qR1a0yvJcs_91Bw–来自百度网盘超级会员v5的分享⚠️合规声明本文内容仅用于图像识别技术学习与研究请勿将验证码识别用于任何违反目标网站服务协议或法律法规的用途刷量、抢购、批量注册等风险自负。一、图标点选验证码长什么样先看清敌人先看要解决的具体问题。这类验证码的典型形态是一张300×150左右的背景图真实照片纹理干扰较强上面散布 4~6 个白色剪影风格小图标礼物盒、挂锁、风车、数据线……带轻微旋转、缩放和透视顶部提示区给出目标图标120×120 的透明底剪影图要求点击图中所有与目标相同的图标。(该部分不参与模型训练模型训练好后需要用该目标与模型检测出来的目标进行匹配验证用什么方法匹配代码需要自己编写网盘里有模型只做目标检测)我们的测试样例与模型检测效果红框 序号为模型输出测试输出 0: 320x640 5 icons, 352.6ms Speed: 9.7ms preprocess, 352.6ms inference, 13.7ms postprocess per image at shape (1, 3, 320, 640) 模板 0.png - 目标框 0 (相似度: 0.72) - 坐标: [39, 102] 模板 1.png - 目标框 3 (相似度: 0.93) - 坐标: [81, 55] 模板 2.png - 目标框 4 (相似度: 0.77) - 坐标: [127, 109] 模板 3.png - 目标框 1 (相似度: 0.66) - 坐标: [163, 68] 匹配完成结果已保存至: ./ceshi\result_112.png 最终生成的点击坐标顺序列表为: [[39, 102], [81, 55], [127, 109], [163, 68]]整体思路检测 匹配两段式一个常见的设计误区是把每个图标种类都建成一个 YOLO 类别。本文的选择是YOLO 只做一件事——把图标从复杂背景里框出来哪个图标是目标交给模板匹配。验证码原图YOLO11 best.pt单类别 icon 检测裁剪每个候选图标目标图标 PNG透明底剪影剪影模板匹配输出匹配图标的中心点坐标 点击位置为什么这样拆见下一节。二、数据集设计为什么只建一个类别2.1 目录结构与配置数据集是标准 YOLO 目标检测格式从网盘下载后目录如下图标点选验证码/ ├── data.yaml # 数据集配置 ├── dataset/ │ ├── images/ │ │ ├── train/ # 99 张训练图 │ │ └── val/ # 12 张验证图 │ ├── labels/ │ │ ├── train/ # 与图片同名的 .txt 标注 │ │ └── val/ │ └── candidates/ # 111 个图标模板库每类一个文件夹 │ ├── 0/0.png 1.png ... │ └── 110/... └── ceshi/ # 测试验证码图 目标图标 检测结果图data.yaml内容非常简洁——只有一个类别path:dataset/train:images/trainval:images/valnc:1names:[icon]标注文件是标准 YOLO 格式类别id 中心x 中心y 宽 高均归一化到 0~1# labels/train/0.txt一张图 5 个图标 0 0.105000 0.453333 0.150000 0.306667 0 0.223333 0.733333 0.153333 0.306667 0 0.410000 0.440000 0.153333 0.293333 0 0.631667 0.503333 0.163333 0.313333 0 0.851667 0.493333 0.163333 0.3200002.2 关键决策nc1 的三个理由维度每种图标一个类别nc111单类别 icon本文方案标注成本每种图标都要单独标新图标上线就要重新标只框是个图标标注快一个数量级数据量要求111 类平摊到 99 张图多数类别只有几个样本训练必翻车单类别 99 张图足够收敛泛化能力没见过的新图标识别不了换新图标库也能检出只补模板库即可分类这件事模板匹配用几行 OpenCV 就能高质量完成图标是标准剪影图形状特征极其稳定没必要让神经网络又当裁判又当运动员。这就是问题 → 分析 → 结论检测交给 YOLO 解决背景干扰问题分类交给模板匹配解决换图标库问题两边各干各的擅长事。【图candidates 图标模板库截图透明底剪影图建议放一张】 顺带一提candidates/里 111 个文件夹就是图标模板库每个图标都是 120×120 透明底 PNG。真正参与匹配目标这一步的其实只需要验证码顶部提示的那一张目标图。三、训练从 yolo11m.pt 到 best.pt含环境安装3.1 环境安装# 建议 Python 3.9CUDA 版 torch 按官网命令安装pipinstallultralytics-U# 验证安装python-cimport ultralytics; print(ultralytics.__version__)# 预期输出8.3.x3.2 训练脚本fromultralyticsimportYOLO# 加载官方预训练权重首次运行会自动下载网盘里也备了一份modelYOLO(yolo11m.pt)model.train(datadata.yaml,epochs150,imgsz320,# 关键验证码只有 300x150图标约 45~50px# 用 640 纯属浪费算力320 正合适batch16,patience30,# 早停小数据集 30 个 epoch 无提升就停防过拟合device0,# 无 GPU 改成 devicecpu建议还是借一张卡)预期运行结果控制台逐 epoch 输出box_loss/cls_loss/dfl_loss与 mAP50训练结束后在runs/detect/train/生成results.png损失与 mAP 曲线、confusion_matrix.png权重保存在runs/detect/train/weights/best.pt和last.pt。【图训练完成后 runs/detect/train/results.png 训练曲线截图建议放一张】为什么选 yolo11m 而不是 n/s单类别小图 n/s 也能跑起来但图标剪影在纹理背景上对比度不稳定m 的特征提取能力明显更稳且推理阶段一次只处理一张 300×150 的小图m 的参数量完全不构成瓶颈。3.3 验证与单图推理fromultralyticsimportYOLO modelYOLO(runs/detect/train/weights/best.pt)# 1) 验证集评估metricsmodel.val()print(mAP50:,metrics.box.map50)# 预期输出99 张训练量的单类别任务mAP50 通常能到 0.95 以上# 2) 单图推理并保存可视化结果model.predict(sourceceshi/112.png,conf0.5,saveTrue)# 结果保存在 runs/detect/predict/ 下即第一节的效果图四、推理实战YOLO 检测 剪影模板匹配这一步是很多同类教程缺掉的最后一公里检测出框只是半成品要判断哪个框是目标图标并输出点击坐标。思路目标图标是透明底剪影 PNGalpha 通道就是天然的标准模板验证码里裁出的候选图标用 Otsu 自适应阈值二值化提取剪影两个掩膜缩放到同一尺寸后算 IoU 相似度即可。完整代码importcv2importnumpyasnpdefsilhouette_from_crop(img_bgr:np.ndarray)-np.ndarray:从验证码裁剪图中提取图标剪影掩膜Otsu 二值化graycv2.cvtColor(img_bgr,cv2.COLOR_BGR2GRAY)_,maskcv2.threshold(gray,0,255,cv2.THRESH_BINARYcv2.THRESH_OTSU)returnmaskdefsilhouette_from_target(png_path:str)-np.ndarray:目标图标是透明底 PNG直接取 alpha 通道当掩膜rgbacv2.imread(png_path,cv2.IMREAD_UNCHANGED)return(rgba[:,:,3]0).astype(np.uint8)*255defmask_iou(m1:np.ndarray,m2:np.ndarray,size(64,64))-float:缩放到统一尺寸后计算两个掩膜的 IoUacv2.resize(m1,size)127bcv2.resize(m2,size)127internp.logical_and(a,b).sum()unionnp.logical_or(a,b).sum()returninter/unionifunionelse0.0defsolve(captcha_path:str,target_path:str,model,conf0.4,thr0.55):返回目标图标在验证码中的中心点坐标列表即点击坐标targetsilhouette_from_target(target_path)imgcv2.imread(captcha_path)resultmodel.predict(img,confconf,verboseFalse)[0]points[]forboxinresult.boxes:x1,y1,x2,y2map(int,box.xyxy[0])cropimg[y1:y2,x1:x2]masksilhouette_from_crop(crop)# 关键细节Otsu 的前背景极性可能颠倒图标比背景亮或暗# 正反掩膜各算一次 IoU 取大者一行代码救活大量误判ioumax(mask_iou(mask,target),mask_iou(255-mask,target))ifiouthr:points.append({xy:((x1x2)//2,(y1y2)//2),score:round(iou,3)})returnpointsif__name____main__:fromultralyticsimportYOLO modelYOLO(best.pt)clickssolve(ceshi/112.png,ceshi/0.png,model)print(clicks)# 预期输出示例# [{xy: (34, 69), score: 0.81}, {xy: (182, 47), score: 0.76}]【图solver 运行后把命中坐标画回原图的效果截图建议放一张】几个容易忽略的实现细节都是实测踩出来的掩膜极性问题图标可能是亮色也可能偏暗Otsu 之后前景/背景可能颠倒max(正掩膜 IoU, 反掩膜 IoU)是成本最低的兜底透明背景要用 alpha 而不是二值化目标 PNG 的黑色部分其实是透明的直接读成灰度图会把整个图当成全黑IMREAD_UNCHANGED alpha 通道才正确conf别设太高0.4 左右配合模板匹配的thr过滤比单靠高 conf 漏检率低得多——YOLO 负责宁滥勿缺匹配负责去伪存真。五、常见问题与排错现象原因解决训练启动报找不到图片/警告数量对不上网盘下载解压后有*.png.baiduyun.uploading残留百度网盘客户端没传完的临时文件数据集里有 18 个全局搜索.baiduyun.uploading删掉即可显存不足 CUDA out of memorym 模型 batch 偏大batch8或换yolo11s.pt再不行降imgsz256mAP 很高但实际漏检conf 阈值过高、验证集太小看不出预测时conf0.4以下交给模板匹配过滤检测框位置整体偏移训练/推理imgsz差异过大训练与推理统一imgsz320匹配 IoU 全都低于阈值目标图读了灰度而非 alpha确认用IMREAD_UNCHANGED读取 PNG换了新图标库后识别变差只影响模板匹配不影响检测向candidates/补充新图标模板即可无需重新训练总结回顾这篇实战能带走的东西两段式建模单类别 YOLO 检测解决从背景里找图标 剪影模板匹配解决哪个是目标比多类别建模省一个数量级的标注量还天然支持图标库更新小图小数据集的调参常识imgsz贴近原图尺寸320 足够、patience早停防过拟合、99 张图也能把 mAP50 做到 0.95一条完整的推理链路代码检测框 → Otsu 剪影 → alpha 模板 → 掩膜 IoU → 输出点击坐标可直接复用到同形态的其他点选验证码上网盘资源开箱即用数据集、yolo11m.pt、训练好的best.pt都在文首链接里下载后删掉.baiduyun.uploading残留即可复现全流程。适用边界与时效本文方案适用于剪影/扁平风格的图标点选验证码如果图标带复杂纹理、强变形模板匹配的 IoU 阈值需要放宽或换用特征匹配ORB/SIFT乃至小型分类网络若验证码要求按提示顺序点击多个不同目标把solve()循环调用每个目标即可YOLO11 训练接口在 ultralytics 8.3.x 验证可用后续大版本若 API 变动以官方文档为准。如果对你有帮助点赞收藏关注不迷路 有问题欢迎在评论区交流。标签YOLO11验证码识别目标检测Python实战教程