简介LNTON羚通烟火识别算法与烟雾检测工具面向安防监控、智慧消防及视频分析方向的开发者与工程人员解决图片、RTSP实时流和mp4视频中烟火目标自动检测与告警输出的问题。资源包共874个文件约324.75MB以843张jpg样本图片为主辅以15个dll动态库、4个exe可执行程序、2个bat批处理脚本、2段mp4测试视频以及weights模型权重、sh脚本、pdf使用文档等覆盖样本、推理与运行环境。已有241人学习下载。工具支持对输入画面进行烟火识别并输出带告警框的叠加图片配套文档与可执行程序便于快速验证效果样本与脚本可用于自建测试集和批量处理适合需要落地烟火检测能力或进行算法二次开发的读者参考使用。1. 烟火识别算法落地从一张告警叠框图说起去年帮一个做园区安防的团队排查误报问题他们用开源模型跑烟雾检测白天好好的一到傍晚路灯亮起、食堂排烟一起告警就炸了。翻他们的日志发现模型把暖色路灯和蒸汽全当成了火。这件事让我意识到烟火识别真正的门槛不在“能不能检出”而在“检出之后那张叠框图能不能让人一眼信服”。LNTON羚通这套烟火识别算法、烟雾检测工具解决的正是这个链路输入可以是单张图片、RTSP实时流也可以是本地mp4文件输出是带告警框的图片。它适合谁适合需要快速搭一套烟火预警 Demo 的算法工程师、做安防集成的实施人员以及想验证自己场景里烟火检测可行性的产品同学。这一章先把“它到底在做什么”讲清楚后面几章再拆怎么跑通、参数怎么调、坑在哪。2. 烟火检测的输入形态与选型图片、RTSP、mp4 该怎么选2.1 三种输入形态对应的真实场景图片输入是最轻的验证方式。你手头有一批历史监控截图想先看看模型对火焰和烟雾的召回率直接喂图片就行。它的好处是可控——同一张图反复跑能对比不同阈值下的叠框效果。缺点是看不到时序信息烟雾这种“逐渐扩散”的目标单帧很容易漏。RTSP实时流是安防场景的主力。摄像头通过 RTSP 协议推流工具拉流后逐帧推理命中烟火就落一张告警图。这里的关键不是模型本身而是拉流稳定性和抽帧策略。我一般会把抽帧间隔设成 3 到 5 帧既不会漏掉持续几秒的烟雾也不会让 GPU 一直满负荷。mp4文件输入适合离线复盘。比如某天发生了告警你想拿当天的录像回放验证模型判断对不对mp4 就是最方便的载体。它和 RTSP 的区别在于mp4 可以按需跳帧、可以暂停调试时比实时流友好得多。选型建议很直接验证模型能力用图片搭实时预警用 RTSP做事后审计用 mp4。三者不是互斥的一套工具能同时支持说明它的输入抽象层做得比较干净。2.2 为什么烟雾检测比火焰检测更难火焰有明确的颜色和纹理特征橙红、跳动、高亮模型相对容易抓。烟雾不一样它是半透明的、边界模糊的、颜色从白到灰到黑都有而且和蒸汽、灰尘、雾霾在视觉上高度相似。这就是为什么很多团队火焰检测做得不错一上烟雾就翻车。LNTON羚通这套工具把烟火检测放在一起实际落地时你要有心理预期火焰的置信度阈值可以设高一点比如 0.5烟雾的阈值要适当放低比如 0.35但同时要配合面积过滤否则小片烟雾会被误判。这个参数差异不是拍脑袋是烟雾的类内差异太大导致的。2.3 最小可跑通的图片检测流程假设你已经拿到工具包第一步不是直接上 RTSP而是先用一张图确认环境没问题。常见做法是准备一张有明显火焰的测试图跑一次推理看输出目录里有没有生成叠框图。# 图片检测的最小命令示例 # --source 指定输入图片路径 # --output 指定告警图片保存目录 # --conf 置信度阈值火焰场景建议 0.5 起步 python detect.py \ --source ./test_fire.jpg \ --output ./output/ \ --conf 0.5 \ --save-img这段命令的逻辑是加载模型权重读取单张图片做一次前向推理把超过置信度阈值的检测框画到原图上保存到 output 目录。参数里--conf是最需要关注的它直接决定告警的松紧。如果你发现漏检多往下调到 0.3如果误报多往上调到 0.6。--save-img是开关不加就只打印结果不落图。跑通这一步之后你至少能确认三件事模型文件路径对不对、依赖库版本兼不兼容、叠框逻辑是不是你想要的样式。很多新手跳过这步直接上 RTSP结果拉流失败和模型加载失败混在一起排查起来就是一团乱麻。2.4 RTSP 实时流的接入要点RTSP 接入的核心是“拉流—解码—抽帧—推理—告警”这条流水线。工具通常会封装一个流读取器你只需要填 RTSP 地址。但有几个参数必须自己调参数作用建议值抽帧间隔每 N 帧取一帧推理3~5推理分辨率送入模型的尺寸640×640告警冷却同一目标多久内不重复告警10 秒置信度阈值火焰/烟雾分开设火焰 0.5烟雾 0.35抽帧间隔太小GPU 扛不住太大快速闪燃会漏。告警冷却是很多人忽略的没有它一个持续燃烧的火点会每秒生成几十张告警图存储直接爆掉。# RTSP 流检测的核心逻辑示意 import cv2 cap cv2.VideoCapture(rtsp://your_camera_stream) frame_id 0 while cap.isOpened(): ret, frame cap.read() if not ret: break frame_id 1 # 每 3 帧推理一次降低算力压力 if frame_id % 3 ! 0: continue # 推理并获取检测结果 results model.predict(frame, conf0.35) # 命中烟火则保存叠框图 if results.has_detection: cv2.imwrite(falarm_{frame_id}.jpg, results.plot())这段代码的关键在frame_id % 3这个取模判断它实现了抽帧。conf0.35是烟雾的阈值火焰场景可以单独再跑一个分支设 0.5。results.plot()是叠框绘制不同工具叫法不同有的叫draw_boxes有的叫render看具体实现。3. 告警叠框图的生成逻辑与参数调优3.1 叠框图里到底画了什么一张合格的告警叠框图至少包含三层信息检测框、类别标签、置信度分数。检测框要贴合目标外接矩形类别标签要能区分火焰和烟雾置信度分数要让人判断这次告警的可信程度。我见过一些实现只画框不写分数结果运维人员拿到图也不知道该不该出警。LNTON羚通这套工具的输出是带叠框的告警图实际使用时建议把标签和分数都打开。火焰用红色框烟雾用黄色框这是行业里比较通用的视觉约定。3.2 置信度阈值和 NMS 的配合置信度阈值决定“哪些框留下”NMS非极大值抑制决定“重叠的框留哪个”。这两个参数要一起调。# 置信度与 NMS 参数配置示例 conf_threshold 0.35 # 烟雾检测阈值 iou_threshold 0.45 # NMS 的 IoU 阈值 # iou_threshold 越低重叠框被合并得越狠 # 烟火场景建议 0.4~0.5太低会导致相邻火点被误合并如果 IoU 设成 0.7两个相邻的火点可能各画各的框看起来框很多设成 0.3它们会被合并成一个大框反而丢失了火点数量的信息。我的经验是 0.45 比较平衡既不会框叠框也不会把两个独立火源吞掉。3.3 告警图片的命名与存储策略告警图如果只是按时间戳命名事后翻找很痛苦。建议命名里带上摄像头编号、日期、置信度。比如cam03_20250115_143022_conf0.87.jpg一眼就能看出是哪路摄像头、什么时候、多确信。存储上要设上限。我一般会按天建目录每天清理超过 30 天的告警图。如果不做清理一个中等园区一个月能攒几十万张图磁盘很快就满。这个策略不复杂但很多 Demo 阶段的项目忘了做上线一周就出问题。3.4 mp4 离线检测的批量处理mp4 输入的价值在于可重复。你可以对同一段录像反复跑调整阈值看效果差异。# mp4 文件批量检测 python detect.py \ --source ./recordings/ \ --output ./alarm_frames/ \ --conf 0.4 \ --frame-interval 5 \ --save-alarm-only--source指向目录时工具会遍历目录下所有 mp4。--frame-interval 5表示每 5 帧取一帧。--save-alarm-only是只保存有告警的帧不然一段 10 分钟的录像会输出上万张图。这个参数在离线复盘时特别有用能把有效告警从海量帧里筛出来。4. 避坑与排查烟火检测落地时最容易翻车的五件事4.1 傍晚误报暴增暖色光源被当成火焰现象是每天傍晚六点到八点告警量突然翻几倍叠框图里框的全是路灯和车灯。原因是模型在训练时可能缺少暖色人工光源的负样本把橙黄色高亮区域判成了火焰。解决办法有两个一是提高火焰置信度阈值到 0.6 以上二是加一个颜色空间过滤把静止不动的暖色区域排除掉。我一般会先调阈值快速见效如果还压不住再上过滤逻辑。4.2 烟雾漏检白色蒸汽和薄烟区分不开现象是食堂排烟、锅炉蒸汽持续飘模型完全不告警但真正起烟时也漏了。原因是烟雾的视觉特征太弱模型没学到“扩散运动”这个时序线索。单帧检测对薄烟本来就吃力。解决思路是引入多帧差分连续几帧同一区域出现灰度上升且边缘模糊才判定为烟雾。这需要在抽帧后加一个简单的帧间比较逻辑不算复杂但能明显降低薄烟漏检。4.3 RTSP 拉流断流跑几小时就黑屏现象是工具跑一段时间后不再输出告警图日志里也没有明显报错。原因是 RTSP 流本身会断而很多实现没有重连机制。解决方法是加一个心跳检测如果连续 N 秒读不到帧就释放 VideoCapture 重新连接。这个逻辑一定要加否则无人值守的场景根本没法用。# RTSP 断流重连的简化逻辑 retry_count 0 while retry_count 5: cap cv2.VideoCapture(rtsp_url) if cap.isOpened(): break retry_count 1 time.sleep(2) # 等待 2 秒后重试4.4 告警图叠框错位分辨率缩放没对齐现象是检测框画偏了框的位置和实际火焰差一截。原因是推理时图片被缩放到了 640×640但画框时用的是缩放后的坐标没有映射回原图尺寸。解决方法是记录缩放比例在绘制前把坐标乘回去。这个问题在图片检测时不容易发现一上 RTSP 就暴露因为流的分辨率和模型输入尺寸往往不一致。4.5 GPU 显存溢出批量 mp4 处理时崩掉现象是处理单个 mp4 正常批量跑几个就报显存不足。原因是每处理一个文件没有释放计算图显存持续累积。解决方法是在每个文件处理完后手动清理缓存或者限制批量大小。如果用的是 PyTorch加一行torch.cuda.empty_cache()就能缓解。5. 进阶技巧用告警冷却和分级策略把误报压到可接受告警冷却是最容易被低估的参数。没有它一个持续燃烧的火点每秒生成一张图运维人员很快就不看告警了——这是最危险的等于系统失效。我的做法是给每个检测区域设一个冷却窗口同一区域 10 秒内只出一次告警。实现上可以用一个字典记录每个区域上次告警时间命中时先查时间差。分级策略是另一个实用技巧。把告警分成两级火焰直接告警烟雾先记日志不推送。因为火焰的误报率远低于烟雾而烟雾的确认需要时间。等烟雾在连续多帧里都被检出再升级为告警。这样能把大部分蒸汽、灰尘的误报挡在推送之前。# 告警冷却与分级策略示意 alarm_cache {} # 记录每个区域上次告警时间 COOLDOWN 10 # 冷却秒数 def should_alarm(region_id, current_time, alarm_type): last_time alarm_cache.get(region_id, 0) if current_time - last_time COOLDOWN: return False # 火焰直接告警烟雾需连续命中 3 次 if alarm_type fire: alarm_cache[region_id] current_time return True elif alarm_type smoke and smoke_counter[region_id] 3: alarm_cache[region_id] current_time return True return False这段逻辑里COOLDOWN控制频率smoke_counter控制烟雾的确认门槛。火焰走快速通道烟雾走确认通道。实际跑下来误报能压掉七成以上而真正的烟火基本不会漏。验证方法也很直接拿一段已知有烟火的录像统计告警次数和实际烟火出现次数的比值。如果比值在 1.5 以内说明策略可用超过 3说明冷却或分级还不够狠。我一般会反复调这两组参数直到比值稳定在 2 以下才敢交付。最后说个血泪教训别在没做冷却的情况下把告警推送到群里。我曾经见过一个项目上线第一天群里刷了几百条告警第二天没人再看第三天真起火时没人响应。烟火检测的价值不在于检出多少而在于让人愿意信、愿意看。希望帮到你。本文还有配套的精品资源点击获取