红外小目标检测实战:YOLOv5预训练权重与4000张数据集快速上手
发布时间:2026/10/13 9:28:03 锦皓数字建站

简介本资源面向红外场景下的目标检测学习者与研究者提供一套可直接复用的YOLOv5红外微小无人机、直升机、飞机、飞鸟检测方案解决红外小目标样本稀缺、标注与训练环境搭建繁琐的问题。包内包含4000余张YOLO格式红外图像数据集标签为txt格式已划分train、val、test并附data.yaml类别涵盖Airplane、Bird、Drone、Helicopter四类yolov5、yolov7、yolov8等算法均可直接训练。资源共2000个文件以1994个xml标注文件为主另含3个Python脚本与3份PDF教程压缩包约587.15MB目录结构清晰便于按模块检索与二次开发。配套PyQt界面支持图片、视频检测及摄像头调用可直观验证模型效果。已有548人学习下载适合需要快速复现红外小目标检测、完成课程设计或科研实验的读者参考使用。1. 红外小目标检测的现成权重与数据集这套资源到底能省多少事红外场景下做微小无人机、直升机、飞机和飞鸟的检测最耗时的从来不是写模型代码而是凑数据、标数据、调类别、配环境这一整套脏活。你拿到一份 yolov5 训练好的权重外加 4000 多张已经标好、划分好 train/val/test 的红外数据集还有一份能直接跑图片、视频、摄像头的 PyQt 界面意味着从解压到看见检测框中间可能只隔着一次环境配置。这套资源面向的是做低空目标探测、红外监控、边缘部署验证的从业者和学生尤其是那些不想在数据清洗上再花两周、只想先把 baseline 跑起来看效果的人。它把 nc4 的类别定义、data.yaml、yolo 格式 txt 标签全部对齐yolov5、yolov7、yolov8 都能直接吃进去训练省掉的是最枯燥的格式转换和目录整理环节。2. 数据集结构与标签格式先看懂目录再动手2.1 data.yaml 与四类目标的定义逻辑这套资源的核心配置就落在 data.yaml 上内容很干净nc: 4 names: [Airplane, Bird, Drone, Helicopter]nc 是类别数names 的顺序决定了标签 txt 里类别索引的含义。这里 0 对应 Airplane1 对应 Bird2 对应 Drone3 对应 Helicopter。顺序一旦改动之前训练好的权重就废了因为输出层的通道顺序和标签索引是绑死的。常见做法是先把 names 抄进自己的训练脚本再检查一遍标签文件里有没有超出 0-3 的索引值有就说明标签和配置对不上。红外图像和可见光图像在标注上有区别红外目标边缘模糊、对比度低微小无人机在画面里可能只有十几个像素标注框稍微偏一点训练时正样本就丢了。这套数据集的标签是 yolo 格式 txt每行五个值类别索引、归一化中心 x、归一化中心 y、归一化宽、归一化高。归一化意味着所有坐标都在 0 到 1 之间和图像绝对尺寸无关换分辨率也不用改标签。2.2 目录划分与 train/val/test 的实操检查数据集已经划分好 train、val、test目录结构通常是 images 和 labels 平行放置每个 split 下再分。拿到之后第一件事不是急着训练而是做一次完整性校验images 里的每张图labels 里有没有同名 txttxt 是不是空的txt 里的数值有没有越界。我一般会跑一段脚本快速过一遍import os # 校验 images 与 labels 是否一一对应并检查标签数值范围 root dataset for split in [train, val, test]: img_dir os.path.join(root, images, split) lbl_dir os.path.join(root, labels, split) imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} missing imgs - lbls print(split, 图片数:, len(imgs), 标签数:, len(lbls), 缺标签:, len(missing)) for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for line in fp: parts line.strip().split() if len(parts) ! 5: print(格式异常:, f, line) continue cls, cx, cy, w, h map(float, parts) if cls not in (0, 1, 2, 3) or not all(0 v 1 for v in (cx, cy, w, h)): print(数值越界:, f, line)这段脚本做三件事比对文件名集合找出缺标签的图片检查每行是不是五个字段检查类别索引和归一化坐标是否在合法范围。参数上 root 指向数据集根目录split 列表按实际划分调整。跑完如果 missing 为 0、没有越界输出说明数据层面基本干净可以进入训练。提示红外数据集里偶尔会有全黑或几乎无目标的负样本图对应 txt 为空是正常的不要当成错误删掉负样本对降低误检有帮助。2.3 从 4000 张到可训练划分比例与类别均衡4000 多张图在目标检测里不算大但红外场景本身数据就稀缺这个量级够跑出一个可用的 baseline。关键是看四类分布是否均衡。无人机和飞鸟在红外下的形态有时接近如果 Drone 和 Bird 样本量差距过大模型容易把两者混淆。检查类别分布可以这样统计from collections import Counter import os # 统计每个类别的标注框数量判断类别是否均衡 counter Counter() lbl_dir dataset/labels/train for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for line in fp: counter[int(line.split()[0])] 1 print(counter)如果某一类明显偏少常见做法是在训练时用数据增强补或者调整损失里各类的权重。yolov5 默认的分类损失对类别不均衡没有特殊处理样本少的那类召回会偏低。我一般会先看统计结果再决定要不要在 data.yaml 之外单独做重采样。3. 环境配置与训练启动把权重和数据接上3.1 环境配置教程的用法与依赖版本资源里带了两份环境配置 PDF覆盖 yolov3 到 yolov8 的配置流程。这类教程的价值在于把 CUDA、cuDNN、PyTorch、torchvision 的版本对应关系列清楚避免装完发现 torch 和显卡驱动不匹配。实际配置时先确认显卡驱动支持的 CUDA 上限再选 PyTorch 版本最后装 yolov5 的 requirements。常见坑是直接 pip install torch 装了 CPU 版训练时发现用不了 GPU所以装完一定要验证python -c import torch; print(torch.__version__, torch.cuda.is_available())输出里 cuda 为 True 才算配置成功。如果为 False先查驱动版本再查装的 torch 是不是 cu 版本。这一步不通过后面训练再快也是白搭。3.2 用预训练权重直接推理资源里的权重可以直接拿来推理不用先训练。yolov5 的推理入口是 detect.py指定权重和来源即可python detect.py --weights best.pt --source test_images --img 640 --conf 0.25 --device 0参数含义weights 指向训练好的权重文件source 可以是单张图、文件夹、视频路径或摄像头编号img 是推理分辨率640 是 yolov5 的常用值红外小目标可以试 1280 看召回是否提升conf 是置信度阈值红外目标响应弱阈值设太高会漏检0.25 是个稳妥起点device 指定 GPU 编号没有 GPU 就去掉。推理结果默认存到 runs/detect/exp 下框和类别会画在图上。3.3 在自己的数据上继续训练如果这套四类数据不够贴合你的场景可以拿预训练权重做迁移学习。yolov5 的训练命令python train.py --weights best.pt --data data.yaml --epochs 100 --batch 16 --img 640 --device 0weights 用资源里的权重做初始化比从头训收敛快很多data 指向 data.yamlepochs 按数据量调4000 张跑 100 轮通常够batch 受显存限制16 是 8G 显存左右的保守值显存够可以加到 32img 训练分辨率要和推理时接近否则小目标尺度对不上。训练过程中重点看 val 的 mAP 和各类的 P、R如果 Drone 类召回一直上不去优先查这一类标注框是不是偏小或偏少。注意红外图像是单通道或伪彩三通道如果自己的数据是单通道灰度图读进来要确认通道数处理一致否则预训练权重的第一层卷积对不上。4. PyQt 界面拆解图片、视频、摄像头三种输入怎么跑4.1 界面结构与 share.py、test.py 的分工资源里的 PyQt 界面由 share.py、test.py 和init.py 组成。share.py 通常放推理封装和界面逻辑的公共部分test.py 是入口或测试脚本init.py 让目录成为可导入的包。界面提供图片、视频、摄像头三个选项对应三种输入源。图片是单帧推理视频是逐帧读取再送模型摄像头是调用本地设备实时取流。三者的差别只在取帧方式推理部分可以复用同一套。4.2 把模型推理接进界面线程PyQt 界面最容易翻车的地方是把推理放在主线程导致界面卡死。正确做法是把推理放到 QThread 里通过信号把结果传回界面刷新。下面是一个可复用的推理线程骨架from PyQt5.QtCore import QThread, pyqtSignal import cv2 import torch class DetectThread(QThread): # 每处理完一帧就发一次信号携带绘制后的图像 frame_ready pyqtSignal(object) def __init__(self, model, source): super().__init__() self.model model # 已加载的 yolov5 模型 self.source source # 图片路径、视频路径或摄像头编号 self.running True def run(self): # 摄像头传 int视频/图片传路径 cap cv2.VideoCapture(self.source) while self.running and cap.isOpened(): ret, frame cap.read() if not ret: break # 推理conf 阈值按红外场景调低 results self.model(frame, size640) annotated results.render()[0] self.frame_ready.emit(annotated) cap.release() def stop(self): self.running False self.wait()逻辑上run 里循环取帧、推理、渲染、发信号界面收到 frame_ready 后把图像转成 QImage 显示。参数上 size 控制推理分辨率摄像头实时性要求高时可以降到 416conf 阈值在模型加载时通过 model.conf 设置。stop 方法保证关闭窗口时线程能退出不然进程会残留。4.3 摄像头与视频输入的参数差异摄像头输入用 cv2.VideoCapture(0)0 是设备编号多摄像头时按顺序试。视频输入传文件路径。两者在界面上的区别是摄像头没有总帧数进度条没法按比例走只能显示实时帧。视频可以拿到总帧数做进度显示。图片输入最简单读一帧推理一次就结束。常见问题是摄像头分辨率太高导致推理跟不上画面延迟累积解决办法是在取帧后先 resize 到模型输入尺寸附近再送推理。提示红外摄像头如果是伪彩输出cv2 读进来是三通道直接送模型没问题如果是原始灰度要确认模型训练时用的是几通道不一致就手动转。5. 避坑与排查红外小目标检测的五个血泪经验5.1 现象训练 loss 正常但 mAP 极低原因通常是标签和图像没对齐或者 data.yaml 的路径写错训练时读到的标签是空的。解决先跑 2.2 的校验脚本确认标签存在且合法再检查 data.yaml 里 train、val 的路径是相对路径还是绝对路径yolov5 对路径解析比较敏感路径不对会静默跳过样本。5.2 现象推理时框很多但全是误检红外场景背景热源多模型把地面热斑、云层边缘当成目标。原因是置信度阈值设太低或者训练时负样本不足。解决把 conf 从 0.25 往上调到 0.4 到 0.5 试同时看训练集里有没有足够的纯背景图。如果误检集中在某一类检查那一类的标注是不是把背景也框进去了。5.3 现象小无人机目标漏检严重红外微小目标只有十几像素下采样几次后在特征图上几乎消失。原因是推理分辨率太低或者模型 neck 对小目标特征利用不足。解决把推理 img 从 640 提到 1280代价是速度下降训练时开启 mosaic 增强让小目标有机会出现在更大尺度上如果还不行考虑换 yolov8 的小目标分支或加 P2 检测层。5.4 现象PyQt 界面点开始后卡死原因是推理跑在主线程界面事件循环被阻塞。解决按 4.2 的方式把推理放进 QThread所有耗时操作都不在主线程做。另外注意信号传递的图像对象要转成 QImage 再发直接传 numpy 数组在某些版本下会出问题。5.5 现象换 yolov7 或 yolov8 训练报类别数不匹配原因是权重文件的 nc 和 data.yaml 的 nc 不一致。资源里的权重是 nc4如果自己的 data.yaml 改成别的类别数加载权重时最后一层对不上。解决要么保持 nc4要么在训练脚本里让框架自动重建检测头yolov5 的 train.py 在 nc 不一致时会重新初始化最后一层但预训练权重的其他部分仍可复用。6. 进阶技巧用 test.py 做批量验证与阈值扫描资源里的 test.py 除了当界面入口还可以改造成批量验证脚本用来在 test 集上跑一遍统计各类的 P、R、mAP并做置信度阈值扫描。红外小目标检测里阈值选多少直接决定漏检和误检的平衡靠眼睛看几张图不够得用数据说话。我一般会固定权重和 test 集把 conf 从 0.1 到 0.6 按 0.05 步进跑一轮记录每档的 mAP 和各类召回import subprocess # 阈值扫描固定权重和数据集遍历 conf 记录指标 for conf in [0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6]: cmd [ python, val.py, --weights, best.pt, --data, data.yaml, --img, 640, --conf-thres, str(conf), --task, test ] print(conf , conf) subprocess.run(cmd)跑完把结果整理成表重点看 Drone 和 Bird 两类的召回随阈值的变化。红外小目标响应弱阈值一高召回掉得很快通常 0.2 到 0.3 之间是拐点。确定阈值后再回到 PyQt 界面里把 model.conf 设成这个值界面上的检测效果才和验证结果一致。另一个技巧是验证权重的泛化边界。这套权重是在特定红外数据上训的换一个红外波段或换一种场景性能会掉。判断方法很简单拿几十张自己场景的图不训练直接推理看框的质量。如果框位置大致对但类别错说明特征还在微调几十轮就能救如果框都出不来说明域差异太大得重新标数据训。我习惯在正式训练前先做这一步避免白跑几百轮。还有一点是导出部署格式。yolov5 支持导出 ONNX、TensorRT 等边缘设备上跑红外检测通常要转格式。导出命令python export.py --weights best.pt --include onnx --img 640 --opset 12opset 12 兼容性较好导出后可以用 onnxruntime 验证输出和原模型是否一致。红外场景对延迟敏感转 TensorRT 后速度提升明显但要注意 FP16 量化对小目标精度的影响量化后一定要在 test 集上复测 mAP掉太多就退回 FP32。从那以后我每次拿到一份带权重的检测资源都强制先跑一遍标签校验和阈值扫描再谈训练和部署不然前面省的时间后面全得还回去。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。