
简介面向yolo系列算法目标检测与热红外无人机场景的数据集包包含360张jpg图像及一一对应的yolo格式txt标签和voc格式xml标签并附带数据集配置文件data.yaml。数据集已经划分好可直接用于yolov5/v8/v9/v7/v10/yolo11等模型的训练、验证与测试。适用于无人机热红外目标识别、遥感图像检测等任务适合有一定深度学习基础、需要现成标注数据快速开展实验的开发者。压缩包共1081个文件包含360个xml、360个txt、360个jpg和1个yaml包大小6.72MB标签格式说明清晰便于转换与适配。目前已有81人学习下载。拿到资源后可快速完成数据加载、模型配置和训练流程省去手工标注与数据划分时间同时提供yolo与voc双格式标签方便在不同框架或脚本间切换提升项目迭代效率。1. 热红外无人机数据集360 张带标签图像能直接把 YOLO 训练跑起来拿到这份热红外无人机数据集时我先做了一个很实际的判断360 张图像规模不大但每个样本同时带 YOLO 格式的 txt 标签和 VOC 格式的 xml 标签还预分了训练、验证、测试子集附带了 data.yaml 配置文件。对想上手 yolov8 目标识别、又不想从零开始标框的开发者来说这份资源的价值不是「大」而是「省事」解压 zip 之后你要做的就是把路径指对、把参数调顺。热红外图像和可见光图像的检测差异很明显目标亮度取决于温度差边缘模糊、对比度低、小目标占比高。你在常规数据集上调 YOLO 的经验放到这类数据上往往要多走几个来回。它适合三类人做遥感图像标注或无人机巡检的工程师想快速跑通 yolo 系列算法「训练-验证-测试」全流程的学生想对比 YOLOv5、YOLOv8、YOLOv9 在同一份热红外数据上表现的算法爱好者。2. 数据集结构拆解YOLO 格式与 VOC 格式双轨并存先理清再动手2.1 压缩包内的目录布局与文件配对关系先讲拿到 zip 之后的第一件事解压然后花五分钟把目录结构看清。这份数据的图像命名方式是img_批次号_帧号.jpg比如 img_0442_2.jpg、img_0804_1.jpg、img_0804_8.jpg、img_0804_15.jpg 这种形态。中间一段对应采集批次后面的数字是同一批次下的多帧编号。在热红外无人机巡检这类连续拍摄场景里相邻帧之间场景高度相似做视频流检测验证时可以直接按帧号拼接推理结果这是一个很实用的隐藏信息。目录层面图像文件、YOLO 格式标签、VOC 格式标签分别放在三个独立目录两个标签目录各自为政。这是热红外遥感数据常见的组织方式txt 给训练直接用xml 留给人机交互复检或者转成其它框架的标注格式。摘要里强调「两种格式分别保存在两个文件夹中」这个设计不是冗余——训练管线读 txt质检管线读 xml互不干扰避免在同一个目录里混着两种扩展名导致解析错乱。我拿到任何带标签数据集的第一动作永远是数量核对命令很简单ls images | wc -l ls yolo_labels | wc -l ls voc_labels | wc -l三个数字应该完全一致都是 360。如果不一致先别急着训练问题一定出在标签导出环节第 5 章我会专门展开讲。数量核对通过之后随机挑 5 张图同时打开对应的 txt 和 xml确认两者框的是同一个目标。这一步的意义在于YOLO 训练时程序靠「同名换扩展名」来配对标签文件名前缀一致、扩展名从 .jpg 换成 .txt 就能对上而 xml 文件内部直接写了图像文件名配对关系更明确。两份标签同时存在相当于给了你一次交叉验证的机会配对检查通过了再往下走能避免训练到一半才发现标签串位这种让人抓狂的问题。2.2 YOLO 标签格式五个数字的归一化坐标换算YOLO 格式每行五个数值对应一个目标框class x_center y_center width heightclass 是类别索引从 0 开始x_center 和 y_center 是目标框中心点坐标但不是像素值而是相对于图像宽度和高度的比例width 和 height 是框的宽高比例同样归一化到 0 到 1 之间。摘要里特意把这几个定义完整写出来了因为它是最容易产生理解偏差的地方。举一个具体换算例子。假设某张热红外图像分辨率是 640×512一个目标框在像素坐标系里的中心点是 (320, 256)框的像素宽高是 (80, 120)那么写入 txt 文件的数值是x_center 320 / 640 0.5y_center 256 / 512 0.5width 80 / 640 0.125height 120 / 512 0.234375对应的 txt 行是0 0.5 0.5 0.125 0.234375这里有一个我见过无数次的低级错误换算 height 的时候也拿图像宽度去除。正确的规则是「宽度方向除以图像宽度高度方向除以图像高度」。虽然归一化之后数值都在 0 到 1 之间看着像那么回事但比例一旦算错目标框在垂直方向上会被整体拉长或压扁。训练时 loss 偏高、验证集 mAP 上不去而你很难第一时间想到是标签本身出了问题。反向换算从归一化坐标还原像素坐标的公式是x_pixel (x_center - width / 2) * image_width y_pixel (y_center - height / 2) * image_height box_w_pixel width * image_width box_h_pixel height * image_heightx_pixel、y_pixel 得到的是目标框左上角的像素坐标。这套反向公式在做结果可视化和目标框裁剪质检时几乎天天用建议直接固化成脚本存着不要每次临时敲。2.3 VOC XML 标签的结构与双格式互转的取舍VOC 格式的 xml 结构相对固定annotation 根节点下是一组 object 节点每个 object 描述一个目标bndbox 子节点记录像素坐标 xmin、ymin、xmax、ymax。和 YOLO 格式的关键差别有两个一是坐标从归一化比例变成绝对像素值二是记录方式从「中心点 宽高」变成「左上角 右下角」。双格式并存时该用哪套训练我的习惯是优先用 YOLO 的 txt理由很朴素yolo 系列算法的训练脚本默认读 txt路径配置最省事纯文本逐行解析也快。xml 则当备份和复核工具用LabelImg 这类标注工具的生态对 xml 支持成熟转给 Detectron2 或 MMDetection 时也更顺。互转的公式是固定的。VOC 转 YOLOx_center (xmin xmax) / 2 / image_width y_center (ymin ymax) / 2 / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_heightYOLO 转 VOC 就是反向推算xmin (x_center - width / 2) * image_width ymin (y_center - height / 2) * image_height xmax (x_center width / 2) * image_width ymax (y_center height / 2) * image_height任何一个转换脚本都必须知道图像的实际像素宽高。这份数据集在导出时已经把参数正确用上了但你处理自己的数据时要特别注意如果一个数据集里图像尺寸不统一必须逐张读取宽高不能拿一张图的固定值套所有图。热红外相机一般分辨率固定但如果是多源数据合并这个坑很容易踩。2.4 数据集划分比例、单位以及一个常被忽略的重叠问题摘要里明确说数据集已经划分好这是目标检测数据集的加分项。常规比例是训练集 70%80%、验证集 10%15%、测试集 10% 左右。360 张图按 8:1:1 划分大约对应 288 张训练、36 张验证、36 张测试。这个比例对热红外小数据集是合理的验证和测试占比再高训练数据就不够用了。但比例合理不代表划分方式合理。真正容易被忽略的是重叠问题img_0804_1.jpg 到 img_0804_15.jpg 是同一场景的连续帧如果这些帧同时混进训练集和验证集验证指标会虚高。为什么模型在训练时见过同一场景几乎相同的画面验证时相当于「开卷考试」mAP 好看但不能真实反映泛化能力。正确做法是以场景批次为单位划分同一批次的所有帧进同一个子集。拿到这份数据集后我建议先按文件名前缀做一次场景分布统计确认各批次在三个子集里的归属。如果发现某个批次的帧被拆散到两个子集里要么接受这个偏差并降低对验证指标的期待要么自己动手重新按场景划分。对热红外无人机数据而言场景间差异大、场景内帧间差异小按场景划分比纯随机划分更贴近真实部署场景。3. data.yaml 与训练前置检查路径指对比调参更优先3.1 data.yaml 字段逐行解读data.yaml 是 yolov8 目标识别训练时的数据集配置文件它的正确性直接决定训练能不能启动。解压后打开这份数据的 data.yaml核心内容长这样目录名、类别数、类别名以你实际拿到的文件为准path: /absolute/path/to/dataset train: images/train val: images/val test: images/test nc: 2 names: 0: class0 1: class1逐行说。path 是数据集根目录建议写成绝对路径省得训练命令在不同目录下执行时出现「找不到数据集」的玄学问题。train、val、test 指向三个子集的路径path 生效时它们通常是相对路径。nc 是类别数量。names 是类别名列表索引从 0 开始顺序必须和 txt 标签里的类别索引严格对应。提示names 的写法在 YOLOv8 里支持字典和列表两种形式但如果你打算用 YOLOv5 跑这份数据旧版本对列表写法的兼容性更好。换框架时先验证数据配置文件能被正确解析拿一张验证集图像跑一次 predict 是最快的验证手段。数据集划分这个动作在摘要里被反复强调它的价值在于省去你手动分目录的工作。但「划分好」和「划分合理」是两回事yaml 文件里路径对不上、子集里混入其它批次的帧这些都不会在训练命令阶段报错只会默默污染你的指标。所以配置文件的检查优先级我放在超参调优之前。3.2 类别索引越界检查写训练命令之前必须先核对标签类别索引和 nc 的一致性。YOLO 格式类别从 0 编号如果标签里出现类别索引 3 而 data.yaml 里 nc 只写了 2训练时索引 3 会被判定越界轻则日志警告重则 loss 计算异常、验证指标错乱。检查命令极简扫描所有 txt 里 class 列的最大值awk {print $1} yolo_labels/*.txt | sort -n | tail -1输出的最大值加 1 应该等于 nc。这个动作成本几乎为零但能拦住最隐蔽的一类数据事故。我每拿到新数据集都把它和图像数量核对放在同一个「五要素自查」里图像总数、标签总数、类别最大索引、坐标范围、子集重叠五项全绿才开始配训练参数。另外要留意空标签文件。有些图像没有目标对应的 txt 是 0 字节这是合法的负样本但如果 awk 扫描时把空文件也读进去输出结果不受影响只是它不产生任何类别索引。真正要警惕的是「本该有目标的图像标签文件被写空」——这种文件在训练时会被当成背景样本相当于喂进去一批错误标注。检查方法是抽查几个 txt 为空的图像肉眼确认画面里确实没有目标。3.3 输入分辨率与图像长宽比的匹配最后一个前置项是 imgsz 的选择。YOLO 训练会把训练图缩放成统一输入尺寸默认 imgsz640。热红外图像如果原始分辨率是 640×512 这类接近方形的规格imgsz640 无压力如果原图长宽比明显偏离 1:1缩放时会产生较多 padding 区域这些区域没有目标信息反而干扰特征提取。选择建议优先让 imgsz 接近原始分辨率的长边同时向上取整到 32 的倍数。YOLO 网络下采样 5 次输入尺寸必须能被 32 整除否则会报维度不匹配的错误。比如原图 640×512imgsz640 就合适原图 1280×1024显存允许的话直接 imgsz1280小目标保留的细节会多很多。显存紧张时可以开矩形训练让同一 batch 内的图像按长宽比分组减少无效填充。热红外图像的小目标问题在 imgsz 这个参数上表现得最直接。同一份 360 张的数据imgsz640 和 imgsz1280 训练出来的模型对小目标的召回率可能差 5 到 10 个百分点。代价是显存占用和训练时间基本翻倍所以这个参数值得你花一轮实验去确定而不是一直用默认值。3.4 用脚本确认三个子集无重叠、无漏标数据集划分的合理性可以靠脚本量化。下面这段是我固定使用的划分检查脚本改了路径就能直接跑import os base dataset_root subsets [images/train, images/val, images/test] label_dir yolo_labels all_images set() total 0 for sub in subsets: files os.listdir(os.path.join(base, sub)) total len(files) print(f{sub}: {len(files)} 张) all_images.update(files) print(去重后总数:, len(all_images), | 子集数量之和:, total) missing [] for sub in subsets: for f in os.listdir(os.path.join(base, sub)): stem os.path.splitext(f)[0] txt os.path.join(label_dir, stem .txt) if not os.path.exists(txt): missing.append(stem) print(缺标签:, missing if missing else 无)逻辑说明先把三个子集的图像文件名做并集去重如果去重后的数量和三个子集数量之和相等说明子集之间没有文件重叠划分干净然后遍历每张图检查同名 txt 是否存在于标签目录找出漏标样本。参数上base 改成你解压后的数据集绝对路径label_dir 改成实际的 YOLO 标签目录名。整个脚本跑完不到十秒但能拦住大部分「数据集不干净」导致的训练异常比回头排查 loss 曲线实惠得多。4. 用 YOLOv8 跑通训练安装、命令与日志解读4.1 环境安装与模型选型YOLOv8 是 yolo 系列算法里目前工程落地最多的版本通过 ultralytics 一个 Python 包分发。安装前确认 Python 不低于 3.8PyTorch 的 CUDA 版本和显卡驱动匹配然后一条命令装完pip install ultralytics安装完先做冒烟测试不要直接开训。拿 yolov8n.pt 预训练权重对一张验证集图像跑一次推理yolo predict modelyolov8n.pt sourceimages/val/img_0442_2.jpg这条命令能正常输出检测结果的话说明 ultralytics、PyTorch、权重文件全部就绪。冒烟测试的意义在于把「环境问题」和「数据集问题」隔离开后续训练报错时你至少能确定不是环境层面出了毛病。模型选型上这份数据只有 360 张图属于典型小数据量场景。我不建议一上来就用 yolov8x 这类大模型——参数多小数据极易过拟合训练周期还长。从 yolov8nnano或 yolov8ssmall起步先把流程跑通再根据验证集指标决定是否升级模型尺寸。对热红外目标检测来说模型尺寸带来的收益通常小于数据增强带来的收益所以选小模型起步是更务实的选择。4.2 训练命令与关键超参说明数据集配置好、环境验证通过之后正式训练命令yolo detect train datathermal_uav.yaml modelyolov8n.pt epochs150 imgsz640 batch16 lr00.01 patience50每个参数都值得展开。data 指向 data.yaml 路径建议用绝对路径。model 指定初始化权重yolov8n.pt 是 COCO 预训练权重用它做初始化能显著加快收敛——360 张图像从零训练基本不会有好效果迁移初始化几乎是必选项。epochs150 是小数据集的合理起点配合早停可以防止无效训练。imgsz 是输入分辨率640 对接近方形原图是安全选择。batch16 要看显存不够降到 8 或 4梯度噪声会变大但小数据集上影响可控。lr0 是初始学习率默认 0.01 通常够用发现 loss 震荡剧烈时降到 0.001。patience50 表示连续 50 轮验证集指标无提升就提前停止训练。训练超参之间有联动关系我习惯用这张表来记忆和调整参数典型值调参方向epochs100200数据量小可以多训靠早停兜底imgsz640 或原图长边小目标多就往上调注意显存batch832显存不足时优先降这个lr00.01 / 0.001loss 震荡就降收敛太慢就升patience2050小数据多轮无提升很正常给足耐心4.3 数据增强参数对热红外图像的影响YOLOv8 的训练命令里可以附加一批数据增强参数这些参数在热红外场景下的调法和可见光很不一样。常用的是这几个yolo detect train datathermal_uav.yaml modelyolov8n.pt epochs150 imgsz640 batch16 hsv_h0.015 hsv_s0.7 hsv_v0.4 fliplr0.5 scale0.5 mosaic1.0hsv_h、hsv_s、hsv_v 控制色调、饱和度、亮度的随机扰动幅度。热红外图像本身没有颜色信息色调扰动基本无效可以保持默认或调低但亮度扰动很关键——飞行高度、光照时段变化会让目标温度差波动适度调大 hsv_v 能提升模型对亮度变化的鲁棒性。fliplr 是水平翻转概率0.5 是常用值对无人机航拍数据安全。scale 是尺度缩放0.5 意味着训练时图像有 50% 的随机缩放空间这对小目标检测是有益的但也别调太大否则目标被缩得太小学习不到特征。mosaic 马赛克增强把四张图拼成一张训练对检测小目标帮助明显但要注意热红外图像背景单调马赛克拼接后可能出现大量无意义的边界线干扰模型学习。如果用了 mosaic 发现 loss 曲线震荡加剧可以先保留但观察几轮或者把 mosaic 概率降到 0.5 试试。增强参数的调整原则是一条一条来每次只动一个参数跑一轮验证集记录 mAP50 变化别一上来全改否则哪个参数有效根本说不清。4.4 训练日志与结果指标解读训练启动后ultralytics 会在 runs/detect/trainN 目录下保存结果其中 results.csv 记录的每一轮的 train_loss、val_loss、precision、recall、mAP50、mAP50-95 是判断训练是否健康的全部依据。训练过程不是黑匣子这个 csv 文件能告诉你所有答案。我习惯做两件事。第一看 train_loss 和 val_loss 的间距。训练初期两条线一起下降是正常的如果 train_loss 一路走低但 val_loss 在某轮开始回升说明过拟合已经开始早停机制会自动截断。第二看 mAP50 和 mAP50-95 的差值。热红外小目标数据上 mAP50 能到 0.8 算可用mAP50-95 通常低 0.2 左右因为小目标框位置稍微偏移高 IoU 阈值下就判定不中了。如果两者差值过大说明框定位精度不足优先检查标签坐标是否有系统偏差。验证集指标之外还有个常被忽视的动作训练结束后用 best.pt 跑一遍测试集对比验证集和测试集的 mAP。如果验证集 0.85、测试集只有 0.4大概率是数据集划分时场景重叠或者测试集混入了分布外样本。这个落差检查应该作为每次训练周期的固定收尾动作它比任何指标曲线都更能反映真实泛化水平。5. 避坑与常见问题热红外图像训练最容易翻车的五个场景5.1 标签文件与图像数量对不上现象数量核对时发现 YOLO 标签目录下的 txt 数量比图像目录少几张或多了几张训练日志里频繁出现 Warning: label file not found。原因数据集导出时部分没有目标的图像被过滤没有生成标签但图像文件本身还被保留或者拷贝压缩包过程中漏掉了个别小文件txt 体积小被同步工具跳过的情况很常见。解决先用文件名列表求差集定位缺失文件comm -23 (ls images | sort) (ls yolo_labels | sed s/\.txt$/.jpg/ | sort)对没有标签的图像先人工看一眼确认是否有目标。如果确实没有目标保留图像不配标签没问题相当于负样本如果有目标但标签丢了这份数据同时带 VOC xml可以直接从 xml 恢复 txt省去重新标注的成本。血泪经验是不要自己手动补标签人工补框的精度波动很大而且 360 张图全部重做一遍代价太高。5.2 归一化坐标越界导致训练警告现象训练日志反复出现 Box coordinates outside of image bounds训练能跑完但最终检测框大量贴边或出画面。原因标注时目标框画到了图像边缘导出程序没有把坐标裁到 0 到 1 范围x_center width / 2 超过 1 或 y_center height / 2 超过 1。热红外图像目标边缘模糊标注员在画框时容易把框超出画面边界这类错误在可见光数据里相对少见但在热红外数据里出现频率明显更高。解决写脚本扫描所有 txt对越界坐标做 clamp 处理import os label_dir yolo_labels for f in os.listdir(label_dir): if not f.endswith(.txt): continue path os.path.join(label_dir, f) lines open(path).readlines() fixed [] for line in lines: parts line.strip().split() if len(parts) ! 5: continue cls, xc, yc, w, h parts xc, yc, w, h map(float, [xc, yc, w, h]) xc min(1.0, max(0.0, xc)) yc min(1.0, max(0.0, yc)) w min(1.0, max(0.0, w)) h min(1.0, max(0.0, h)) fixed.append(f{cls} {xc:.6f} {yc:.6f} {w:.6f} {h:.6f}) if fixed ! lines: open(path, w).writelines(line \n for line in fixed) print(越界坐标已修正)注意 clamp 是兜底手段只对轻微越界有效如果某个框有一半在画面外处理前先人工确认是不是标注错误而不是盲目修正。5.3 类别编号从 0 还是从 1 开始现象训练 loss 正常下降但可视化检测结果时发现类别标签整体错位比如把甲类目标全部识别成乙类。原因YOLO 格式类别索引从 0 开始但采集端标注工具导出时类 ID 从 1 编号转换脚本漏减 1导致所有标签类别索引整体偏移一个位置。这个问题在双格式数据集里更容易出现因为 VOC 转 YOLO 的过程中如果只转坐标忘了处理类别索引就会带病投产。解决扫描所有 txt 的 class 列最大值和 data.yaml 里的 nc 对比。如果最大值等于 nc 而不是 nc - 1说明存在一个没有定义在 names 里的类别索引基本可以判定是编号偏移。修正时把每个 txt 里的 class 字段统一减 1然后重新跑一遍最大值检查。整个过程务必保留修正前的备份用 cp -r 复制一份原始标签目录万一判断错误还有后悔药。5.4 热红外图像对比度低导致小目标漏检现象训练正常跑完指标也不差但推理时对远处的小目标频繁漏检尤其当目标和地面背景温度接近时误检率也明显上升。原因热红外图像信噪比低目标与背景的亮度差异取决于温差而不是纹理特征小目标有效像素常只有几十个特征极弱模型很难学出稳定表达。这和可见光数据的「目标边缘清晰、颜色可分」完全不同是热红外检测最核心的难点。解决三个方向叠加。一是数据增强对训练图做 CLAHE 对比度增强和随机亮度扰动让模型对温度差别的鲁棒性更强二是模型侧把 imgsz 往上提保留更多小目标空间细节三是后处理侧推理时把 conf 阈值从默认 0.25 降到 0.15 左右配合 NMS IoU 阈值适当放宽。三个手段一次只改一个变量跑一轮验证集看 mAP 变化别同时改多个参数否则你根本不知道是哪个起了作用。5.5 训练中断丢进度现象训练到第 80 轮时断电或者显存溢出进程被杀重新执行命令发现从头开始训练。原因没有理解 ultralytics 的断点机制。其实每次 epoch 结束它都会自动保存 last.pt 和 best.pt 到 weights 目录恢复训练只需要把 model 参数指向 last.pt。很多人以为训练命令一断就全完了其实这份数据集的训练成本不高重训一次也就几十分钟但如果你在更大的数据上断了没续损失就不是时间问题了。解决断点续训命令如下yolo detect train datathermal_uav.yaml modelruns/detect/trainN/weights/last.pt epochs150注意 epochs 要填完整的轮次目标ultralytics 会从 last.pt 里读取已训练轮数并自动调整剩余轮次。显存溢出导致的训练中断核心解法是降 batch从 16 降到 8再把 imgsz 略降通常就能稳定跑完。训练前把 batch 和 imgsz 的乘积控制在显存安全线以下比中断后再调省心得多。6. 最后一步训练前用十分钟跑一遍标注自检脚本训练代码没问题、超参配好了但数据不干净照样翻车。我最后一次建议是在敲训练命令之前把下面这个标注自检脚本跑掉。它把 5.1 到 5.3 的三个检查合并成一次执行覆盖数量配对、类别索引、坐标范围三个最容易出问题的维度import os import glob image_dir images/train label_dir yolo_labels issues [] class_max -1 image_count 0 for img in glob.glob(os.path.join(image_dir, *.jpg)): image_count 1 stem os.path.splitext(os.path.basename(img))[0] txt os.path.join(label_dir, stem .txt) if not os.path.exists(txt): issues.append(f{stem}: 缺少标签) continue with open(txt) as f: for line in f: parts line.strip().split() if len(parts) ! 5: issues.append(f{stem}: 字段数异常) continue cls, xc, yc, w, h parts cls int(float(cls)) xc, yc, w, h map(float, [xc, yc, w, h]) class_max max(class_max, cls) if xc 1 or yc 1 or xc 0 or yc 0: issues.append(f{stem}: 中心点越界) if w 1 or h 1 or w 0 or h 0: issues.append(f{stem}: 宽高越界) print(f图像数: {image_count}) print(f最大类别索引: {class_max} | data.yaml 里 nc 应为 {class_max 1}) print(f发现问题: {len(issues)} 条) for item in issues[:20]: print( -, item)用法说明把 image_dir 和 label_dir 改成你实际解压后的路径先跑训练集再分别跑验证集和测试集。输出的最大类别索引用 6.2 的对比逻辑和 data.yaml 的 nc 做减法核对有任何一条 issue 出现都要先处理掉再训练。这个脚本的本质是把前面几章的手工检查固化成了自动化动作十分钟内能完成对全部图像的体检。从那以后我拿到任何新数据集不管来源多正规都强制先跑一遍这个流程数量核对、类别索引核对、坐标越界扫描、子集重叠检查四项全绿才允许自己动训练命令。这套习惯救过我几次有一次就是靠越界扫描发现某一批标签是从另一套分辨率数据里直接拷贝过来的所有框都整体偏移了要不是提前拦住训练完才发现就得全部返工。希望这份数据集和这套检查流程能帮你少走一段弯路。本文还有配套的精品资源点击获取