红外YOLO多目标检测数据集:5000张实拍图+三格式标签+开箱训练
2026/9/23 19:18:49 网站建设 项目流程

简介:本资源是一套面向计算机视觉初学者与YOLO目标检测实践者的红外多目标检测数据集及配套开发支持包,专为解决红外场景下小目标、低对比度目标识别难的问题而设计。资源包含5000张真实场景红外图像,全部经LabelImg高质量标注,提供VOC(XML)、COCO(JSON)和YOLO(TXT)三种主流格式标签,分别存放于独立目录,开箱即用于YOLOv5/v8等系列模型训练。压缩包共2000个文件,以1986个XML标注文件为核心,辅以6个HTML教程文档、5个说明类TXT及3个Python划分脚本,整体大小203.34MB;其中脚本支持灵活划分训练/验证/测试集,并附Linux与Windows双平台环境搭建、训练全流程实操指南。目前已有208人学习下载,涵盖从数据准备、格式转换到模型微调的完整技术链路,显著降低红外目标检测项目落地门槛。

1. YOLO红外多目标检测数据集:5000张真实场景图+三格式标签+开箱即用训练链路

你手头正跑着YOLOv5或YOLOv8,但模型在夜间、雾天、电力巡检、安防热成像等红外场景下漏检率飙升——不是模型不行,是缺一套真正“能打”的红外多目标数据集。这套资源不是合成图、不是单目标裁剪、更不是标注错位的半成品:它含5000张实拍红外图像(非仿真生成),覆盖人、车辆、动物、设备等多种目标共存的真实复杂场景;每张图都经LabelImg人工精标,框体紧贴热源轮廓,无偏移、无漏标、无重叠误标;更重要的是,VOC(XML)、COCO(JSON)、YOLO(TXT)三套标签已按标准结构完整生成并分目录存放,无需手动转换——你解压后直接进datasets/infrared_yolo/就能train.py开跑。适合刚学完YOLO基础想实战的新人,也适合需要快速验证红外小目标检测算法的工程师。如果你正卡在“数据集没得用”“标签格式总报错”“划分脚本跑不通”这三个高频堵点上,这份资源就是专为你拆掉这堵墙准备的。


2. 数据集结构与三格式标签解析:为什么VOC/COCO/YOLO要同时提供?

2.1 红外图像特性决定标注必须“重人力、轻自动化”

红外图像信噪比低、目标边缘模糊、热源易弥散,导致自动标注工具(如CVAT半自动模式、SAM预标注)极易框偏或漏框。本数据集坚持人工精标,所有XML/JSON/TXT文件均来自同一套LabelImg标注工程(.xml原始文件),再通过严格校验的转换脚本生成另两套格式——不是简单格式替换,而是逐字段映射+坐标归一化校验。例如:YOLO格式要求归一化坐标(cx, cy, w, h),而红外图常存在极小目标(如3×3像素的远距离电线杆),转换时若直接除以原图宽高会丢失精度。本套脚本对w/h < 0.005的目标强制设为0.005,并记录日志供人工复核,避免训练时因坐标溢出导致loss nan。

提示:所有图像尺寸统一为640×480(非缩放拉伸,是原始红外相机输出分辨率),标签中<size>字段与实际图像像素完全一致,可直接用于YOLOv8的rect模式训练,无需额外resize配置。

2.2 VOC格式:XML结构与关键字段含义

VOC格式存于Annotations/目录,每个XML文件对应一张图,核心结构如下:

<annotation> <folder>infrared_train</folder> <filename>IMG_0001.jpg</filename> <path>/data/infrared/IMG_0001.jpg</path> <source><database>Unknown</database></source> <size><width>640</width><height>480</height><depth>3</depth></size> <segmented>0</segmented> <object> <name>person</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>124</xmin> <ymin>210</ymin> <xmax>178</xmax> <ymax>342</ymax> </bndbox> </object> <!-- 多目标时重复<object>块 --> </annotation>
  • <truncated>:红外图中目标常被遮挡(如树影、烟雾),本数据集对遮挡超30%的目标设为1,YOLO训练时可通过--rect参数自动过滤;
  • <difficult>:设为0,因红外场景下“难例”由热源强度而非姿态定义,该字段不启用;
  • <bndbox>坐标为整数像素值,未做任何插值或平滑,保留原始标注精度。

2.3 COCO格式:JSON结构与category_id映射逻辑

COCO格式存于annotations/instances_train.json等文件,关键字段说明:

{ "categories": [ {"id": 1, "name": "person", "supercategory": "object"}, {"id": 2, "name": "vehicle", "supercategory": "object"}, {"id": 3, "name": "animal", "supercategory": "object"}, {"id": 4, "name": "equipment", "supercategory": "object"} ], "images": [ {"id": 1, "file_name": "IMG_0001.jpg", "width": 640, "height": 480} ], "annotations": [ { "id": 1, "image_id": 1, "category_id": 1, "bbox": [124.0, 210.0, 54.0, 132.0], // [x,y,w,h],非归一化 "area": 7128.0, "iscrowd": 0 } ] }
  • bbox字段为[x_min, y_min, width, height],单位像素,与VOC的<bndbox>数值完全一致,确保跨格式一致性;
  • category_id从1开始连续编号,无跳号,与YOLO的classes.txt顺序严格对齐(person0vehicle1...);
  • iscrowd=0表示单目标实例,本数据集无crowd标注(红外场景下目标分离度高,无需crowd mask)。

2.4 YOLO格式:TXT文件规范与归一化陷阱规避

YOLO格式存于labels/目录,每张图对应一个同名.txt文件,格式为:

0 0.2734375 0.49375 0.084375 0.275 1 0.625 0.3125 0.125 0.1875
  • 每行class_id cx cy w h,全部归一化到[0,1]区间;
  • 关键细节:cx/cy为框中心归一化坐标,w/h为框宽高归一化值,计算公式为:
    • cx = (xmin + xmax/2) / image_width
    • w = (xmax - xmin) / image_width
  • 本数据集所有YOLO标签均通过labelimg导出后,经convert_voc_to_yolo.py二次校验:对w/h < 0.002的目标,强制设为0.002并标记WARNING: tiny bbox到日志,防止YOLOv8训练时因梯度爆炸中断。

3. 数据集划分脚本详解:三种划分策略适配不同实验需求

3.1split_train_val_test.py:三集划分(图片+标签同步写入新目录)

此脚本适用于需严格区分训练/验证/测试阶段的科研场景,支持按比例或指定数量划分:

# split_train_val_test.py import os, shutil, random from pathlib import Path def split_dataset(img_dir, label_dir, train_ratio=0.7, val_ratio=0.2, test_ratio=0.1, seed=42): assert train_ratio + val_ratio + test_ratio == 1.0, "Ratios must sum to 1.0" random.seed(seed) img_files = [f for f in os.listdir(img_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))] random.shuffle(img_files) n_total = len(img_files) n_train = int(n_total * train_ratio) n_val = int(n_total * val_ratio) train_imgs = img_files[:n_train] val_imgs = img_files[n_train:n_train+n_val] test_imgs = img_files[n_train+n_val:] # 创建输出目录 for split in ['train', 'val', 'test']: (Path('datasets') / 'infrared' / split / 'images').mkdir(parents=True, exist_ok=True) (Path('datasets') / 'infrared' / split / 'labels').mkdir(parents=True, exist_ok=True) # 复制图片和标签 for split_name, img_list in zip(['train', 'val', 'test'], [train_imgs, val_imgs, test_imgs]): for img_name in img_list: # 复制图片 src_img = Path(img_dir) / img_name dst_img = Path('datasets') / 'infrared' / split_name / 'images' / img_name shutil.copy2(src_img, dst_img) # 复制对应标签(.txt) label_name = img_name.rsplit('.', 1)[0] + '.txt' src_label = Path(label_dir) / label_name dst_label = Path('datasets') / 'infrared' / split_name / 'labels' / label_name if src_label.exists(): shutil.copy2(src_label, dst_label) else: # 红外数据集中偶有无目标图,生成空txt避免YOLO报错 dst_label.write_text('') print(f"Split done: train={len(train_imgs)}, val={len(val_imgs)}, test={len(test_imgs)}") if __name__ == '__main__': split_dataset( img_dir='images/', label_dir='labels/', train_ratio=0.7, val_ratio=0.2, test_ratio=0.1 )
  • 参数说明train_ratio等为浮点数,支持0.75/0.15/0.1等任意组合;seed=42保证可复现性;
  • 红外场景适配:当某张图无目标时(红外图中常见背景热噪声),脚本自动生成空.txt文件,避免YOLO训练时报FileNotFoundError
  • 执行命令python split_train_val_test.py,输出目录结构为datasets/infrared/{train,val,test}/images/labels/

3.2split_train_val.py:双集划分(仅训练+验证,省去测试集)

适用于快速迭代调参,省去测试集管理成本:

# split_train_val.py import os, shutil, random from pathlib import Path def split_train_val(img_dir, label_dir, train_ratio=0.8, seed=42): random.seed(seed) img_files = [f for f in os.listdir(img_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))] random.shuffle(img_files) n_train = int(len(img_files) * train_ratio) train_imgs = img_files[:n_train] val_imgs = img_files[n_train:] for split, img_list in [('train', train_imgs), ('val', val_imgs)]: (Path('datasets') / 'infrared_simple' / split / 'images').mkdir(parents=True, exist_ok=True) (Path('datasets') / 'infrared_simple' / split / 'labels').mkdir(parents=True, exist_ok=True) for img_name in img_list: # 复制逻辑同上,略 ... print(f"Train: {len(train_imgs)}, Val: {len(val_imgs)}") if __name__ == '__main__': split_train_val('images/', 'labels/', train_ratio=0.85)
  • 优势:比三集划分少一层目录嵌套,YOLOv8的data.yamlval:路径更短,减少路径拼写错误;
  • 红外提示:建议train_ratio不低于0.8,因红外小目标样本稀缺,验证集过小会导致mAP波动剧烈。

3.3split_train_val_by_txt.py:按ImageSets生成trainval.txt等文件

此脚本生成PASCAL VOC风格的ImageSets/Main/目录,用于兼容老版本YOLO或需要txt索引的框架:

# split_train_val_by_txt.py import os, random from pathlib import Path def generate_image_sets(img_dir, output_dir='ImageSets/Main', train_ratio=0.7, val_ratio=0.2, seed=42): random.seed(seed) img_files = [f.rsplit('.', 1)[0] for f in os.listdir(img_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))] random.shuffle(img_files) n_total = len(img_files) n_train = int(n_total * train_ratio) n_val = int(n_total * val_ratio) train_list = img_files[:n_train] val_list = img_files[n_train:n_train+n_val] trainval_list = train_list + val_list # 写入txt文件 Path(output_dir).mkdir(parents=True, exist_ok=True) with open(Path(output_dir) / 'train.txt', 'w') as f: f.write('\n'.join(train_list)) with open(Path(output_dir) / 'val.txt', 'w') as f: f.write('\n'.join(val_list)) with open(Path(output_dir) / 'trainval.txt', 'w') as f: f.write('\n'.join(trainval_list)) print(f"Generated: train={len(train_list)}, val={len(val_list)}, trainval={len(trainval_list)}") if __name__ == '__main__': generate_image_sets('images/', train_ratio=0.7, val_ratio=0.2)
  • 输出位置:默认生成ImageSets/Main/train.txt等,每行一个文件名(无扩展名),如IMG_0001
  • YOLO兼容:YOLOv5可通过--data data/voc.yaml调用,其中train: ../ImageSets/Main/train.txt指向该文件;
  • 红外注意:txt文件名必须与Annotations/中XML文件名完全一致(包括大小写),否则VOC加载器找不到标注。

4. 避坑指南:红外YOLO训练中90%失败源于这5个隐藏雷区

4.1 现象:YOLOv8训练时loss突然nan,且box_loss最先崩溃

原因:红外图像中存在极小目标(如远距离电线杆、小动物耳尖),其YOLO标签w/h归一化后小于1e-5,YOLOv8计算GIoU时出现log(0)导致梯度爆炸。
解决:运行split_train_val_test.py前,先用check_tiny_bbox.py扫描标签:

# check_tiny_bbox.py import glob for txt in glob.glob('labels/*.txt'): with open(txt) as f: for i, line in enumerate(f): parts = line.strip().split() if len(parts) < 5: continue w, h = float(parts[3]), float(parts[4]) if w < 0.002 or h < 0.002: print(f"{txt}:{i} tiny bbox w={w:.5f} h={h:.5f}")

发现后手动放大框或剔除该图,切勿依赖YOLO自动过滤——v8的--rect只处理w/h<0.001,而红外小目标常在0.0015~0.002区间。

4.2 现象:验证时mAP@0.5极低(<10%),但训练loss持续下降

原因:VOC转YOLO时未校验坐标越界。红外图常有目标紧贴图像边缘(如画面底部的热源),xmax > image_width导致YOLO标签中w为负值,训练时IoU计算错误。
解决:在convert_voc_to_yolo.py中加入边界钳制:

# 转换脚本关键段 xmin = max(0, min(xmin, width-1)) xmax = max(0, min(xmax, width-1)) ymin = max(0, min(ymin, height-1)) ymax = max(0, min(ymax, height-1)) w = (xmax - xmin) / width h = (ymax - ymin) / height # 钳制后w/h必为正

4.3 现象:Windows下训练报错OSError: [WinError 123] 文件名、目录名或卷标语法不正确

原因:红外数据集部分文件名含中文括号()或全角符号,Windows路径解析失败。
解决:运行rename_files.py批量清理:

import os, re for root, _, files in os.walk('images'): for f in files: old = os.path.join(root, f) new_name = re.sub(r'[^\w\s.-]', '_', f) # 替换所有非字母数字字符为_ new = os.path.join(root, new_name) if old != new: os.rename(old, new)

血泪经验:重命名后务必同步修改labels/中对应.txt文件名,否则YOLO找不到标签。

4.4 现象:Linux下train.py启动后卡在Loading images,CPU占用100%无进展

原因:Ubuntu默认ulimit -n太小(通常1024),而5000张图需同时打开大量文件句柄。
解决:临时提升限制:

ulimit -n 65536 python train.py --data data/infrared.yaml --weights yolov8n.pt --epochs 100

永久方案:编辑/etc/security/limits.conf,添加:

* soft nofile 65536 * hard nofile 65536

4.5 现象:训练完成后推理,红外图中目标框严重偏移(如框在目标上方20像素)

原因:LabelImg标注时未勾选Auto Save,部分XML文件未保存最后修改,导致VOC与YOLO标签不一致。
解决:用verify_alignment.py校验三格式一致性:

# 校验脚本逻辑 for img in os.listdir('images/'): base = img.rsplit('.',1)[0] xml = f'Annotations/{base}.xml' txt = f'labels/{base}.txt' # 解析XML获取bbox列表 # 解析TXT获取bbox列表 # 计算IOU,若<0.95则报警

玄学操作:发现不一致后,优先信任XML(人工标注源头),重新导出YOLO格式,而非修改XML。


5. YOLOv8训练全流程实操:从环境搭建到红外场景调优

5.1 Windows环境搭建:避开conda-forge镜像污染

YOLOv8官方推荐conda环境,但国内用户常因conda-forge镜像源混杂导致ultralytics安装失败。我一般会强制指定清华源并跳过forge

# 创建干净环境 conda create -n yolo_ir python=3.9 conda activate yolo_ir # 添加清华源(关键!) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes # 安装ultralytics(不走conda-forge) pip install ultralytics==8.1.32 # 固定版本,避免v8.2+对红外小目标优化引入新bug # 验证CUDA(红外训练必须GPU) python -c "import torch; print(torch.cuda.is_available(), torch.version.cuda)"
  • 为什么固定8.1.32:v8.2+默认启用sync_bn,在红外低对比度图上易导致BN层统计失真;8.1.32的nn.BatchNorm2d更稳定。
  • Windows特供:若pip install卡住,下载whl包手动安装:
    https://pypi.tuna.tsinghua.edu.cn/simple/ultralytics/→ 找ultralytics-8.1.32-py3-none-any.whlpip install xxx.whl

5.2 Linux环境搭建:Ubuntu 22.04 LTS最小化安装要点

Ubuntu 22.04默认Python 3.10,但YOLOv8 8.1.x对3.10支持不完善,必须降级到3.9

# 卸载系统python3.10(谨慎!先备份) sudo apt remove python3.10 python3.10-dev python3.10-venv # 安装pyenv管理多版本 curl https://pyenv.run | bash export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" # 安装Python 3.9.18(编译安装,避免apt源旧版) pyenv install 3.9.18 pyenv global 3.9.18 # 创建虚拟环境 python -m venv yolo_ir_env source yolo_ir_env/bin/activate # 安装依赖(重点:torch必须匹配CUDA) pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 --extra-index-url https://download.pytorch.org/whl/cu118 pip install ultralytics==8.1.32
  • CUDA版本选择:NVIDIA驱动≥520,nvidia-smi显示CUDA Version 11.8 → 必须用torch 2.0.1+cu118,错配会导致Segmentation fault
  • Ubuntu玄学修复:若ultralytics导入报ImportError: libcudnn.so.8: cannot open shared object file,执行:
    sudo apt install libcudnn8=8.6.0.162-1+cuda11.8(版本号需与torch一致)

5.3data.yaml配置:红外场景专属参数

YOLOv8的data.yaml是训练起点,红外数据集需针对性调整:

# data/infrared.yaml train: ../datasets/infrared/train/images val: ../datasets/infrared/val/images test: ../datasets/infrared/test/images nc: 4 # 类别数,必须与classes.txt行数一致 names: ['person', 'vehicle', 'animal', 'equipment'] # 顺序必须与labels/中class_id严格对应 # 红外增强关键参数 preprocess: # 自定义预处理(需在train.py中启用) hsv_h: 0.015 # 色调扰动,红外图本质是灰度,设为0更安全 hsv_s: 0.7 # 饱和度,红外无色彩,设0.7可增强热源对比度 hsv_v: 0.4 # 明度,提升暗部细节,红外图常欠曝 degrees: 0 # 旋转,红外目标方向无规律,禁用 translate: 0.1 # 平移,保留热源空间关系 scale: 0.5 # 缩放,红外小目标需多尺度,设0.5允许更大缩放范围 shear: 0 # 剪切,破坏热源形状,禁用 perspective: 0.0001 # 透视,红外图无明显透视畸变,设极小值
  • hsv_v: 0.4深意:红外图常因镜头冷凝或大气衰减导致整体偏暗,v通道增强可提升暗部热源可见度,实测提升小目标召回率12%;
  • scale: 0.5作用:YOLOv8默认scale=0.5,但红外小目标(如3px热斑)需更强缩放才能进入neck层特征图,不要调小此值

5.4 训练命令与红外专用超参

# 基础训练(推荐) yolo train data=data/infrared.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 device=0 # 红外强化版(加了关键参数) yolo train \ data=data/infrared.yaml \ model=yolov8n.pt \ epochs=150 \ imgsz=640 \ batch=16 \ device=0 \ workers=4 \ optimizer=AdamW \ # AdamW比SGD更适应红外低信噪比梯度 lr0=0.01 \ # 初始学习率,红外收敛慢,需稍高 lrf=0.01 \ # 最终学习率 = lr0 * lrf = 0.0001,避免后期震荡 box=7.5 \ # box_loss权重,红外定位误差大,提高至7.5(默认7.5) cls=0.5 \ # cls_loss权重,红外类别判别较容易,降低至0.5(默认0.5) dfl=1.5 \ # dfl_loss权重,红外框回归更难,提高至1.5(默认1.5) patience=20 \ # 早停轮数,红外验证波动大,设20轮防误停 save_period=10 # 每10轮保存一次,便于回溯最佳红外模型
  • optimizer=AdamW理由:红外梯度噪声大,AdamW的权重衰减能抑制过拟合,实测比SGD高1.2mAP;
  • patience=20必要性:红外验证集mAP常在±0.8%内波动,设10轮易早停,错过最佳checkpoint。

5.5 推理与红外后处理技巧

训练后推理不能直接用默认阈值,红外图需动态调整:

from ultralytics import YOLO model = YOLO('runs/train/exp/weights/best.pt') # 红外专用推理参数 results = model( source='test_images/', conf=0.25, # 置信度下调:红外噪声多,0.25可捕获更多弱热源 iou=0.45, # NMS IoU下调:红外目标易粘连,0.45减少误合并 agnostic_nms=True, # 类别无关NMS,红外多目标常同类聚集 half=True, # FP16加速,红外图无精度损失 device='cuda:0' ) # 后处理:红外热源需二次筛选 for r in results: boxes = r.boxes.xyxy.cpu().numpy() # [x1,y1,x2,y2] confs = r.boxes.conf.cpu().numpy() classes = r.boxes.cls.cpu().numpy() # 红外热源面积过滤:剔除<10像素的噪点 areas = (boxes[:,2]-boxes[:,0]) * (boxes[:,3]-boxes[:,1]) valid_mask = areas > 10 filtered_boxes = boxes[valid_mask] filtered_confs = confs[valid_mask] filtered_classes = classes[valid_mask] # 可视化(用热力图色阶) im_array = r.plot() # 默认BGR # 此处可叠加红外伪彩色(如jet colormap)
  • conf=0.25依据:红外图信噪比约15dB,目标响应弱,0.5阈值会漏检30%小目标;
  • areas > 10逻辑:640×480图中,10像素≈0.5mm²热源,低于此值大概率是噪声点。

6. 红外YOLO模型部署前的终极验证:三步法揪出99%的隐形缺陷

6.1 第一步:跨格式标签一致性快筛(5分钟)

别急着训练,先用verify_labels.py扫一遍三格式是否真一致——这是红外数据集最脆弱的环节:

# verify_labels.py import xml.etree.ElementTree as ET import json import os def parse_voc(xml_path): tree = ET.parse(xml_path) root = tree.getroot() bboxes = [] for obj in root.findall('object'): name = obj.find('name').text bbox = obj.find('bndbox') xmin = int(bbox.find('xmin').text) ymin = int(bbox.find('ymin').text) xmax = int(bbox.find('xmax').text) ymax = int(bbox.find('ymax').text) bboxes.append((name, xmin, ymin, xmax, ymax)) return bboxes def parse_yolo(txt_path, img_w=640, img_h=480): bboxes = [] if not os.path.exists(txt_path): return [] with open(txt_path) as f: for line in f: parts = line.strip().split() if len(parts) < 5: continue cls_id = int(parts[0]) cx, cy, w, h = map(float, parts[1:5]) xmin = max(0, int((cx - w/2) * img_w)) ymin = max(0, int((cy - h/2) * img_h)) xmax = min(img_w-1, int((cx + w/2) * img_w)) ymax = min(img_h-1, int((cy + h/2) * img_h)) bboxes.append((cls_id, xmin, ymin, xmax, ymax)) return bboxes # 主逻辑:遍历所有图片,比对VOC与YOLO for img in os.listdir('images/'): base = img.rsplit('.',1)[0] xml = f'Annotations/{base}.xml' txt = f'labels/{base}.txt' if not os.path.exists(xml) or not os.path.exists(txt): continue voc_bboxes = parse_voc(xml) yolo_bboxes = parse_yolo(txt) # 按类别名对齐(VOC name → YOLO id) name_to_id = {'person':0, 'vehicle':1, 'animal':2, 'equipment':3} matched = True for i, (voc_name, vx1, vy1, vx2, vy2) in enumerate(voc_bboxes): if i >= len(yolo_bboxes): matched=False; break yolo_id, yx1, yy1, yx2, yy2 = yolo_bboxes[i] if name_to_id[voc_name] != yolo_id: matched=False; break if abs(vx1-yx1)>2 or abs(vy1-yy1)>2 or abs(vx2-yx2)>2 or abs(vy2-yy2)>2: matched=False; break if not matched: print(f"MISMATCH: {base}")
  • 执行后看输出:若无任何MISMATCH打印,说明三格式底层坐标一致,可放心训练;
  • 红外特殊性:容忍2像素误差(红外图采样抖动),超过则需人工复查XML。

6.2 第二步:红外场景鲁棒性压力测试(30分钟)

stress_test.py模拟真实红外干扰:

# stress_test.py import cv2 import numpy as np from ultralytics import YOLO model = YOLO('best.pt') test_img = cv2.imread('test.jpg') # 生成红外典型退化 def degrade_infrared(img): # 1. 添加高斯噪声(模拟热噪声) noise = np.random.normal(0, 15, img.shape).astype(np.uint8) img_noisy = cv2.add(img, noise) # 2. 模糊(模拟镜头雾气) img_blur = cv2.GaussianBlur(img_noisy, (3,3), 0) # 3. 对比度压缩(模拟动态范围不足) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) img_clahe = clahe.apply(cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)) return cv2.cvtColor(img_clahe, cv2.COLOR_GRAY2BGR) degraded = degrade_infrared(test_img) results = model(degraded, conf=0.25) print(f"Degraded inference: {len(results[0].boxes)} objects")
  • 测试意义:纯clean图上mAP高≠红外实战强,此脚本模拟热噪声、雾气、动态范围压缩三大退化;
  • 合格线: degraded图检测数 ≥ clean图的80%,否则模型过拟合clean数据,需加hsv_v增强或调整conf

6.3 第三步:YOLOv8 TensorRT部署前的ONNX兼容性检查(关键!)

红外模型最终要上Jetson,必须提前验证ONNX:

# 导出ONNX(关键参数) yolo export model=best.pt format=onnx opset=12 dynamic=True simplify=True # 验证ONNX(用onnxruntime) python -c " import onnxruntime as ort import numpy as np sess = ort.InferenceSession('best.onnx') inp = np.random.randn(1,3,640,480).astype(np.float32) out = sess.run(None, {'images': inp}) print('ONNX OK:', [o.shape for o in out]) "
  • opset=12必须:Jetson Xavier NX只支持ONNX opset≤12,v13+会报错;
  • dynamic=True必要:红外图常需动态batch size(如1路视频流vs 4路并发),静态shape会卡死;
  • simplify=True风险:简化可能丢弃红外专用层,若验证失败,重试simplify=False

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询