java1234_小锋头像
【免费】基于YOLO26的火焰烟雾目标识别(火灾监控预警)系统(FastAPI+Vue3) 计算机视觉课程设计 机器学习毕业设计 YOLO 智慧消防 目标检测 锋哥原创出品,必属精品封面图

【免费】基于YOLO26的火焰烟雾目标识别(火灾监控预警)系统(FastAPI+Vue3) 计算机视觉课程设计 机器学习毕业设计 YOLO 智慧消防 目标检测 锋哥原创出品,必属精品

大家好,我是Java1234_小锋老师,分享一套锋哥原创的基于YOLO26的火焰烟雾目标识别(火灾监控预警)系统(FastAPI+Vue3)。

项目介绍

火灾是工业厂房、仓储场所和公共建筑中破坏力很强的一类事故。火焰和烟雾出现得越早,可用于疏散和扑救的时间就越充分。传统烟感、温感探测器依赖烟气浓度或温度升高,在大空间、通风强烈或火灾初期往往响应偏慢。视频监控已经广泛部署,如果能直接从画面中识别火焰和烟雾,就可以把现有摄像机变成预警传感器。

本文设计并实现了基于YOLO26的火焰烟雾目标识别(火灾监控预警)系统。系统以Python为主要开发语言,使用FastAPI提供后端接口,使用Vue3构建管理端页面,使用MySQL保存用户、模型、检测记录、告警和日志。识别能力由Ultralytics接口加载的YOLO26权重提供,支持图片、视频和浏览器实时画面三种输入。检测结果写入数据库后,再按类别和置信度阈值生成告警,并关联火灾处置知识。

论文完成了需求分析、总体架构、功能结构、数据库概念结构与逻辑结构、主要业务时序以及各功能模块的实现。数据库采用以db_为前缀的库名和以t_为前缀的表名,给出了九张业务表的字段名、类型、长度、是否为空和备注。系统实现部分结合登录注册、个人中心、图片识别、视频识别、实时检测、告警、记录查询、模型管理和统计分析,给出了与工程代码一致的核心片段。

在本机训练记录中,以yolo26n为初始权重、输入尺寸640、批大小16、训练5个周期后,验证集精度约为0.599,召回率约为0.483,mAP50约为0.512。该结果说明检测流程已经打通,同时也说明短周期微调还不能当作高可靠的现场报警器。系统把模型文件与业务代码分开管理,后续可以在不改接口的情况下替换更充分训练的权重。

源码下载

链接: https://pan.baidu.com/s/1hRykcLMBDM3VcM7cDLPRFQ?pwd=1234
提取码: 1234

系统展示

核心代码

"""根据告警规则生成告警记录。"""
from datetime import datetime, timedelta
from typing import Optional

from sqlalchemy.orm import Session

from app.models.alarm import Alarm, AlarmRule
from app.models.detect import DetectDetail


def match_and_create_alarms(db: Session, record_id: int, details: list[DetectDetail], dedup_seconds: int = 0) -> list[Alarm]:
    """
    将检测明细与告警规则匹配,命中则写入告警表。

    Args:
        db: 数据库会话
        record_id: 检测记录ID
        details: 检测明细列表
        dedup_seconds: 实时检测去重间隔,0 表示不去重
    Returns:
        新产生的告警列表
    """
    rules = db.query(AlarmRule).filter(AlarmRule.enabled == 1).all()
    rule_map = {r.class_id: r for r in rules}
    created: list[Alarm] = []
    for detail in details:
        rule = rule_map.get(detail.class_id)
        if rule is None:
            continue
        conf = float(detail.confidence or 0)
        if conf < float(rule.conf_threshold):
            continue
        if dedup_seconds > 0:
            since = datetime.now() - timedelta(seconds=dedup_seconds)
            exists = (
                db.query(Alarm)
                .filter(Alarm.class_name == detail.class_name, Alarm.alarm_time >= since)
                .first()
            )
            if exists:
                continue
        alarm = Alarm(
            record_id=record_id,
            detail_id=detail.id,
            class_name=detail.class_name,
            confidence=conf,
            alarm_level=rule.alarm_level,
            alarm_time=datetime.now(),
            status="未处理",
        )
        db.add(alarm)
        created.append(alarm)
    if created:
        db.flush()
    return created
<template>
  <div class="page-card">
    <div class="search-bar">
      <el-input v-model="keyword" placeholder="火焰/烟雾" clearable style="width: 200px" />
      <el-select v-model="status" placeholder="状态" clearable style="width: 140px">
        <el-option label="未处理" value="未处理" />
        <el-option label="已处理" value="已处理" />
        <el-option label="已忽略" value="已忽略" />
      </el-select>
      <el-select v-model="alarmLevel" placeholder="等级" clearable style="width: 120px">
        <el-option label="高" value="高" />
        <el-option label="中" value="中" />
        <el-option label="低" value="低" />
      </el-select>
      <el-button type="primary" @click="load">查询</el-button>
      <el-button @click="batch('已处理')">批量处理</el-button>
      <el-button @click="batch('已忽略')">批量忽略</el-button>
    </div>
    <el-table :data="list" style="width: 100%" @selection-change="sel = $event">
      <el-table-column type="selection" width="48" />
      <el-table-column prop="id" label="ID" min-width="70" />
      <el-table-column prop="class_name" label="目标类别" min-width="180" show-overflow-tooltip />
      <el-table-column prop="confidence" label="置信度" min-width="90" />
      <el-table-column prop="alarm_level" label="等级" min-width="80">
        <template #default="{ row }">
          <el-tag :type="row.alarm_level === '高' ? 'danger' : row.alarm_level === '中' ? 'warning' : 'success'">{{ row.alarm_level }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="状态" min-width="90" />
      <el-table-column prop="alarm_time" label="告警时间" min-width="170" />
      <el-table-column prop="handler_name" label="处理人" min-width="100" />
      <el-table-column prop="handle_remark" label="备注" min-width="140" show-overflow-tooltip />
      <el-table-column label="操作" min-width="160" fixed="right">
        <template #default="{ row }">
          <el-button v-if="row.status === '未处理'" type="primary" link @click="handle(row, '已处理')">处理</el-button>
          <el-button v-if="row.status === '未处理'" type="warning" link @click="handle(row, '已忽略')">忽略</el-button>
          <el-button v-if="row.record_id" type="success" link @click="$router.push(`/record/${row.record_id}`)">记录</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination style="margin-top: 12px" background layout="total, prev, pager, next" :total="total" v-model:current-page="page" @current-change="load" />
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { alarmPageApi, alarmHandleApi, alarmBatchApi } from '@/api/alarm'

const list = ref([])
const total = ref(0)
const page = ref(1)
const keyword = ref('')
const status = ref('')
const alarmLevel = ref('')
const sel = ref([])

const load = async () => {
  const res = await alarmPageApi({ page: page.value, page_size: 10, keyword: keyword.value, status: status.value, alarm_level: alarmLevel.value })
  list.value = res.data.list
  total.value = res.data.total
}
const handle = async (row, st) => {
  const { value } = await ElMessageBox.prompt('请输入处理备注', st, { inputPlaceholder: '可选' }).catch(() => ({ value: '' }))
  await alarmHandleApi(row.id, { status: st, handle_remark: value })
  ElMessage.success('已更新')
  load()
}
const batch = async (st) => {
  if (!sel.value.length) return ElMessage.warning('请先选择')
  await alarmBatchApi({ ids: sel.value.map(i => i.id), status: st, handle_remark: '批量处理' })
  ElMessage.success('批量完成')
  load()
}
onMounted(load)
</script>

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/caoli201314/article/details/167701397

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--