ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

热红外无人机数据集+YOLO训练全流程实战指南

热红外无人机数据集+YOLO训练全流程实战指南 简介面向YOLO系列目标检测训练与验证场景提供一套热红外无人机图像数据集包含三百六十张已标注图像可直接用于YOLOv5、YOLOv7、YOLOv8、YOLOv9、YOLOv10、YOLO11等常用算法版本。压缩包内共有一千零八十一个文件其中包含三百六十张JPG原图、三百六十个YOLO格式TXT标签、三百六十个VOC格式XML标签以及一个data.yaml配置文件压缩包大小约六点七二兆字节轻量易用。数据已经预先完成划分配合配置文件可免去手动整理标注的步骤TXT与XML两种标签格式分目录存放方便不同框架或算法切换使用也便于对比验证。目前已有八十人浏览学习适合目标检测入门者、无人机视觉研究者以及需要快速验证YOLO系列算法效果的开发者可直接投入模型训练、指标评估和结果测试节省从零标注与预处理的时间。1. 拿到这个360张的热红外无人机数据集先别急着跑训练拿到一个名为yolo算法-热红外无人机数据集-360张图像带标签的zip包第一反应通常是两件事360张热红外图能训练出一个能用的检测模型吗打包好的标签到底是不是标准的YOLO格式我的看法是360张对一个有经验的人来说足够启动一个项目对新手则很容易在训练时翻车。热红外图像和普通可见光照片不一样小目标、低对比度、位深都是常见的坑但反过来无人机热红外场景目标类型固定、场景单一反而比泛化的目标检测更容易收敛。这篇笔记是给两类读者准备的正准备用无人机热红外数据做检测的工程师以及一切准备用YOLO训练自采数据集的人。2. 拆开zip先做三件事校验完整性、看标签格式、确认图像位深数据集买到手第一件要做的事不是解压后立刻训练而是花十分钟检查三样东西压缩包本身有没有损坏标签文件是不是规范的YOLO格式图像数据是不是YOLO能直接吃的格式。这三项检查能省掉后面训练时一大半的玄学问题。2.1 用 unzip 与 7-Zip 打开压缩包先测试再解压Linux 下我一般会用下面这条命令测试压缩包完整性测试通过后再真正解压。这个习惯是从一次 2GB 数据集解压到一半报错养成的那次教训很直接不校验就解压解压出来的文件缺了大半训练时各种 key error。unzip -t thermal_dataset.zip这条命令只做测试不实际解压。输出末尾出现No errors detected in compressed data就说明压缩结构完好。如果下载文件本身不完整这里会直接报unexpected end of file或cannot find zipfile directory。确认完整后再正式解压。Linux 下如果解压出来中文文件名乱码通常是压缩包在 Windows 下用 GBK 编码创建、而系统默认 UTF-8 解码导致的加-O参数指定编码即可解决unzip thermal_dataset.zip -d ./thermal unzip -O CP936 thermal_dataset.zip -d ./thermal # 文件名乱码时用Windows 下我推荐用 7-Zip 而不是系统自带的资源管理器解压。右键压缩包选择“打开方式 - 7-Zip File Manager”先点“测试”按钮绿色提示说明压缩包没问题。7-Zip 对 zip64 格式和大目录的兼容性比系统自带解压工具好碰到解压途中报错的情况也更容易定位是哪个文件坏了。提示解压后立即检查解压目录看图片数量和标签文件数量是否和压缩包内一致。这类数据集经常出现“图像 360 张、标签 359 个”之类的少文件情况后面训练时就会有多张图找不到标签文件的错误。2.2 标签文件是不是 YOLO 格式一行 5 个数怎么看YOLO 标签的标准格式是每个 txt 文件对应一张图片txt 中每行代表一个目标格式固定为类别ID x_center y_center width height后四个值全部归一化到 0 到 1 之间。labelimg 标注时选 YOLO 格式保存的就是这种 txt 文件。我的习惯是先不急着看全部标签而是抽一张图和一个标签文件写脚本叠加画框。这样一眼就能看出标签和图像是否对得上类别 ID 和实际目标是否匹配。下面这个脚本很基础但每次拿到新数据集我都会先跑一遍import os from PIL import Image, ImageDraw def verify_label(img_path, label_path, output_pathverify.jpg): img Image.open(img_path) draw ImageDraw.Draw(img) with open(label_path, r, encodingutf-8) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(f格式错误: {label_path} 中异常行: {line}) continue cls, xc, yc, bw, bh parts cls, xc, yc, bw, bh int(cls), float(xc), float(yc), float(bw), float(bh) # 检查坐标是否越界 if not (0 xc 1 and 0 yc 1 and 0 bw 1 and 0 bh 1): print(f越界框: {label_path} 行: {line}) continue # 归一化坐标换算成像素坐标 x1 (xc - bw / 2) * img.width y1 (yc - bh / 2) * img.height x2 (xc bw / 2) * img.width y2 (yc bh / 2) * img.height draw.rectangle([x1, y1, x2, y2], outlinered, width2) draw.text((x1, y1 - 10), str(cls), fillred) img.save(output_path) # 使用示例 verify_label(images/IR_001.png, labels/IR_001.txt, check_001.jpg)这个脚本的逻辑核心是读 txt 每一行把归一化坐标乘上图像宽高还原成像素坐标再画矩形框。输出图里每个框上会标类别 ID人工扫一眼就能发现很多问题比如类别 ID 标反、框画到图外、目标中心点偏移。width2 是矩形边框宽度在小目标上 width 太大会直接把目标盖住影响肉眼判断。如果标签是 VOC 的 xml 格式不能直接用于 YOLO 训练常见的做法是写一个转换脚本把xmin ymin xmax ymax四角坐标换算成x_center y_center width height的归一化格式同时保持类别 ID 的映射一致。这一步没什么高深的逻辑但很容易出错转换后再跑上面的可视化验证脚本比直接丢进训练器可靠得多。2.3 热红外图像的常见坑灰度图、伪彩色与 16 位数据热红外图像和普通单反照片最大的差别在存储格式。很多热像仪 SDK 导出的是 16 位 PNG用普通图片查看器打开会看到一团黑这是正常的因为 16 位数据的动态范围和 8 位显示不匹配。训练 YOLO 前必须先确认图像的位深和通道数否则后面的数据增强和归一化都可能出问题。常见的三种热红外图像格式格式特征训练前处理8 位灰度 PNG/JPG单通道范围 0-255可直接使用16 位 PNG单通道范围可能到 65535需要归一化到 8 位伪彩色 BMP/PNG三通道颜色代表温度谨慎转灰度可能丢温差信息我自己处理 16 位热红外图的做法是先用 Python 读一下图像 mode再做一个最小最大归一化把动态范围拉伸到 0 到 255import numpy as np from PIL import Image import os os.makedirs(images_8bit, exist_okTrue) for f in os.listdir(images): if not f.lower().endswith((.png, .bmp)): continue img Image.open(os.path.join(images, f)) if img.mode in (I;16, I;16L, I;16B): arr np.array(img, dtypenp.float32) # 最小最大归一化把16位热红外动态范围压到0-255 arr (arr - arr.min()) / (arr.max() - arr.min() 1e-6) * 255 arr arr.astype(np.uint8) im Image.fromarray(arr) else: im img.convert(RGB) im.save(os.path.join(images_8bit, f))这段代码的作用是扫描 images 目录把 16 位热红外图转成 8 位其他格式直接转 RGB 保存。1e-6是防止整张图像素值完全相同比如全黑的全温区图时出现除零。注意这里的归一化是全局拉伸如果一张图里同时包含高温目标和低温背景对比度会被拉开得很明显但如果是整段视频逐帧处理每帧独立归一化会导致帧间亮度闪烁后续做视频检测时需要考虑。伪彩色图我一般建议直接保留三通道用于训练不转灰度。热红外伪彩色的编码方式五花八门铁红、彩虹、灰度各有各的映射转成灰度会丢掉温度层次差异尤其是“同温度目标在伪彩色里同色、在灰度里也同色”的这种信息损失对检测不利。3. 从环境到权重用这套数据集训练 YOLOv5/YOLOv8检查完数据接下来就是训练流程了。这里我同时给出 YOLOv5 和 YOLOv8 两套操作因为目前用这两套的人最多而且它们对这类小数据集的适配都比较成熟。安装方式、数据划分、训练参数分别讲清楚。3.1 Anaconda 建环境与依赖安装YOLO 训练对 Python 和 PyTorch 版本有要求直接用系统 Python 装容易把环境搞乱。我一般用 Anaconda 单独建一个环境互不干扰。conda create -n yolo python3.10 -y conda activate yolo pip install ultralytics这样装的是 YOLOv8 的环境安装完成后会得到yolo命令行工具训练、验证、预测全部由它统一管理。如果你更习惯 YOLOv5 的代码组织方式也可以单独克隆官方仓库再按仓库内 requirements.txt 安装依赖。YOLOv8 对新手更友好YOLOv5 对想要逐行改代码的人更直观。我的习惯是先跑通一个模型用 YOLOv8确认思路没问题再回头用 YOLOv5 做对照实验。安装好之后先用python -c import torch; print(torch.cuda.is_available())确认 GPU 是否可用。输出True才代表 CUDA 环境正常False就是 CPU 训练360 张图,CPU 训练也能跑但速度会慢很多。3.2 划分训练集和验证集数据量小就必须分层抽样360 张图不算多划分方式直接影响验证结果的可信度。简单随机切一刀很容易出现某类目标在验证集里一个都没有的情况所以我一般用 sklearn 的train_test_split做分层抽样按标签里第一个目标的类别作为分层的依据。import os from sklearn.model_selection import train_test_split images_dir images labels_dir labels imgs [f for f in os.listdir(images_dir) if f.lower().endswith((.jpg, .png, .bmp))] imgs.sort() # 读取每张图对应标签的第一个目标类别作为分层依据 classes [] for im in imgs: stem os.path.splitext(im)[0] txt os.path.join(labels_dir, stem .txt) with open(txt) as f: lines [line.strip() for line in f if line.strip()] if lines: classes.append(lines[0].split()[0]) else: classes.append(-1) # 空标签图单独归一类 train_imgs, val_imgs train_test_split( imgs, test_size0.2, random_state42, stratifyclasses ) with open(train.txt, w) as f: for im in train_imgs: f.write(os.path.join(os.getcwd(), images_dir, im) \n) with open(val.txt, w) as f: for im in val_imgs: f.write(os.path.join(os.getcwd(), images_dir, im) \n) print(ftrain: {len(train_imgs)}, val: {len(val_imgs)})这段代码的关键点有两个。第一stratifyclasses让验证集的类别比例和整个数据集一致避免小类别在验证集里被抽空。第二random_state42固定随机种子保证每次运行划分结果一致实验结果可复现。test_size0.2意味着 360 张图里有 288 张训练、72 张验证。一个容易被忽略的坑无人机航拍数据天然具有航带相关性同一条航线上相邻帧几乎一模一样。如果这些高度相似的图被同时分进训练集和验证集验证指标会虚高。我建议划分前先把图像按采集时间或航线编号排好序用分组的方式切分而不是纯随机切。3.3 编写 data.yaml 并启动训练YOLO 训练需要一个 yaml 文件描述数据位置和类别信息。文件结构如下path: /home/user/thermal_data train: train.txt val: val.txt nc: 2 names: 0: person 1: vehiclepath是数据集根目录的绝对路径YOLOv8 会把train和val字段作为相对路径拼接上去。nc是类别总数必须和names里的条目数一致这个数字填错会直接导致训练报错或者 loss 异常。names的排列顺序和标签文件里第一个数字的 ID 必须一一对应。然后启动训练。YOLOv8 的命令是yolo detect train \ datathermal.yaml \ modelyolov8n.pt \ epochs100 \ batch16 \ imgsz640 \ close_mosaic10如果用的是 YOLOv5对应命令是python train.py \ --data thermal.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --patience 30这里几个参数值得单独说明。imgsz640是对小目标检测的底线——热红外无人机图像里的人可能只有十几到几十个像素输入尺寸再小的话下采样过程中特征就丢了。close_mosaic10是让模型在最后 10 个 epoch 关闭 mosaic 增强让模型从“看拼图”平滑过渡到“看清原图分布”这个细节能明显减少验证集和测试集效果不一致的问题。batch16在 12G 显存上是稳妥的选择显存更大可以提到 32。epochs100对 360 张图偏多配合patience30早停模型一般会在 40 到 60 轮之间收敛。训练过程中日志输出的损失分为三类box 回归损失、分类损失和 DFL 分布焦点损失。热红外场景里分类损失常常是降得最慢的一个因为不同目标在热红外图像里都是“一团白热轮廓”人、车、动物之间外观差异远没有可见光大。这是热红外数据本身的特性不是代码写错了。3.4 训练日志里真正要盯的几个数字很多新手盯着 loss 一直看其实对小数据集来说loss 的绝对值没什么指导意义更值得关注的是验证集上的 precision 和 recall以及模型卡在哪个 epoch 停止提升。输出字段含义观察建议box_loss边界框回归损失持续下降就是正常的cls_loss分类损失热红外场景可能偏高正常precision验证集查准率关注最终值别盯每轮波动recall验证集查全率漏检严重的场景优先提升mAP50IoU0.5 下的平均精度小数据集最重要的参考指标我习惯在训练跑完后看模型在哪一个 epoch 达到了 mAP50 的最高值。如果这个 epoch 靠后说明模型是在充分学习如果前 10 轮就到了峰值后面一直下跌说明过拟合很严重数据增强不够或训练轮数太多。4. 热红外小数据集常见问题与排查现象、原因、解法训练热红外小数据集时最容易踩的坑很多是数据集本身的“暗伤”而不是模型结构问题。下面这四条是我在类似项目里遇到过的真实问题按“现象 - 原因 - 解决”的顺序记录下来你可以直接对照排查。4.1 解压报错、zip 伪加密与“移除密码”的骗局现象解压到一半报unexpected end of file或者 7-Zip 提示需要输入密码但数据集来源明明没有提供密码。原因分两种。第一种是下载文件不完整或传输丢包zip 中央目录损坏。第二种是 zip 伪加密——文件的通用位标志里设置了加密位但数据区实际上根本没有真正加密常见于部分国产网盘压缩工具或打包脚本的 bug。伪加密的特征是工具提示要密码但在 7-Zip 里能看到文件名列表甚至双击某个文件能直接看到内容。解决先跑一遍unzip -t确认压缩包结构是否完整如果只是伪加密在 7-Zip 里直接把内容拖出来即可不需要密码。拖出来之后用 7-Zip 重新打包一次去掉加密标志再继续后续流程。需要提醒的是如果压缩包是真加密AES-256 或 ZipCrypto那没有密码就无法解压市面上所谓“密码移除”工具绝大多数只能处理上面这种伪加密情况对真加密只能在字典攻击上碰运气。注意这里只讨论你对自己合法获得的数据文件做校验和修复。如果确实是发布方加密数据但没有提供密码正确做法是联系发布方获取密码。4.2 标签文件与图像不匹配导致的 loss 异常现象训练能启动但 loss 在几十个 epoch 里纹丝不动或者验证集指标极低。查看训练日志时还可能出现image X not found或key error之类的警告。原因解压后发现有些图像没有对应标签文件有些标签文件对应的图像不存在或者标签文件中出现了越界的归一化坐标比如 width 大于 1 的框。这些脏数据不会让训练直接崩溃但会持续给 loss 注入噪声。解决训练前先做一次文件名匹配检查把缺失和多余的文件列出来import os imgs set(os.path.splitext(f)[0] for f in os.listdir(images)) labels set(os.path.splitext(f)[0] for f in os.listdir(labels)) print(缺标签的图像:, sorted(imgs - labels)) print(缺图像的标签:, sorted(labels - imgs))运行后根据输出做两件事缺标签的图像用 labelimg 补标注或者直接移出训练目录缺图像的标签直接删除。然后再检查标签文件里有没有坐标越界的框用脚本过滤掉import os for f in os.listdir(labels): if not f.endswith(.txt): continue path os.path.join(labels, f) with open(path) as fd: lines fd.readlines() valid [] for line in lines: parts line.strip().split() if len(parts) ! 5: continue try: cls, xc, yc, bw, bh int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) except ValueError: continue if not (0 xc 1 and 0 yc 1 and 0 bw 1 and 0 bh 1): continue valid.append(f{cls} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) with open(path, w) as fd: fd.write(\n.join(valid))这个脚本会把每个标签文件重写一遍只保留格式正确、坐标在合法范围内的框。注意这里把浮点数格式化成 6 位小数精度足够且文件更紧凑。4.3 热红外小目标漏检目标只有十几个像素现象训练完的模型在验证图上对 50 米外的行人、视野边缘的车辆大面积漏检但近处的目标检得很好。可视化测试图片时小目标区域完全没有框。原因热红外图像中远距离目标本身就只占几十个像素YOLO 的下采样倍数比较大特征图上的一个点对应原图的十几甚至几十个像素小目标的空间信息在深层特征图里基本消失。这是目标检测的通病热红外因为目标对比度低表现得比可见光更明显。解决最直接的办法是把输入分辨率提上去。从imgsz640提到imgsz960甚至imgsz1280小目标的特征保留程度会有明显提升。代价是显存占用和训练时间上升。如果显存不够可以采用切片推理的思路推理时把大图切成四等分或九等分分别送入模型再把检测结果映射回原图坐标。这个思路比直接缩小输入图更可靠也是当前无人机巡检场景里比较常用的推理策略。4.4 验证指标好看、现场实测翻车数据划分的假象现象训练结束验证集 mAP50 到 0.8模型看起来很好。结果带着无人机到现场飞一圈检测结果惨不忍睹漏检误检扎堆。原因训练集和验证集划分得太“随机”。无人机航拍是一条航线连续采集的相邻帧之间重叠度高随机划分后验证集里的图和训练集里的图高度相似导致验证指标虚高这个现象在学术上叫数据泄漏。飞机一换高度、换时间、换天气模型的真实泛化能力立刻现出原形。解决划分数据集时必须按“采集单元”来分组。比如 360 张图来自 3 次飞行任务那就按飞行任务把 6 组数据整体切分保证同一次飞行的图像不会同时出现在训练集和验证集里。这样做会让验证指标稍微下降但这才是真实水平。我在第 3 节划分代码里特意把random_state固定下来就是为了在发现指标虚高时能回溯数据划分方式。5. 模型验证与评估不是 loss 降了就万事大吉训练完只是第一步。对小数据集来说模型的真实表现往往和训练日志显示的差距不小。这一节讲训练完成后怎么评估模型、怎么调置信度门限、怎么把模型部署到实际环境中去跑。5.1 看准四个指标precision、recall、mAP50、mAP50-95训练结束后YOLOv8 会在验证集上算出一组指标输出在 runs/detect/train 目录下的 results.csv 里。我一般会打开这个文件重点看最后一行高亮部分的四个数字也就是严格按“航班划分”后的验证集指标。下表是各指标在小数据集上需要注意的事项指标含义这里的观察要点mAP50IoU 阈值 0.5 下的平均精度均值小数据集的首选参考0.5 左右通常就算可用mAP50-95IoU 从 0.5 到 0.95 逐档计算再取平均数值一般比 mAP50 低很多正常precision预测的框里有多少是对的误检多是 precision 低优先调置信度门限recall真实目标里有多少被检出漏检多是 recall 低优先提分辨率或增强这四个指标里mAP50-95 是最苛刻的它要求框的位置非常准对小目标尤其不友好。热红外小目标经常 mAP50 在 0.6 以上而 mAP50-95 只有 0.3 左右这不代表模型不能用只代表框不精准。真正决定模型能不能上线的是 precision 和 recall 的平衡而这和业务场景直接相关巡检漏了一个目标可能造成损失误报顶多浪费人工确认时间。5.2 调整置信度门限与 IOU 门限适配无人机巡检场景模型输出的每个框都带一个置信度预测时默认的门限是conf0.25。这个门限对于热红外小目标来说经常太高了。我在实际项目中一般会把置信度降下来测一轮看看漏检和误报的分布再定门限。# YOLOv8 预测 yolo predict modelruns/detect/train/weights/best.pt \ source./test_imgs \ conf0.15 \ iou0.45 # YOLOv5 预测 python detect.py \ --weights runs/train/exp/weights/best.pt \ --source ./test_imgs \ --conf-thres 0.15 \ --iou-thres 0.45conf0.15表示置信度高于 0.15 才保留框。门限调低召回率上升但误报也会变多。热红外场景里树的轮廓、房顶铁皮、太阳反光都会在红外图像里形成高亮区域低门限下很容易被误检成目标。如果单帧误报多一个常见的应对是用连续帧投票去抖同一目标在连续 5 帧里至少出现 3 次才输出报警无人机巡检场景中这种后处理比单纯调门限更有效。iou0.45控制在重叠框的合并力度。默认 0.45 适用于大多数场景。如果图像中目标密集、互相遮挡可以降低到 0.4 让更少的框被合并如果目标是稀疏的大目标可以提高到 0.6 来减少重复检测。参数本身不难理解难的是调完参数后要回答一个业务问题漏检和误报哪个代价更高。5.3 把模型导出成 ONNX在边缘设备上跑推理训练验证完的模型最终要部署到无人机或地面边缘设备上。YOLO 模型在 PyTorch 环境里跑推理是很方便的但实际部署时通常要转成中间格式再用推理引擎加速。最常见的格式是 ONNXyolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640导出成功后边缘设备上可以配合 TensorRT 或 OpenVINO 转换后运行。TensorRT 会把 ONNX 模型编译成针对特定 GPU 高度优化的 engine 文件推理速度能比 PyTorch 快数倍。如果你部署的目标是无人机机载小盒子一般还会用到 FP16 精度和动态 batch 优化这一步能显著降低显存占用和延迟。导出的模型要和训练时一致的imgsz否则输入尺寸不匹配会导致精度明显下降。部署到边缘盒子之后建议把测试图集也拷到盒子上跑一遍和 PC 上的结果做对比。同一模型在不同推理引擎下输出略有差异这是正常的浮点计算精度问题但如果差异大大概率是导出时的预处理和后处理配置不一致。6. 把 360 张用出超过 1000 张的效果增强与伪标签迭代360 张图是固定的但训练策略是灵活的。这一章讲两个在小数据集上效果最显著的操作按热红外特性调整数据增强以及用伪标签迭代扩充训练集。6.1 增强参数按热红外特性调整而不是用默认值YOLO 的数据增强默认是按可见光设计的热红外图像只有灰度或伪彩色很多增强策略需要调整。在 YOLOv8 中我通常这样配yolo detect train \ datathermal.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ mosaic1.0 \ mixup0.2 \ hsv_h0.0 \ hsv_s0.0 \ hsv_v0.4 \ flipud0.5 \ fliplr0.5hsv_h0.0和hsv_s0.0是关掉色调和饱和度扰动因为灰度热红外图根本没有色彩信息扰动只是白白增加计算量。hsv_v0.4保留亮度扰动热红外图像的亮度受发射率影响同一个目标在不同角度下温度表现确实不同适当的亮度扰动能提升鲁棒性。flipud0.5是垂直翻转无人机航拍图像里“颠倒”是真实的常见视角飞机倾斜飞行时这个增强对航拍数据的收益很直接。6.2 伪标签迭代用模型自己扩充训练集训练完第一版模型后我常用的操作是用模型对无人机热红外视频抽帧做推理把置信度高于 0.7 的预测框自动导出成伪标签人工只检查这些高置信框修正明显错框再把修正后的数据并入训练集重新训练。这样迭代两轮360 张图通常能扩充到 800 到 1200 张。这个方法的原理是模型自己已经学到的特征可以做“半自动标注”人工从“全部标注”降级为“只修正错误”工作量直接减半。需要提醒的是伪标签会放大模型的错误——模型误检的框会被当成正确标签进入下一轮训练因此必须做人工质检而且新增样本要尽量覆盖不同飞行高度、角度、时间段否则模型在不同场景下的误检会被越扩越固化。我最初做小数据集训练时习惯把 epoch 拉到 300结果验证集指标好看、现场测试翻车。后来排查发现问题出在验证集没有按飞行任务划分、mosaic 增强在训练后期没有关闭。现在我的流程固定下来了数据先校验再按航班分组划分训练时安排增强计划评估时以严格划分的验证指标为准。伪标签迭代是当前阶段扩展热红外小数据集最实际的路径但前提是每一轮新增的样本都要有人在看。希望帮到你。本文还有配套的精品资源点击获取
返回列表