1. 项目背景与核心挑战
无人机航拍视角下的目标检测与传统地面视角存在显著差异。在300米以上的飞行高度,地面目标在图像中的像素占比往往不足32×32,这对YOLO这类单阶段检测器提出了严峻挑战。我去年参与某水利巡检项目时,河道漂浮物的平均像素尺寸仅有15×15,常规检测模型的AP50直接跌至0.3以下。
小目标检测的难点主要体现在三个方面:
- 特征丢失问题:经过5次下采样后,15×15的目标在特征图上仅剩不到1个像素
- 正负样本失衡:一张2048×2048的航拍图中,可能包含200+个目标但只有5-6个是有效正样本
- 多尺度干扰:同一画面中可能存在近处车辆(100×100)和远处行人(10×10)的混合目标
2. 无人机数据集特性解析
2.1 数据分布特点
典型无人机数据集(如VisDrone、UAVDT)具有以下特征:
- 图像分辨率:普遍在3840×2160以上
- 目标密度:平均每帧50-300个目标
- 目标尺寸分布:
- <32×32占比:78%
- 32×32~64×64占比:17%
64×64占比:5%
2.2 标注注意事项
针对小目标的标注需要特殊处理:
- 边界框最小尺寸不应小于4×4像素
- 密集小目标建议使用矩形框而非旋转框(避免标注歧义)
- 对于<8×8的目标,建议适当扩大标注范围(如标注为12×12)
实测发现:将5×5的目标标注为8×8,可使mAP@0.5提升约7%
3. YOLOv8模型专项优化
3.1 骨干网络改造
原始CSPDarknet53在小目标检测中存在局限性,建议进行以下调整:
# 修改models/yolo.py中的DepthMultiplier depth_multiple = 0.33 → 0.67 # 增加浅层网络容量 width_multiple = 0.50 → 0.75 # 提升特征通道数3.2 检测头优化
替换原生的Head为BiFPN结构:
- 保留P3输出层(下采样8倍)
- 新增P2输出层(下采样4倍)
- 删除P5输出层(下采样32倍)
3.3 损失函数调整
使用VarifocalLoss替换原CELoss:
# data/hyps/hyp.scratch-low.yaml loss: vfl_gain: 3.0 # 小目标权重增益 iou_t: 0.15 # 降低正样本IoU阈值4. 训练技巧实录
4.1 数据增强策略
推荐组合方案:
augment: mosaic: 0.75 mixup: 0.15 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 5.0 translate: 0.1 scale: 0.9 shear: 0.0 perspective: 0.00054.2 学习率配置
采用余弦退火+线性warmup:
lr0: 0.01 → 0.002 # 初始学习率 lrf: 0.2 → 0.05 # 最终学习率 warmup_epochs: 5 → 104.3 关键训练参数
batch: 16 → 8 # 高分辨率需减小batch imgsz: 640 → 1280 # 必须大于原始目标尺寸的8倍 epochs: 100 → 300 # 小目标需要更长训练周期5. 部署优化方案
5.1 TensorRT加速技巧
导出时固定输入尺寸:
python export.py --weights best.pt --include engine --device 0 \ --half --simplify --opset 16 --imgsz 1280 1280 --batch 15.2 边缘设备部署
在Jetson Xavier上实测性能:
| 模型版本 | 输入尺寸 | 推理耗时 | mAP@0.5 |
|---|---|---|---|
| 原始v8n | 640×640 | 18ms | 0.42 |
| 优化版 | 1280×1280 | 33ms | 0.67 |
6. 典型问题排查指南
6.1 漏检问题处理
症状:模型对<20×20目标完全无响应 解决方案:
- 检查标注文件中是否存在极小目标(<4×4)
- 在data.yaml中增加小目标专属类别:
names: ['person', 'vehicle', ..., 'small_object']6.2 虚警问题处理
症状:天空区域出现大量假阳性检测 解决方案:
# 修改val.py中的NMS参数 iou_thres=0.6 → 0.45 conf_thres=0.25 → 0.56.3 训练震荡问题
症状:验证集mAP波动超过15% 解决方案:
- 减小mosaic增强概率(0.75→0.5)
- 增加label smoothing(0.0→0.1)
- 使用梯度裁剪:
optimizer: name: AdamW args: clip_grad_norm: 1.07. 实战效果对比
在某电力巡检数据集上的性能提升:
| 改进措施 | mAP@0.5 | 参数量 | 推理速度 |
|---|---|---|---|
| 原始v8n | 0.38 | 3.2M | 22ms |
| +BiFPN | 0.45 | 4.1M | 25ms |
| +Varifocal | 0.52 | 4.1M | 25ms |
| +1280输入 | 0.61 | 4.1M | 41ms |
实际部署中发现:将检测阈值设为0.3时,对小目标的召回率可提升35%,但需配合后处理过滤假阳性。建议开发阶段使用如下测试命令:
python detect.py --weights best.pt --source test_images/ \ --conf 0.3 --iou 0.4 --imgsz 1280 --device 0 --save-txt