news 2026/10/22 3:11:51

YOLOv5与自动脚本:DNF识别算法从训练到部署实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv5与自动脚本:DNF识别算法从训练到部署实践

简介:这是一套采用YOLOv5目标检测算法开发的地下城与勇士游戏自动化脚本资源,面向具备一定Python编程基础、希望将识别模型与自动操作结合使用的学习者和开发者。压缩包共包含九十五个文件,总体积约二十七点二七兆字节,以Python源码与编译后的字节码为主,另配模型配置文件、预训练权重、测试截图及说明文档,并对官方YOLOv5结构做了游戏场景化裁剪,目录清晰,支持直接运行与二次开发。资源内封装了屏幕抓取、键鼠模拟、方向移动和技能识别等核心模块,并带有多个实战场景的测试脚本,完整呈现了从图像识别、逻辑决策到自动执行的流程;同时保留了模型调用、工具函数和数据装载等工程代码,便于拆解学习或迁移到其他目标检测项目。通过阅读源码与运行测试,可以直观了解到神经网络推理与游戏窗口交互间的衔接方式,适合作为课程设计、毕业设计或业余自动化工坊的参考样例。目前已有四百零六人学习浏览。

1. 从“看见画面”到“自动操作”:YOLOv5在DNF自动脚本里解决的核心问题

把“基于YOLOv5 DNF识别算法的DNF自动脚本实现”这句话拆开看,最不重要的是“自动”两个字,最重要的是“识别”。脚本要自动操作,先得知道当前屏幕里哪个位置是怪物、哪个位置是可拾取物品、哪个位置是技能按键,这一层信息只能靠视觉模型从游戏画面里拿。我第一次做DNF自动脚本实验时,先用了OpenCV模板匹配,游戏界面只要发生缩放、特效遮挡或装备发光,匹配阈值就全线崩;替换成YOLOv5目标检测之后,识别一帧的延迟低到可以接受,而且能同时返回多个目标的边界框,决策模块才算真正“看得见”。这套方案适合两类读者:一类是刚练完目标检测、想找一个真实场景做模型落地的初学者;另一类是有自动化业务需求、想评估视觉识别能否替代规则判断的开发者。再次强调,游戏自动脚本通常违反服务条款,请只在离线录像和隔离环境里复现,不要把它挂到正式账号上长时间运行。

2. 基于YOLOv5的DNF识别算法:选型理由、数据准备和标注规范

2.1 为什么是YOLOv5:先把“识别”这件事选对工具

一个DNF自动脚本里,“识别”承担的任务是:在每一帧游戏画面里找到怪物、可拾取物品、技能按钮、NPC等目标,并返回它们在屏幕上的边界框。这个任务属于目标检测,而不是图像分类,因为多个目标会同时出现在一帧里,位置本身是决策输入。

我在最开始尝试过两类传统方案。一类是颜色阈值,针对血条和技能栏这种固定颜色目标确实有效,但地图背景一变就失效;另一类是模板匹配,把技能图标的小图在画面里滑动匹配,缩放、抗锯齿和UI特效一上就彻底翻车,而且一帧跑多种模板非常耗时。传统视觉不是不能做,而是通用性太差,每换一张地图就要重新调一遍阈值,建模成本反而比训练一个检测模型更高。

目标检测选型上,Faster-RCNN系列精度略高,但推理速度和工程部署都重,不适合每帧都要处理的脚本;YOLOv5是单阶段检测,一张图和所有框同时输出,640x640输入下在消费级GPU上表现不错。它同时提供了PyTorch生态的训练脚本、验证脚本和模型导出工具,从训练到ONNX/TensorRT的链路都很顺。到后来YOLOv8、v9在精度和训练体验上做得更好,但YOLOv5的文档、踩坑案例和第三方适配最丰富。做游戏识别时我特别依赖社区经验,所以最终选了YOLOv5作为主力,而不是盲目追新。

如果场景是背包界面这种静止UI,用模板匹配其实更省事;但DNF刷图过程画面是滚动的、技能会遮挡目标,识别条件远比静止界面复杂。我确定的原则是:YOLOv5负责动态场景里的目标检测,OpenCV模板匹配只补充技能冷却图标这类位置固定、样式完全不变的小目标。选型不是越新越好,而是要看落地上手难度和画面环境变化程度两个变量。

2.2 数据采集:从游戏录像抽帧,别靠截图一张张攒

模型的数据质量直接决定识别效果。我踩过最深的一次坑是前期为了省时间,直接从第三方图片集里补了一部分数据,结果模型训练完后只框出了一些背景噪点,原因是图片风格和DNF画面差太远。更好的做法是自己录游戏视频,按固定间隔抽帧,再做清洗。

实验环境优先用离线录像录制:录一段包含跑图、打怪、拾取、开背包的素材,时长最好覆盖多种地图和怪物种类。抽帧命令常见用ffmpeg:

ffmpeg -i dnf_gameplay.mp4 -vf fps=10 frame_%04d.jpg

-fps=10表示每秒抽10帧,抽太少会漏掉部分元素;抽太多会出现大量连续近似帧,导致训练集冗余。我一般先抽几千帧,再人工浏览删掉模糊、重复、没有目标的帧,留下800到1500张作为基础集。对于DNF这种目标类别不算多的场景,这个量级已经够用。

抽帧后还需要做一次清洗:画面里如果出现大段聊天框遮挡、死亡倒计时、结算弹窗,这些帧要么删除,要么单独标注。否则模型会把弹窗里的按钮也学进去,检测结果会多出一堆假框。

2.3 标注哪些目标:类别别贪多,先保“决策必需”

标注类别要直接对应脚本决策。我一般会先和需求方对齐“脚本下一步动作依据什么”,再定类别清单。最简单的小型刷图脚本只需要三类:

类别含义决策用途
monster地图中的怪物技能释放和走位目标
item可拾取物是否移动过去拾取
skill_icon技能栏里的按键图标释放哪个技能

如果要做商店售价识别,才把商店物品相关UI加入类别。不要把角色立绘、宠物、背景装饰都标进去,类别越多标签噪声越大,脚本决策反而变慢。标注工具常见用LabelImg,可以保存成VOC格式再转成YOLOv5的txt,也可以直接选YOLO格式导出。

YOLOv5的标签格式每一行是:

class_index center_x center_y width height

其中坐标是归一化后的0到1数值,对应整张图。我刚开始标注时把目标框坐标理解成整个游戏窗口的绝对坐标,转成txt后训练损失一直降不下去,最后发现是忘了归一化。标注规范也要统一:怪物被技能特效挡住一半时,是按完整身体标还是按可见部分标?我统一按可见部分标,因为目标是“脚本能看到的范围”,而不是背后完整对象。UI图标之间间距很小时,框取图标主体,不要带入外部阴影。

2.4 数据集划分与目录结构:先设置好,免得训练时到处找Label

YOLOv5的train.py默认会读取数据配置里的train和val路径。目录结构我习惯这样组织:

datasets/dnf/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── dnf.yaml └── classes.txt

很多人会忽略的是images和labels的目录名必须一一对应,同一张图的图片文件与标签文件必须保持同名,只是后缀不同。例如图像路径是datasets/dnf/images/train/frame_0001.jpg,标签路径必须是datasets/dnf/labels/train/frame_0001.txt。路径不对时训练程序会在日志里报无法加载标签,但loss还是能下降一点,很容易被忽略。

目录建完后我会先跑一条校验脚本:

find datasets/dnf/images -name '*.jpg' | while read img; do label="${img/images/labels}" label="${label/.jpg/.txt}" [ -f "$label" ] || echo "missing label: $img" done

这条脚本把images目录下每个jpg对应的txt标签检查一遍,缺失会在终端打印出来,能在训练前把数据问题暴露掉。另一个容易翻车的地方是连续帧同时放进训练集和验证集。如果同一段录像的帧按时间顺序划分,随机拆分很容易让模型“背住画面”,验证指标虚高。我通常按录像片段划分:比如录制了a、b、c三段,a段的帧做训练,b段做验证,c段做测试,这样验证集和训练集没有时空重叠,指标才可信。

3. 训练YOLOv5 DNF识别模型:命令、参数和收敛判断

3.1 环境准备:克隆代码、安装依赖、先确认GPU

常见做法是准备一个Python 3.8到3.11的虚拟环境,不必追求最新版本。先安装PyTorch,再执行仓库里的requirements.txt把opencv、pandas等依赖装好:

git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt

如果显卡驱动支持CUDA,装完先确认torch是否正确识别GPU:

python -c "import torch; print(torch.__version__, torch.cuda.is_available())"

输出里torch.cuda.is_available()如果是False,先别急着开始训练,要确认显卡驱动和CUDA版本匹配,再重装对应版本的torch。CPU也能训练,但迭代一版实验要等很久,模型调试节奏会非常难受。我一般会固定用一个独立的虚拟环境,避免不同项目之间的opencv和torch版本互相污染。

依赖装完后还会遇到一个奇怪问题:代码目录名里带中文或空格。YOLOv5本身对路径有处理,但Windows下训练日志和模型保存路径解析偶尔会出问题。最稳妥的做法是git clone后把目录放在纯英文路径下,比如D:\work\yolov5,不放在桌面或带中文用户名的目录里。

3.2 数据配置:写dnf.yaml并保证类别索引一致

训练时真正要改的第一个文件是数据配置。不推荐每次训练都去改models/yolov5s.yaml里的nc,改错会导致维度不匹配。更通用的做法是在数据配置里指定数据集根目录和类别名:

# datasets/dnf/dnf.yaml path: datasets/dnf train: images/train val: images/val test: images/test nc: 3 names: 0: monster 1: item 2: skill_icon

path是相对YOLOv5根目录的路径,train、val、test是相对于path的子目录。names的索引顺序必须和标签txt里的数字一一对应;顺序反了模型也能收敛,但推理时类别名全是错的,后续脚本的分支逻辑会乱掉。

对于models/yolov5s.yaml,我一般不动它,只保留默认的网络结构。如果显存很小,比如只有4G,可以换成yolov5n.yaml,这是更瘦小的网络;如果对精度要求高且显存充足,再用yolov5m.yaml。启动训练后观察日志里打印的网络结构,确认nc变成3,这是配置生效的关键信号。

3.3 训练命令与参数:batch、epoch、img-size怎么定

训练命令最基本的一行是:

python train.py --img 640 --batch 16 --epochs 100 \ --data datasets/dnf/dnf.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --name dnf_run \ --device 0

--img 640是训练分辨率。如果屏幕实际是1920x1080,640会丢失一部分小目标,比如地上的金币碎片;能开到768或960更好,但显存占用会上升。我一般先用640把流程跑通,再针对小目标场景提高分辨率做二次训练。--batch 16在单卡16G显存下基本能用,显存不足就降到8或4,不要硬扛,OOM不只是报错,还会污染缓存。--epochs 100对DNF这种界面相对固定的场景通常够用,训练到后期如果验证指标开始回退,说明已经过拟合。

--hyp没有写在命令里,默认使用data/hyps/hyp.scratch-low.yaml。如果游戏画面里有大角度旋转,可以适当降低mosaic增强比例,避免模型把奇怪的拼接图当成真实游戏画面。UI图标识别容易过拟合时,我也会降低hyp中scale和mosaic的值,让模型多关注图标本身的结构而不是背景纹路。

训练启动后,终端每轮会输出box_loss、cls_loss、obj_loss和验证mAP。我看收敛的习惯是:头几轮loss跌幅明显,后面波动变小;如果loss曲线反复大跳,大概率是验证集太小或学习率设置不合适,先补数据而不是继续调参。训练结束后判断标准不是train loss接近0,而是看val mAP。DNF的识别目标很多是大物体,mAP50大于0.5时已经能把基本脚本逻辑跑通,mAP50-95稳定在0.3以上也不差。

3.4 模型验证:用detect.py跑一段离线段

训练完成后,在runs/train/dnf_run/weights/下能看到best.pt和last.pt。best.pt是验证集效果最好的权重;不要用last.pt发布,因为最后一轮可能已经过拟合。验证命令:

python detect.py --weights runs/train/dnf_run/weights/best.pt \ --source data/dnf_test_video.mp4 \ --conf-thres 0.25 --iou-thres 0.45 \ --save-txt --save-conf

detect.py会把识别结果画框保存到runs/detect/exp下。这一步重点看三类问题:漏检、误检、框位漂移。比如模型把地面纹理识别成monster,说明负样本不够,需要加入没有怪物只有场景的地图帧,并保证这些帧的label是空文件,表示图里没有目标要检测。空标签样本在目标检测里非常关键,后面避坑章节会再展开。

4. 自动脚本主循环实现:抓帧、模型推理、坐标映射和操作决策

4.1 抓帧与预处理:稳定画面的第一个细节

自动脚本的主循环一般是:抓一帧画面 -> 模型识别 -> 收集边界框 -> 规则决策 -> 模拟操作 -> 等待一段时间 -> 下一帧。我会先分两部分来实现,视觉部分和操作部分不要混在一起,否则一旦识别有问题,你根本分不清是模型错了还是点击逻辑错了。

抓帧常用成熟的屏幕捕获库,例如mss。它依赖少、速度快,适合抓普通桌面窗口。如果游戏使用独占全屏导致普通抓帧黑屏,实验时我会先把游戏改成固定分辨率的窗口模式;离线实验则直接对录好的视频逐帧读取,完全不依赖屏幕捕获。处理一帧并推理的代码可以这样写:

import cv2 import numpy as np import torch from models.experimental import attempt_load from utils.general import non_max_suppression, scale_coords from utils.augmentations import letterbox device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = attempt_load("runs/train/dnf_run/weights/best.pt", device=device) model.eval() def inference_frame(frame_bgr): # letterbox 保持宽高比缩放到640x640,多余边填充灰色 img, ratio, pad = letterbox(frame_bgr, (640, 640), stride=32, auto=False) img = img.transpose((2, 0, 1))[::-1] # BGR转RGB,HWC转CHW img = np.ascontiguousarray(img) tensor = torch.from_numpy(img).to(device).float() / 255.0 if tensor.dim() == 3: tensor = tensor.unsqueeze(0) with torch.inference_mode(): pred = model(tensor)[0] det = non_max_suppression(pred, conf_thres=0.3, iou_thres=0.45)[0] result = [] if det is not None: det[:, :4] = scale_coords((640, 640), det[:, :4], frame_bgr.shape).round() for *xyxy, conf, cls in det.tolist(): result.append({ "class": int(cls), "conf": float(conf), "bbox": [float(x) for x in xyxy], }) return result

逻辑说明:letterbox先按宽高比缩放,而不是直接拉伸,避免物体形变影响识别。模型训练用RGB,OpenCV抓到的是BGR,所以要做通道反转。scale_coords把模型输出的640x640坐标换算回原图坐标,这是整个脚本最容易出错的位置之一,不能省。如果抓的是窗口内部截图,返回的坐标就是窗口内坐标;需要点击屏幕时,还要加上窗口左上角在屏幕上的偏移量。

4.2 坐标映射与目标选择:从多个检测框里找“该打的那个”

模型一帧可能同时返回多个怪物、多个物品,操作层需要定义选择策略。最常用的策略是找离屏幕中心最近的目标,因为游戏镜头通常以角色为中心,越靠近中心的目标就是越优先处理的:

def pick_nearest(objects, class_id, center): candidates = [] for o in objects: if o["class"] != class_id or o["conf"] < 0.4: continue bbox = o["bbox"] x = (bbox[0] + bbox[2]) / 2 y = (bbox[1] + bbox[3]) / 2 dist = (x - center[0]) ** 2 + (y - center[1]) ** 2 candidates.append((dist, x, y, o)) if not candidates: return None candidates.sort() return candidates[0][3]

这个函数把置信度低于0.4的框过滤掉,再按中心点到预设点的欧氏距离排序。center通常传(W / 2, H / 2),也就是屏幕中心。需要说明的是,脚本判断“离得最近”用的是像素距离,不一定是游戏内的真实世界距离;DNF是横版卷轴,屏幕坐标系和游戏世界坐标有换算关系,严格项目里还需要用角色坐标做二次换算。离线Demo阶段,像素距离已经足够验证主流程。

4.3 状态机:把单帧识别变成稳定的脚本行为

单帧识别只是“看见了”,自动脚本还需要“连续不乱”。如果用一段if从头写到尾,遇到连续几帧没有怪物,脚本就会不断重复同一个动作,表现得很僵。常见做法是引入状态机,状态设计和触发条件大致如下:

状态触发条件行为
待机当前无目标或目标丢失小范围移动寻找怪物
战斗找到怪物且距离足够近移动到攻击范围,释放技能
拾取出现item且附近无怪物移动到item坐标,执行拾取
暂停连续多帧无有效识别结果停下等待,防止重复无效操作

简化代码:

state = "IDLE" while running: frame = grab_frame() objs = inference_frame(frame) if state == "IDLE": if any(o["class"] == 0 for o in objs): state = "FIGHT" elif state == "FIGHT": target = pick_nearest(objs, class_id=0, center=(W // 2, H // 2)) if target is None: state = "IDLE" else: press_skill_and_click(target) time.sleep(0.05)

time.sleep(0.05)是为了限制主循环频率,避免占满CPU和显存。识别频率并不是越高越好,操作冷却时间没到,识别再快也是空转;我一般先按20FPS调,遇到画面漂移再降到10FPS。

4.4 异常保护:画面黑屏、连续无目标、窗口变化

脚本长时间运行时,最怕的不是识别不准,而是异常后陷入死循环。比如游戏弹窗覆盖了画面,模型什么都识别不到,脚本还在不停点击。需要加保护规则:连续N帧无目标就进入暂停状态,等待几秒再恢复;连续多次识别结果完全一致,说明画面静止,也放到暂停状态。另一个常见问题是用户手动改了窗口大小,抓帧尺寸变了,推理时scale_coords返回的坐标全部漂移。我的解决办法是启动脚本时先读取一次窗口尺寸,运行过程中每隔一段时间校验尺寸,变化了就停止。自动脚本的可靠性,来自这些边界保护,而不是模型精度本身。

5. DNF自动脚本避坑指南:识别偏移、空标签、资源泄漏和安全边界

5.1 识别框和真实位置对不上,点击偏了几十像素

现象:模型框出的目标位置看起来在怪物旁边,但点击后打到空处,尤其在1366x768和1920x1080两种分辨率之间切换后特别明显。

原因:抓帧区域和推理坐标没有对齐。一是letterbox的padding没有扣除,直接用640坐标换算到原图;二是只截取了窗口客户区,但操作坐标没有加上窗口边框和标题栏的偏移量。

解决:推理结果统一用scale_coords映射回原图,再在抓帧入口明确记录截图的像素区域。把“窗口内坐标”和“屏幕坐标”分成两套变量维护,写清楚换算函数,不要直接在循环里做裸加减。换分辨率后先跑一次离线录像回归测试,确认坐标没漂移再继续。

5.2 训练loss正常,但地上的金币小球识别不到

现象:monster和skill_icon识别都挺好,只有item类对小物块漏检严重,仔细看置信度也很低。

原因:小目标在640x640输入下只占几个像素,模型特征不足;同时地面背景复杂,模型容易把小碎石也归入背景。

解决:训练时提高--img到768或960,推理时也同步提高分辨率。另一个有效做法是单独做小目标复刻,把包含小物品的截图裁剪放大后加入训练集,和原图同时训练。实机验证时,把item类的conf_thres单独降到0.25,但要接受一些小概率误报,再用“点击前必须有连续两帧识别到同一坐标”做过滤。

5.3 验证mAP很高,一到实机就出现满地假怪物

现象:验证视频里效果很好,换到一张没有怪物的地图,模型疯狂框出monster,甚至把地板纹理都识别成怪物。

原因:训练集里几乎全是带着怪物的战斗片段,缺少“空场景”负样本。模型没学过“没有怪物时该输出什么”,于是把背景纹理当成目标。

解决:单独录制一批纯场景帧,包含草地、城镇、楼梯、墙面,不标注任何目标,标签写成空的txt文件。把空样本和带目标样本混合进训练集。目标检测的空样本不是噪声,而是告诉模型“这片背景里不该输出框”的关键数据。标注完跑一次目录校验,确保空标签文件确实存在,而不是漏标。

5.4 脚本跑几十分钟后画面卡死,内存持续上涨

现象:刚开始抓帧和推理都正常,运行一段时间后帧率下降,最后报错;有时是mss抓不到画面,有时是torch显存不足。

原因:循环里创建了太多临时对象,屏幕捕获对象没有释放,或者连续推理导致显存碎片累积;最容易被忽略的是抓帧频率过高,CPU和内存一直被挤占。

解决:用with方式管理屏幕捕获连接,确保每帧都释放资源;主循环里限制最高FPS,10到20FPS足够;长时间运行场景,每处理一定帧数或检测到显存增长时重启进程。我通常会在Demo里加一个“最大运行时长”参数,超过就自动退出,比挂机几小时更容易发现问题。显存碎片问题可以通过torch.cuda.empty_cache()缓解,但不能完全替代重启机制。

5.5 模拟键鼠被游戏安全组件拦截,账号被标记风险

现象:脚本正确识别到目标,模拟按键执行后游戏没有反应,或强制弹出,甚至账号被临时限制。

原因:游戏安全策略会对模拟输入设备做检测,自动化脚本本身也违反服务条款;这不是识别算法问题,而是操作层的合规问题。

解决:把实验边界严格控制在离线录像和隔离环境里,不接真实账号,不尝试绕过安全策略。离线Demo可以做完整闭环:读取录像帧、模型推理、决策、把动作写进日志,模拟点击只是打印坐标,这样能验证所有思路,又不会造成现实风险。任何游戏脚本项目的第一步都应该是明确边界,这一点比模型精度更重要。

6. 离线录像验证与指标自检:把DNF自动脚本做成可回放的Demo

6.1 用同一段录像做回归,不再“每次全凭手感”

我现在的固定习惯是准备三到五段离线录像,分别覆盖怪物密集、没有怪物、拾取阶段、UI弹窗四种情况。每改一次模型或脚本逻辑,就把这段录像重新跑一遍,输出带检测框的视频和动作日志。这个做法能快速发现两类问题:坐标漂移和空转行为。某次改窗口分辨率后,在线环境出现严重漂移,我跑离线录像两分钟就定位到了坐标换算错误,而不是对着游戏界面反复试错。

6.2 定义指标:目标命中率、漏检率、无效点击率

只在肉眼看视频,很难判断当前版本是否回退。我会把识别结果保存成CSV,与标注好的关键帧做比对,计算三组指标:

指标含义可接受范围
目标命中率正确识别的目标占真实目标的比例0.7以上
无效点击率点到非怪物区域的次数占比越低越好
单帧推理耗时从截图到输出坐标的时间小于50ms

验证命令可以做成一个简单的入口:

python evaluate_demo.py --source gameplay_fix.mp4 --weights best.pt --log demo_actions.csv

这个脚本会把每个动作写入日志,并汇总三类指标。指标不过就回去看是哪一类目标出了问题,而不是盲目加epoch或者换更大模型。很多“训练到死也不准”的问题,最后回头看都是数据划分或坐标换算,不是网络结构的问题。

我每次还会保留一份最早期翻车的权重,专门用来做对照。某一次模型效果变差,翻出旧权重一跑,发现是那次顺手改了数据集目录导致训练集混入了验证集图片,指标虚高,实机自然崩。离线回归加指标记录,对于DNF自动脚本这类需要反复调优的项目来说,就是防止自己反复踩同一个坑的后悔药。

希望这套从数据到推理、再到闭环验证的思路,能帮你在做游戏目标检测自动化时少走一段黑路。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 3:14:30

SWIFT报文实战避坑指南:从PPT到生产系统的字段级校验与状态追踪

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 6:01:38

110KV单电源环形网络短路保护课程设计:整定计算与仿真校验

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/20 23:09:39

Photoshop 2024从入门到实战:合法获取、核心技术与自动化导出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 1:45:32

PCA9422与STM32L152超低功耗电源管理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 9:20:34

PCA9422+TM4C129X电源管理方案:动态调压与供电路径智能控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 22:07:14

嵌入式低功耗电源管理实战:PCA9422与TM4C129动态调压方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华