尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

夜间无人机车辆检测数据集与YOLO11多平台训练实战

夜间无人机车辆检测数据集与YOLO11多平台训练实战 简介面向无人机夜间车辆检测任务这份资源整理了1000张夜间真实场景图片及对应标签可解决航拍视角下夜间车辆样本稀缺、场景单一等问题适合计算机视觉初学者、算法工程师及无人机项目开发者用于模型训练、算法验证以及作为通用车辆检测数据集的有效补充。资源为单个PDF文档形式交付大小约4.13MB文档内包含数据集基本情况介绍、缩略图预览、labelimg标注截图及百度网盘获取方式实际图片和VOC/COCO/YOLO三种格式标签需按文档指引下载。目前已有372人学习/浏览。数据集覆盖夜间城市道路行驶、道边停车、停车场、小区等多类无人机视角场景并包含车辆遮挡与严重遮挡图像整体统一标注为car类别采用labelimg工具完成高质量标注不区分轿车、SUV或货车便于直接用于YOLO等目标检测算法。附赠的YOLO11一键训练脚本支持GPU(GPUs)、CPU和Mac(M芯片)三平台提供博主训练结果日志读者可按脚本快速搭建训练流程并进行多平台效果对比。1. 夜间无人机拍到的车辆为什么比白天数据难训十倍晚上用无人机拍车光看画面我觉得“没那么难”但真把目标检测模型放到夜间航拍上漏检率和误检率会同时飙升。白天训练好的权重直接拿来跑夜晚车灯会被当作圆形目标路灯和地面反光也能骗过网络而车体本身因为暗反而被漏掉。要做到夜间车辆检测落地最实在的做法就是给模型喂专门的夜间数据并配合更小、更强的训练控制。这个标题给的方案很直接一个无人机场景的夜间车辆检测数据集1000张图同时带VOC、COCO、YOLO三种格式标签外加一套能在GPU、CPU、Mac三平台跑YOLO11的一键训练脚本。它适合无人机巡检、夜间安防、智慧交通这类白天晚上都要工作的从业者。2. 先拆这份夜间车辆检测数据集1000张图与三种标签格式的真实用途拿到数据集先别急着训练。脚本能一次跑通的前提是目录结构和标签格式匹配YOLO11的读取规则。三种格式同时给并不只是“多一份存档”而是让同一个数据集能喂给不同的训练链VOC适合老标注工具和传统检测COCO适合做预训练迁移和统一管理YOLO的txt格式是YOLO11训练时真正会读取的东西。下面我把三种格式差异、目录布局和一个常用的格式转换脚本都展开。2.1 VOC/COCO/YOLO三种格式的差异你手里拿到的到底是什么先看最常见也最容易被忽视的差异坐标定义和类别映射方式。用一张表说清楚。格式典型文件形态坐标定义类别表示VOC每张图一个XML文件xmin、ymin、xmax、ymax绝对像素值objectnamecar/name类别名在XML里COCO整个数据集一个JSON文件bbox为[x, y, width, height]绝对像素值categories数组里维护id到name的映射YOLO每张图一个txt文件class_id x_center y_center width height全部归一化到0~1只有类别id必须配合names列表关键点在于YOLO的txt是“无头”文件它自己不带类别名。很多人把标注导成YOLO格式后拷贝到新机器发现只有一堆数字不知道0是car还是van这就是典型的黑匣子问题。VOC和COCO自带类别名反而安全。三种格式同时给真正价值不是格式本身而是把类别映射关系、坐标基准都留住了。我拿到任何数据集会先看一眼labels里的数字范围和data.yaml的names是否一致这一步能避免后面训练彻底跑偏。如果有机会往遥感图像目标检测或三维目标检测延伸COCO JSON也更容易扩展深度标注。2.2 标签文件目录怎么摆才能让YOLO11训练脚本直接读YOLO11的训练入口是yolo detect train它不关心你的数据集叫什么名字只关心data.yaml里给的路劲。常规目录安排如下dataset_root/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── annotations/ │ ├── train.xml │ └── val.xml ├── coco.json └── data.yaml这个结构的好处是训练时只用到images和labelsannotations和coco.json留作可视化、格式转换和后续做迁移学习的备份。很多团队把VOC的XML和YOLO的txt混在一起放训练前还要现做索引很耽误事。data.yaml是训练脚本的第一依赖内容通常是path: /absolute/path/to/dataset_root train: images/train val: images/val names: 0: carpath最好写绝对路径不要写..这种相对路径Mac和Windows对斜杠的处理不一样容易踩坑。names必须和labels里的id顺序严格一致。如果这个数据集只有一个类别car那0: car就够了。检查完这两项训练脚本就能直接索引到图片和标签。2.3 只有VOC标注用Python把XML转成YOLO txt和COCO JSON虽然标题说三种格式都带但实际工作中经常只能拿到其中一种。我一般会在目录里准备一个转换脚本方便从VOC XML生成另外两种格式。下面这段代码是常用的转换核心。# voc2yolo_coco.py import xml.etree.ElementTree as ET import json def voc2yolo(xml_file, txt_file, img_width, img_height, class_names): tree ET.parse(xml_file) root tree.getroot() lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in class_names: continue x1 int(obj.find(bndbox/xmin).text) y1 int(obj.find(bndbox/ymin).text) x2 int(obj.find(bndbox/xmax).text) y2 int(obj.find(bndbox/ymax).text) # 转成归一化的中心点坐标和宽高注意宽高要除以图片尺寸 x_center (x1 x2) / 2.0 / img_width y_center (y1 y2) / 2.0 / img_height w (x2 - x1) / img_width h (y2 - y1) / img_height lines.append(f{class_names.index(cls)} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(txt_file, w) as f: f.write(\n.join(lines))这段代码里最容易错的是x_center和wx1和x2是绝对像素相减得到宽度再除以图片宽度才是归一化数值。很多人只归一化中心点忘了除宽高导致训练loss不降。class_names.index(cls)能保证类别id和data.yaml一致前提是你传入的class_names列表顺序固定。转COCO json则要维护全局的image_id和annotation_iddef voc2coco(xml_files, out_json, class_names): images, annotations [], [] ann_id 1 for img_id, xml_file in enumerate(xml_files): root ET.parse(xml_file).getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) images.append({ id: img_id, file_name: root.find(filename).text, width: w, height: h }) for obj in root.iter(object): cls obj.find(name).text if cls not in class_names: continue x1 int(obj.find(bndbox/xmin).text) y1 int(obj.find(bndbox/ymin).text) x2 int(obj.find(bndbox/xmax).text) y2 int(obj.find(bndbox/ymax).text) annotations.append({ id: ann_id, image_id: img_id, category_id: class_names.index(cls), bbox: [x1, y1, x2 - x1, y2 - y1], area: (x2 - x1) * (y2 - y1), iscrowd: 0 }) ann_id 1 coco { images: images, annotations: annotations, categories: [{id: i, name: n} for i, n in enumerate(class_names)], } with open(out_json, w) as f: json.dump(coco, f)这段代码里COCO的bbox用的是x, y, width, height和VOC的xmin, ymin, xmax, ymax不同。转完后验证一条读取json里任意annotation再用OpenCV画框框体应该完全贴合车辆轮廓。只要这一步过了三种格式才算真正对齐。3. 一键训练脚本怎么落地GPU/CPU/Mac三平台的环境判断与最小命令一键脚本不是炫技是防止每次训练前被环境问题逼疯。YOLO11使用的ultralytics训练器靠device参数控制设备NVIDIA显卡写cuda纯CPU写cpuApple Silicon的GPU写mps。三者的计算后端完全不同所以脚本第一步必须是平台检测而不是让用户手动填device。3.1 脚本先做平台检测为什么GPU(CUDA)、CPU、Mac(MPS)不能共用一套启动参数GPU训练依赖CUDA需要NVIDIA驱动、CUDA运行时和GPU版PyTorch三样对齐。CPU训练最稳但夜间航拍图像尺寸大一个epoch跑起来可能比GPU慢十倍。Mac的MPS走Metal接口速度介于两者之间但PyTorch对MPS的算子支持不如CUDA完整某些层会在跑到一半才报错。平台检测脚本通常长这样# platform_check.py import torch if torch.cuda.is_available(): device cuda # NVIDIA GPU走CUDA后端 elif torch.backends.mps.is_available(): device mps # Apple Silicon GPU走Metal后端 else: device cpu # 兜底 print(fdetected device: {device}) print(fpytorch: {torch.__version__})这段代码里有两个坑第一torch.cuda.is_available()为False很可能是PyTorch装成了CPU版而不是硬件不支持第二在Intel Mac上mps.is_available()会是False所以条件顺序不能反否则所有Mac都会落到mps然后报错。脚本最好再提供一个环境变量开关比如FORCE_CPU1当MPS训练中途被杀时能快速切回CPU兜底。3.2 一键脚本的核心逻辑从数据集目录到YOLO11训练的最小bash一键脚本的本质是拼命令同时把参数默认值写进去减少每次重复输入。下面这个脚本是常见做法#!/bin/bash # train_yolo11.sh DATA$1 # data.yaml的绝对路径 EPOCHS${2:-100} # 默认100轮 BATCH${3:-16} # 默认batch 16 IMGSZ${4:-1280} # 输入尺寸夜间小目标建议1280 DEVICE$(python platform_check.py) echo Using device: $DEVICE yolo detect train \ modelyolo11n.pt \ data$DATA \ epochs$EPOCHS \ batch$BATCH \ imgsz$IMGSZ \ device$DEVICE \ projectruns/detect \ nametrain_nightmodelyolo11n.pt是让脚本第一次运行时自动下载预训练权重如果没有联网YOLO11会把权重下载失败但脚本仍然能用随机初始化的权重训练。imgsz1280不是随便写的无人机俯视视角下车辆像素少640的输入会把目标压成几个像素后面第4章会详细讲。nametrain_night用来区分多次实验所有输出会放到runs/detect/train_night目录。如果你在Windows原生环境没有bash可以用Git Bash或WSL跑也可以把同样的参数改成python -m形式。3.3 手动分解这条训练命令batch/epoch/workers在三种平台的推荐值一键脚本给出了默认值但真到调参时要按平台能力改。我一般按这个表起步平台device推荐batch推荐workers备注NVIDIA GPU8G显存cuda8~164~8imgsz1280时建议降到8Apple Silicon Macmps8~162~4共享内存太大容易被系统杀纯CPUcpu4~80~2workers过高反而卡在数据加载imgsz翻倍显存占用约翻4倍所以batch和imgsz必须一起看。我在8G显存的笔记本上会先用batch8 imgsz1280如果OOM就降到batch4。Windows上DataLoader的worker经常抽风一旦报错就先workers0虽然慢一点但不会卡死。epochs多少要看数据集规模1000张图的夜间任务100轮够起步200轮看收敛曲线。3.4 用GPU训练时驱动和PyTorch的CUDA版本怎么对齐这个坑出现频率极高torch.cuda.is_available()返回False或者训练到一半报CUDA error。先看两张牌nvidia-smi python -c import torch; print(torch.version.cuda)nvidia-smi右上角显示驱动支持的最高CUDA版本torch.version.cuda显示PyTorch编译用的CUDA版本。PyTorch的CUDA版本不必等于驱动最高版本只要PyTorch要求的CUDA不高于驱动支持的上限就能跑。例如驱动支持CUDA 12.2PyTorch用CUDA 12.1没问题。但很多新手装的是CPU版PyTorch这时候torch.cuda.is_available()永远为FalsePyTorch安装教程里选GPU版才能解决。这个检查放在训练脚本开头省得跑一小时后才发现用了CPU。4. 针对夜间车辆检测的四个参数必调项小目标、车灯过曝与误检数据、脚本都齐了直接训练可能能跑但效果不一定好。夜间车辆检测最常见的两个失败模式是小目标漏检以及把路灯或地面反射当车。下面这四个参数是调优时的优先对象。4.1 输入分辨率大小在俯视小车面前别用默认640YOLO11的网络结构本身有不错的多尺度融合能力但输入分辨率直接决定网络能“看到”的目标大小。无人机在60米高度看一辆轿车目标宽度可能只有30像素如果缩放到640目标就变成不到10像素特征被严重压缩。训练命令里把imgsz提上去yolo detect train ... imgsz1280imgsz同时影响训练集和验证集的resize尺寸。8G显存跑1280有压力就配batch4或者把图像裁剪成分块再训练。我见过不少团队在640下模型一直漏检改成1280后同样的数据mAP50直接提升十多个点这就是输入分辨率的力量。4.2 数据增强别照搬白天HSV、Mosaic、MixUp在夜间的取舍YOLO11默认开启一系列增强HSV颜色扰动、Mosaic拼图、MixUp混图。这些在白天数据集上很好用但夜间图像整体偏暗、色彩分布窄过强的颜色扰动反而破坏暗部轮廓。常用做法是把增强参数调保守yolo detect train ... hsv_v0.2 mosaic0.5 mixup0.0hsv_v控制亮度变化幅度白天我常设0.4夜间建议0.2以下否则车体和柏油路的对比会被随机打没。mosaic0.5保留一部分拼接增强让模型看到不同场景的拼接车辆但概率降低避免小目标在拼接时被切掉。mixup0.0是我在夜间任务里的默认值因为两张暗图叠加后车灯区域会过曝成一大片光斑反而制造假样本。4.3 类别不均衡和难例挖掘夜间车灯像路灯怎么压误检很多夜间车辆数据集只有一个类别car但难例不在类别数上而在背景路灯是圆形亮斑地面反光是长条形亮斑远处车灯更像车灯。模型很自然会把所有亮斑都预测成车辆。压误检最直接的办法是加负样本。在数据集里放一批完全没有车的夜间道路图像并给它们空标签txt让网络知道“背景区域不该输出目标”。训练命令里无需特殊参数YOLO11会正常读取空txt。如果负样本不够先跑一次val看混淆矩阵里background被预测成vehicle的比例再针对高频误检场景补图。上线时我也会调高置信度阈值yolo detect val ... conf_thres0.35conf_thres默认0.25夜间误检多提到0.35或0.5能压掉很多路灯但代价是暗处真车也可能被滤掉。阈值不是一次定死要看具体告警场景允许的误报率。4.4 早停与模型选择看哪个指标决定最终权重训练脚本默认会根据验证集mAP50-95挑选best.pt。但对夜间航拍mAP50-95容易被大量低置信度框拉低真正落地时更关心mAP50和召回率。我一般会把早停提前yolo detect train ... patience30patience30表示连续30轮验证指标没提升就停。夜间数据集小训练到后期很容易过拟合太长的patience只会浪费时间。选权重时不要只盯着best.pt也看一眼last.pt如果两者mAP差太多说明训练过程不稳定先检查数据划分和增强是否太激进。5. 常见问题与避坑从数据标注到三平台训练最容易翻车的五个点在YOLO11落地时绝大多数问题不是模型不行而是坐标系、平台和数据集割裂造成的。下面五条按发生频率排序基本每一条都能让人浪费半天。5.1 标注坐标系搞混VOC的xmin/ymin与YOLO的归一化中心点现象训练loss一直不降或者训练能收敛但框全偏到图片角落。原因把VOC的绝对坐标直接当成分母没有除以图片宽高或者把xmax当成了框宽度。解决检查labels里所有txt的数值正常必须全部在0~1之间。转换公式固定为x_center(xminxmax)/2/widthw(xmax-xmin)/widthy方向同理。我每次转换后会随机抽三张图用OpenCV画框验证确认框贴合车辆再训练避免闷头跑。5.2 夜间图像标注容易漏标暗处的车辆肉眼看不见现象验证集mAP不低但单独统计暗部车辆时召回率奇差。原因标注员在黑暗画面上看不清车体轮廓只标了车灯亮的目标车尾和车身被漏掉。解决给标注用的图片先做亮度增强或直方图均衡让标注软件能显示暗部细节训练时仍用原始暗图。如果数据集有多个相机位优先把俯视暗部的样本多标几遍。夜间数据集的标注质量直接决定模型对“没亮灯的车”敏不敏感。5.3 Mac上MPS训练不稳定不是报错就是中途被杀现象在Apple Silicon上跑MPS训练几分钟后系统直接把进程杀掉或者报算子不支持。原因PyTorch的MPS后端还不够完整某些卷积或归一化算子没有对应实现batch太大也会让内存压力飙升。解决先强制devicecpu跑一个epoch做冒烟测试确认数据和脚本没问题再切回MPS把batch减半workers设成2。如果MPS还是挂就用CPU把声明周期跑完夜间数据量不大1000张图CPU训练一天也能接受。5.4 Windows GPU上训练报CUDA out of memory或DataLoader worker崩溃现象batch16一开工就OOMworkers8时训练界面一直不动。原因imgsz1280加batch16远超显卡显存Windows平台多进程数据加载有更高安全限制。解决先workers0、batch8跑通再逐步往上加。同时用nvidia-smi确认没有别的进程占显存。如果电脑有两个GPU但训练只想用一张明确传device0不要让它自动选到第二张卡。5.5 训练结果飘重复训练两次mAP差5个点以上现象同一数据集、同一脚本两次训练结果差异很大best.pt和last.pt差距也很大。原因数据集只有1000张验证集随机划分带来的波动被放大mosaic增强带来更多随机性。解决在训练命令里固定随机种子YOLO11可以传seed42把验证集单独留出来不要每次重新划分。多跑两轮取稳定权重是我最常做的急救动作。这属于典型的“玄学”问题背后其实是小数据集的方差。6. 训练完怎么验证夜间检测的mAP、混淆矩阵和误检排查技巧训练完拿到best.pt不等于能上线。夜间车辆检测最怕误检把路灯光斑当车真到接入告警时会被迫关掉整个识别。我的习惯是先用val脚本复现验证指标再看混淆矩阵最后导出模型。三步做完才敢交付。先跑一次标准验证yolo detect val modelruns/detect/train_night/weights/best.pt datayour_data.yaml imgsz1280输出里有两个关键指标mAP50和mAP50-95。夜间航拍我更看重mAP50因为实际业务不会把IoU卡到0.75。如果mAP50高但线上误检多重点去调置信度阈值。然后打开验证输出目录里的混淆矩阵图。单类别时最该看的是background被预测成vehicle的那一格数值高说明路灯和反光被当成车。此时优先加负样本或提阈值。如果是vehicle被漏到background则要先回分辨率再考虑增强是否过度。最后导出部署格式yolo export modelbest.pt formatonnx imgsz1280导出ONNX可以用onnxruntime在Jetson、RK3588这类边缘设备上跑也有利于后续做TensorRT优化。无人机机载算力有限导出时模型用yolo11n这类小结构速度才跟得上。我这些年吃过最大的亏就是拿训练指标直接当交付指标。夜间场景骗人最狠验证集上mAP再漂亮到了路灯密集路段还是会漏。所以现在无论多急我都会先跑val、再看混淆矩阵最后导出一个真实测试视频来验收。希望帮到你。本文还有配套的精品资源点击获取
返回列表