ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

无人机航拍火灾烟雾识别:从数据集构建到模型部署的全链路实践

无人机航拍火灾烟雾识别:从数据集构建到模型部署的全链路实践

从 10443 期这个编号就能看出来,这套无人机航拍火灾烟雾识别数据集的迭代,不是一次性整理完就交付的“一次性资产”,而是一个长期滚动的项目。我在无人机安防和森林防火这个方向上做了不少实际项目,深知烟火识别这个任务有多别扭:人、车、船这些目标再小,至少边缘是清晰的;但烟雾没有固定形状,没有清晰轮廓,颜色还随着光照和环境变化,经常把云、雾、水汽、工厂排烟混在一起。真正要做的是无人机航拍场景下的烟火危险自动识别,让算法在森林火灾巡检、工业厂区安全预警这些实际任务里真能顶用。

这篇文章会把我们团队从数据采集、筛选标注、模型训练到机载端部署的全链路经验拆开讲,重点说清楚烟雾识别为什么难、数据集的“底料”是怎么构建的、训练时怎样平衡召回率和误报率、部署阶段有哪些坑不在算法里。适合正在做无人机安防识别、森林防火巡检、厂区烟火预警的算法工程师、项目负责人,也适合打算自己构建烟火数据集的研究者参考。

1. 火灾烟雾识别到底难在哪:先认清“看得见”和“认得出”之间的距离

很多人以为烟火识别就是一个普通的目标检测任务,把烟标注出来,训练一个检测模型就行。实际跑过真实项目后会发现,最核心的难点不是模型能力不够,而是这个目标本身就不符合常规目标检测的假设。

1.1 烟雾在视觉上不是一个“物体”

常规检测目标比如行人、车辆,有相对固定的形态和边界,模型学的是“形状+纹理+上下文”的组合特征。但烟雾是流体,它的边界在每一帧都在变,边缘是半透明渐变的,你没法用一个紧致的矩形框去贴合它。哪怕标注员手很稳,同一个烟团的框在不同帧之间的宽高比也可能剧烈变化,这会导致检测头的回归损失一直抖,模型不容易稳定收敛。

还有一点很关键:烟雾没有固定的颜色。森林火灾初期可能是灰白色烟,烧起来之后变黑,再往后由于燃烧物不同可能偏黄褐色;工业厂区的水蒸气在逆光下看起来也像白烟。颜色特征完全不可靠,模型不能只靠颜色判断。

1.2 无人机视角叠加了多重干扰

固定摄像头的烟火识别已经有不少成熟方案,但无人机视角要麻烦得多:

  • 高度变化范围大。巡检时飞行高度可能从 30 米到 150 米不等,同一个烟团在画面里的像素尺寸可能相差好几倍。
  • 云台姿态变化。航拍不总是正俯视,经常有 45 度倾斜角,烟团的投影形状完全不一样。
  • 飞行抖动。即使有云台增稳,高空风力大时画面仍会有轻微运动模糊,对半透明的小目标影响尤其严重。
  • 背景极度复杂。森林场景里树冠纹理本身就杂乱,远处山体阴影、晨雾、云层投影都会干扰判断。

这些干扰叠加起来,导致一个典型现象:在地面固定摄像头上效果不错的模型,一搬到无人机航拍数据上,精度掉得很难看。这也是为什么一定要有专门的无人机航拍数据集,而不能直接拿公开的烟火数据集凑合。

1.3 早期预警的时间窗口逼迫模型做更敏感的取舍

森林防火巡检的逻辑是“早发现、早处置”,理想情况是在烟刚冒头、还没有明火的时候就告警。这个时间窗口其实很短,从烟雾出现到火势蔓延可能只有几分钟到十几分钟。所以模型必须对很小的、很淡的烟也保持高召回率。

但高召回率必然带来高误报率,这是所有检测任务都逃不掉的矛盾。在真实安防项目里,误报是有代价的:每次误报都要有人去复核,复核次数多了,值班人员会对告警麻木,真正出事时反而被忽略。所以烟雾识别系统不能只做一个检测模型,而是要在“灵敏度”和“可信度”之间做分层设计,这个后面会细讲。

为了更直观理解烟、雾、云、水汽这些易混淆目标,可以看这个对比表:

类别颜色表现边缘特征动态行为与火灾烟雾的关键差异
火灾烟雾灰白至黑褐,随燃烧物变化半透明渐变,边界模糊持续扩散、上升、随风向漂移动态持续性强,浓度通常递增
晨雾/低云均匀乳白大范围弥散,边界极不明显整体缓慢移动,形态变化很小没有“从一点向外扩散”的源点
厂区水蒸气白色,逆光下偏亮有较明显的柱状轮廓从固定烟囱/冷却塔持续排出源点位置固定,扩散范围有限
炊烟淡灰色较淡,低矮随风快速消散持续时间短,多出现在居民区
车辆扬尘黄褐色贴地,浓密而不透明沿道路移动,随车轨迹变化位置贴近地面,有明显移动方向

这里的关键判断线索是“是否有固定的源点”和“动态扩散趋势”。真正的火灾烟雾通常有一个出发点,然后持续向外滚动扩散,范围逐渐扩大;而雾、云、水汽要么没有源点,要么源点固定且扩散模式稳定。这也是为什么后续做算法时,我会特别强调用视频时序信息,而不是单帧判断。

2. 数据集线下工作:采集、筛选、标注的每一步都有取舍

数据集的质量决定了模型表现的上限,模型只是尽可能接近这个上限。无人机航拍火灾烟雾识别数据集也不只是“找些带烟的视频,抽帧画框”这么简单。这一节把采集、筛选、标注三个环节的关键取舍掰开讲。

2.1 巡飞采集不是“飞出去拍就行”

采集阶段首先要明确覆盖维度,否则数据会出现严重的场景偏置。我们做这套数据集时,按下面几个维度规划采集计划:

  • 场景维度:森林、草原、农田、工业厂区、城乡结合部。每个场景的植被、建筑、热源分布都不一样。
  • 飞行高度:低空(30-50 米)、中空(50-100 米)、高空(100-150 米)。同一个烟雾在不同高度下的尺度和视角差异很大。
  • 相机角度:正俯视和 30-45 度倾斜视角都要覆盖。实际巡检常使用倾斜视角,因为正俯视时烟雾高度信息会丢失。
  • 气象条件:晴天、阴天、薄雾、逆光、顺光。烟雾在逆光下对比度低,是最难的样本;在阴天散射光下反而更清晰。
  • 时间覆盖:早晨、中午、傍晚都要有。早晚低角度阳光会让烟投射出长阴影,颜色也会偏暖。

采集的方式主要有两种:一是真火演练,在受控区域进行计划燃烧,无人机盘旋记录从冒烟到明火再到熄灭的全过程;二是事件记录,在实际火情或厂区异常排烟发生时,如果有无人机在场,同步保存原始视频。真火演练的优点是可以从“烟刚开始出现”就完整记录,这一点特别重要,因为模型最需要学习的就是早期微弱烟雾的特征。

2.2 抽帧筛选的关键帧策略

一个 15 分钟的巡飞视频,如果按 25 帧每秒抽帧,就是 22500 帧。不可能全标,也没必要全标。连续帧之间内容高度重复,全标反而会让训练集被大量相似样本主导,模型过拟合到某一段画面上。

我们的筛选策略是按“关键帧”而非“均匀抽帧”来操作:

  • 烟雾初现阶段:从烟刚可见到明显扩散,每 3-5 帧选一帧,这是最高价值样本。
  • 稳定扩散阶段:每 10-15 帧选一帧,覆盖不同形态和方向。
  • 目标接近消失阶段:保留最后几帧,让模型学会在目标模糊时也能保持追踪。
  • 火焰出现阶段:如果发展到了明火,重点保留,但这类样本不是主要学习对象,因为早期预警才是核心目标。

另外会刻意保留一些“目标很小”的帧,烟团只占画面面积的 2%-5%,甚至更小。这些难样本是提升模型在小目标上召回率的关键。很多数据集为了标注省事,喜欢保留目标大的清晰帧,结果是模型部署后对早期微弱烟雾完全没有反应。

2.3 标注规则与易错点

烟雾的标注比普通目标更容易出现标准不一致的问题。我们内部定了几条规则,踩过不少坑之后沉淀下来的:

第一个规则是“只标注有源点的烟,不标注无源扩散物”。云层投影、大面积低雾这种没有明确源点的扩散物,一律不标注为烟雾。标注员初期经常把云误标成烟,主观上觉得“像”,但这类样本会让模型学到错误特征。

第二个规则是记录“烟源类别”,而不是只画一个框。烟源分为森林植被燃烧、建筑火灾、工业排烟、秸秆燃烧等。不同烟源的烟雾形态差异明显,这个属性后续可以用于做分层训练或误报分析。

第三个规则是标注透明度等级:明显烟雾、轻度烟雾、模糊疑似。轻度烟雾和模糊疑似这两种样本会被单独管理,作为后续难例挖掘的种子池。

标注工具方面,日常用的是开源工具,比如 LabelImg 的矩形框标注和 X-AnyLabeling 的半自动辅助标注。烟雾目标边缘模糊,纯手动画框很容易画偏,半自动标注可以先框一个大范围,再用分割模型辅助修正边缘。不过辅助标注完必须人工逐帧过一遍,特别是“框是否包含了太多背景”这个问题,背景里的树冠纹理会被框进去,让模型以为烟雾应该包含树冠纹理,这是个隐性坑。

2.4 误报样本是数据集的“隐藏半壁江山”

很多刚接触烟火识别的人只关心正样本有多少,忽略了负样本。实际上在安防预警场景里,负样本的数量和设计水平直接决定了系统能不能用。

我们专门采集和标注了一批“易混淆负样本汇”:云层、晨雾、炊烟、工业水蒸气、车辆扬尘、建筑玻璃反光、逆光下的树叶亮斑、飞鸟群。这些样本不参与烟雾类训练,而是作为独立的负样本集,用于后续做分类复检模型的训练。模型在正负样本比例上,我们控制在正样本占 60%-70%,负样本占 30%-40% 左右,既保证对烟雾的敏感度,又让模型见过足够多的“假烟”。

在标注负样本时有个细节:不要只标“整幅图中没有烟”的纯负样本,还要标“图中存在疑似区域但实际不是烟”的静态帧。后者才是真正有价值的负样本,因为它能逼着模型学习区分“像烟的云”和“真正的烟”之间的细微差异。

数据标注的质量控制也值得提一句。我们采用“双人标注 + 交叉抽检”的方式:同一批帧由两位标注员独立标,计算框的 IoU,低于 0.5 的帧进入复核池,由唯一有经验的人做最终裁决。烟雾框的尺度差异本来就大,标注一致性不好控制,这个环节不能省。

3. 训练烟火识别模型时,我后来放弃了单模型方案

数据集构建完成后,真正开始训练算法时,我意识到烟火识别不适合用“一个大模型搞定所有事”的思路。原因很简单:检测模型的定位能力和分类模型的判别能力是两个维度,混合在一个模型里,往往两头都不够极致。我们最后采用的形式是“检测主模型 + 图像分类复检 + 视频时序投票”的组合方案。

3.1 检测主模型的选型:YOLO 系与 RT-DETR 的取舍

主模型我们用过 YOLOv8、YOLOv11,也测过 RT-DETR,最后项目落地更多选择 YOLO 系。原因主要有三个:

第一,部署生态成熟。无人机的机载算力有限,常用 Jetson 系列平台,YOLO 系模型转 TensorRT 引擎很顺手,各种量化工具链都是现成的。RT-DETR 的精度在某些测试集上略高,但部署时要处理 transformer 结构的动态 shape 问题,在低算力设备上延迟优势不明显。

第二,烟雾目标小且尺度变化大,YOLO 的多尺度检测头配合合适的训练策略,效果足够用。我们内部测试中,YOLO 系模型通过难例挖掘和增强策略,小目标召回率已经接近 RT-DETR 的水平,而推理速度明显更快。

第三,YOLO 系可以方便地启用分割辅助分支,用分割头辅助检测头学习烟雾轮廓。因为烟雾边缘模糊,单纯用矩形框回归容易抖动,加上分割分支后检测头相当于多学了一个“软边界”的中间表示,收敛更稳定。

但这不意味着 RT-DETR 一无是处。如果目标是对离线视频做事后分析,不追求实时性,RT-DETR 的全局建模能力在处理大面积弥散烟雾时有优势。我们的结论是:机载实时检测用 YOLO 系,地面离线二次分析用 RT-DETR 或更大模型。

3.2 训练策略:预训练、增强和难例回灌

训练细节上,我们积累了几点对烟雾识别特别有效的经验:

  • 预训练权重不可少。自建数据集规模有限,不可能从零训练。用大规模公开检测数据集预训练后,再在烟火数据集上微调,收敛速度和最终精度都有明显提升。
  • 数据增强策略要有针对性。除了常规的马赛克增强、随机裁剪、翻转,我们重点加了色彩抖动模块和模拟运动模糊模块。色彩抖动是为了对抗烟雾在不同光照下的色偏,运动模糊是模拟无人机飞行时的抖动拍摄效果。另外随机遮挡增强也很有效,因为真实巡检中烟雾经常被树冠部分遮挡。
  • 难例回灌要持续进行。第一轮训练结束后,拿模型去跑一遍未标注的原始视频,把模型预测置信度在 0.3-0.7 之间的候选框挑出来,人工确认后回流到训练集。这些“让模型犹豫不决”的样本是提升模型能力最划算的投入。

值得单独说的是损失函数里的类别不平衡问题。烟雾检测里正样本远少于背景,常见做法是把分类损失里的正负样本比例调成 1:5 到 1:10 之间,或者直接用带聚焦损失的变体。我们实践下来,最简单的调整是增大烟雾类别的损失权重,这个对 min 类别的召回率提升非常直观,比堆复杂度更有效。

3.3 图像分类复检和视频时序投票:降误报的核武器

检测模型负责尽可能找出所有可疑目标,但它的缺点是对外观相似的假目标不够挑。于是我们把检测模型的每个候选框裁出来,送进一个独立的图像分类模型,让分类模型判断“这是烟还是不是烟”。

这个分类复检模型用 ResNet 或 EfficientNet 就够。训练数据用前面提到的人类标注的疑似烟样本、易混淆负样本,再把检测模型检出的假阳性框作为额外负样本加入。效果非常明显:某厂区场景里,白天太阳照射下的白色屋顶在检测模型里经常被当成烟,但分类复检模型能把这些滤掉,因为它在训练里见过足够多“白色矩形物体”的负样本。

视频时序投票进一步降低单帧误报。无人机视频是连续的,真正的烟雾不会只出现一帧就消失,而误报往往是瞬间的、闪烁的。我们设置了一个缓存窗口,连续 N 帧里如果有 M 帧命中了“检测+分类复检”两级确认,才判定为一次有效告警。在实际部署中,N 取 5 到 10 帧、M 取 3 到 6 帧,可视帧率调整。这样处理后,单帧噪声基本被消除。

4. 机载端与平台端的落地实战:很多坑不在算法里

算法在电脑上跑得好,不代表到了现场就能用。机载端的算力、带宽、散热,平台端的数据回传、人工复核,这些环节才是项目真正落地时最容易翻车的部分。

4.1 Jetson 上的模型转换与量化:烟雾特征最容易被量化吃掉

机载我们主要用的是 Jetson 系列。模型从 PyTorch 转到 TensorRT 要做 FP16 或 INT8 量化,这里有一个特别需要注意的现象:烟雾是低纹理目标,边缘渐变平滑,没有锐利的角点和强纹理,这类特征在 INT8 量化后非常容易丢失。量化感知训练比训练后直接量化好得多,校准集的数据构成也直接影响精度。

我们做过对比:用常规校准集做 INT8,量化后小目标召回率掉了 7 个百分点以上;换成包含大量小目标、低对比度烟雾帧的校准集后,降幅缩小到 2-3 个百分点以内。FP16 虽然占用资源多些,但在机载端如果显存够用,我建议优先用 FP16。只有在显存吃紧时才上 INT8,并且一定要做量化后的全量测试集评估,不能只看几张样例图。

另一个细节是输入分辨率。烟雾是小目标,输入分辨率太低会直接丢掉微弱烟团。我们在 Jetson 上把输入分辨率定为 1280 或 1536,推理帧率虽然比 640 低一些,但对小目标的召回率提升是值得的。这个取舍要根据实际巡检任务调节,如果飞机飞得高、目标小,分辨率优先级要高于帧率。

4.2 低带宽回传链路:不需要把全部视频传回地面

森林巡检场景经常面临 4G 信号覆盖差、卫星链路带宽小的问题。如果每路视频都全程回传,链路根本撑不住。我们的方案是在机载端先跑检测,只有当检测链路确认了疑似目标后,才将告警帧前后的短视频片段回传。平时只传低码率的缩略视频流供地面人员监视,或者干脆只传关键帧。

这个方案的代价是会依赖机载端模型的单机判断,所以两级确认中的分类复检在机载端也要跑,尽可能把误报在源头过滤掉。同时回传的片段要有冗余:从疑似目标出现前 10 秒开始截取,到确认消失后 5 秒结束,方便地面人员看到烟雾的运动趋势。

链路恢复方面,断点续传是刚需。我们遇到过飞行中信号丢失、回传失败的情况,如果片段没有本地缓存并自动续传,地面端就会漏掉关键数据。这个在野外巡检里是常见问题,处理方案很简单:录制的短视频存到机载存储卡,回传成功后自动删除,否则保留并在下次链路恢复时补传。

4.3 工业厂区场景的差异化调优:固定烟源和“白名单”

森林和厂区的烟火识别逻辑很不一样。厂区里常年存在正常排放的烟囱烟雾、冷却塔水蒸气、燃气锅炉排烟,这些都是“合法的烟”,如果模型一看到烟就告警,系统基本废掉。

我们在厂区落地时做了一套“固定烟源白名单”机制。第一步是先对厂区做一次专门的航拍建模,标出所有已知烟囱、水塔、蒸汽排放点的 GPS 坐标和大致高度。第二步是在检测结果中做地理信息过滤:如果检测框的中心点落在已知固定烟源的坐标范围内,且烟雾特征和该烟源的常规排烟模式匹配,就降级为“常规排烟记录”,不触发高级别告警。

但这个白名单不能一刀切。热电厂锅炉启动时排烟量大、颜色异常,这种潜在故障也需要预警。所以对白名单烟源我们单独设置了一套“排烟模式异常检测”逻辑,关注排烟浓度突变、颜色异常、持续异常时间等指标,而不是简单的“见烟就报警”。这套设计需要在项目初期和厂区安全负责人反复确认需求边界,否则模型训练和逻辑设计都会走偏。

4.4 告警分级设计:让每一条告警都有明确含义

部署初期,我们的告警只有“有烟/无烟”两态,结果值班人员一天收到几十条提示,大多数人直接不管了。后续改成了四级状态:

  • 记录级:检测到疑似目标但置信度低,系统只记录,不推送。
  • 提示级:单帧检测加分类复检通过,但时序投票未满足,推送给页面提示,不触发声音报警。
  • 预警级:时序投票通过,人工复核前先行推送,通知值班人员关注。
  • 确认级:地面人员通过回传视频确认,或者多源数据(热成像、火点监测)同时触发,直接推送处置指令。

这个分级设计既保证了早期烟雾的高灵敏识别,又避免大量无效提示消耗注意力。预警级的判定里还可以加入温度信息:如果机载端有红外热成像模块,将可见光烟雾检测和高温点检测做投票融合,能显著增强告警可信度。森林场景里,一个“疑似烟 + 高温点”的组合几乎没有误报空间。

5. 数据集版本管理:一个新手最容易忽视的长期问题

数据集建好、模型训好、系统跑起来之后,真正的长期成本才刚开始。无人机巡检项目是持续采集数据的,每新增一批视频,每发现一批新的误报,数据集都会变化。如果版本管理不到位,整个算法迭代会变得一团糟。

5.1 明确数据集的适用边界

任何数据集都有边界,这套无人机航拍火灾烟雾识别数据集也不例外。我们内部明确规定了它的适用范围:无人机中低空航拍视角、可见光相机、白天和黄昏环境为主。它不完全适用于固定摄像头视角、夜间红外场景、极高空卫星视角。边界写清楚不是坏事,反而能避免把模型用到不适合的场景里得出错误结论。

实际使用中,我发现最大的泛化问题是地域差异。我们采集的数据主要集中在某几个区域,植被类型、建筑风格相对固定;换到气候和植被完全不同的区域,模型表现会有明显下滑。所以如果要在新区域部署,第一件事是补充当地场景的采集数据,哪怕只有几百帧,也能有效缓解地域偏置。

5.2 主动学习闭环:让误报样本自动回流到训练流程

模型落地后不能停在原地。我们在项目里搭了一个简化的主动学习闭环:

  1. 每次巡检结束,机载端和平台端记录的告警结果、置信度日志自动汇总。
  2. 筛选出置信度在 0.4-0.7 之间的“模糊区间”检测结果,以及被人工复核判定为误报的样本。
  3. 这些样本自动打包进入标注队列,标注员确认后并入数据集新版本。
  4. 定期用新版本数据集重新训练和评估模型。

这套机制能让模型逐步适应新增场景,尤其对厂区这种固定场景每天积累的负样本非常有效。我们每两到四周触发一次小规模训练更新,每次加入数百到数千张新样本,模型误报率呈现持续下降曲线。

5.3 记录采集元信息,让数据集“可追溯”

最后说一个很多人忽略的事:数据集的元信息记录。每一帧样本不仅要有人工标注,还应该记录采集时间、GPS 坐标、飞行高度、云台角度、天气条件、能见度等元信息。

这些元信息有几个用途:一是做数据分布分析,比如可以快速发现当前数据集里晴天样本占比过高,阴天和低光样本不足;二是排查模型失败原因,比如某个场景连续误报,翻元信息发现是逆光条件样本覆盖太少;三是做数据版本回溯,当模型在新版本上效果回退时,能够定位是哪些数据变化导致的。我们每一期数据集都会生成一个版本清单,包含样本数量、场景分布、天气分布、标注版本、模型评估指标,这样整个项目迭代过程完全可以追溯。

在实际项目中,我最大的体会是:烟火识别系统的长期能力提升,不取决于评测集刷了多少分,而取决于数据闭环跑得多顺。每次出现新的误报、新的漏报,都是在给数据集补充最有价值的样本。只要这个循环在转,系统的实用性和鲁棒性就会持续变好。

最后分享一个具体的小技巧:在标注界面里把每帧的采集高度和天气条件直接显示出来,标注员看到高度信息后会更有意识地去判断目标尺度,避免把高空小目标漏标。这个改动很小,但对小目标样本的覆盖度改善非常明显。如果你也正在做无人机烟火识别项目,我建议从第一天就建立数据版本日志,把每一期的采集条件、标注规则、模型评估结果都记录下来,等迭代到数十期之后,你一定会庆幸当初做了这件事。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进