欢迎光临
我们一直在努力

基于Django + Vue的YOLO Web端通用检测系统 yolo web端检测系统成品 可替换自己的模型 使用Django和vue前后端分离

yolo web端检测系统成品源代码 可以替换自己的模型 在这里插入图片描述

使用Django和vue前后端分离 功能包含有注册,登录,图片检测,视频检测,摄像头检测,用户管理,历史检测图片管理,历史检测视频管理,历史检测摄像头管理等功能 在这里插入图片描述

使用mysql数据库或sqlite数据库,可切换 默认使用yolov8默认模型 可以替换为你自己的模型 实现不同的检测功能 支持yolov5,yolov8 ,yolov9 , yolov10 ,yolo11 ,yolov12等版本的模型 支持警报功能+邮件功能 在这里插入图片描述 1 在这里插入图片描述 1 在这里插入图片描述 “基于Django + Vue的YOLO Web端通用检测系统”。该系统采用前后端分离架构,支持多种YOLO模型版本(v5/v8/v9/v10/v11/v12),并具备完善的用户管理、历史记录管理和实时摄像头检测功能。

以下是构建该系统的核心简易代码方案。

🏗️ 1. 项目结构概览

yolo_web_system/
├── backend/ # Django 后端
│ ├── manage.py
│ ├── core/ # 核心配置
│ ├── app/ # 业务应用
│ │ ├── models.py # 数据库模型
│ │ ├── views.py # API 接口 (检测、用户、记录)
│ │ ├── urls.py # 路由
│ │ └── utils.py # YOLO 推理工具类
│ └── requirements.txt
├── frontend/ # Vue 前端
│ ├── src/
│ │ ├── views/ # 页面 (Login, ImageDetect, Camera…)
│ │ ├── components/ # 组件 (Upload, VideoPlayer…)
│ │ ├── api/ # Axios 请求
│ │ └── router/ # 路由
│ └── package.json
└── weights/ # 模型权重目录
└── yolov8n.pt # 默认模型


🛠️ 2. 后端实现 (Django + YOLO)

A. 环境依赖 (backend/requirements.txt)

django>=4.0
djangorestframework
django-cors-headers
ultralytics>=8.0.0 # 支持 YOLOv8/v9/v10/v11
opencv-python
numpy
pillow
mysqlclient # 如果使用 MySQL

B. 数据库模型 (app/models.py)

用于存储检测历史记录。

from django.db import models
from django.contrib.auth.models import User

class DetectionRecord(models.Model):
DETECT_TYPE_CHOICES = [
('IMAGE', '图片'),
('VIDEO', '视频'),
('CAMERA', '摄像头'),
]

user = models.ForeignKey(User, on_delete=models.CASCADE)
detect_type = models.CharField(max_length=10, choices=DETECT_TYPE_CHOICES)
original_file = models.ImageField(upload_to='uploads/original/')
result_file = models.ImageField(upload_to='uploads/result/', null=True, blank=True)
result_labels = models.CharField(max_length=255) # 存储检测到的标签,如 "person,smoke"
confidence = models.FloatField(default=0.0)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return f"{self.user.username}{self.detect_type}{self.created_at}"

C. YOLO 推理工具类 (app/utils.py)

核心逻辑:加载模型并推理,支持动态切换模型版本。

from ultralytics import YOLO
import cv2
import numpy as np
import os

# 全局模型实例 (启动时加载,避免重复加载)
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../weights/yolov8n.pt')
model = YOLO(MODEL_PATH)

def run_detection(image_path, conf_threshold=0.5):
"""
执行检测
:param image_path: 图片路径或 numpy 数组
:param conf_threshold: 置信度阈值
:return: (annotated_image_path, labels_string, max_confidence)
"""

results = model.predict(source=image_path, conf=conf_threshold, verbose=False)

labels = []
max_conf = 0.0

for r in results:
for box in r.boxes:
cls_id = int(box.cls[0])
conf = float(box.conf[0])
class_name = model.names[cls_id]
labels.append(class_name)
if conf > max_conf:
max_conf = conf

# 保存绘制了框的图片
output_path = image_path.replace('original', 'result') if isinstance(image_path, str) else 'temp_result.jpg'
os.makedirs(os.path.dirname(output_path), exist_ok=True)
r.save(filename=output_path)

unique_labels = list(set(labels))
return output_path, ",".join(unique_labels), max_conf

def run_camera_detection(frame):
"""
处理摄像头单帧画面 (用于视频流)
:param frame: numpy 数组 (BGR)
:return: annotated_frame (bytes), labels
"""

results = model.predict(source=frame, conf=0.5, verbose=False)
annotated_frame = results[0].plot() # ultralytics 自带绘图

labels = [model.names[int(box.cls[0])] for r in results for box in r.boxes]
return annotated_frame, list(set(labels))

D. 核心视图接口 (app/views.py)

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .models import DetectionRecord
from .utils import run_detection
from django.core.files.base import ContentFile
import base64
import cv2
import numpy as np

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def detect_image(request):
"""图片检测接口"""
file_obj = request.FILES.get('file')
if not file_obj:
return Response({"error": "No file"}, status=400)

# 1. 保存原图
record = DetectionRecord.objects.create(
user=request.user,
detect_type='IMAGE',
original_file=file_obj
)

# 2. 运行检测
result_path, labels, conf = run_detection(record.original_file.path)

# 3. 保存结果图到模型
with open(result_path, 'rb') as f:
record.result_file.save(f"result_{file_obj.name}", ContentFile(f.read()))

record.result_labels = labels
record.confidence = conf
record.save()

return Response({
"id": record.id,
"original_url": request.build_absolute_uri(record.original_file.url),
"result_url": request.build_absolute_uri(record.result_file.url),
"labels": labels,
"confidence": conf
})

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def camera_stream(request):
"""摄像头视频流接口 (MJPEG)"""
from django.http import StreamingHttpResponse

cap = cv2.VideoCapture(0) # 打开默认摄像头

def generate():
while True:
success, frame = cap.read()
if not success: break

# 调用 YOLO 检测
annotated_frame, _ = run_camera_detection(frame)

# 编码为 JPEG
ret, buffer = cv2.imencode('.jpg', annotated_frame)
frame_bytes = buffer.tobytes()

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

cap.release()
return StreamingHttpResponse(generate(), content_type='multipart/x-mixed-replace; boundary=frame')


🎨 3. 前端实现 (Vue 3 + Element Plus)

A. 图片检测页面 (src/views/ImageDetect.vue)

<template>
<div class="detect-container">
<el-row :gutter="20">
<!– 左侧:上传区 –>
<el-col :span="12">
<el-card class="box-card">
<template #header>原始图片</template>
<el-upload
drag
action="#"
:http-request="handleUpload"
:show-file-list="false"
accept="image/*"
>

<el-icon class="el-icon–upload"><upload-filled /></el-icon>
<div class="el-upload__text">拖拽图片到此处或 <em>点击上传</em></div>
</el-upload>
<div v-if="originalImg" style="margin-top: 20px;">
<img :src="originalImg" style="width: 100%; border-radius: 4px;" />
</div>
</el-card>
</el-col>

<!– 右侧:结果区 –>
<el-col :span="12">
<el-card class="box-card">
<template #header>检测结果</template>
<div v-loading="loading" class="result-area">
<img v-if="resultImg" :src="resultImg" style="width: 100%; border-radius: 4px;" />
<div v-else class="empty-text">等待检测结果…</div>

<div v-if="labels.length > 0" class="info-tag">
<el-tag v-for="label in labels" :key="label" type="success" style="margin-right: 5px;">
{{ label }}
</el-tag>
<span>置信度: {{ confidence }}</span>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>

<script setup>
import { ref } from 'vue';
import { UploadFilled } from '@element-plus/icons-vue';
import axios from 'axios';
import { ElMessage } from 'element-plus';

const loading = ref(false);
const originalImg = ref('');
const resultImg = ref('');
const labels = ref([]);
const confidence = ref(0);

const handleUpload = async (options) => {
const file = options.file;
const formData = new FormData();
formData.append('file', file);

// 显示原图预览
originalImg.value = URL.createObjectURL(file);

loading.value = true;
try {
const res = await axios.post('/api/detect/image/', formData, {
headers: { 'Content-Type': 'multipart/form-data', 'Authorization': 'Token YOUR_TOKEN' }
});

resultImg.value = res.data.result_url;
labels.value = res.data.labels.split(',');
confidence.value = res.data.confidence.toFixed(4);
ElMessage.success('检测完成');
} catch (e) {
ElMessage.error('检测失败');
} finally {
loading.value = false;
}
};
</script>

<style scoped>
.detect-container { padding: 20px; }
.result-area { min-height: 300px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.empty-text { color: #999; }
.info-tag { margin-top: 15px; width: 100%; text-align: left; }
</style>

B. 摄像头检测页面 (src/views/CameraDetect.vue)

<template>
<div class="camera-container">
<el-card>
<template #header>实时摄像头检测</template>
<div class="video-box">
<!– 直接嵌入后端返回的视频流 –>
<img
v-if="isStreaming"
src="http://localhost:8000/api/camera/stream/"
alt="Camera Stream"
style="width: 100%; border-radius: 4px;"
/>

<div v-else class="placeholder">
<el-icon :size="50"><video-camera /></el-icon>
<p>点击开启摄像头</p>
</div>
</div>
<div style="margin-top: 20px; text-align: center;">
<el-button type="primary" @click="toggleStream" v-if="!isStreaming">开启摄像头</el-button>
<el-button type="danger" @click="toggleStream" v-else>关闭摄像头</el-button>
</div>
</el-card>
</div>
</template>

<script setup>
import { ref } from 'vue';
import { VideoCamera } from '@element-plus/icons-vue';

const isStreaming = ref(false);

const toggleStream = () => {
isStreaming.value = !isStreaming.value;
};
</script>

<style scoped>
.camera-container { padding: 20px; }
.video-box { height: 500px; background: #000; display: flex; align-items: center; justify-content: center; color: #fff; }
.placeholder { text-align: center; }
</style>


🚀 4. 如何运行与配置

1. 后端启动 (Django)

cd backend
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver

注意:在 settings.py 中配置好 MEDIA_URL 和 MEDIA_ROOT 以便访问上传的图片。

2. 前端启动 (Vue)

cd frontend
npm install
npm run dev

3. 替换模型

只需将训练好的模型(如 yolov5m.pt, yolov11x.pt)放入 backend/weights/ 目录,并修改 app/utils.py 中的 MODEL_PATH 变量即可。系统无需重启即可支持新的检测任务(如烟雾、火焰、安全帽等)。

4. 数据库切换

在 backend/core/settings.py 中修改 DATABASES 配置:

  • SQLite (默认): 无需配置,直接使用文件。
  • MySQL:DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'yolo_db',
    'USER': 'root',
    'PASSWORD': 'your_password',
    'HOST': 'localhost',
    'PORT': '3306',
    }
    }

这套代码提供了一个功能完备的 Web 检测系统骨架。同学你可以直接在此基础上扩展警报功能和邮件通知功能。

赞(0)
未经允许不得转载:171主机测评 » 基于Django + Vue的YOLO Web端通用检测系统 yolo web端检测系统成品 可替换自己的模型 使用Django和vue前后端分离
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址