news 2026/10/22 23:17:01

无人机林火巡检实战:基于YOLOv11的红外小目标检测与部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
无人机林火巡检实战:基于YOLOv11的红外小目标检测与部署

无人机林火巡检这个题目,我想先跟真正做过一线项目的人握个手:最难的部分永远不在飞手和飞机,而在让模型在几千张红外航拍图里,把那一小撮正在燃烧的东西从灌木、石头、地热和建筑余温里揪出来。我去年用一套航拍红外森林火灾图像数据集,在 Ultralytics YOLOv11 框架下完整跑了一遍训练、调优、验证和端侧部署,踩了不少坑,也沉淀出一套可以复用的流程。这篇不是广告,就是把我实际操作中验证过的东西,连同失败路径一起讲清楚,给准备在这个方向起步的人当个参照。


1. 红外成像下的森林火灾目标,跟普通目标检测到底不一样在哪

1.1 可见光拍烟、红外拍热,目标特征完全两个思路

很多第一次接触这个项目的人会默认把 YOLOv11 当普通目标检测用,拿着可见光火灾照片就去标框训练。老实说,如果数据量够多,可见光方案也能做出不错的结果,但它在真实林区里有个致命短板:烟一大,火就看不见了;夜里没光照,火也看不见了。而无人机林火巡检真正要补的,恰是这种全天时能力。

红外(热成像)传感器抓的是物体表面的热辐射差异,火焰区在热像上往往是高亮甚至饱和的白色块,背景植被和地面则呈现低温暗色。这个特性带来两个直接后果:

  • 模型不需要学颜色纹理,只需要学“亮度分布和形态”,所以灰度单通道就能训练,不需要为了颜色做复杂预处理。
  • 但热成像的对比度受环境影响极大:午后阳光晒热的岩石、公路、铁皮屋顶,甚至反光的积水,都是天然误检源。

所以在动手训练之前,第一件事不是装环境,而是想清楚你的模型是在学“火的热特征”还是“火加背景的热特征”。我习惯把红外单通道转成伪彩后,先人工看一版归一化统计,确认正样本区域与背景在数值分布上有足够的可分性,再决定后续增强方案。

1.2 远距离火点只有十几个像素,小目标问题躲不掉

无人机巡航高度通常在100米以上,一架 640×512 的红外相机,视野里一棵树冠可能占不到 20×20 像素,初起的小火点大概就落在 8×8 到 30×30 这个区间。这个尺寸在 YOLOv11 默认的输入分辨率 640×640 下,经过几次下采样后,特征图上的响应往往只剩下几个像素的峰值。

这也是为什么有人拿通用目标检测权重直接训火灾数据,mAP 很难看的原因之一。通用数据集里小目标占比不算高,模型天然偏向中大型目标。针对红外林火任务,我建议从模型的输入、锚框分配和增强策略三个方向同时下手,后面会专门讲。


2. 喂给YOLOv11之前:红外数据集整理与标注里的几个硬要求

2.1 数据来源、目录结构与YOLO标注格式

训练一个可用于实际巡检的红外火灾模型,数据来源基本有两类:一类是常见的公开红外火灾图像集,另一类是自采的无人机航拍红外视频抽帧。如果条件允许,建议以自采为主、公开数据集为辅,因为无人机视角下的俯视红外目标分布,和地面手持红外相机的平视视角差别不小,模型很容易在视角迁移上掉点。

文件规范照着 YOLO 系列标准格式整理即可:

  • 图片按images/train、images/val、images/test分目录存放;
  • 标注文本放在同名的labels目录下,txt 文件名与图片名严格一致;
  • 每行内容为class_id x_center y_center width height,坐标用相对图片宽高的比例归一化。

实际整理的时候有一个很容易错的地方:无人机的原始航拍图分辨率可能很高(比如 3840×2160),强行直接喂给 YOLOv11 训练,一方面 batch size 被显存卡死,另一方面大量图形细节超过模型输入尺寸,反而容易过拟合。我的做法是先把原图切成 640×640 的滑动窗口块,切块时相邻窗口保留 20% 重叠,然后只保留包含标注目标的窗口,其余全部丢弃。这样既保住了小火点的原始像素信息,又不会因为整图缩放到 640 而把火点压没。

2.2 红外图像的增强策略不能照搬可见光方案

很多教程会让你直接用 Ultralytics 默认的 HSV 扰动增强,但红外图像根本没有 H 和 S 通道,HSV 扰动只作用于彩图,对灰度红外图几乎不生效。我自己在代码里实际测试过,把默认hsv_h、hsv_s、hsv_v全部调低,对红外数据集收敛速度没有明显影响,所以别在这上面浪费精力。

真正有效的是这几类增强:

  • 水平翻转和轻微旋转:无人机姿态变化时林区地物方向会变,做角度增强合理;
  • 随机亮度对比度微调:对应红外相机自动增益在不同高度上的波动;
  • CLAHE(限制对比度自适应直方图均衡):对远景低对比度火点非常友好,能让灰度暗部细节更清晰;
  • 随机裁剪、缩放组合:帮助你模拟不同飞行高度下的尺度变化。

2.3 类别设计:明火、暗火、烟还是合并成一类

红外热像在白天能拍到的烟往往是低温遮挡,不见得是明显目标;夜的烟几乎不可见。所以在红外数据集里,把“烟”单独成一类的收益,远不如可见光数据大。大部分项目我建议直接只设一个 fire 类,最多再加一个 smoulder(阴燃/暗火)类,别贪多。

如果你的场景必须识别烟,那建议把可见光图像和红外图像训练成两个并联模型,而不是硬塞进同一个 YOLOv11 模型。这两个模态的目标分布差异太大,硬凑在一起,训练时类别间会互相抢梯度,最后两边都训不好。


3. Ultralytics YOLOv11起步:环境装配、数据集配置与第一次启动训练

3.1 环境依赖与模型规格选择

Ultralytics 的安装近乎无脑,Python 3.9 以上、PyTorch 2.0 以上即可,执行pip install ultralytics之后,命令行yolo和 Python 接口就都能用了。训练时我会习惯用 Python 脚本而不是纯命令行,方便记录指标和动态调参。

模型规格上,YOLOv11 提供 n、s、m、l、x 几个档位,是否训练更大的模型要视你的部署设备而定。我在这个项目里做了个小对比:训练同样的红外火灾集,yolo11n 和 yolo11m 的精度差距,并没有普通目标数据集上那么大。原因还是小目标红外样本的有效特征信息量有限,参数更大的模型吸收不到更多知识,反而更容易记住背景噪声。如果你的最终部署目标是低功耗边缘设备,直接选 n 或 s,别心疼;如果只是服务器做后处理,用 m 求稳也可以。

3.2 数据集配置文件的写法

只需要写一个forest_fire.yaml,把路径和类别声明清楚,Ultralytics 会自动匹配图片和标注文件。

path: /home/drone_ir_forest_fire train: images/train val: images/val test: images/test nc: 1 names: 0: fire

这里有一个细节值得关注:path字段建议写绝对路径,但在项目迁移时要当成一个需要修改的配置项,而不是写死到底。我遇到过几次因为换机器忘了改目录配置,训练直接报了Dataset not found的错。

3.3 第一次跑训练,命令参数该给什么

基准配置我建议这样起手:

yolo train model=yolo11n.pt \ data=forest_fire.yaml \ epochs=200 \ imgsz=640 \ batch=16 \ device=0 \ project=runs_fire \ name=y11n_ir_v1 \ patience=30 \ save_period=5

几个参数的选择理由:

  • epochs=200看起来偏高,但因为红外火灾样本量通常不大,模型真正收敛经常要到 120 轮以后,提前早停会损失不少 mAP;
  • patience=30是防止模型在中后期抖动明显时浪费算力;
  • save_period=5是为了保留中间权重,后面做损失曲线分析时,你能看到每一阶段模型的性能变化,而不是只有一个终点权重;
  • imgsz=640是精度和速度的折中点。如果你的显存大鱼 24G,直接用imgsz=1280对小目标会有明显增益,但推理速度会掉下来。

哦对,第一次训练前记得看一眼model=yolo11n.pt的下载目录,Ultralytics 会自动从官方源拉权重,国内网络环境慢的话,可以手动下载好再放到~/.config/Ultralytics对应目录,避免卡在权重下载那一步。


4. 训练中最折腾人的部分:损失曲线、超参与红外小目标的拉锯战

4.1 判断收敛不能只看总 loss,要看每一张图的难例

后台打印的 loss 曲线初次看会让人心动过速:前 20 轮降得飞快,但 val 精度一直不高。这不是 Bug,是目标分布太偏。红外火灾集里,背景占比极大、目标占比极小,模型前段在学“什么不是火”,后段才开始真正学“什么是火”。

所以训练时别只盯 loss,要把每个 epoch 的 precision、recall、mAP50、mAP50-95 同时记录下来。我习惯通过下面的脚本持续看验证结果:

from ultralytics import YOLO model = YOLO("runs_fire/y11n_ir_v1/weights/best.pt") metrics = model.val(data="forest_fire.yaml", imgsz=640, batch=16, plots=True) print(metrics.box.map50, metrics.box.map)

如果 mAP50 能稳定到 0.8 以上、mAP50-95 在 0.5 上下,这个模型在真实场景就基本可用了。对红外火灾这种「背景极其复杂、目标极其简单」的任务,mAP50 的可信度比 mAP50-95 高,因为火的边界本身就不是清晰边缘,过高的 IoU 阈值实际上是在惩罚正确的检测。

4.2 超参调优:几个关键旋钮,往哪个方向拧

在 Ultralytics 的训练参数里,真正需要针对红外场景反复试的有这么几个:

  • lr0:默认 0.01 有点激进。我用 AdamW 优化器时,lr0=0.001起步,配合lrf=0.01做余弦退火,收敛更稳。红外目标小、正样本少,学习率太冲很容易直接把模型推到局部噪声解上。
  • mosaic:默认 0.5 或者更高。但问题来了,一张 640×512 的红外图切四块合成一块,原来的小火点会被进一步缩小到接近消失,模型学不到东西。我的实际做法是前 100 轮mosaic=0.5,后 100 轮降到mosaic=0.1,让模型在后期回归真实目标尺度。
  • close_mosaic:Ultralytics 也支持在训练后段自动关闭 mosaic,这个对任何小目标任务都建议用上,能明显缓解增强与真实分布之间的偏差。
  • degrees:建议 5 到 10,不要随便给到 30 以上。无人机俯视图地面朝向变化没有你想象的那么大,旋转太多反而把长条形的火焰方向性搞乱。
  • box、cls、dfl这些损失权重,我认为保留默认就好,不要一上来就魔改,先观察一轮基线再说。

4.3 实测定格:n 和 m 到底差多少

以我自己的红外火灾数据集为例,同类图像量 2500 张,目标总框数约 4800 个,yolo11n 训完 mAP50 能到 0.82,yolo11m 提高到了 0.86 左右。差异存在,但没有到“不可替代”的程度。反而推理速度的差距非常现实:n 在边缘设备上能达到 40 FPS 上下,m 掉到 20 FPS 左右。

这就是一个典型的产品取舍:无人机巡检要求的是在飞行中尽快发现火点,而不是把一个框的 IoU 从 0.82 抬到 0.86。因此我最终线上方案选了 n,同时配合后面会讲的切片推理来弥补小目标召回。

yolo train model=yolo11m.pt \ data=forest_fire.yaml \ epochs=200 imgsz=640 batch=16 device=0 \ lr0=0.001 lrf=0.01 optimizer=AdamW \ mosaic=0.5 close_mosaic=10

用起来会比默认配置更稳,尤其当你换了一个数据分布不太一样的新林区时,掉点幅度明显小于裸奔的默认参数。


5. 验证集再好看也没用:真实巡检场景的误检漏检排查经验

5.1 红外图里最容易被当成火的几种东西

在仿真/公共数据集上训出来的模型,拿到真实航拍红外视频里跑一轮,大概率会见到这样一批对手:

  • 烈日暴晒后的裸露岩石、沙地,热惯量不同导致局部热斑;
  • 金属建筑屋顶、铁皮棚,强反照率加高热容量,形成和火相似的亮块;
  • 道路、停机坪这类大面积高温区域;
  • 正在运行的工程机械,排气管、发动机舱是天然的“热点”。

处理办法不能只靠继续堆数据。我记得很清楚,第一次跑实飞视频时,模型把一条晒了一下午的土路识别成了条状火带。我当时的解决思路是给训练集增加“负样本”比例,但亲手把几千张单纯背景图塞回去,标负样本这事又太蠢——最后发现更实际的方法是调置信度阈值,把默认的 0.25 提到 0.4,误检直接降了一半,真火召回率几乎没有损失。

5.2 漏检高发区:逆光、烟雾遮挡、远距离小目标

与误检相对的漏检,通常发生在三种条件下:

  • 火点过小且对比度低:白天强烈的阳光压制了火焰的热信号,距离稍远就融进了背景;
  • 烟遮挡:红外热像里烟呈现为低温半透明区,火被半层烟盖住时边缘亮度下降,模型会犹豫;
  • 传感器噪声干扰:个别边缘像素过热或坏点,形成假热点,反而把注意力引开。

在实际工程里,我发现漏检几乎都是“切片推理”能救回来的。做法很简单:把原始大图按 640×640 滑窗切块,每一块独立推理,再将结果映射回原图坐标做 NMS。在 3840×2160 的航拍原始帧上,切片推理能把小火点检测率提升明显,代价是推理耗时翻倍。为了控制实时性,我设置了轮流切片策略:每隔一帧做全图推理,中间帧只做疑似火点区域局部推理,效果和耗时都能兼顾。

5.3 置信度、NMS 和帧间逻辑,三重过滤

只靠单帧检测结果上报告警,会被闪烁噪声打爆。我的最终判断管线分成三层:

  1. 模型层:YOLOv11 输出所有conf > 0.3的框;
  2. 单帧层:对框做merge和过滤,只留下置信度高于 0.45 的框;
  3. 帧间层:同一个 GPS 位置连续 3 帧以上出现框,才触发上报。红外相机随机噪声不会连续多帧叠到同一个坐标上,这个逻辑能滤掉九成以上的虚警。
from ultralytics import YOLO model = YOLO("runs_fire/y11n_ir_v1/weights/best.pt") res = model.predict( source="fly_frames", conf=0.3, iou=0.45, imgsz=640, device=0, save_txt=True, save_conf=True, )

这样输出的 txt 结果再脚本做 GPS 坐标映射,就能直接对接地面站的告警列表了。


6. 从训练机到无人机:模型导出、量化与端侧部署的一段记录

6.1 从 PyTorch 权重到可上机的推理引擎

训练完毕,best.pt还只是一个 PyTorch 权重。真实部署到无人机边缘板卡上,这一步必须做个“格式转换”,否则推理延迟没法看。

yolo export model=runs_fire/y11n_ir_v1/weights/best.pt format=onnx imgsz=640 yolo export model=runs_fire/y11n_ir_v1/weights/best.pt format=engine device=0 half=True imgsz=640

我用 TensorRT 导出 engine 后,在同样的边缘设备上推理速度比 PyTorch 原生模式提升了约 3 倍。FP16 精度在这类任务上完全够用,除非你要部署的芯片不支持 FP16,才考虑 INT8 量化。INT8 在小目标任务上风险很高:红外火点和背景之间的数值差异一旦被量化到 256 级里,静默失真的可能性非常大,训好的模型可能直接趴窝。我这里踩过的坑就是强行 INT8,结果漏检率翻倍,后来老老实实退回 FP16。

6.2 帧率、功耗和检测距离的三方平衡

无人机端侧部署最大的敌人永远是功耗和散热。红外相机本身工作温度就高,板卡再满负载推理,机器很容易热降频。一个可落地的配比是:

  • 模型:yolo11n,FP16 TensorRT;
  • 输入:640×640 单通道灰度,推理时强制转三分通道喂入;
  • 频率:常规巡航 5 FPS,发现疑似目标后自动切到 10 FPS 锁定;
  • 峰值功耗:控制在 8W 左右,整机续航不会被拖垮。

检测距离是一个非常诚实的指标:大目标(一米见方的火堆)在 300 米高度能被稳定检出,小火点(如烟头引燃的初期灌木)在 150 米以上就开始不稳定,这个性能分布必须写在项目文档里,别给业务方超预期的承诺。

6.3 一套可以带走的优化清单

最后把我跑通整个流程后认为最值得复用的优化点整理如下,当你自己动手训练时直接照着检查:

  • 数据层面:优先自采无人机视角红外视频抽帧,不要只依赖公开红外火灾图集;切块训练而非整图缩放。
  • 增强层面:关掉 HSV 默认增强,打开 CLAHE、水平翻转、轻微旋转;后 10% epoch 调低 mosaic。
  • 超参层面:用 AdamW、lr0=0.001、mosaic=0.5、close_mosaic=10、imgsz=640(显存大就 1280)。
  • 推理层面:大图切片推理 + 帧间稳定性过滤 + 置信度阈值提到 0.4 以上。
  • 部署层面:导出 TensorRT FP16,谨慎对待 INT8 量化,预留热降频余量。

照这个流程走一遍,哪怕你手里的红外火灾数据和我的分布差异很大,至少能保证第一版模型就落在可迭代的区间里,而不是在乱调参数的道路上白白烧掉一周时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 23:16:12

AI Agent原理与Function Calling实战:零基础可运行Demo

最近总有朋友问我:AI Agent到底是什么?网上概念文章满天飞,讲得云里雾里,真到自己动手时,连一个能跑的最小Demo都没见过。我也是从这种状态过来的,最早以为Agent就是“更聪明的大模型”,后来才明…

作者头像 李华
网站建设 2026/10/22 22:30:46

PIC18F97J60与PJ85718DM实现远程温度采集系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 22:28:05

Spring Cloud Data Flow实战:统一流处理与批任务编排平台

在微服务与云原生技术浪潮中,数据集成与批处理任务的编排难度常被低估:当接口调用链超过三层、定时任务数量过百、实时流处理逻辑频繁变更时,硬编码调度正成为系统脆弱性的首要来源。Spring Cloud Data Flow作为一个构建于Spring生态之上的统…

作者头像 李华
网站建设 2026/10/22 22:26:01

2026实测:8款AI论文工具全维度测评与写作实战指南

本科毕业论文写到崩溃的时候,正好是AI论文工具最泛滥的时候。打开任何一个分享平台,都能看到七八个“论文神器”“一键生成初稿”的推送,每个都吹得天花乱坠,但真拿来用,有的连开题报告的“选题背景”都写不像样&#…

作者头像 李华
网站建设 2026/10/22 22:24:26

Qwen-Image-2.1云部署避坑指南:GPU选型、显存规划与生产实践

说实话,接到 Qwen-Image-2.1 的云端部署任务时,我一开始是有点轻敌的。毕竟这些年跑过的生成模型不少了,心想无非是装个驱动、拉个权重、起个服务。真上手才发现,光是把环境理干净、让请求稳定返回,就够喝一壶的。这篇…

作者头像 李华
网站建设 2026/10/22 22:21:17

机器人平台化十年演进:从架构分层到能力沉淀

1. 平台化不是终点,而是机器人落地的那道坎先说一个可能反直觉的结论:做了十年机器人平台化,回头看真正难的不是算法、不是硬件,而是"把所有人拉到同一张图纸上干活"这件事本身。我做机器人相关的工作差不多十年了&…

作者头像 李华