目标检测——flask后端YOLOv8检测视频,前端实时显示检测结果

前端代码:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>YOLOv8 Video Stream</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        img {
            max-width: 100%;
            height: auto;
            border: 2px solid #ddd;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        table, th, td {
            border: 1px solid black;
        }
        th, td {
            padding: 10px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
    </style>
</head>
<body>
    <h1>YOLOv8 实时检测</h1>
    <img src="{{ url_for('video_feed') }}">
    
    <h2>检测到的目标信息</h2>
    <table id="objects-table">
        <thead>
            <tr>
                <th>类别</th>
                <th>坐标</th>
                <th>置信度</th>
                <th>时间</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>

    <script>
        // 定时从后端获取检测到的目标信息
        function fetchDetectedObjects() {
            fetch('/get_detected_objects')
                .then(response => response.json())
                .then(data => {
                    // 获取表格的主体部分
                    const tableBody = document.querySelector("#objects-table tbody");
                    tableBody.innerHTML = '';  // 清空表格内容

                    // 遍历检测到的对象并插入表格
                    data.forEach(item => {
                        const row = document.createElement("tr");
                        row.innerHTML = `
                            <td>${item.class}</td>
                            <td>[${item.coordinates.map(coord => coord.toFixed(2))}]</td>
                            <td>${(item.confidence * 100).toFixed(2)}%</td>
                            <td>${item.time}</td>
                        `;
                        tableBody.appendChild(row);
                    });
                })
                .catch(error => console.error('Error fetching detected objects:', error));
        }

        // 每1秒更新一次目标信息表格
        setInterval(fetchDetectedObjects, 1000);
    </script>
</body>
</html>

后端代码

app.py

from flask import Flask, render_template, Response, jsonify
import cv2
from ultralytics import YOLO
import datetime

app = Flask(__name__)

# 初始化YOLOv8模型
model = YOLO("yolov8n.pt")

# 使用OpenCV打开摄像头
camera = cv2.VideoCapture(0)

# 实时目标信息
detected_objects = []

def gen_frames():  
    global detected_objects
    while True:
        success, frame = camera.read()  # 从摄像头读取一帧
        if not success:
            break
        else:
            # 使用YOLOv8模型进行目标检测
            results = model(frame)
            annotated_frame = results[0].plot()  # 获取渲染后的检测结果图像
            
            # 获取检测结果并存储类别、坐标、置信度和当前时间
            detected_objects = []
            for box in results[0].boxes:
                # 获取检测到的类别、坐标和置信度
                class_name = results[0].names[int(box.cls[0])]
                xyxy = box.xyxy[0].cpu().numpy().tolist()
                confidence = float(box.conf[0])  # 获取置信度
                timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                
                detected_objects.append({
                    "class": class_name,
                    "coordinates": xyxy,
                    "confidence": confidence,
                    "time": timestamp
                })
            
            # 将检测结果转换为JPEG格式
            ret, buffer = cv2.imencode('.jpg', annotated_frame)
            frame = buffer.tobytes()
            
            # 使用yield生成器传输图像到前端
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    # 视频流路由
    return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/get_detected_objects')
def get_detected_objects():
    # 返回当前检测到的目标信息
    return jsonify(detected_objects)

@app.route('/')
def index():
    # 主页面路由
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张飞飞飞飞飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值