ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

屏幕目标识别与自动点击:YOLOv5完整实践教程

屏幕目标识别与自动点击:YOLOv5完整实践教程 简介该资源是基于YOLOv5识别算法实现的DNF自动脚本工程面向具备一定Python基础、希望了解目标检测在实际游戏场景中落地的开发者与爱好者。整体围绕“画面识别—逻辑决策—按键模拟”链路组织适合作为计算机视觉项目实战参考。压缩包共94个文件约27.28MB核心为32个Python脚本和34个pyc文件覆盖图像抓取、方向控制、技能识别等模块另有8个YAML模型配置、2个pt权重文件及若干图片、XML标注文件用于模型加载与测试。目前已有177人学习下载。通过该工程读者可获得可运行的YOLOv5推理与自动操作示例包括best.pt模型权重、屏幕截图与按键模拟工具、小型识别脚本以及对应测试截图和配置文件便于快速复现运行也可在此基础上针对其他游戏或场景调整模型与逻辑。 做屏幕目标识别这件事一开始我没想到会这么“坑”。最开始我只是想做一个小工具让电脑自动找到屏幕上某个固定样式的图标并点掉把每天重复几百次的机械操作省下来。试过模板匹配、边缘检测、颜色过滤折腾一圈之后最后稳定跑通的方案是YOLOv5。这篇就是把整套链路——从数据集标注、模型训练、屏幕捕获、坐标映射到自动点击——完完整整拆开讲清楚。无论你是想给办公软件做UI自动化测试还是想研究目标检测在真实屏幕场景下的落地这套思路都能直接参考。先说清楚这类“目标识别自动操作”的技术栈最适合的场景是日常办公自动化、RPA流程、UI自动化测试以及各类辅助开发调试工具。但如果你脑子里的目标是某款在线游戏的自动脚本那我劝你先停一下绝大多数游戏的用户协议都明确禁止这类行为账号一旦被封损失的是自己而且会破坏其他玩家的体验。技术本身是中性的用在哪、怎么用是每个人自己的选择。本文只讨论合法合规的工程实现思路。1. 为什么是YOLOv5屏幕识别场景的选型逻辑1.1 模板匹配方案为什么撑不住我最早用OpenCV的模板匹配来做屏幕定位思路很简单把目标图标保存成一张小图然后在截屏里全图滑动搜索取响应值最高的位置作为点击坐标。在固定窗口、固定缩放比例、纯色背景下这套方案跑得挺欢但一旦界面发生一点变化就露馅。实际会遇到的问题比想象中多第一窗口缩放或DPI变化后图标尺寸变了模板匹配直接失效得准备多尺寸模板第二按钮背景有渐变、阴影、高光模板匹配容易在相似区域产生误检第三界面元素发生部分遮挡时匹配分数会掉到阈值以下第四如果同一屏幕里出现多个相同图标模板匹配经常返回错误的那一个。表面上看是“找个图”但实际上模板匹配对条件的要求非常苛刻不适合真实的多变界面。1.2 YOLOv5在这种场景下的真实优势YOLOv5是端到端的目标检测模型输入整张屏幕截图输出所有目标的位置、类别和置信度。它不要求目标保持固定大小也不要求背景单一模型在训练阶段见过各种“长得像但不是目标”的负样本之后天然具备抗干扰能力。对于屏幕上那些尺寸偏小、特征相对简单的UI图标YOLOv5s这种轻量级权重完全够用。在选型的时候我也对比过YOLOv8和YOLOv6。YOLOv8的Ultralytics生态更好训练接口更现代但YOLOv5的社区资料量最大遇到报错几乎都能搜到解决方案YOLOv6在部分硬件上有性能优势但在工程落地、模型导出、推理框架兼容性上YOLOv5的成熟度明显更高。屏幕识别场景不追求“极致精度”也不需要视频流级别的超低延迟YOLOv5s在GTX 1660级别的显卡上单帧推理大约5-7毫秒完全够用。稳定、资料多、部署省心是我选它的核心原因。2. 数据标注与模型训练最耗时间但最值得投入的环节2.1 环境搭建的版本组合训练环境建议直接用Anaconda建一个独立环境避免和日常开发环境互相污染。我这里用的是Python 3.9 PyTorch 1.13.1 CUDA 11.7的组合YOLOv5仓库版本选的是7.0的release分支整体非常稳定。安装命令很简单conda create -n yolo-screen python3.9 conda activate yolo-screen pip install torch1.13.1cu117 torchvision0.14.1cu117 --extra-index-url https://download.pytorch.org/whl/cu117 git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt这里最容易踩的坑是PyTorch和CUDA版本不匹配如果你机器上的NVIDIA驱动不是特别新建议先跑一句nvidia-smi看驱动的CUDA版本号再决定装哪个版本的PyTorch。装完以后务必执行一次import torch; print(torch.cuda.is_available())确认GPU可用否则后面训练时你会在CPU上慢慢熬。2.2 数据采集和标注截图质量决定模型上限数据是这一步的重中之重。我当时用mss库写了个批量截屏脚本手动操作界面、切换不同窗口状态每切换一个状态就截一张图最终收集了大概800张带目标的屏幕截图。需要注意几点截屏分辨率要覆盖实际使用场景比如目标屏幕是1920x1080就统一在这个分辨率下采集。同一个目标尽量出现在不同位置、不同背景下避免模型把“位置”当成特征。如果界面上目标特别小建议在采集时保持目标最小不低于32x32像素。太小的目标对检测模型来说确实有难度。留出20%左右的负样本——完全不包含目标的截图用来降低误检率。标注工具我用的是LabelImgYOLO格式导出。标注的时候有两条经验一是目标边界框一定要贴着目标边缘宁小勿大框太大的话模型会学到大量背景特征二是类别设计尽量精简如果界面上有“开始按钮”和“停止按钮”两个不同样式的目标建议分成两个类不要都归成一类否则模型很难区分。标注800张图大概花了三四个小时这个过程比较枯燥但属于“磨刀不误砍柴工”。标注质量差后面训练出来的模型一定不准返工成本会更让人崩溃。2.3 训练参数设置与过程观察训练命令我直接沿用了官方推荐的参数只做了少量调整python train.py --img 640 --batch 16 --epochs 200 --data screen.yaml --weights yolov5s.ptscreen.yaml里面配置了训练集和验证集路径以及类别名称和数量。batch大小根据显存调整6GB显存用16比较安全12GB以上可以加到32。epochs设了200但实际上模型在大约100轮之后就收敛了后面主要是观察有没有过拟合。训练过程中要盯着两个关键输出一个是results.png里的train/obj_loss和val/obj_loss如果验证集损失不降反升说明在过拟合需要提前停止另一个是confusion_matrix.png如果某个类别频繁被误检成背景说明标注数据里这个类别的样本不够或标注框质量不行。最终我训练出来的模型在验证集上mAP0.5达到0.97对于这类目标特征明显的UI图标来说这是一个比较理想的水平。2.4 导出推理模型训练完成后直接用官方脚本把权重导出后面推理不需要再依赖训练环境python export.py --weights runs/train/exp/weights/best.pt --include onnx导出ONNX格式的好处是可以脱离PyTorch环境运行后续如果部署到树莓派等边缘设备ONNX还可以再转成OpenVINO或TensorRT格式。如果是纯CPU环境跑ONNX配合onnxruntime推理速度比PyTorch原生快不少。3. 屏幕捕获与坐标映射把识别结果变成“可以点的位置”3.1 从截屏到模型输入这一步是整个链路里最容易出问题的地方。模型训练时输入是640x640的RGB图但实际截屏是1920x1080或者更高不能直接把原始截图丢进模型而是要先把截图缩放到640x640。YOLOv5的推理接口内部会自动做letterbox处理——保持长宽比缩放剩余部分用灰色填充。关键点在于模型输出的目标框坐标是相对于缩放后图像的不是相对于原始屏幕的。所以拿到检测结果后必须做坐标逆变换才能得到真实屏幕坐标。如果跳过这一步直接拿模型输出的坐标去点击点位会整体偏移而且偏移量会随着目标在屏幕上的位置不同而变化。3.2 坐标映射的计算方法用YOLOv5官方detect.py的时候它会自动帮你做好映射并画框输出。但做自动点击脚本需要拿到精确的屏幕坐标所以自己写推理更可控。下面是我用的简版推理与映射逻辑import cv2 import numpy as np import mss import onnxruntime as ort # 加载ONNX模型 session ort.InferenceSession(best.onnx) input_name session.get_inputs()[0].name # 截屏 with mss.mss() as sct: monitor sct.monitors[1] # 主屏幕 screenshot np.array(sct.grab(monitor)) screenshot cv2.cvtColor(screenshot, cv2.COLOR_BGRA2BGR) orig_h, orig_w screenshot.shape[:2] # letterbox 缩放 scale min(640 / orig_w, 640 / orig_h) new_w, new_h int(orig_w * scale), int(orig_h * scale) resized cv2.resize(screenshot, (new_w, new_h)) canvas np.full((640, 640, 3), 114, dtypenp.uint8) canvas[:new_h, :new_w] resized # 推理 input_img canvas[:, :, ::-1].transpose(2, 0, 1).astype(np.float32) / 255.0 input_img np.expand_dims(input_img, axis0) outputs session.run(None, {input_name: input_img}) # 对每个检测框做坐标逆变换 # outputs 中每个框是 [x_center, y_center, w, h, conf, class_id]归一化坐标 for det in outputs[0][0]: x_center, y_center, w, h, conf, cls det if conf 0.5: continue # 还原到letterbox前 x_center_orig (x_center * 640 - (640 - new_w) / 2) / scale y_center_orig (y_center * 640 - (640 - new_h) / 2) / scale x_click int(x_center_orig) y_click int(y_center_orig) print(f目标类别: {int(cls)}, 置信度: {conf:.2f}, 点击坐标: ({x_click}, {y_click}))核心就三行一个是缩放比例scale一个是letterbox填充偏移(640 - new_w) / 2一个是把归一化坐标还原到原始截屏尺寸。这套逻辑是从YOLOv5源码里的scale_coords函数拆出来的理解一次以后换分辨率、换模型也能直接用。3.3 多目标与误检的筛选策略真实场景里同一个屏幕上可能出现多个同类目标比如一个软件里有多个功能按钮长得一样。这时候不能盲目点第一个检测结果需要按业务规则筛选可以按置信度排序取最高分也可以按坐标位置排序比如点最左边、最上边的。如果单一帧的误检率偏高我会连续截两到三帧取多次检测结果中坐标距离最近的同一个目标来确认。另外模型输出的置信度阈值不要设太低屏幕识别场景建议设置在0.5-0.6之间。阈值太低会混入误检导致鼠标点错位置阈值太高又可能漏检特别是目标只有32x32时。这个参数值得你在实际场景里多调几次找到最合适的点。4. 自动点击的稳定性设计别让脚本“手抖”4.1 输入控制的方式选择坐标拿到了接下来就是让鼠标移动过去、点击。Python里控制鼠标的库有几个pyautogui、pynput、pydirectinput。屏幕识别自动操作场景下更推荐pydirectinput它对Windows消息的发送方式和真实输入更接近兼容性也更好pyautogui在部分窗口全屏应用下会失效这属于老问题了。基础调用import pydirectinput import time def click_at(x, y, delay0.1): pydirectinput.moveTo(x, y, duration0.05) time.sleep(delay) pydirectinput.click()moveTo的duration参数控制移动耗时不要设成0稍微有一点过渡更接近人工操作习惯。如果程序需要移动鼠标到多个位置每次移动前加一个极短的暂停避免输入事件堆积导致界面响应卡顿。4.2 点击节奏的控制逻辑固定频率做一次点击虽然代码上最简单但在真实运行中很容易让目标应用来不及响应进而出现界面卡死、点击落空的问题。我自己的做法是“状态等待重试机制”点击一次之后检查目标是否已经消失或者状态是否已经变化如果没变化就再点一次最多重试三次。这个检查不一定要靠模型有时候通过窗口标题变化、剪贴板内容变化也能判断。举个具体的例子如果操作目标是“点击某个按钮后弹出一个新对话框”那点击之后可以用模型检测“新对话框”的标志性元素是否出现。检测到了再继续下一步没检测到就等待200毫秒后重试。这种轮询式的逻辑比“闷头点击固定次数”要可靠很多。4.3 异常恢复和日志记录任何自动脚本都会遇到意外情况——应用崩溃、窗口最小化、网络延迟导致界面没加载出来。不能假设一切顺利一定要在脚本里加入异常保护每次执行核心动作前确认目标窗口存在且处于前台。点击前后记录日志包含时间、坐标、置信度、执行结果。连续重试多次仍然失败时主动停止脚本并告警而不是继续空转。日志看起来不起眼但它是排查问题的唯一抓手。我调试阶段踩过不少坑后来习惯把每次检测结果的关键信息写入CSV文件方便事后回放分析。没有日志出了问题就只能靠猜。5. 合规边界与这套能力的正确打开方式聊回开头的话题。YOLOv5识别配合屏幕截图和自动点击本质是一套“计算机视觉流程自动化”的通用技术组合。它真正发光的场景是那些重复、耗时、规则明确的数字化劳动自动填写表单、批量处理文档、软件界面自动化冒烟测试、无人值守的数据录入。这些场景下这套脚本每天能帮人节省好几个小时而且不会出错。反过来如果把它用在在线游戏的自动操作上性质就完全变了。这种行为几乎都会被游戏用户协议明确禁止轻则封禁账号重则影响整个游戏环境的公平性。更现实的问题是游戏运营方对异常输入行为的检测技术也在不断升级这类脚本的生命周期很短投入产出完全不成比例。我个人在实际使用中的体会是目标检测模型的泛化能力远比你想象中好但也不要想当然地以为训练一次就能一劳永逸。运行环境的屏幕分辨率变了、目标图标的样式更新了、甚至界面背景颜色调整了都可能让识别效果下降。遇到这种情况补采一些新数据、微调几个epoch模型很快就能重新适配。把这套训练-验证-迭代的流程跑熟比单次训练出一个“完美模型”有用得多。后面如果你想进一步提升运行速度可以研究一下用TensorRT做模型加速或者把ONNX模型部署到OpenVINO上在CPU环境里跑——扩展空间很大但前提始终是把技术用在正确的方向上。本文还有配套的精品资源点击获取
返回列表