基于MATLAB的火灾烟雾检测系统 可以识别视频和图像 有代码注释

最近在折腾视频分析的项目,发现用MATLAB搞烟火检测还挺有意思。今天就跟大伙唠唠怎么用颜色特征和运动检测来揪出视频里的火灾苗头。先放个效果图镇楼(想象一下正常画面突然框出红色烟雾区域)——这玩意儿对森林防火或者仓库监控应该挺实用。

基于MATLAB的火灾烟雾检测系统 可以识别视频和图像 有代码注释

先说说整体思路:烟火在颜色空间里有明显特征(比如HSV中的高饱和度),再加上动态扩散的运动特性。咱分三步走:视频预处理→颜色特征提取→运动区域分析。MATLAB的视频读取器用起来是真香:

videoObj = VideoReader('forest_fire.mp4');
frame = readFrame(videoObj);
imshow(frame);
% 这里有个坑:不同视频的色域可能不一致
% 上周处理无人机视频时就碰到过YUV转换问题

颜色空间转换是重头戏。RGB转HSV后,烟雾的色相和饱和度范围比较集中。实测发现烟雾的H分量在0~0.1(红色系),S在0.3~0.8之间效果最佳:

hsvFrame = rgb2hsv(frame);
% 红色通道阈值
hMask = (hsvFrame(:,:,1) > 0) & (hsvFrame(:,:,1) < 0.1); 
sMask = (hsvFrame(:,:,2) > 0.3) & (hsvFrame(:,:,2) < 0.8);
combinedColorMask = hMask & sMask;

但这样会误伤红衣路人或者红色车辆。这时候就需要运动检测来救场了。用三帧差分法捕捉动态区域,和颜色特征做与运算:

% 缓存前三帧
prevFrame = rgb2gray(readFrame(videoObj));
currFrame = rgb2gray(readFrame(videoObj));
nextFrame = rgb2gray(readFrame(videoObj));

diff1 = imabsdiff(currFrame, prevFrame);
diff2 = imabsdiff(nextFrame, currFrame);
motionMask = diff1 > 15 & diff2 > 15; % 阈值需要根据场景调整
% 工地场景建议调高到25,避免机械振动误判

组合颜色和运动特征后,用形态学操作优化检测区域。这里有个小技巧:先用腐蚀去掉噪点,再用膨胀连接断裂区域:

finalMask = combinedColorMask & motionMask;
se = strel('disk',3);
cleanMask = imopen(finalMask, se); % 开运算去毛刺
filledMask = imfill(cleanMask, 'holes'); % 填充空洞

最后来个实时报警机制。当检测区域超过画面10%时触发警报,并在画面左上角打警示文字:

areaRatio = nnz(filledMask)/numel(filledMask);
if areaRatio > 0.1
    position = [30 30];
    frame = insertText(frame, position,'FIRE DETECTED!',...
        'FontSize',40,'BoxColor','red','TextColor','white');
end
imshow(frame);

实际测试中发现几个坑点:

  1. 黄昏时分的火烧云容易误报(解决办法:加入形状扩散分析)
  2. 电焊作业会产生类似特征(需要结合温度传感器数据)
  3. 浓烟和薄雾的区分(正在尝试纹理分析算法)

完整代码里还加了进度条和参数调节滑块,方便调试。有兴趣的可以在GitHub上搜"FireSmokeDetection-MATLAB",记得点个star哈。下期可能讲讲怎么用迁移学习搞更精准的识别,或者结合无人机航拍做立体监测,看大伙反馈啦。

更多推荐