资讯详情

烟火识别算法实战:图片、RTSP与mp4三种输入路径详解

📅 2026/10/10 16:33:03 | 华诺云谱 👁 阅读
烟火识别算法实战:图片、RTSP与mp4三种输入路径详解
简介面向视频监控烟火检测场景的LNTON羚通烟火识别算法工具支持对图片、RTSP实时流及mp4视频文件进行火焰与烟雾检测识别到目标后自动输出叠框告警图片适合安防、消防等领域的算法验证与快速部署。压缩包共874个文件约324.75MB其中包含843张jpg样例图片、15个dll动态库、4个exe可执行程序、2个bat批处理脚本及2个mp4测试视频另有weights模型权重、pdf使用文档等资源类型清晰便于按需调用。目前已有241人学习使用工具实测可用随包附有详细使用文档可帮助用户快速掌握调用流程、参数配置及告警结果输出方式。整体结构兼顾模型、演示素材与运行依赖是一套开箱即用的烟火识别实用工具。1. LNTON羚通烟火识别算法从一张告警叠框图讲起的实用工具很多人第一次接触烟火识别以为难点全在“算法能不能认出来”。放到现场走一圈才发现真正让烟火检测工具翻车的往往是输入源——RTSP流十分钟断一次、mp4解出来的画面是花的、上午十点的阳光被当成烟雾反复告警。LNTON羚通烟火识别算法就是这类烟火检测工具的典型代表同时支持图片、RTSP实时流和mp4文件三种输入对火焰和烟雾输出检测框并把告警帧存成叠框图片。它适合园区安防、森林防火、工地监控的集成商和运维工程师也适合需要在现有摄像头网络里快速加一路烟火识别能力的开发者。这篇文章按“选型—跑通—接流—避坑—调优”的顺序把这三条输入路径一次讲透。2. 烟火检测的选型逻辑为什么说输入源决定算法成败2.1 烟火检测为什么选检测网络而不选分类网络烟火识别算法在落地时最容易被低估的一点是烟雾没有固定边缘火焰没有固定颜色。一团烟在顺光、逆光、夜间红外补光下完全是两种纹理火焰从橙红到蓝白都有单独用颜色阈值或者图像分类做出门就会被现实教育。所以市面上的烟火检测工具基本都走目标检测路线。分类网络只能给整张图打一个“有烟”或“没烟”的标签但报警联动时需要知道火在画面哪个位置、烟雾扩散到了哪个区域还要在原始帧上叠框输出给值班人员看。检测网络天然输出边界框坐标直接对应叠框需求。具体到模型选型YOLO 系是常见选择原因有三个。第一单阶段检测在 CPU 和边缘设备上都能跑出现实可用的帧率第二烟火这类目标不像人车那样有丰富公开数据集训练样本往往要现场自采YOLO 系的迁移学习成本低第三部署生态成熟OpenCV、ONNX Runtime、各家的 NPU 工具链都有现成转换路径。实践里我一般会盯两个点。输入分辨率不低于 640最好上 1280烟火目标在监控画面里通常占比很小分辨率不够时小火苗直接被下采样丢掉。另一个是模型的类别数不要把“火焰”“烟雾”合并成一类两类分开训练、分开调阈值因为烟雾的置信度天生比火焰低一截合并后要么火焰漏报要么烟雾全是误报。2.2 输入源对比图片适合验算法mp4 适合复核RTSP 负责实时同一个烟火识别算法喂图片、mp4、RTSP跑起来完全是三套逻辑。图片是单帧静态输入没有时序信息只能依赖单帧的空间特征做判断适合验证算法“能不能认出烟火”mp4 是离线视频可以抽帧、跳帧、反复回放适合做批量复核和事后取证RTSP 是实时流对延迟、断线重连、帧率控制都有额外要求。输入源典型场景帧率/处理方式最常踩的坑图片抓拍机上传、单帧验证一次性推理通道顺序、分辨率过低mp4历史录像复核、离线批量检测抽帧后逐帧推理h265 解码花屏、时间戳对不上RTSP 实时流摄像头实时监控预警实时拉流抽帧断线、延迟堆积、UDP 丢包理解了这三类输入的区别就不会出现“拿图片测好了接到实时流上全是告警”这种翻车。很多团队第一次接 RTSP直接把图片检测脚本套上去每一帧都推理结果 CPU 跑满、延迟拉高、告警风暴这不是算法问题是输入源的处理方式没跟着换。2.3 硬件后端与模型档位CPU、GPU 与边缘盒子怎么选烟火识别工具跑在什么硬件上直接决定模型档位和推理帧率。工控机 CPU 上跑轻量级模型单帧推理 20 到 50 毫秒是常见区间足够了带 GPU 的服务器可以跑更大模型在 4K 画面上保持实时而像 RV1106 这类边缘 IPC 方案一般要把模型量化转成 RKNN 格式用 NPU 推理。选型时记住一个原则先定输入路数和帧率再定硬件最后定模型。一个点位一路 RTSP 流CPU 完全能扛八路摄像头集中检测就该考虑 GPU 或边缘盒子分摊。3. 用最小代码跑通烟火识别图片、mp4 检测与告警叠框输出3.1 图片烟火检测的最小代码骨架不管你最后用命令行还是写服务图片检测都是最基础的一环。下面这套骨架基于 OpenCV 加统一检测接口LNTON 羚通这类工具包的 Python 调用逻辑也基本一致核心是“读图—推理—画框—落盘”。import cv2 # 以通用烟火检测模型接口为例模型内部已经包含 # 火焰、烟雾两个类别的检测权重 model SmokeFireDetector( model_pathweights/fire_smoke.pt, conf_thres0.25, # 置信度阈值烟雾建议调低到 0.2 附近 iou_thres0.45 # NMS 的 IoU 阈值 ) img cv2.imread(scene_20250314.jpg) # BGR 读入 img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 模型训练时用的是 RGB detections model.detect(img_rgb) # 返回 [x1, y1, x2, y2, cls, conf] for box in detections: x1, y1, x2, y2, cls, conf box color (0, 0, 255) if cls fire else (128, 128, 128) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) label f{cls} {conf:.2f} cv2.putText(img, label, (x1, y1 - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2) cv2.imwrite(alarm_scene.jpg, img) print(fdetected {len(detections)} target(s))先说两个最容易忽视的细节。第一OpenCV 默认读图是 BGR 顺序而深度学习模型训练时几乎都用 RGB。不做通道转换火焰的橙红色特征在模型眼里会错位原本该检测出来的火苗直接漏掉。第二画框用的坐标必须是原图坐标。如果预处理阶段把图缩放过推理输出的框要先按缩放比例映射回原图再传给 cv2.rectangle否则叠框位置会偏。置信度阈值这块火焰和烟雾要分开设。火焰目标比较“实”0.25 起步没问题烟雾边缘模糊、透光性强很多真烟帧的置信度只有 0.15 到 0.2把全局阈值设到 0.3 以上烟雾漏报会很严重。建议火焰 0.30、烟雾 0.20 作为第一版参数跑完现场样本再微调。3.2 mp4 逐帧检测抽帧、画框与告警落盘mp4 文件检测比图片多一层“时间维度”。一般做法是把视频按帧读出来每隔 N 帧抽一帧做推理命中烟火的帧立即画框保存。抽帧不是越密越好火焰从出现到成势通常有几十秒过程每秒抽 5 帧足够推理负载却能降九成。import cv2 cap cv2.VideoCapture(camera_03_20250314_180000.mp4) fps cap.get(cv2.CAP_PROP_FPS) frame_interval max(1, int(fps // 5)) # 每秒抽 5 帧 frame_idx 0 alarm_count 0 while cap.isOpened(): ret, frame cap.read() if not ret: break # 视频读完了或者解码出错 if frame_idx % frame_interval ! 0: frame_idx 1 continue # frame 直接是 BGR推理接口内部会处理颜色转换 detections model.detect(frame) if len(detections) 0: # 用视频内时间戳命名方便事后回看时定位 ts cap.get(cv2.CAP_PROP_POS_MSEC) out_name falarms/frame_{ts:.0f}ms.jpg cv2.imwrite(out_name, draw_boxes(frame, detections)) alarm_count 1 frame_idx 1 cap.release() print(falarm frames: {alarm_count})这份代码里frame_interval 的计算是个常规操作用视频原始帧率除以 5得到“每 5 帧取 1 帧”的间隔并保证最小为 1。时间戳取的是视频播放位置毫秒而不是系统当前时间这样回放录像时能直接跳到对应时刻确认现场情况。mp4 检测有一个隐藏前提视频编码必须是 OpenCV 内置 FFmpeg 能解的格式。H.264 基本没压力但对 H.265/HEVC 的支持要看编译版本很多 Windows 下预编译的 OpenCV 对 10bit H.265 视频直接解出绿屏或报错。后面避坑章节会专门讲转码方案。3.3 用时间戳与区域去重把“每一帧告警”变成“每一起事件”逐帧检测跑起来马上会遇到一个实际问题同一团烟雾持续两分钟每帧都告警一个事件能存几百张图。值班人员不可能挨个看告警图片的意义就没了。我一般会在检测之后加一层简单的去重逻辑。记录上一次告警的时间和位置如果当前帧告警框与上一个告警框的中心距离小于画面宽度的 5%且时间间隔小于 10 秒就认为是同一事件只更新“最近一次告警帧”不保存新图。只有距离拉开或间隔超过阈值才算新事件。这里不要写复杂逻辑一个字典按区域分组就够了last_alarm {} # key: 区域编号, value: (last_ts, last_center) def is_dup(region, ts, center, width, interval10): if region not in last_alarm: return False last_ts, last_center last_alarm[region] if ts - last_ts interval * 1000: return False dist abs(center - last_center) return dist width * 0.05去重之后再保存图片一个真实烟火事件的告警图一般会控制在 3 到 5 张既保留过程信息又不至于把磁盘写爆。这个逻辑对图片输入不适用但 mp4 和 RTSP 流一定要加后面避坑章节还会从磁盘角度再提一次。4. RTSP 实时流的烟火检测拉流参数、断线重连与告警落盘4.1 RTSP 拉流地址怎么找海康、大华、萤石的常见路径格式RTSP 是实时流传输协议摄像头把 H.264/H.265 编码后的 RTP 包推给客户端。LNTON 羚通这类烟火识别工具接 RTSP 时第一步是拿到正确的取流地址。不同厂商路径不一样但结构都是rtsp://用户名:密码IP:端口/流路径。品牌主码流路径示例海康威视rtsp://admin:pass192.168.1.64:554/Streaming/Channels/101大华rtsp://admin:pass192.168.1.65:554/cam/realmonitor?channel1subtype0萤石rtsp://admin:pass192.168.1.66:554/h264/ch1/main/av_stream拉流时建议优先用子码流做检测。主码流一般是 4K 或 1080p 高码率解码开销大而烟火检测并不需要极高的细节子码流分辨率 640×360 到 1280×720 就够用帧率也稳定。等到报警瞬间再去回拉主码流存证据图是常见的省资源做法。刚才说的地址后面还有个容易被忽略的传输参数。RTSP 底层 RTP 可以跑 UDP 或 TCPUDP 延迟低但容易丢包丢狠了画面全是马赛克误报漏报跟着来TCP 更稳但延迟略高。现场网络环境差时我一般会把传输协议锁成 TCP用 OpenCV 的 FFmpeg 后端加参数import os os.environ[OPENCV_FFMPEG_CAPTURE_OPTIONS] rtsp_transport;tcp|stimeout;5000000stimeout 单位是微秒设成 5000000 表示连接和读取超时 5 秒避免摄像头掉线后程序卡死在 read 上。4.2 拉流参数与断线重连RTSP 实时流的稳定性配置RTSP 和 mp4 最大的区别是mp4 读错了可以从头再来RTSP 流断了就没了。大部分摄像头设备在遇到网络抖动时会自动断掉不活跃的会话检测程序如果不做重连第二天早上过去发现黑屏了一整夜这种事在工地、园区项目里太常见了。稳定拉流的代码骨架通常长这样import cv2 import time RTSP_URL rtsp://admin:pass192.168.1.64:554/Streaming/Channels/102 cap None while True: if cap is None: cap cv2.VideoCapture(RTSP_URL, cv2.CAP_FFMPEG) # 缓冲只留 1 帧防止延迟堆积 cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) ret, frame cap.read() if not ret: # 读不到帧了先释放句柄避免摄像头侧会话残留 cap.release() cap None time.sleep(3) # 等 3 秒再重连不要死循环空转 continue detections model.detect(frame) if len(detections) 0: ts time.strftime(%Y%m%d_%H%M%S, time.localtime()) cv2.imwrite(frtsp_alarm_{ts}_{channel_id}.jpg, draw_boxes(frame, detections)) time.sleep(0.05) # 控制循环节奏防止 CPU 空转CAP_PROP_BUFFERSIZE 设成 1 是经验值。FFmpeg 默认会缓冲多帧推理速度跟不上拉流速度时缓冲越堆越多画面延迟越来越大告警出来时火已经烧了半分钟。只保留最新一帧相当于主动丢弃处理不过来的帧对烟火这类慢速目标来说完全够用。断线重连的节奏也要讲究。每 3 秒重试一次比较合理连续失败 5 次后把间隔拉长到 10 秒给摄像头和网络一个恢复时间。频繁重连不仅没有意义还可能触发摄像头厂商的连接数限制把其他客户端一起踢下线。4.3 告警叠加通道号与时间戳便于人工核实的落盘规范RTSP 检测的告警叠框图输出规范比算法本身更重要。现场值班人员看到一张图第一反应是“这是哪个点位、什么时候发生的”如果文件名只有一串自增数字一个小时后想去复核现场录像都找不到对应的摄像头。我习惯的命名规范是点位ID_日期时间_目标类型_置信度.jpg例如site_03_20250314_183025_fire_0.87.jpg。同时在图片左上角用 putText 叠上通道名和精确时间这样即使图片被转发、改名信息也不会丢。告警信息同步追加一行 JSON 或 CSV 日志记录时间、通道、类型、置信度、目标坐标为后面做误报分析和阈值调优留数据。还有一个原则值得坚持保存叠框图的同时再存一张不带框的原图。叠框图给值班人员看效率高原图留作证据哪天有纠纷要追溯原始画面才是最可信的。磁盘紧张时原图可以压缩质量保存但不能不存。5. 烟火识别工具避坑指南误报、漏报与性能的四个翻车现场5.1 阳光把围墙照成橘色误报率飙升现象晴天上午 10 点到下午 2 点固定机位对着的砖墙或铁皮房被太阳晒成橘红色系统持续输出“火焰告警”一天能弹几十条。原因单帧检测模型主要靠颜色、纹理和形状特征。阳光下的橘色墙面、电焊火花、橙色工作服、红色卡车在特征空间里都和火焰有重叠。火焰的形状又不像人车那么规整模型本身对“疑似火焰”就宽容。解决加时序确认。单帧命中不算告警连续 3 到 5 帧大约 1 秒都命中同一区域才触发报警。同时叠加一个轻量帧间差分计算告警区域的像素位移——火焰有抖动墙壁是静止的差分幅度小直接认为是静态热源干扰。再进一步把火焰类的置信度阈值从 0.25 提高到 0.35 到 0.4宁可晚报警 2 秒也不要天天狼来了。5.2 mp4 解码花屏、h265 视频检测不到问题出在解码器现象同一个 mp4 文件用播放器打开画面正常烟火识别工具跑起来要么报错退出要么输出的画框图全是绿块和马赛克。原因OpenCV 自带的 FFmpeg 对 H.265 的兼容性取决于编译选项。播放器通常内置了完整的商用解码器而 OpenCV 在部分平台上只能用内置的软解10bit H.265、高码率 4K 视频就解不动。这不是烟火算法的问题是视频解码链路先崩了。解决先确认编码格式再决定转码。用 FFprobe 查一眼最保险ffprobe -v error -show_entries streamcodec_name,pix_fmt -of defaultnoprint_wrappers1 input.mp4输出显示codec_namehevc或pix_fmtyuv420p10le就直接转成 H.264 8bitffmpeg -i input.mp4 -c:v libx264 -pix_fmt yuv420p -c:a copy output.mp4转码会损失一点画质但对烟火检测够用。日常处理历史录像时我一般会写一个批处理脚本先 ffprobe 过滤出 H.264 的文件直接检测H.265 的先丢进转码队列两个流程并行省时间也省心。5.3 RTSP 延迟越跑越高告警比现场慢半分钟现象RTSP 流刚接入时延迟 1 到 2 秒运行一个小时后告警图片对应的事件比现场慢了 30 多秒重启程序后恢复再跑一小时又复发。原因这是典型的拉流端处理不过来导致缓冲区堆积。FFmpeg 解码线程按固定速率从网络读包推理线程如果跟不上帧就积压在下游队列里。烟火识别一帧跑 100 毫秒拉流端每秒进 25 帧越积越多延迟自然滚雪球。解决把 CAP_PROP_BUFFERSIZE 设成 1只保留最新帧主动丢帧检测改成抽帧模式每秒最多推理 5 帧中间帧直接丢弃传输协议用 TCP 减少因丢包重传引入的额外延迟。做完这三步延迟基本能稳定在 1 到 3 秒内。还有个冷门原因有些摄像头默认开了多路组播客户端不去读设备端也会持续推流把带宽占满。检查交换机端口流量能发现这类问题。5.4 告警叠框图把磁盘写满现象单点烟火检测跑了一个月磁盘满了系统告警中断检查发现全是告警图片一天几百张一张 200KB一个月轻松十几 GB。原因告警图片保存没有做数量上限和定期清理。叠框图是 JPEG一张不大但 7×24 小时跑下来积累量非常可观。解决按天建目录同时限制总文件数超出后自动删除最早的目录。最粗暴但有效的办法是加一个定时清理任务find /data/alarms/*.jpg -mtime 7 -delete我一般会在程序启动时和每天零点各跑一次清理保留最近 7 天告警图。有取证需求就再额外备份到对象存储或 NAS本地不留全量。这个习惯看起来不起眼但很多烟火检测项目交付后半年内的电话有一半是“磁盘满了”打过来的。6. 把烟火识别调成可用状态置信度阈值与现场验证方法6.1 先调两个参数置信度阈值与 NMS IoU烟火检测落地时最值得花时间调的就是置信度阈值。火焰目标的置信度分布通常比较靠上0.35 到 0.45 之间能过滤掉大部分阳光、车灯干扰烟雾则相反真烟的边缘模糊、透明度高置信度常年徘徊在 0.15 到 0.25阈值一高就漏报。参数火焰烟雾说明置信度阈值0.35~0.450.20~0.30先按区间设现场样本再微调NMS IoU0.500.45烟雾框大且重叠多IoU 太高会拆出多个框NMS 的 IoU 参数很多人忽略。默认 0.5 在人车检测上没问题但烟雾是一大片弥散区域同一团烟可能会被输出多个互相重叠的框IoU 阈值设太低会导致一个烟团拆成三四个告警去重逻辑失效。我会把烟雾的 IoU 降到 0.45让重叠框合并得更果断。6.2 用一段现场录像回放来验收算检出率和误报率参数调完不能直接上线先用现场录像回放验一遍。我的做法是固定一路要部署的摄像头录 2 小时白天时段和 1 小时傍晚/夜间时段按每个 10 分钟切段人工标记每段有没有烟火、烟火出现的起止时间再用工具跑一遍把算法输出和人工标记对比。对比时只记三类检出算法告警且人工确认属实、漏报人工看到烟火但算法没报、误报算法告警但实际没有烟火。统计完算一下检出率和误报率达不到要求的回去调阈值再跑一轮。傍晚和夜间是重灾区路灯、地灯、车灯和火焰特征高度相似必须单独验证不能只看白天数据。我现在的习惯是每到一个新点位先花半小时录一段现场视频跑一次回放再上线。这个习惯帮我避开了无数个“白天没事、晚上狂叫”的售后电话。烟火识别是一个需要持续用现场样本养着的系统没有一劳永逸的参数但把验证流程固定下来后面每次调整都有据可依。希望这些踩坑记录能帮你在部署时少走几趟弯路也祝你的烟火告警系统上线后安安静静只在真正需要的时候响。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑