ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于计算机视觉的火情定位检测系统:OpenCV与双目测距实战

基于计算机视觉的火情定位检测系统:OpenCV与双目测距实战 简介这份PDF文献面向计算机视觉、图像处理及消防智能化方向的本科生、研究生与工程技术人员系统讲解如何利用开源计算机视觉库OpenCV构建火情定位与检测系统解决传统接触式传感器在恶劣环境下检测效果差的问题。资源包为单一PDF文件大小约1.78MB内容完整涵盖红外基础理论、双目立体视觉测距原理、火灾图像预处理技术以及红外测温、轴向比判别、内外焰判别、形状不规则判别等核心算法并给出火源定位与跟踪的实现思路及实验测试结论。目前已有136人学习下载适合作为课程设计、毕业设计或相关课题的参考文献。读者可从中获取从理论推导到算法选型的完整技术路线理解中值滤波、灰度化、二值化等预处理步骤的作用并借鉴其系统架构与实验验证方法为同类火灾检测系统的设计提供可落地的技术参考。1. 从一篇论文到一个可跑的系统这套火情检测方案到底能解决什么工业场景里做火情检测最头疼的从来不是“有没有火”而是“什么时候报”和“火在哪”。传统烟感、温感这类接触式传感器在变电站、油库、大型仓储这类开阔或高粉尘环境里等它触发的时候火往往已经烧起来了。这篇《基于计算机视觉技术的火情定位及检测系统》给了一条非接触式的路子用带红外滤光片的双目摄像头采集图像靠 OpenCV 做预处理和特征判别再用双目视差算火源的三维坐标。整套东西不依赖昂贵的热成像仪普通 CCD 加滤光片就能起步对做计算机视觉大作业或者电力、消防方向工程落地的读者来说是一份结构完整、算法链路清晰的参考实现。它适合谁适合已经懂点 OpenCV、想找一个“多特征融合 双目测距”完整案例的开发者也适合需要给现有监控系统加一层图像火情判别逻辑的工程师。2. 红外测温与图像预处理火焰判别的第一道门槛2.1 为什么先做红外测温而不是直接看颜色火焰的颜色特征在白天和夜晚差异极大单纯靠 RGB 阈值分割遇到电焊弧光、夕阳、红色物体基本就翻车。这篇论文的思路是先回到红外物理任何物体都在辐射红外能量温度越高辐射出射度越大峰值波长越短。普朗克辐射定律给出了黑体辐射出射度与波长、温度的关系维恩位移定律进一步说明峰值波长与温度成反比。早期火灾的阴燃阶段温度在 600 到 1000 K火羽流在 500 到 1700 K对应的峰值波长都落在红外波段。所以给摄像头贴上红外滤光片滤掉大部分可见光保留红外辐射火焰在图像里就是一个高亮区域背景干扰被大幅压制。论文里给出的红外测温模型是一个线性修正公式T 0.8 * P_real 454 P_real P_measured d * 0.46其中P_measured是图像上读到的像素值d是目标到摄像头的距离P_real是修正后的真实像素值T是估算温度。这个模型不是普适的它是在特定摄像头和滤光片组合下标定出来的经验公式。我一般会建议如果你换一套硬件这个系数必须重新标定拿黑体炉或者已知温度的热源采几组距离-像素值-温度数据做一次线性拟合。直接抄 0.8 和 454 这两个数大概率会翻车。2.2 OpenCV 预处理链中值滤波、灰度化、二值化、直方图均衡、轮廓跟踪论文里的预处理流程是标准五步用 OpenCV 实现起来很直接。下面这段代码把关键步骤串起来你可以直接拿去改import cv2 import numpy as np # 读取双目摄像头的一帧这里以左目为例 frame cv2.imread(left_frame.jpg) # 1. 中值滤波滤除椒盐噪声同时保留火焰边缘 # 核大小取 3 或 5太大容易把小火苗抹掉 denoised cv2.medianBlur(frame, 3) # 2. 灰度化把三通道降到单通道减少计算量 gray cv2.cvtColor(denoised, cv2.COLOR_BGR2GRAY) # 3. 直方图均衡化增强对比度让火焰区域更突出 # 注意如果图像本身已经很亮均衡化可能引入噪声 equalized cv2.equalizeHist(gray) # 4. 二值化设定阈值把火焰区域从背景里切出来 # 阈值 100 是论文实验值实际要根据红外图像亮度分布调 _, binary cv2.threshold(equalized, 100, 255, cv2.THRESH_BINARY) # 5. 轮廓跟踪找到火焰的外轮廓 contours, _ cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 画出来看看效果 vis cv2.cvtColor(binary, cv2.COLOR_GRAY2BGR) cv2.drawContours(vis, contours, -1, (0, 0, 255), 2) cv2.imshow(contours, vis) cv2.waitKey(0)逻辑说明中值滤波放在第一步是因为红外图像在低照度下噪声比较重中值滤波对椒盐噪声的抑制效果比高斯滤波好而且不会像均值滤波那样把火焰边缘糊掉。灰度化是必须的后面所有算法都基于单通道。直方图均衡化解决的是红外图像整体偏暗、火焰和背景灰度差不够的问题。二值化的阈值 100 来自论文实验但实际部署时这个值要跟着环境温度、摄像头增益走我一般会加一个自适应阈值或者 Otsu 方法作为备选。轮廓跟踪拿到的是火焰的外边界后面轴向比判别和形状不规则判别都要用这个轮廓。参数说明cv2.medianBlur的核大小必须是奇数3 适合小目标5 适合稍大的火焰区域。cv2.threshold的阈值类型用THRESH_BINARY就够如果火焰区域和背景灰度有交叠可以试THRESH_OTSU让算法自己找阈值。cv2.findContours的检索模式用RETR_EXTERNAL只取外轮廓避免内焰轮廓干扰后续判别。提示直方图均衡化在火焰面积很小的时候可能反而降低信噪比因为大部分像素是背景均衡化会把背景的灰度也拉高。如果发现二值化后火焰区域和背景粘连先关掉均衡化试试。3. 四种判别算法怎么串轴向比、内外焰、形状不规则与延时报警3.1 轴向比判别火焰纵向燃烧特性的量化火焰燃烧时有一个很直观的物理特征向上燃烧上尖下宽红外图像里表现为纵向尺寸大于横向尺寸。论文把这个特征量化成轴向比即外接矩形的高度除以宽度阈值设为 1。超过 1 判定为火焰否则不是。代码实现很简单# 对每个轮廓计算外接矩形 for cnt in contours: x, y, w, h cv2.boundingRect(cnt) # 过滤掉太小的噪点区域 if w * h 50: continue axial_ratio h / float(w) if axial_ratio 1.0: # 轴向比超过阈值标记为疑似火焰 cv2.rectangle(frame, (x, y), (x w, y h), (0, 255, 0), 2) cv2.putText(frame, Fire?, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)逻辑说明cv2.boundingRect返回的是轮廓的正外接矩形h / w就是轴向比。论文里还提到一个“连续 10 帧中有 6 帧超过阈值”的投票机制这是为了排除单帧噪声导致的误报。实际写的时候可以维护一个长度为 10 的环形缓冲区每帧把判别结果存进去统计超过阈值的帧数。参数说明轴向比阈值 1.0 是论文实验值但在实际场景里如果摄像头不是正对火焰透视变形会让轴向比失真。我一般会建议把摄像头安装角度控制在俯仰角 15 度以内或者加一个透视校正。另外外接矩形面积过滤阈值 50 像素是经验值分辨率越高这个值要相应调大。3.2 内外焰判别与形状不规则判别内外焰分层的物理基础是火焰从内到外温度递减内焰温度高、亮度大外焰温度低、亮度小。在红外图像里内焰区域像素值更高外焰区域像素值稍低。论文的做法是在二值化后的火焰区域里再做一次阈值分割把高亮部分和次高亮部分分开如果两层都存在且面积比在合理范围内就判定为火焰。这个逻辑用 OpenCV 实现就是两次cv2.threshold第一次切出火焰整体第二次在火焰 ROI 里切出内焰。形状不规则判别利用的是火焰边缘抖动特性。火焰不像电灯那样有规则圆形或矩形轮廓它的边缘是破碎的、不规则的。论文用轮廓的周长平方除以面积类似圆形度来衡量不规则程度值越大越不规则。代码上就是cv2.arcLength和cv2.contourArea的组合perimeter cv2.arcLength(cnt, True) area cv2.contourArea(cnt) if area 0: irregularity (perimeter ** 2) / area # 圆形度理论最小值为 4*pi越大越不规则 if irregularity 20: # 形状高度不规则疑似火焰 pass参数说明圆形度阈值 20 是经验值标准圆形的值是 4π 约等于 12.56火焰一般在 20 以上。但这个值受轮廓提取精度影响很大如果二值化边缘毛刺多圆形度会虚高。建议先做一次形态学开运算把毛刺去掉再算。3.3 延时报警排除电灯等稳定光源干扰电灯、白炽灯在红外图像里也是高亮区域但它们的亮度是稳定的不会像火焰那样抖动。论文的延时报警算法逻辑是如果连续多帧检测到疑似火焰区域且区域面积和位置变化超过一定幅度才触发报警。这个“变化”可以是质心位移也可以是面积波动。实现上就是维护一个历史队列每帧和前一帧做比较。# 维护上一帧的火焰质心 prev_centroid None stable_count 0 for cnt in contours: M cv2.moments(cnt) if M[m00] 0: continue cx int(M[m10] / M[m00]) cy int(M[m01] / M[m00]) if prev_centroid is not None: dx abs(cx - prev_centroid[0]) dy abs(cy - prev_centroid[1]) if dx dy 5: # 质心抖动超过 5 像素 stable_count 1 prev_centroid (cx, cy) # 连续 10 帧中有 6 帧抖动才认为不是稳定光源 if stable_count 6: trigger_alarm()逻辑说明电灯的质心几乎不动火焰的质心因为燃烧抖动会有几像素的位移。这个判别放在轴向比和形状不规则之后作为最后一道过滤。参数说明质心位移阈值 5 像素和投票帧数 6 都是论文实验值实际要根据帧率和火焰大小调。帧率越高相邻帧位移越小阈值要相应降低。4. 双目定位从视差到三维坐标的完整链路4.1 双目视觉测距的几何原理论文用的双目模型是两个平行摄像头光心距离 T焦距 f。空间点 P 在左右图像上的水平坐标分别是 xl 和 xr视差 D xl - xr。根据三角形相似关系深度 Z f * T / D。这个公式是双目测距的核心所有后续计算都从这里展开。论文还给出了 X 和 Y 方向的计算公式把像素坐标映射到空间坐标X (u - u0) * Z * wu / f Y (v - v0) * Z * wv / f其中 (u0, v0) 是图像主点坐标wu 和 wv 是像素的物理尺寸。实际用 OpenCV 的时候这些参数都来自立体标定不需要手算。4.2 立体标定与视差计算双目定位能不能准八成看标定。论文里给的摄像头参数是焦距 6 mm、间距 15 cm但这是硬件参数不是标定结果。真正要跑起来必须用棋盘格做一次立体标定拿到左右摄像头的内参矩阵、畸变系数、旋转矩阵和平移向量。OpenCV 提供了一套完整的标定流程import cv2 import numpy as np # 棋盘格内角点数量比如 9x6 pattern_size (9, 6) # 棋盘格方格实际物理尺寸单位毫米 square_size 25.0 # 生成棋盘格三维坐标 objp np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32) objp[:, :2] np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) objp * square_size # 收集左右图像的角点 objpoints [] imgpoints_l [] imgpoints_r [] # 假设你已经采集了若干组左右图像 for left_path, right_path in image_pairs: img_l cv2.imread(left_path, 0) img_r cv2.imread(right_path, 0) ret_l, corners_l cv2.findChessboardCorners(img_l, pattern_size, None) ret_r, corners_r cv2.findChessboardCorners(img_r, pattern_size, None) if ret_l and ret_r: objpoints.append(objp) imgpoints_l.append(corners_l) imgpoints_r.append(corners_r) # 分别标定左右摄像头 ret_l, mtx_l, dist_l, _, _ cv2.calibrateCamera( objpoints, imgpoints_l, img_l.shape[::-1], None, None) ret_r, mtx_r, dist_r, _, _ cv2.calibrateCamera( objpoints, imgpoints_r, img_r.shape[::-1], None, None) # 立体标定拿到 R 和 T ret, mtx_l, dist_l, mtx_r, dist_r, R, T, E, F cv2.stereoCalibrate( objpoints, imgpoints_l, imgpoints_r, mtx_l, dist_l, mtx_r, dist_r, img_l.shape[::-1], flagscv2.CALIB_FIX_INTRINSIC) # 立体校正让左右图像行对齐 R1, R2, P1, P2, Q, _, _ cv2.stereoRectify( mtx_l, dist_l, mtx_r, dist_r, img_l.shape[::-1], R, T, alpha0) # 生成映射表后续每帧直接 remap map1_l, map2_l cv2.initUndistortRectifyMap( mtx_l, dist_l, R1, P1, img_l.shape[::-1], cv2.CV_16SC2) map1_r, map2_r cv2.initUndistortRectifyMap( mtx_r, dist_r, R2, P2, img_r.shape[::-1], cv2.CV_16SC2)逻辑说明cv2.findChessboardCorners找棋盘格角点cv2.calibrateCamera分别标定左右摄像头内参cv2.stereoCalibrate算两个摄像头之间的旋转和平移关系cv2.stereoRectify做立体校正让左右图像行对齐最后cv2.initUndistortRectifyMap生成映射表。之后每帧图像先 remap 再做立体匹配视差计算就只需要在同一行上找匹配点搜索空间从二维降到一维。参数说明棋盘格内角点数量要和你实际打印的棋盘格一致9x6 表示每行 9 个内角点、每列 6 个。方格尺寸 square_size 用毫米标定结果的平移向量 T 也会是毫米单位。cv2.stereoCalibrate的flags用CALIB_FIX_INTRINSIC表示固定已经标定好的内参只优化外参这样更稳定。4.3 立体匹配与火源三维坐标计算标定完之后每帧的流程是remap 校正、立体匹配算视差、根据视差算深度、再算 X 和 Y。OpenCV 提供了StereoBM和StereoSGBM两种立体匹配算法。火焰区域纹理弱StereoBM在这种场景下效果一般StereoSGBM更稳但慢一些。实际用的时候可以只在火焰轮廓的 ROI 里做匹配减少计算量。# 假设已经 remap 校正过 left_rect cv2.remap(left_img, map1_l, map2_l, cv2.INTER_LINEAR) right_rect cv2.remap(right_img, map1_r, map2_r, cv2.INTER_LINEAR) # 转灰度 left_gray cv2.cvtColor(left_rect, cv2.COLOR_BGR2GRAY) right_gray cv2.cvtColor(right_rect, cv2.COLOR_BGR2GRAY) # SGBM 立体匹配 stereo cv2.StereoSGBM_create( minDisparity0, numDisparities64, # 必须是 16 的倍数 blockSize11, # 奇数5 到 21 之间 P18 * 3 * 11 ** 2, P232 * 3 * 11 ** 2, disp12MaxDiff1, uniquenessRatio10, speckleWindowSize100, speckleRange32 ) disparity stereo.compute(left_gray, right_gray).astype(np.float32) / 16.0 # 从 Q 矩阵反投影到三维 points_3d cv2.reprojectImageTo3D(disparity, Q) # 取火焰质心处的三维坐标 cx, cy int(flame_centroid[0]), int(flame_centroid[1]) if disparity[cy, cx] 0: X, Y, Z points_3d[cy, cx] print(f火源空间坐标: X{X:.1f}mm, Y{Y:.1f}mm, Z{Z:.1f}mm)逻辑说明cv2.StereoSGBM_create创建 SGBM 匹配器compute返回的是视差图数值是真实视差的 16 倍所以要除以 16。cv2.reprojectImageTo3D用标定得到的 Q 矩阵把视差图反投影成三维点云每个像素对应一个空间坐标。取火焰质心位置的坐标就是火源位置。参数说明numDisparities决定搜索范围越大能测的距离越近但计算量也越大。blockSize是匹配块大小火焰纹理弱的时候适当调大但太大会让视差图变糊。uniquenessRatio是唯一性检查值越大匹配越严格误匹配越少但可能漏掉弱纹理区域。speckleWindowSize和speckleRange用来过滤小面积噪声视差。注意双目定位的精度和基线 T 成正比和距离 Z 的平方成反比。论文里基线 15 cm在 5 米距离上误差可能到几十厘米。如果场景需要更远距离定位要么加大基线要么换更高分辨率的摄像头。5. 避坑与排查这套系统在实际部署中最容易翻车的五个点5.1 红外滤光片选错火焰和背景一起过曝现象二值化后整个画面几乎全白火焰区域和背景粘连轮廓提取出来是一大坨。原因滤光片截止波长选得太宽可见光没滤干净或者滤光片透射率太高红外辐射饱和了。解决先确认滤光片截止波长。火焰红外辐射峰值在 2 到 5 微米但普通 CCD 响应范围到 1 微米左右所以实际用的是近红外波段。选 850 nm 或 940 nm 窄带滤光片透射率控制在 70% 左右。如果已经装了滤光片还是过曝调摄像头曝光时间或增益别让像素值顶到 255。5.2 轴向比判别在摄像头倾斜安装时失效现象明明有火焰轴向比一直小于 1系统不报警。原因摄像头俯仰角太大火焰在图像里被压扁纵向尺寸被压缩。解决安装时尽量让摄像头光轴平行于地面俯仰角控制在 15 度以内。如果必须倾斜先做透视校正把图像映射到正视角再算轴向比。或者把轴向比阈值从 1.0 降到 0.8但这样误报率会上升。5.3 立体标定用错棋盘格尺寸深度值整体偏移现象火源定位的 Z 值总是比实际距离大一圈或小一圈比例不对。原因标定时square_size填错了比如实际方格是 25 mm填了 30 mm标定出来的平移向量 T 就偏大深度计算跟着偏。解决拿卡尺量一下打印出来的棋盘格实际方格尺寸精确到 0.1 mm。打印时不要缩放用原始尺寸。标定完拿一个已知距离的物体验证一下比如把火焰换成 LED 灯放在 3 米处看 Z 值是不是 3000 mm 左右。5.4 SGBM 在火焰弱纹理区域产生大片空洞现象视差图在火焰区域全是黑色reprojectImageTo3D出来的坐标是无效值。原因火焰表面纹理弱SGBM 找不到足够的匹配特征视差计算失败。解决两个方向。一是调 SGBM 参数把blockSize降到 5uniquenessRatio降到 5放宽匹配条件。二是换思路不依赖火焰表面纹理而是用火焰轮廓的角点或质心作为匹配点只算这几个关键点的视差而不是全图稠密匹配。论文里用的就是质心匹配的思路。5.5 GSM 报警模块在室内没信号报警发不出去现象系统检测到火灾语音报警响了但手机收不到短信。原因GSM 模块依赖蜂窝网络地下室、变电站屏蔽室、金属机柜里信号极弱。解决GSM 天线引到室外或窗边用延长线把天线和模块分开。如果现场确实没信号换 4G 模块走网络报警或者加一个本地声光报警器作为兜底。论文里用的 TC35 是较老的 GSM 模块现在选型可以看 4G Cat.1 模块价格差不多但信号适应性更好。6. 从论文到工程把检测帧率提上去的两个实操技巧论文里的算法链路跑一遍在普通 PC 上大概能到 10 到 15 帧但如果你要上嵌入式平台或者多路摄像头这个帧率不够看。我自己的习惯是先把 ROI 缩小再做算法降频。第一个技巧是动态 ROI。不要每帧都对全图做中值滤波和直方图均衡化先用一个轻量的帧差法或者背景减除把变化区域框出来只在这个 ROI 里跑完整流程。OpenCV 的cv2.createBackgroundSubtractorMOG2就够用计算量比全图预处理小一个数量级。火焰区域一般只占画面很小一部分ROI 能把处理面积压到 10% 以下。第二个技巧是判别算法降频。红外测温每帧都做但轴向比、内外焰、形状不规则这三个判别不需要每帧跑。我一般设成每 3 帧跑一次中间帧只做红外测温。因为火焰的形态变化没有那么快3 帧间隔在 25 帧的摄像头下是 120 毫秒完全够用。这样整体计算量能降一半左右。frame_count 0 while True: ret, frame cap.read() if not ret: break frame_count 1 # 每帧都做红外测温 temp infrared_temperature(frame) # 每 3 帧做一次完整判别 if frame_count % 3 0: roi detect_roi(frame) # 动态 ROI if roi is not None: result full_discrimination(frame, roi) if result[fire]: trigger_alarm(result[position])逻辑说明infrared_temperature是轻量函数只做灰度化和最大值统计耗时极低。full_discrimination包含轴向比、内外焰、形状不规则和延时报警放在条件分支里降频执行。detect_roi用背景减除或帧差法拿到变化区域如果 ROI 为空说明画面静止直接跳过判别。参数说明降频系数 3 是经验值帧率越高可以越大。如果摄像头是 60 帧可以设成 5 甚至 6。ROI 的最小面积阈值要设一个下限比如 100 像素太小的 ROI 可能是噪声不值得跑完整判别。从那以后我每次部署类似的视觉检测系统都强制先跑一遍 ROI 覆盖率统计和单帧耗时剖面确认瓶颈在预处理还是判别再决定降频策略。这套论文里的算法链路本身不复杂难的是把参数标定和场景适配做扎实。希望帮到你。本文还有配套的精品资源点击获取
返回列表