烟火识别算法落地实战:图片、RTSP与mp4统一接入及告警叠框

发布时间:2026/9/25 23:59:28

烟火识别算法落地实战:图片、RTSP与mp4统一接入及告警叠框 简介LNTON羚通烟火识别算法与烟雾检测工具面向安防监控、消防预警及AI视觉开发者解决图片、RTSP实时流与mp4视频中的烟火检测和烟雾识别需求输出带告警叠框的结果图适合具备一定计算机视觉基础、需要快速落地烟火分析功能的工程人员。资源包共874个文件约324.75MB以843张jpg样本图片为主辅以dll动态库、exe可执行程序、bat批处理脚本、mp4测试视频、weights模型权重及pdf使用文档覆盖样本生成、模型推理与结果输出等环节。目前已有241人学习下载。工具内附使用文档与可执行程序亲测可用读者可借助样本图片与批处理脚本完成数据准备通过模型权重与动态库直接运行烟火检测并利用mp4与RTSP流验证实时识别效果快速搭建从样本到告警叠框的完整流程。1. 烟火识别算法落地从一张告警叠框图说起凌晨两点仓库外围的摄像头拍到一缕白烟值班室的屏幕上却什么都没弹出来。第二天调录像才发现那缕烟持续了四十多秒足够烧起来。这件事之后我开始认真折腾烟火识别算法也就是标题里说的 LNTON羚通烟火识别算法、烟雾检测工具这套东西。它要解决的核心问题很具体把图片、RTSP实时流、mp4文件这三种输入统一接进来跑烟火检测和烟雾识别最后输出一张带告警框的图片。对做安防、园区、仓储、森林防火的工程师来说这套流程能不能稳定跑起来比模型精度多一个点重要得多。这篇笔记就按我实际搭过的路径把选型、拉流、推理、叠框、排错一层层拆开新手能照着复现熟手能直接看到参数边界和踩坑点。2. 三种输入源怎么统一图片、RTSP实时流与mp4文件的接入设计2.1 为什么要把三种输入抽象成同一个帧迭代器图片、RTSP流、mp4文件看起来是三种完全不同的东西但落到检测环节它们最终都变成「一帧一帧的 BGR 图像」。如果每接一种输入就写一套推理逻辑代码会迅速失控改一个叠框样式要动三处。我一般会先定义一个统一的帧源接口把「打开、读帧、释放」三件事抽出来图片源读一次就结束视频文件和 RTSP 流则循环读帧。这样后面的检测、叠框、告警保存只认帧不认来源。这个抽象带来的直接好处是调参只调一处换输入源不动检测代码。代价是要处理好「读帧失败」的语义——图片读完是正常结束RTSP 读失败可能是断流mp4 读失败可能是文件损坏三者要区分对待否则实时流一断就整个进程退出。import cv2 class FrameSource: 统一帧源图片、mp4、RTSP 都走这里 def __init__(self, src, is_streamFalse): self.src src self.is_stream is_stream # 图片用 imread视频/流用 VideoCapture if isinstance(src, str) and src.lower().endswith((.jpg, .png, .jpeg)): self.mode image self.frame cv2.imread(src) else: self.mode video self.cap cv2.VideoCapture(src) # RTSP 走 TCP减少丢包导致的花屏 if is_stream: self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) def read(self): if self.mode image: f, self.frame self.frame, None return f is not None, f ok, frame self.cap.read() return ok, frame def release(self): if self.mode video: self.cap.release()逻辑说明FrameSource用文件后缀判断是不是图片是图片就一次性读入内存否则走VideoCapture。CAP_PROP_BUFFERSIZE设成 1 是为了让 RTSP 尽量取最新帧而不是排队取旧帧——实时告警场景里处理一帧旧画面比丢一帧更糟。参数上is_streamTrue时建议同时把解码方式设成 TCP避免 UDP 丢包造成的画面撕裂这个在 OpenCV 里通过环境变量或后端参数控制不同版本写法略有差异常见做法是设OPENCV_FFMPEG_CAPTURE_OPTIONS。2.2 RTSP 拉流地址的拼法与 mp4 的读取差异RTSP 地址各家摄像头不一样海康常见的格式是rtsp://用户名:密码IP:554/Streaming/Channels/101大华是rtsp://用户名:密码IP:554/cam/realmonitor?channel1subtype0。主码流清晰但码率高做烟火检测其实子码流就够能显著降低解码压力。mp4 文件则简单得多直接传路径即可但要注意有些 mp4 是 HEVC 编码OpenCV 默认后端不一定能解遇到打不开先确认编码格式。# 先用 ffprobe 确认流/文件能不能通再进代码省得在 Python 里瞎猜 ffprobe -v error -show_entries streamcodec_name,width,height -of defaultnw1 rtsp://user:pass192.168.1.64:554/Streaming/Channels/102 ffprobe -v error -show_entries streamcodec_name -of defaultnw1 test.mp4逻辑说明ffprobe能在不写代码的前提下告诉你编码是 h264 还是 hevc、分辨率多少。如果这里就报错问题在地址或网络不在检测代码。参数上-v error只打印错误输出干净-show_entries streamcodec_name只取编码名。这一步是我排查「代码读不到流」时的第一站能省掉大量无效调试。2.3 抽帧策略实时流不能每帧都推理RTSP 流一般 25 帧每秒如果每帧都跑检测普通工控机根本扛不住而且烟火是缓变目标相邻帧结果几乎一样。我一般按时间抽帧比如每 0.5 秒处理一帧既保证响应速度又把算力降下来。mp4 文件可以按帧间隔抽图片则只处理一次。抽帧逻辑要放在帧源和检测之间别写进检测函数里。import time class FrameSampler: 按时间间隔抽帧实时流和文件都适用 def __init__(self, interval_sec0.5): self.interval interval_sec self.last_ts 0.0 def should_process(self): now time.time() if now - self.last_ts self.interval: self.last_ts now return True return False逻辑说明should_process用单调递增的时间戳判断是否到了处理间隔。参数interval_sec是核心实时告警建议 0.3 到 0.5 秒太小算力浪费太大可能漏掉快速起烟。mp4 离线分析可以设成 0.2 秒甚至按帧因为不要求实时。注意这里用time.time()而不是帧计数因为 RTSP 实际帧率会波动按帧计数会导致处理节奏漂移。3. 烟火检测推理与告警叠框从模型输出到一张能看的告警图3.1 检测结果的数据结构要先定死不管用什么检测模型输出最好统一成[x1, y1, x2, y2, score, class_id]这种结构。烟火检测通常分两类烟smoke和火fireclass_id 用 0 和 1 区分。把结果结构定死之后叠框、保存、上报都只依赖这个结构换模型不用改下游。我见过太多项目因为模型输出格式变来变去最后叠框代码里全是 if-else。def postprocess(raw_output, conf_thres0.4, iou_thres0.45): 把模型原始输出整理成统一结构含 NMS boxes [] # raw_output 假设为 [N, 6]: x1,y1,x2,y2,score,class_id for det in raw_output: x1, y1, x2, y2, score, cls det if score conf_thres: continue boxes.append([x1, y1, x2, y2, score, int(cls)]) # 按类别分别做 NMS避免烟和火互相抑制 keep [] for c in set(b[5] for b in boxes): cls_boxes [b for b in boxes if b[5] c] cls_boxes.sort(keylambda x: x[4], reverseTrue) while cls_boxes: best cls_boxes.pop(0) keep.append(best) cls_boxes [b for b in cls_boxes if iou(best, b) iou_thres] return keep def iou(a, b): xx1, yy1 max(a[0], b[0]), max(a[1], b[1]) xx2, yy2 min(a[2], b[2]), min(a[3], b[3]) w, h max(0, xx2 - xx1), max(0, yy2 - yy1) inter w * h area_a (a[2]-a[0]) * (a[3]-a[1]) area_b (b[2]-b[0]) * (b[3]-b[1]) return inter / (area_a area_b - inter 1e-6)逻辑说明conf_thres是置信度阈值烟火检测里建议 0.35 到 0.5太低误报多太高漏报。iou_thres控制重叠框合并0.45 是通用值。关键点是按类别分别做 NMS——烟和火经常同时出现且框重叠如果混在一起做 NMS火框可能把烟框压掉导致只报火不报烟。这个细节很多现成代码没处理是血泪经验。3.2 告警叠框的样式与保存逻辑告警图片要让人一眼看懂框的颜色、标签、置信度都得有。我一般火用红色框烟用橙色框标签写「fire 0.87」这种。叠框之后按时间戳命名保存同时可以留一份原图方便事后核对。保存路径要按日期分目录不然跑几天目录里几万张图找都找不到。import os import cv2 from datetime import datetime COLORS {0: (0, 140, 255), 1: (0, 0, 255)} # 0烟橙 1火红 LABELS {0: smoke, 1: fire} def draw_and_save(frame, detections, out_diralarm): os.makedirs(out_dir, exist_okTrue) vis frame.copy() for x1, y1, x2, y2, score, cls in detections: color COLORS.get(cls, (0, 255, 0)) cv2.rectangle(vis, (int(x1), int(y1)), (int(x2), int(y2)), color, 2) text f{LABELS.get(cls, cls)} {score:.2f} cv2.putText(vis, text, (int(x1), int(y1) - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) if detections: ts datetime.now().strftime(%Y%m%d_%H%M%S_%f) path os.path.join(out_dir, f{ts}.jpg) cv2.imwrite(path, vis) return path return None逻辑说明COLORS和LABELS把类别映射成颜色和文字改样式只改这两个字典。draw_and_save只在有检测结果时保存避免存一堆空图。参数上cv2.rectangle的线宽 2 在 1080p 上够清晰4K 建议加到 3 到 4。putText的 y 坐标减 6 是为了让文字不压框线。文件名带微秒防止同一秒多张告警互相覆盖。3.3 把三种输入串成一条完整流水线前面几块拼起来就是主循环打开帧源按间隔抽帧推理后处理叠框保存。RTSP 流要加断线重连mp4 读完自然退出图片处理一次就结束。主循环里还要控制日志别每帧都打印不然日志文件比告警图还大。def run(src, is_streamFalse, interval0.5): source FrameSource(src, is_streamis_stream) sampler FrameSampler(interval) while True: ok, frame source.read() if not ok: if is_stream: # 实时流断了等两秒重连 time.sleep(2) source FrameSource(src, is_streamTrue) continue break if not sampler.should_process(): continue dets infer(frame) # 你的推理函数 dets postprocess(dets) draw_and_save(frame, dets) source.release()逻辑说明run是整条流水线的入口。is_streamTrue时读帧失败会重连这是 RTSP 场景必须有的网络抖动、摄像头重启都会导致断流。interval控制抽帧节奏。infer是占位替换成实际模型调用即可。注意重连时重新构造FrameSource而不是复用旧的cap旧对象在断流后往往已经不可用。4. 烟火识别落地避坑五条踩出来的排查记录4.1 现象RTSP 能连上但画面花屏、检测框乱跳原因默认走 UDP 传输网络稍有丢包就花屏解码出来的帧本身是坏的检测自然乱。解决强制 RTSP over TCP。OpenCV 里通过设置OPENCV_FFMPEG_CAPTURE_OPTIONS为rtsp_transport;tcp实现不同版本写法有差异设完用ffprobe确认能稳定读流再进代码。这个坑我踩过不止一次花屏问题九成出在传输层。4.2 现象mp4 文件用 OpenCV 打不开返回空帧原因文件是 HEVCH.265编码OpenCV 默认后端不带对应解码器。解决先用ffprobe看codec_name如果是 hevc要么换用带 HEVC 支持的构建要么先用 ffmpeg 转成 h264 再处理。转码命令ffmpeg -i in.mp4 -c:v libx264 -c:a copy out.mp4离线分析场景完全可接受。4.3 现象实时流跑几分钟后内存持续上涨原因VideoCapture的缓冲区在堆积或者每帧都创建了新的大对象没释放。解决设CAP_PROP_BUFFERSIZE为 1抽帧后及时让旧帧被回收叠框用frame.copy()而不是在原图上反复画。另外日志别缓存用行缓冲或定期 flush。4.4 现象烟和火同时出现时只报了一个原因NMS 没按类别分开做火的高分框把烟的框抑制掉了。解决按 class_id 分组分别做 NMS就是 3.1 里那段代码的做法。这个坑很隐蔽因为单类测试时完全正常只有两类同时出现才暴露。4.5 现象告警图片保存了几万张磁盘爆了原因没有去重和限流同一处烟持续十几分钟每 0.5 秒存一张。解决加告警冷却时间同一区域同一类别在 N 秒内只存一张或者按小时聚合只保留每个事件的首帧和末帧。冷却时间我一般设 30 到 60 秒既不错过事件又不至于刷爆磁盘。5. 进阶用告警冷却与区域屏蔽把误报压下来跑通流水线只是第一步真正决定这套烟火识别工具能不能上线的是误报率。我踩过最大的坑是傍晚的晚霞、车灯、蒸汽管道全被当成烟火一天几百条告警值班员直接不看了。后来我加了两样东西误报降了一个数量级。第一是告警冷却。同一类别、同一大致区域在冷却窗口内只报一次。实现上给每个类别维护一个最近告警时间戳检测到目标时先判断是否在冷却期内。区域判断可以用框中心点落在哪个网格来粗略划分不必做复杂的跟踪。class AlarmCooldown: 按类别网格做告警冷却压重复告警 def __init__(self, cooldown_sec60, grid4): self.cooldown cooldown_sec self.grid grid self.last {} # key: (cls, gx, gy) - ts def allow(self, cls, cx, cy, w, h): gx, gy int(cx / w * self.grid), int(cy / h * self.grid) key (cls, gx, gy) now time.time() if now - self.last.get(key, 0) self.cooldown: self.last[key] now return True return False逻辑说明cooldown_sec是冷却窗口60 秒适合大多数场景grid把画面切成 4×4同一格内同类目标才算重复。allow返回 True 才保存告警图。参数上网格太细会导致同一处烟因为框轻微移动就被当成新事件太粗又会把不同位置的告警合并4×4 到 6×6 是比较稳的范围。第二是区域屏蔽。摄像头画面里总有固定干扰源比如某个反光的窗户、某段蒸汽管。做法是维护一个屏蔽区域列表检测框中心落在屏蔽区内就直接丢弃。屏蔽区可以硬编码也可以做成配置文件现场调试时改配置不用改代码。参数建议值作用调大后果调小后果conf_thres0.35~0.5置信度阈值漏报增多误报增多iou_thres0.45NMS 重叠阈值框合并过度重复框增多interval_sec0.3~0.5抽帧间隔响应变慢算力吃紧cooldown_sec30~60告警冷却漏掉连续事件告警刷屏grid4~6冷却网格数重复告警事件被合并验证方法很直接拿一段已知有烟火的 mp4 离线跑统计告警数量和实际事件数算误报率和漏报率再拿一段纯干扰视频晚霞、车灯跑看会不会误报。两个指标都达标再上实时流。我现在的习惯是任何烟火识别方案上线前先用这两段视频各跑一遍参数表照着上面调基本能避开大部分翻车。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/25 23:59:28

GitLab pre-receive钩子:用Go拦截不规范commit的实践指南

简介:这是一份面向GitLab仓库管理员与Go语言开发者的服务端钩子实践资源,聚焦于用Go编写pre-receive脚本,在推送落地前校验commit消息格式,从而阻止不符合规范的提交进入仓库。包内共4个文件,以1个main.go核心实现为主…

2026/9/25 23:59:28

Java调海康SDK实现摄像头预览:JNA动态库加载与多路并发实战

简介:本资源面向Java开发者与视频监控集成方向的技术人员,聚焦如何通过JNA调用海康威视SDK实现摄像头预览功能,适合具备一定Java基础、希望快速接入安防设备的工程师学习参考。压缩包共302个文件,约7.74MB,以262个clas…

2026/9/25 23:59:28

Java 调海康威视 SDK 实现摄像头预览:JNA 桥接与回调取流实战

简介:这是一份面向Java开发者的海康威视SDK二次开发实战源码,聚焦物联网与视频监控场景下的摄像头预览功能实现。资源以JNA技术调用海康威视SDK,涵盖设备连接初始化、通道选择、预览句柄申请、参数设置、视频流渲染及资源释放等完整流程&…

2026/9/26 2:19:35

C# WebApi实例:从前后端分离到联调发布的完整实战指南

简介:这套C# WebAPI实战资源,面向刚入行IT的新人以及尚未系统掌握Web API的朋友。项目以真实职场开发为蓝本,演示最精髓的WebAPI特性路由与前后端调用分离技术,让读者直接看到接口如何设计、前端如何异步调用后端,以及…

2026/9/26 2:19:35

精密电源设计:稳准净三要素与实战避坑指南

1. 什么是“精密电源设计”?它到底解决什么问题?“精密电源设计”这五个字,乍看像实验室里贴在设备外壳上的标签,冷峻、专业、带着点拒人千里的距离感。但如果你拆开一台高精度示波器、一块医疗级心电图采集板、或者一套工业级PLC…

2026/9/26 2:19:35

ArkClaw零安装容器管理:浏览器云养虾,轻量运维新选择

最近朋友问我周末在忙什么,我说在“云养虾”,他愣了两秒。其实我说的虾,是那几台躲在机房里跑着各种小服务的 Linux 服务器,以及上面一个个 Docker 容器——我用 ArkClaw 在浏览器里就能看到它们的状态,远程拉镜像、启…

2026/9/26 2:19:35

AI替你盯监控:OneUptime MCP 服务器实战

AI替你盯监控:OneUptime MCP 服务器实战 【免费下载链接】oneuptime Complete open-source monitoring and observability platform. 项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime 凌晨三点,告警轰炸而来,值班人还没睁…

2026/9/26 2:19:35

Word制表符原理与精准排版实战指南

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

2026/9/25 21:00:17

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/25 20:59:52

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/26 0:04:28

画质修复APP怎么选?Wink影像修复能力与产品实力解析

现如今手机拍摄场景愈发丰富,演唱会直拍、漫展记录、老视频翻新、日常vlog录制,都会遇到画面模糊、噪点多、曝光失衡等问题,不少用户在挑选工具时比较在意一款画质修复APP能够兼顾修复效果与自然质感。Wink作为美图公司推出的全球化AI影像增强…

2026/9/26 0:04:28

超低能耗建筑K值要求能否满足?浙东铝业建筑型材解析

核心摘要浙东铝业的超低能耗系统门窗产品,资料显示保温性能可达 K≤1.4W/(㎡K),能够对应上海地区超低能耗住宅对门窗保温性能的应用需求。判断建筑是否满足超低能耗要求,不能只看铝型材本身,还需要结合玻璃、隔热条、密封系统、开…

2026/9/25 20:55:38

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/25 18:41:36

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/25 18:34:56

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑