资讯详情

资讯详情

红外多目标检测数据集:1000张图+三格式标签+划分脚本

简介本资源为面向目标检测学习者的YOLO红外多目标检测数据集适用于红外场景下的算法训练、课程设计与科研实验可解决红外图像样本稀缺、标注格式不统一的问题。压缩包共2000个文件约96.39MB包含1000张真实场景红外图片以及vocxml、cocojson和yolotxt三种格式标签另附yaml配置文件、划分脚本与教程页面方便直接接入YOLO系列训练流程。资源还提供训练集、验证集、测试集划分脚本可按需生成ImageSets下的txt文件并附Windows与Linux环境搭建及训练案例教程帮助读者快速跑通从数据准备到模型训练的全过程。目前已有458人学习下载适合具备一定深度学习基础、希望快速开展红外多目标检测实践的高校学生与算法工程师参考使用。1. 红外多目标检测数据集1000 张图、三套标签、划分脚本一次到位做红外目标检测的同行大概都有过这种体验算法论文里的 mAP 刷得飞起真到自己上手卡住的地方往往不是模型结构而是数据。可见光数据集一抓一大把红外波段的却少得可怜要么是场景单一要么是标注质量堪忧要么只给一种标签格式光格式转换就能耗掉一整天。这份 YOLO 红外多目标检测数据集就是冲着这个痛点来的——1000 张真实场景红外图像用 labelImg 标注同时提供 VOCxml、COCOjson、YOLOtxt三种格式标签还附带了数据集划分脚本和 Windows/Linux 双平台的 YOLO 环境搭建与训练教程。它适合正在做红外目标检测、需要快速搭起训练流水线的从业者也适合想跑通 YOLO 全流程但不想在数据准备上反复踩坑的新手。下面我按「数据长什么样 → 怎么划分 → 怎么训练 → 坑在哪」的顺序把这份资源拆开讲清楚。2. 三套标签格式与目录结构先搞懂手里有什么再动手2.1 VOC、COCO、YOLO 三种标签的差异与选用逻辑很多人拿到多格式标签的第一反应是「随便挑一个用」结果训练脚本报错才发现格式对不上。这三种格式的本质区别在于坐标表示和文件组织方式。VOC 格式用 xml 文件描述每张图坐标是绝对像素值结构是xmin ymin xmax ymax一个目标一个object节点。它的好处是可读性强、工具兼容广labelImg 默认就输出这个。COCO 格式把所有标注塞进一个 json 文件坐标同样是绝对像素值但用[x, y, width, height]表示还带category_id、image_id等字段适合做多数据集统一管理。YOLO 格式最简洁每张图对应一个 txt每行是类别 x_center y_center width height坐标全部归一化到 0~1 之间。选哪个取决于你的训练框架。YOLO 系列v5/v7/v8直接吃 YOLO 格式省去转换步骤如果你要用 Detectron2 或 MMDetectionCOCO 格式更顺手VOC 格式则适合做数据审查和二次标注。这份资源三种都给全了等于把选择权交回你手里。提示三种格式的标注框必须一一对应如果发现某个格式的目标数量对不上优先检查是否有图片漏标或标签文件缺失。2.2 目录组织与文件命名规范拿到压缩包解压后常见的目录结构是这样的dataset/ ├── images/ # 所有红外图片 ├── labels_voc/ # VOC 格式 xml ├── labels_coco/ # COCO 格式 json ├── labels_yolo/ # YOLO 格式 txt ├── ImageSets/ # 划分后的索引文件 │ └── Main/ │ ├── train.txt │ ├── val.txt │ └── test.txt └── scripts/ # 划分脚本图片和标签的对应关系靠文件名维系比如00123.jpg对应00123.xml、00123.txt。这里有个容易翻车的点如果图片是.jpg而标签脚本里写死了.png划分出来的 txt 里路径全是错的训练时直接报「找不到文件」。我一般会先跑一遍文件名一致性检查确认图片和标签的主文件名完全匹配再往下走。2.3 用 Python 快速校验图片与标签的配对情况在动手划分之前先花两分钟做一次配对校验能省掉后面大量排查时间。下面这段脚本扫描图片目录和 YOLO 标签目录找出缺失对应文件的样本import os img_dir dataset/images label_dir dataset/labels_yolo # 收集主文件名不含扩展名 img_names {os.path.splitext(f)[0] for f in os.listdir(img_dir) if f.lower().endswith((.jpg, .png, .jpeg))} label_names {os.path.splitext(f)[0] for f in os.listdir(label_dir) if f.lower().endswith(.txt)} # 找出有图无标签、有标签无图的情况 img_no_label img_names - label_names label_no_img label_names - img_names print(f图片总数: {len(img_names)}) print(f标签总数: {len(label_names)}) print(f有图无标签: {len(img_no_label)} - {sorted(img_no_label)[:10]}) print(f有标签无图: {len(label_no_img)} - {sorted(label_no_img)[:10]})逻辑很直白用集合差集找出不配对的文件。参数上img_dir和label_dir按你实际解压路径改。如果输出里「有图无标签」数量不为零说明这些图没标注或者标注文件命名不一致训练前必须处理掉否则 YOLO 加载时会直接跳过甚至报错。3. 数据集划分脚本train/val/test 怎么切才不翻车3.1 三个划分脚本的分工与适用场景资源里带了三个划分脚本名字分别是「训练集、验证集、测试集划分脚本」「训练集、验证集划分脚本」和「split_train_val 生成 ImageSets 下 txt 文件划分脚本」。它们解决的是同一个问题的不同层次第一个脚本把数据切成 train/val/test 三份适合需要独立测试集评估最终性能的场景。第二个只切 train/val 两份适合数据量不大、想把更多样本留给训练的情况。第三个脚本生成的是 ImageSets/Main 下的 txt 索引文件这种组织方式更接近 VOC 数据集的惯例适合配合某些按索引读取数据的训练框架。我一般会先想清楚评估策略再选脚本如果要做严格的泛化性能对比就用三划分如果只是快速迭代调参两划分够用。别小看这个选择测试集切多了训练样本不够模型欠拟合切少了评估结果波动大今天涨两个点明天掉三个点纯属玄学。3.2 划分脚本的核心参数与运行方式以三划分脚本为例典型用法是在命令行传入图片目录、标签目录、输出目录和比例python split_train_val_test.py \ --img_dir dataset/images \ --label_dir dataset/labels_yolo \ --out_dir dataset/ImageSets/Main \ --train_ratio 0.7 \ --val_ratio 0.2 \ --test_ratio 0.1 \ --seed 42参数说明train_ratio、val_ratio、test_ratio三者之和必须为 1常见配比是 7:2:1 或 8:1:1。seed是随机种子固定它才能保证每次划分结果一致——这点在做对比实验时特别重要否则你换了模型结构结果变好了可能只是因为这次划分恰好把简单样本分到了验证集。out_dir下会生成 train.txt、val.txt、test.txt每行是一个图片的相对或绝对路径。脚本内部一般做三件事读取所有图片文件名、用random.shuffle打乱、按比例切片写入 txt。有的脚本还会同步复制图片和标签到对应子目录方便直接喂给训练框架。3.3 划分后如何验证结果没有重叠和遗漏划分完别急着开训先验证三份索引没有交集、并集等于全集。下面这段检查脚本很短但很关键def load_set(path): with open(path, r) as f: return set(line.strip() for line in f if line.strip()) train load_set(dataset/ImageSets/Main/train.txt) val load_set(dataset/ImageSets/Main/val.txt) test load_set(dataset/ImageSets/Main/test.txt) print(ftrain: {len(train)}, val: {len(val)}, test: {len(test)}) print(ftrain∩val: {len(train val)}) print(ftrain∩test: {len(train test)}) print(fval∩test: {len(val test)}) print(f并集总数: {len(train | val | test)})理想输出是三个交集都为 0并集总数等于图片总数。如果交集不为 0说明脚本的切片逻辑有 bug常见原因是用了random.choices而不是random.sample导致同一样本被重复抽到。并集小于总数则说明有样本没被分到任何集合通常是比例之和没凑够 1 或者浮点取整出了问题。注意划分脚本里的路径分隔符在 Windows 和 Linux 下不一样Windows 用反斜杠Linux 用正斜杠。如果脚本里硬编码了分隔符跨平台跑就会出问题建议用os.path.join拼接。4. 从环境搭建到跑通训练Windows 与 Linux 两条路4.1 环境搭建的关键差异与依赖版本资源里给了 Windows 和 Linux 两套环境搭建教程外加一份 Ubuntu 安装教程。两条路的核心差异在 CUDA 和 cuDNN 的安装方式Windows 下通常是下载安装包一路下一步Linux 下更多用 apt 或 conda 管理。不管哪个平台YOLO 训练的依赖链大致是Python 3.8、PyTorch带 CUDA 支持、torchvision、OpenCV、numpy、tqdm、pyyaml。版本匹配是最大的坑——PyTorch 版本和 CUDA 版本必须对应比如 PyTorch 2.0 对应 CUDA 11.7/11.8装错了要么 import 报错要么训练时提示「CUDA not available」然后默默退回 CPU速度慢到你怀疑人生。我一般用 conda 建独立环境避免和系统 Python 打架conda create -n yolo_ir python3.9 -y conda activate yolo_ir pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install opencv-python numpy tqdm pyyaml matplotlib--index-url指定 PyTorch 官方源cu118表示 CUDA 11.8 版本。装完跑一句python -c import torch; print(torch.cuda.is_available())输出 True 才算环境通了。4.2 修改配置文件适配自己的数据集YOLO 训练教程里通常会让你改一个 yaml 配置文件核心字段包括train、val、nc、names。以 YOLOv5 为例# data/ir_dataset.yaml train: dataset/ImageSets/Main/train.txt val: dataset/ImageSets/Main/val.txt nc: 3 names: [person, vehicle, animal]train和val指向划分脚本生成的 txt 文件里面是图片路径。nc是类别数必须和你标注时的类别数一致多一个少一个都会导致训练时报维度不匹配。names是类别名称列表顺序要和标注时的类别 id 对应——labelImg 标注时类别 id 从 0 开始names 列表的第 0 个就是 id 0 对应的类名。改完配置后先跑一次train.py --data ir_dataset.yaml --epochs 1 --batch-size 4做冒烟测试确认数据能正常加载、loss 能正常下降再放开轮数正式训练。这一步能帮你提前发现路径错误、标签格式错误、类别数不匹配等问题。4.3 训练启动命令与关键参数解读正式训练时常用命令长这样python train.py \ --data data/ir_dataset.yaml \ --weights yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --img-size 640 \ --device 0 \ --workers 4 \ --project runs/train \ --name ir_exp1--weights指定预训练权重从yolov5s.pt开始比从零训练收敛快得多红外数据量不大时尤其明显。--img-size是输入分辨率红外图像细节少640 通常够用显存紧张可以降到 416。--batch-size受显存限制16 跑不动就降到 8 或 4。--device 0指定第一块 GPU多卡用0,1。--workers是数据加载线程数Windows 下设太大会报共享内存错误一般 2~4 就够。训练过程中重点看三个指标box_loss 是否稳定下降、mAP0.5 是否在涨、验证集 loss 是否开始反弹。如果训练 loss 降但验证 loss 涨说明过拟合了可以加数据增强或者减轮数。5. 避坑排查红外数据集训练最容易翻车的五个地方5.1 标签坐标越界导致训练报错现象训练启动后报AssertionError: Label out of bounds或类似提示进程直接退出。原因YOLO 格式要求归一化坐标在 0~1 之间但标注时如果框拖到了图像边界外或者转换脚本没做裁剪就会出现大于 1 或小于 0 的值。解决跑一遍标签清洗脚本把越界坐标裁剪回 [0,1] 范围或者直接剔除这些异常标注。下面这段可以快速定位问题文件import os label_dir dataset/labels_yolo for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname)) as f: for i, line in enumerate(f): parts line.strip().split() if len(parts) 5: print(f{fname} 第{i}行格式异常: {line.strip()}) continue coords list(map(float, parts[1:5])) if any(c 0 or c 1 for c in coords): print(f{fname} 第{i}行坐标越界: {coords})5.2 类别 id 不连续导致 nc 配置错误现象训练时提示IndexError: index out of range或者类别预测全乱。原因标注时类别 id 可能不是从 0 连续编号的比如只有 0 和 2 两类中间缺了 1。但配置文件里nc: 2模型输出两个类别标签里的 id 2 就溢出了。解决统计所有标签文件里出现过的类别 id确认是否连续。如果不连续要么重新映射成连续 id要么把nc设成最大 id 加一。我一般会在划分前先跑一次类别统计心里有数再配。5.3 图片路径含中文或空格导致读取失败现象训练时部分图片加载失败日志里显示路径被截断或乱码。原因OpenCV 在 Windows 下对中文路径支持不好路径里有空格也会被命令行解析截断。解决把数据集放在纯英文、无空格的路径下比如D:/datasets/ir_data/。如果实在要用中文路径改用cv2.imdecode(np.fromfile(path, dtypenp.uint8), cv2.IMREAD_COLOR)读取但这需要改训练框架的源码不如直接换路径省事。5.4 划分时随机种子不固定导致结果不可复现现象同样的数据和脚本跑两次划分结果不一样模型评估指标波动大。原因划分脚本没设随机种子每次random.shuffle都是新的顺序。解决在脚本开头加random.seed(42)并把seed作为命令行参数暴露出来。做对比实验时固定种子才能保证变量只有一个——你改的那个模型结构。5.5 验证集和测试集混用导致评估虚高现象模型在验证集上 mAP 很高换一批数据就崩。原因调参时反复用验证集评估无形中把验证集「训」进了模型选择过程它不再代表真实泛化能力。解决严格区分验证集和测试集。验证集用于调参和早停测试集只在最终确定模型后跑一次。如果数据量实在小至少保证测试集从头到尾不参与任何调参决策。6. 进阶技巧用 ImageSets 索引做交叉验证与增量训练跑通单次训练只是起点。这份资源里的 ImageSets 索引文件其实还能玩出更多花样。比如做 K 折交叉验证把 train.txt 和 val.txt 合并用脚本重新切成 K 份每次取一份做验证、其余做训练跑 K 次取平均指标。这样评估结果比单次划分稳得多尤其适合 1000 张这种中小规模数据集。具体做法是写一个 K 折划分脚本核心逻辑是sklearn.model_selection.KFoldfrom sklearn.model_selection import KFold with open(dataset/ImageSets/Main/train.txt) as f: all_lines [line.strip() for line in f if line.strip()] kf KFold(n_splits5, shuffleTrue, random_state42) for fold, (train_idx, val_idx) in enumerate(kf.split(all_lines)): with open(fdataset/ImageSets/Main/fold{fold}_train.txt, w) as f: f.write(\n.join(all_lines[i] for i in train_idx)) with open(fdataset/ImageSets/Main/fold{fold}_val.txt, w) as f: f.write(\n.join(all_lines[i] for i in val_idx))n_splits5是折数shuffleTrue打乱顺序random_state固定种子。生成五组 train/val 后依次改 yaml 配置跑训练最后把五次的 mAP 平均一下比单次结果可信得多。另一个实用场景是增量训练。红外数据往往需要持续补充新场景样本每次重新从头训练成本太高。可以拿上一次训练好的权重做初始化只在新数据上微调几个 epoch。命令上就是把--weights从yolov5s.pt换成runs/train/ir_exp1/weights/best.pt学习率调小到原来的十分之一避免把已经学好的特征冲掉。还有个细节值得注意红外图像和可见光图像的像素分布差异很大直接用可见光预训练权重做初始化前几个 epoch 的 loss 可能会跳一下。我的习惯是先用红外数据跑 5 个 epoch 的 warmup学习率从 0.001 线性升到 0.01让模型先适应红外域的数据分布再进入正常训练。这个技巧在数据量不大时对最终精度有肉眼可见的帮助。从那以后我每次拿到新数据集都强制先跑一遍配对校验和类别统计再动划分脚本最后才碰训练命令。顺序反了后面全是后悔药。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →