使用 Yolov8 Flask 自定义训练实时火灾和烟雾检测

近年来,人工智能和机器学习的进步彻底改变了包括公共安全在内的各个行业。 这些技术在火灾和烟雾检测方面取得了显著进展,这对于早期预警系统和高效的应急响应至关重要。 实现这一目标的最有效方法之一是将YOLOv8强大的目标检测能力与基于Python的轻量级Web框架Flask的灵活性相结合。

近年来,人工智能和机器学习的进步彻底改变了包括公共安全在内的各个行业。这些技术在火灾和烟雾检测方面取得了显著进展,这对于早期预警系统和高效的应急响应至关重要。实现这一目标的最有效方法之一是将YOLOv8强大的目标检测能力与基于Python的轻量级Web框架Flask的灵活性相结合。它们共同构成了一个通过视频流实现的强大实时火灾和烟雾检测解决方案。

使用 Yolov8 Flask 自定义训练实时火灾和烟雾检测

本文开发了一个专门用于火灾和烟雾检测的自定义训练YOLOv8模型。用于此训练的数据集可在Kaggle上找到,如果需要重新训练模型,训练脚本也可供使用。

数据集:

https://www.kaggle.com/code/deepaknr/yolov8-fire-and-smoke-detection?source=post_page-----79058b024b09--------------------------------

使用 Yolov8 Flask 自定义训练实时火灾和烟雾检测

训练脚本:

使用 Yolov8 Flask 自定义训练实时火灾和烟雾检测

实际示例:使用YOLOv8和Flask进行火灾和烟雾检测

假设一个实际场景,您需要监控一个有火灾风险的工业场地。通过摄像头建立实时视频流并利用YOLOv8模型的火灾检测功能,您可以及早识别火灾或烟雾,从而预防潜在的灾难。以下是一个Python代码片段,展示了如何将YOLOv8与Flask集成以实现火灾和烟雾检测。

import os
import cv2
import numpy as np
from flask import Flask, render_template, Response, request
from werkzeug.utils import secure_filename
from ultralytics import YOLO

app = Flask(__name__)

YOLOV8_MODEL_PATH = 'path-to-yolov8-model'

ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov'}
video_path = None


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


model = YOLO(YOLOV8_MODEL_PATH)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/upload', methods=['POST'])
def upload():
    global video_path
    if 'file' not in request.files:
        return 'No file part', 400

    file = request.files['file']

    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        filepath = os.path.join('uploads', filename)
        file.save(filepath)
        video_path = filepath
        return render_template('index.html')

    return 'Invalid file type', 400


def generate_frames():
    global video_path
    if video_path is None:
        return None
    cap = cv2.VideoCapture(video_path)

    alpha = 0.4
    while True:
        success, frame = cap.read()
        if not success:
            break

        result = model(frame, verbose=False, conf=0.35)[0]

        bboxes = np.array(result.boxes.xyxy.cpu(), dtype="int")
        classes = np.array(result.boxes.cls.cpu(), dtype="int")
        confidence = np.array(result.boxes.conf.cpu(), dtype="float")

        for cls, bbox, conf in zip(classes, bboxes, confidence):
            (x1, y1, x2, y2) = bbox
            object_name = model.names[cls]
            if object_name == 'fire':

                color = (19, 127, 240)
            else:
                color = (145, 137, 132)

            cropped_image = frame[int(y1):int(y2), int(x1):int(x2)]
            white_layer = np.ones(cropped_image.shape, dtype=np.uint8) * 255
            cropped_image = cv2.addWeighted(cropped_image, 1 - alpha, white_layer, alpha, 0)
            frame[int(y1):int(y2), int(x1):int(x2)] = cropped_image
            cv2.rectangle(frame, (x1, y1 -30), (x1 + 200, y1), color, -1)

            cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)

            cv2.putText(frame, f"{object_name.capitalize()}: {conf * 100:.2f}%", (x1, y1 - 5), cv2.FONT_HERSHEY_DUPLEX,
                        0.8, (255, 255, 255), 1)

        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()

        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

    cap.release()


@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    os.makedirs('uploads', exist_ok=True)

    app.run(host='0.0.0.0', port=5000, debug=True)import os
import cv2
import numpy as np
from flask import Flask, render_template, Response, request
from werkzeug.utils import secure_filename
from ultralytics import YOLO

app = Flask(__name__)

YOLOV8_MODEL_PATH = 'path-to-yolov8-model'

ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov'}
video_path = None


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


model = YOLO(YOLOV8_MODEL_PATH)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/upload', methods=['POST'])
def upload():
    global video_path
    if 'file' not in request.files:
        return 'No file part', 400

    file = request.files['file']

    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        filepath = os.path.join('uploads', filename)
        file.save(filepath)
        video_path = filepath
        return render_template('index.html')

    return 'Invalid file type', 400


def generate_frames():
    global video_path
    if video_path is None:
        return None
    cap = cv2.VideoCapture(video_path)

    alpha = 0.4
    while True:
        success, frame = cap.read()
        if not success:
            break

        result = model(frame, verbose=False, conf=0.35)[0]

        bboxes = np.array(result.boxes.xyxy.cpu(), dtype="int")
        classes = np.array(result.boxes.cls.cpu(), dtype="int")
        confidence = np.array(result.boxes.conf.cpu(), dtype="float")

        for cls, bbox, conf in zip(classes, bboxes, confidence):
            (x1, y1, x2, y2) = bbox
            object_name = model.names[cls]
            if object_name == 'fire':

                color = (19, 127, 240)
            else:
                color = (145, 137, 132)

            cropped_image = frame[int(y1):int(y2), int(x1):int(x2)]
            white_layer = np.ones(cropped_image.shape, dtype=np.uint8) * 255
            cropped_image = cv2.addWeighted(cropped_image, 1 - alpha, white_layer, alpha, 0)
            frame[int(y1):int(y2), int(x1):int(x2)] = cropped_image
            cv2.rectangle(frame, (x1, y1 -30), (x1 + 200, y1), color, -1)

            cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)

            cv2.putText(frame, f"{object_name.capitalize()}: {conf * 100:.2f}%", (x1, y1 - 5), cv2.FONT_HERSHEY_DUPLEX,
                        0.8, (255, 255, 255), 1)

        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()

        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

    cap.release()


@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    os.makedirs('uploads', exist_ok=True)

    app.run(host='0.0.0.0', port=5000, debug=True)

主要函数说明:

  • def generate_frames():此函数从上传的视频中提取帧,并利用YOLOv8模型进行目标检测,特别是针对火灾和烟雾等元素。帧上会渲染带有相应类别标签(火灾、烟雾)的边界框。为了增强可见性,在检测到物体的区域应用了半透明的白色覆盖层。处理后的帧被转换为JPEG格式,并持续输出以生成视频流。
  • def video_feed():此路由使用generate_frames函数将处理后的视频帧作为HTTP响应流式传输。它使用MIME类型multipart/x-mixed-replace向Web客户端发送JPEG图像流。

应用程序启动:

if __name__ == '__main__':
    os.makedirs('uploads', exist_ok=True)
    app.run(host='0.0.0.0', port=5000, debug=True)

如果直接运行脚本,它会确保uploads目录存在,然后在端口5000上启动Flask应用程序,并监听所有接口(0.0.0.0)。

使用 Yolov8 Flask 自定义训练实时火灾和烟雾检测

相关资讯

计算机视觉:使用 YOLOv8 创建交通热力图

在一个由数据驱动和导向的世界中,解释、可视化并基于这些数据做出决策的能力变得越来越重要。 这意味着,应用正确的工具和技术可能决定一个项目的成败。 在计算机视觉领域,有许多技术可以解释从视频(录制、流媒体或实时)中获取的数据。

人工智能的历史:从古代神话到现代机器,从图灵到未来

在人类宏伟成就的历史上,很少有演员能像人工智能一样如此引人注目、充满争议且大胆无畏。 深入人工智能 (AI) 的历史迷宫及其可能的未来,就像踏上一场穿越时空的冒险之旅,科幻小说与现实之间的界限比量子计算机解决魔方的速度更快。 请想象一下,如果有一天,机器不仅能执行任务,还能学习、适应和进化,你的烤面包机也许有一天会在国际象棋上胜过你,你的吸尘器也许能写出一首与莎士比亚媲美的十四行诗。

终于把机器学习中的类别不平衡搞懂了!!

今天给大家分享机器学习中的一个关键概念,类别不平衡。 类别不平衡指的是在分类问题中,不同类别的数据样本数量相差悬殊的情况。 在机器学习和深度学习的应用中,类别不平衡是一个常见的问题,尤其是在一些实际场景中,某些类别的数据相对较少,而其他类别的数据较多。