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

2023-10-27

开始做这个之前,了解一些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' },但总觉得哪里不妥。。。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue+flask实现视频目标检测yolov5 的相关文章

随机推荐

  • 类加载机制—详解

    1 类加载 class 文件中都是一个一个的二进制 通过前面个两个字节进行判断 2 双亲委托机制 class 文件通过类加载器进入到 JVM虚拟机中运行 2 1类加载器 类加载器分为两种 一种是引导类加载器 启动类加载器是已经提供好的 一种
  • 世间万物,音乐不可辜负

    世间万物 唯有爱不可辜负 爱 除了来自家人的亲情 恋人的爱情 朋友的友情 爱 还来自你对世间万物的感受 比如 美食 通过嗅觉 品尝到美味 又比如音乐 通过听觉 调动你的情绪 激发你的想象力 共情能力 愉悦你的身心 安慰你 鼓励你 今天 跟大
  • 大数据实战 Linux Ubuntu 20.04.1 server 最小化安装及其网络配置

    1 Uduntu 的诞生 Ubuntu是一个以桌面应用为主的Linux操作系统 其名称来自非洲南部祖鲁语或豪萨语的 ubuntu 一词 意思是 人性 我的存在是因为大家的存在 是非洲传统的一种价值观 buntu Linux是由南非人马克 沙
  • 【Linux篇】fwrite函数

    include
  • 深入理解 synchronized 关键字

    看书的时候 看到这里 觉得有必要记录一下 那就顺手写一下 先看一下 synchronized 的官方解释的翻译 synchronized 关键字可以实现一个简单的策略来防止线程干扰和内存一致性错误 如果一个对象对多个线程是可见的 那么该对象
  • node.JS之中转服务器

    经过前面node的学习 我们对node已经有了一定的了解下面我直接上中转服务器实现过程和思路说明 let http require http let https require https var iconv require iconv l
  • mysql的binlog详解

    author skate time 2012 03 27 mysql的binlog详解 什么是binlog binlog日志用于记录所有更新了数据或者已经潜在更新了数据 例如 没有匹配任何行的一个DELETE 的所有语句 语句以 事件 的形
  • 洛谷T160512 G - 森林(并查集)

    题目思路 按照正常的并查集思路来想的话 对于操作一 分裂成两颗树后 比较难维护的是其中一颗子树的所有子节点的祖先节点 因为 在find找祖先节点的时候会找到分裂前的的那个祖先节点 如果给每个子节点都更改的话 复杂度不允许 但是 如果我们把删
  • 【Yarn】yarn源码阅读之AsyncDispatcher

    文章目录 1 概述 1 1 图示如下 2 源码解读 2 1 继承关系 2 2 构造方法 2 3 serviceInit方法 2 4 serviceStart 2 5 dispatch 2 6 注册类型方法 2 7 GenericEventH
  • (三)Qlabel显示图片

    在 一 QT学习中 我们说过label这个控件是可以显示图片的 那么这篇让我们看下如何显示图片 首先让我们创建一个项目picture 为项目布置上对应的控件label 让图片显示在label上 代码很简单 如下 QLabel abel ne
  • Unity+ECS框架(Entity Component System)学习(图文详细+源码)(一)——概念

    Unity ECS框架 Entity Component System 学习 图文详细 源码 一 概念 官方链接 一 ECS介绍 Entity 实体 Component 组件 System 系统 实例化系统 实例化系统 二 ECS概念 En
  • Java开发主流框架有哪些?

    SSM组合 SSM是一种Java Web开发的组合框架 是Spring Spring MVC和MyBatis的缩写 Spring是一个轻量级的Java应用框架 提供了一系列的模块 包括IoC容器 AOP MVC框架 数据访问和事务等 可以帮
  • react native xcode unable to open configuration settings file

    解决方案 pod install 然后重开 pod install可能会很久 pod install verbose 可以看进度
  • blender动画全面学习教程

    大小解压后 31 8G 时长28小时 包含项目文件 1920X1080 MP4 语言 英语 中英文字幕 根据原英文字幕机译更准确 Gumroad 活着 Blender中的动画课程 云桥网络 平台获取课程 信息 Alive 是迄今为止发布的最
  • Python import Queue ImportError: No module named 'Queue'

    python3 中引入Queue 会报出这个问题 python3 中这样引入 import queue python2 中这样引入 import Queue 为了兼容 可以这样 import sys if sys version gt 3
  • 机器学习-线性回归-多维度特征变量

    1 假设函数 之前的几篇文章里面 我们都只是介绍了单维特征变量的线性回归模型 比如预测房价的时候 我们只用了房子的面积这个维度 接下来我们会去研究多个维度的线性回归模型 还是从预测房价这个例子入手 假设我们现在不只是单纯的考虑房子的面积 还
  • verilog 简单分频程序

    偶数分频 最简单二分频 在输入时钟上升沿翻转即可 N分频 N为偶数 计数器计数到N 2 1翻转 如进行4分频 count 4 2 1 1时翻转 6分频计数器计到2 翻转 程序如下 经过实测验证 正确 时序如图 可以看出 从36到42是一个周
  • 西瓜书 第一章 绪论

    1 1 引言 理解机器学习 人类的 经验 对应计算机中的 数据 让计算机来学习这些经验数据 生成一个算法模型 在面对新的情况中 计算机便能作出有效的判断 这便是机器学习 1 2 基本术语 假设我们收集了一批西瓜的数据 例如 色泽 青绿 根蒂
  • linux下只读文件的修改方法

    命令前面加sudo 是以管理员方式打开
  • vue+flask实现视频目标检测yolov5

    开始做这个之前 了解一些vue的基础 然后对flask完全不知道 所以特别感谢很多博主的文章 主要参考的是这篇文章 在WEB端部署YOLOv5目标检测 Flask VUE 博主在GitHub上详细的代码给我一个很好的参考 他采用的是前后端分