1. 项目概述与背景
火灾识别系统是计算机视觉在公共安全领域的重要应用。传统基于温度传感器或烟雾探测器的方案存在响应延迟大、误报率高的问题。我在实验室搭建的这套基于CNN的火灾识别系统,通过分析监控视频流中的图像特征,能够在明火出现前的烟雾阶段就发出预警。实测表明,在标准测试集上达到98.4%的准确率,比传统方法提前3-5分钟发现火情。
这个毕设项目的核心价值在于:
- 采用暗通道先验预处理增强烟雾特征
- 设计17层深度CNN网络结构
- 实现端到端的实时检测流水线
- 在树莓派等边缘设备上部署验证
2. 核心设计思路
2.1 技术选型依据
选择CNN而非传统图像处理算法的原因:
- 特征提取优势:烟雾的纹理、扩散模式等特征难以用规则描述
- 抗干扰能力:能区分真实烟雾与蒸汽、雾霾等干扰物
- 端到端学习:自动优化从像素到分类结果的映射关系
对比实验显示,在相同测试集上:
- 传统SVM方法准确率82.3%
- 简单CNN模型准确率91.7%
- 本方案准确率98.4%
2.2 数据处理流程
数据采集规范
- 正样本:从火灾演练视频中截取10712帧(含烟雾)
- 负样本:公共场所监控视频截取8501帧
- 测试集:独立采集1383帧(烟雾/正常场景比例1:1.5)
特别注意:负样本需包含厨房蒸汽、汽车尾气等易混淆场景
暗通道预处理
python复制def get_dark_channel(img, patch_size=15):
min_channel = np.min(img, axis=2)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (patch_size, patch_size))
return cv2.erode(min_channel, kernel)
处理效果对比:
| 原始图像 | 暗通道图 | 特征差异 |
|---|---|---|
| ![原始图] | ![暗通道] | 烟雾区域对比度提升3-5倍 |
3. 模型架构详解
3.1 网络结构设计
mermaid复制graph TD
A[Input 48x48x1] --> B[Conv64-BN-ReLU]
B --> C[MaxPool]
C --> D[Conv128-BN-ReLU]
D --> E[MaxPool]
E --> F[Conv256-BN-ReLU]
F --> G[Flatten]
G --> H[FC2048-Dropout]
H --> I[FC2048-Dropout]
I --> J[Output2]
关键参数说明:
- 卷积核:3x3,步长1,padding='same'
- 池化:2x2最大池化,步长2
- Dropout率:0.5
- 优化器:Adam(lr=0.001)
3.2 训练技巧
类别不平衡处理:
python复制class_weight = {
0: len(train_labels)/(2*np.bincount(train_labels)[0]),
1: len(train_labels)/(2*np.bincount(train_labels)[1])
}
model.fit(..., class_weight=class_weight)
学习率调度:
python复制reduce_lr = ReduceLROnPlateau(
monitor='val_loss',
factor=0.2,
patience=5,
min_lr=1e-6
)
4. 实现步骤
4.1 环境配置
bash复制conda create -n fire_det python=3.8
conda install pytorch==1.12.1 torchvision==0.13.1 -c pytorch
pip install opencv-python pillow matplotlib
4.2 关键代码实现
数据加载器:
python复制class FireDataset(Dataset):
def __init__(self, img_dir, transform=None):
self.img_labels = pd.read_csv(os.path.join(img_dir,"labels.csv"))
self.img_dir = img_dir
self.transform = transform
def __getitem__(self, idx):
img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
image = cv2.imread(img_path)
image = get_dark_channel(image) # 暗通道转换
label = self.img_labels.iloc[idx, 1]
if self.transform:
image = self.transform(image)
return image, label
模型定义:
python复制class FireCNN(nn.Module):
def __init__(self):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 64, 3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2),
... # 其他层
)
self.classifier = nn.Sequential(
nn.Linear(256*6*6, 2048),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(2048, 2)
)
def forward(self, x):
x = self.features(x)
x = torch.flatten(x, 1)
x = self.classifier(x)
return x
5. 部署优化
5.1 模型压缩方案
| 方法 | 准确率下降 | 推理速度提升 |
|---|---|---|
| 原始模型 | - | 23ms/帧 |
| 参数量化 | 0.8% | 11ms/帧 |
| 知识蒸馏 | 1.2% | 15ms/帧 |
5.2 边缘设备部署
树莓派4B实测性能:
bash复制# 转换ONNX格式
torch.onnx.export(model, dummy_input, "fire_det.onnx",
opset_version=11)
# 使用TensorRT加速
trtexec --onnx=fire_det.onnx \
--saveEngine=fire_det.engine \
--fp16
6. 常见问题解决
误报问题排查:
- 检查负样本中是否包含蒸汽场景
- 调整暗通道的patch_size参数(建议15-25)
- 在输出层增加温度缩放(Temperature Scaling)
模型不收敛对策:
python复制# 梯度裁剪
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
# 改用SWA优化器
swa_model = torch.optim.swa_utils.AveragedModel(model)
7. 扩展方向
- 多模态融合:结合红外热成像数据
- 三维CNN:处理视频时序特征
- 迁移学习:使用EfficientNet作特征提取器
这个项目最让我惊喜的是暗通道预处理对模型性能的提升——仅这一项改进就让准确率提高了7个百分点。在实际部署时,建议先用Python原型验证算法,再用C++重写核心模块以获得最佳性能。
