vue+flask实现视频目标检测yolov5

开始做这个之前,了解一些vue的基础,然后对flask完全不知道。所以特别感谢很多博主的文章。
主要参考的是这篇文章:在WEB端部署YOLOv5目标检测(Flask+VUE),博主在GitHub上详细的代码给我一个很好的参考,他采用的是前后端分离开发的方式。
一.前端搭建
参考视频:vue+elementUI管理平台系列
参考博客:Flask + Vue 搭建简易系统步骤总结

vue-cli2.9.6+ElementUI搭建。(首先要安装node)
1.搭建脚手架:npm install -g vue-cli@2.9.6
2.创建一个基于webpack模板的项目vue init webpack 自定义项目名
3.运行项目npm run dev
二.后端搭建
主要是yolov5环境的一个搭建。

参考博客:(1)使用conda创建python的虚拟环境,介绍了如何安装与删除虚拟环境
(2)【小白CV】手把手教你用YOLOv5训练自己的数据集(从Windows环境配置到模型部署),我的配置就是根据这个来的。

1.首先是虚拟环境的配置(最好是在虚拟环境中搭建,血与泪的教训),conda create -n torch107 python=3.7
2.激活虚拟环境activate torch107
3.安装pytorch,首先已经安装anaconda3,yolov5需要pytorch1.6以上,pip3 install torch==1.8.1+cu102 torchvision==0.9.1+cu102 torchaudio===0.8.1 -f https://download.pytorch.org/whl/torch_stable.html在这里插入图片描述
4.下载源码和安装环境依赖
源码指路:https://github.com/Sharpiless/Yolov5-Flask-VUE
安装依赖库:pip install -r requirements.txt,txt文件内容如下:

# pip install -r requirements.txt

# base ----------------------------------------
matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.2
Pillow
PyYAML>=5.3.1
scipy>=1.4.1
torch>=1.7.0
torchvision>=0.8.1
tqdm>=4.41.0

# logging -------------------------------------
tensorboard>=2.4.1
# wandb

# plotting ------------------------------------
seaborn>=0.11.0
pandas

# export --------------------------------------
# coremltools>=4.1
# onnx>=1.9.0
# scikit-learn==0.19.2  # for coreml quantization

# extras --------------------------------------
# Cython  # for pycocotools https://github.com/cocodataset/cocoapi/issues/172
pycocotools>=2.0  # COCO mAP
thop  # FLOPS computation

三.yolov5检测视频
参考视频:https://www.bilibili.com/video/BV1FK411K78w?t=1536,时间25:36以后
我的代码:
检测代码Detect.py:

import torch
import numpy as np
from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_coords, letterbox
from utils.torch_utils import select_device
import cv2
from random import randint


class VideoCamera(object):
    def __init__(self):
        # 通过opencv获取实时视频流
        self.img_size = 640
        self.threshold = 0.4
        self.max_frame = 160
        self.video = cv2.VideoCapture("E:/videodata/1.mp4")  #换成自己的视频文件
        self.weights = 'weights/final.pt'   #yolov5权重文件
        self.device = '0' if torch.cuda.is_available() else 'cpu'
        self.device = select_device(self.device)
        model = attempt_load(self.weights, map_location=self.device)
        model.to(self.device).eval()
        model.half()
        # torch.save(model, 'test.pt')
        self.m = model
        self.names = model.module.names if hasattr(
            model, 'module') else model.names
        self.colors = [
            (randint(0, 255), randint(0, 255), randint(0, 255)) for _ in self.names
        ]


    def __del__(self):
        self.video.release()

    def get_frame(self):
        ret, frame = self.video.read()   #读视频
        im0, img = self.preprocess(frame)  #转到处理函数

        pred = self.m(img, augment=False)[0]  #输入到模型
        pred = pred.float()
        pred = non_max_suppression(pred, self.threshold, 0.3)

        pred_boxes = []
        image_info = {}
        count = 0
        for det in pred:
            if det is not None and len(det):
                det[:, :4] = scale_coords(
                    img.shape[2:], det[:, :4], im0.shape).round()

                for *x, conf, cls_id in det:
                    lbl = self.names[int(cls_id)]
                    x1, y1 = int(x[0]), int(x[1])
                    x2, y2 = int(x[2]), int(x[3])
                    pred_boxes.append(
                        (x1, y1, x2, y2, lbl, conf))
                    count += 1
                    key = '{}-{:02}'.format(lbl, count)
                    image_info[key] = ['{}×{}'.format(
                        x2 - x1, y2 - y1), np.round(float(conf), 3)]

        frame = self.plot_bboxes(frame, pred_boxes)


        # 因为opencv读取的图片并非jpeg格式,因此要用motion JPEG模式需要先将图片转码成jpg格式图片
        ret, jpeg = cv2.imencode('.jpg', frame)
        return jpeg.tobytes()

    def preprocess(self, img):

        img0 = img.copy()
        img = letterbox(img, new_shape=self.img_size)[0]
        img = img[:, :, ::-1].transpose(2, 0, 1)
        img = np.ascontiguousarray(img)
        img = torch.from_numpy(img).to(self.device)
        img = img.half()  # 半精度
        img /= 255.0  # 图像归一化
        if img.ndimension() == 3:
            img = img.unsqueeze(0)

        return img0, img

    def plot_bboxes(self, image, bboxes, line_thickness=None):
        tl = line_thickness or round(
            0.002 * (image.shape[0] + image.shape[1]) / 2) + 1  # line/font thickness
        for (x1, y1, x2, y2, cls_id, conf) in bboxes:
            color = self.colors[self.names.index(cls_id)]
            c1, c2 = (x1, y1), (x2, y2)
            cv2.rectangle(image, c1, c2, color,
                          thickness=tl, lineType=cv2.LINE_AA)
            tf = max(tl - 1, 1)  # font thickness
            t_size = cv2.getTextSize(
                cls_id, 0, fontScale=tl / 3, thickness=tf)[0]
            c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
            cv2.rectangle(image, c1, c2, color, -1, cv2.LINE_AA)  # filled
            cv2.putText(image, '{}-{:.2f} '.format(cls_id, conf), (c1[0], c1[1] - 2), 0, tl / 3,
                        [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
        return image

app.py代码:

from flask import *
import cv2
import logging as rel_log
from datetime import timedelta
from flask_cors import CORS
from Detect import VideoCamera

app = Flask(__name__)
cors = CORS(app, resources={r"/getMsg": {"origins": "*"}})  #解决跨域问题,vue请求数据时能用上

@app.route('/')
def index():
    return render_template('index.html')  #template文件夹下的index.html
def gen(camera):
    while True:
        frame = camera.get_frame()
        # 使用generator函数输出视频流, 每次请求输出的content类型是image/jpeg
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')  # 这个地址返回视频流响应
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == "__main__":
    app.run(host='127.0.0.1', port=5000, debug=True)

index.html:

<html>
  <head>
    <title>视频检测</title>
    <style>
      div{
        margin: 0 auto;
        text-align: center;
        width: 1200px;
        height: 800px;
      }
      img{
        width: 100%;
        height: 100%;
        
      }
    </style>
  </head>
  <body>
    <div>
      <h1>linjie</h1>
    <img src="{{ url_for('video_feed') }}">
    </div>
    
  </body>
</html>

运行后端python app.py
输入http://localhost:5000/,得到一个用flask实现的网页端目标检测。至于如何将这个视频与vue写的前端结合起来,还请大家给点意见,我是直接通过:response = { 'image_url': 'http://127.0.0.1:5000/video_feed' },但总觉得哪里不妥。。。

目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
### 回答1: YOLOv5 是一个目标检测模型,Flask 是一个 Python 的 Web 框架。 要在 Flask 中部署 YOLOv5,需要以下步骤: 1. 安装 Flask 和相关依赖 2. 加载 YOLOv5 模型 3. 创建一个 Flask 应用程序 4. 定义路由,处理图像上传请求 5. 使用 YOLOv5 模型处理图像并返回结果 6. 部署 Flask 应用程序 有关详细信息,请参考 Flask 官方文档和 YOLOv5 文档。 ### 回答2: YoloV5是一种非常流行的目标检测框架,它能够在实时物体检测任务中取得非常出色的表现。在实际部署中,常常需要将YoloV5模型进行封装,并将其制作成Web服务,以便能够对外提供接口。 其中,Flask是一种非常常用的Python Web框架,它可以用于快速构建Web应用程序。因此,使用FlaskYoloV5模型制作成Web服务,是一种常见而且非常有效的方式。 具体来说,Flask可以帮助我们实现如下功能: 1. 构建基础的Web服务框架,提供HTTP请求的解析、路由分发、错误统一处理等功能。 2. 将YoloV5模型嵌入到Flask中,并提供对外接口,以便于客户端进行调用。 3. 提供静态文件和模板管理功能,方便Web应用程序的开发和管理。 4. 支持插件扩展、中间件管理、Session管理等高级功能,提供更灵活、更强大的Web服务能力。 在具体实现中,我们可以参考一些可用的代码库,例如GitHub上提供的yolov5-flask代码示例。该示例包含了完整的YoloV5模型封装、Flask服务构建、路由分发、图像预处理和结果返回等所有必要功能,可以直接用于实际环境中。同时,该示例也提供了多种配置选项、调试信息和日志记录等辅助功能,方便开发者进行自定义修改和优化。 总之,使用FlaskYoloV5模型封装成Web服务,是一种非常有效和流行的做法。它可以帮助我们快速构建出高可用、高性能的Web服务,实现物体检测任务的端到端处理。对于需要实现物体检测的应用场景,这种方法是一种非常值得尝试的技术方案。 ### 回答3: YOLOv5 是近年来最为热门的目标检测模型之一,其能够快速、准确地检测图像或视频中的物体,被广泛应用于智能监控、自动驾驶、人脸识别等领域。而 Flask 是一个轻量级的 Python Web 开发框架,可以方便地构建 Web 服务器应用。这里将介绍如何将 YOLOv5 模型与 Flask 框架结合起来进行部署。 步骤一:准备工作 首先,我们需要确保已经安装好了 Python 环境、Flask 框架和 YOLOv5 模型。可以在终端中输入以下命令检查: ``` python --version # 检查Python是否安装成功 pip install flask # 安装Flask ``` 步骤二:导入模型 在 Flask 应用程序中,我们需要将 YOLOv5 模型载入内存中,以便进行目标检测。我们可以使用 PyTorch 框架进行模型的导入操作。 ``` import torch MODEL_PATH = 'path/to/your/yolov5_model.pt' model = torch.hub.load('ultralytics/yolov5', 'custom', path=MODEL_PATH, force_reload=True) ``` 注意,这里的 `path` 参数应该填写你训练好的 YOLOv5 模型的路径。 步骤三:定义 Flask 应用程序 我们可以在 Flask 应用程序中定义一个路由,直接将图片文件作为参数传入目标检测模型中,返回检测结果。代码如下: ``` from flask import Flask, jsonify, request from PIL import Image app = Flask(__name__) @app.route('/detect', methods=['POST']) def detect(): file = request.files['image_file'] im = Image.open(file) result = model(im) # 处理检测结果,生成JSON格式返回 ... return jsonify(result) ``` 在代码中,我们定义了一个 `/detect` 路由,用于接收 POST 请求并传入图片文件,进行目标检测并返回 JSON 格式的检测结果。 步骤四:启动 Flask 应用程序 最后,我们只需要在终端中执行以下代码即可启动 Web 服务器: ``` if __name__ == '__main__': app.run() ``` 此时,我们访问 `http://localhost:5000/detect` 即可进行目标检测操作。 以上就是 YOLOv5 模型和 Flask 框架进行部署的简要流程。总的来说,如果熟悉 Python 和深度学习知识,使用 Flask 部署 YOLOv5 并不难。当然,如果需要更加深入的了解和优化,还需要花费更多的时间和精力。
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值