yolov5 web端部署进行图片和视频检测

目录

1、思路

2、代码结构

3、代码运行

4、api接口代码

5、web ui界面

6、参考资料

7、代码分享 


1、思路

通过搭建flask微型服务器后端,以后通过vue搭建网页前端。flask是第一个第三方库。与其他模块一样,安装时可以直接使用python的pip命令实现。flask是web开发框架,简单易学,因此用flask来搭建web服务也非常简单。

在pycharm新建一个项目,命名为web2020,然后新建一个python文件,命名为main.py。在代码中输入如下代码:

from flask import  Flask    #导入Flask类
app=Flask(__name__)         #实例化并命名为app实例
if __name__=="__main__":app.run(port=2020,host="127.0.0.1",debug=True)   #调用run方法,设定端口号,启动服务

路由定义:

from flask import  Flask
app=Flask(__name__)@app.route('/')
def index():return 'welcome to my webpage!'if __name__=="__main__":app.run(port=2020,host="127.0.0.1",debug=True)

通过这种方式,实现python调用模型,然后通过web服务器进行数据输入输出,最后通过浏览器web页面进行展示。

2、代码结构

前端代码结构

后端代码结构

3、代码运行

4、api接口代码

import datetime
import logging as rel_log
import os
import shutil
from datetime import timedelta
from flask import *
from flask import Flask, render_template, Response
from processor.AIDetector_pytorch import Detectorimport core.main# import camera driver
if os.environ.get('CAMERA'):Camera = import_module('camera_' + os.environ['CAMERA']).Camera
else:from camera import CameraUPLOAD_FOLDER = r'./uploads'ALLOWED_EXTENSIONS = set(['png', 'jpg'])
app = Flask(__name__)
app.secret_key = 'secret!'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDERwerkzeug_logger = rel_log.getLogger('werkzeug')
werkzeug_logger.setLevel(rel_log.ERROR)# 解决缓存刷新问题
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = timedelta(seconds=1)# 添加header解决跨域
@app.after_request
def after_request(response):response.headers['Access-Control-Allow-Origin'] = '*'response.headers['Access-Control-Allow-Credentials'] = 'true'response.headers['Access-Control-Allow-Methods'] = 'POST'response.headers['Access-Control-Allow-Headers'] = 'Content-Type, X-Requested-With'return response#图片检测接口
def allowed_file(filename):return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS#@app.route('/')
#def hello_world():
#    return redirect(url_for('static', filename='./index.html'))
@app.route('/')
def index():"""Video streaming home page."""return render_template('index.html')@app.route('/upload', methods=['GET', 'POST'])
def upload_file():file = request.files['file']print(datetime.datetime.now(), file.filename)#if file and allowed_file(file.filename):src_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)file.save(src_path)shutil.copy(src_path, './tmp/ct')image_path = os.path.join('./tmp/ct', file.filename)pid, image_info = core.main.c_main(image_path, current_app.model, file.filename.rsplit('.', 1)[1])return jsonify({'status': 1,'image_url': 'http://127.0.0.1:5003/tmp/ct/' + pid,'draw_url': 'http://127.0.0.1:5003/tmp/draw/' + pid,'image_info': image_info})#return jsonify({'status': 0})@app.route("/download", methods=['GET'])
def download_file():# 需要知道2个参数, 第1个参数是本地目录的path, 第2个参数是文件名(带扩展名)return send_from_directory('data', 'testfile.zip', as_attachment=True)# show photo
@app.route('/tmp/<path:file>', methods=['GET'])
def show_photo(file):if request.method == 'GET':if not file is None:image_data = open(f'tmp/{file}', "rb").read()response = make_response(image_data)response.headers['Content-Type'] = 'image/png'return response#视频检测接口
def gen(camera):"""Video streaming generator function."""while True:frame = camera.get_frame()yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')@app.route('/video_start')
def video_feed():"""Video streaming route. Put this in the src attribute of an img tag."""return Response(gen(Camera()),mimetype='multipart/x-mixed-replace; boundary=frame')#视频流检测接口
#@app.route('/livestream_start')#程序启动入口
if __name__=='__main__': files = ['uploads', 'tmp/ct', 'tmp/draw','tmp/image', 'tmp/mask', 'tmp/uploads']for ff in files:if not os.path.exists(ff):os.makedirs(ff)with app.app_context():current_app.model = Detector()app.run(host='127.0.0.1', port=5003, debug=True)

5、web ui界面

<template><el-tabs stretch=true v-model="activeName" type="card" @tab-click="handleClick"><el-tab-pane  label="图片检测" name="first"><div id="Content"><el-dialogtitle="AI预测中":visible.sync="dialogTableVisible":show-close="false":close-on-press-escape="false":append-to-body="true":close-on-click-modal="false":center="true"><el-progress :percentage="percentage"></el-progress><span slot="footer" class="dialog-footer">请耐心等待约3秒钟</span></el-dialog><div id="CT"><div id="CT_image"><el-cardid="CT_image_1"class="box-card"style="border-radius: 8px;width: 800px;height: 360px;margin-bottom: -30px;"><div class="demo-image__preview1"><divv-loading="loading"element-loading-text="上传图片中"element-loading-spinner="el-icon-loading"><el-image:src="url_1"class="image_1":preview-src-list="srcList"style="border-radius: 3px 3px 0 0"><div slot="error"><div slot="placeholder" class="error"><el-buttonv-show="showbutton"type="primary"icon="el-icon-upload"class="download_bt"v-on:click="true_upload">上传图像<inputref="upload"style="display: none"name="file"type="file"@change="update"/></el-button></div></div></el-image></div><div class="img_info_1" style="border-radius: 0 0 5px 5px"><span style="color: white; letter-spacing: 6px">原始图像</span></div></div><div class="demo-image__preview2"><divv-loading="loading"element-loading-text="处理中,请耐心等待"element-loading-spinner="el-icon-loading"><el-image:src="url_2"class="image_1":preview-src-list="srcList1"style="border-radius: 3px 3px 0 0"><div slot="error"><div slot="placeholder" class="error">{{ wait_return }}</div></div></el-image></div><div class="img_info_1" style="border-radius: 0 0 5px 5px"><span style="color: white; letter-spacing: 4px">检测结果</span></div></div></el-card></div><div id="info_patient"><!-- 卡片放置表格 --><el-card style="border-radius: 8px"><div slot="header" class="clearfix"><span>检测目标</span><el-buttonstyle="margin-left: 35px"v-show="!showbutton"type="primary"icon="el-icon-upload"class="download_bt"v-on:click="true_upload2">重新选择图像<inputref="upload2"style="display: none"name="file"type="file"@change="update"/></el-button></div><el-tabs v-model="activeName"><el-tab-pane label="检测到的目标" name="first"><!-- 表格存放特征值 --><el-table:data="feature_list"height="390"borderstyle="width: 750px; text-align: center"v-loading="loading"element-loading-text="数据正在处理中,请耐心等待"element-loading-spinner="el-icon-loading"lazy><el-table-column label="目标类别" width="250px"><template slot-scope="scope"><span>{{ scope.row[2] }}</span></template></el-table-column><el-table-column label="目标大小" width="250px"><template slot-scope="scope"><span>{{ scope.row[0] }}</span></template></el-table-column><el-table-column label="置信度" width="250px"><template slot-scope="scope"><span>{{ scope.row[1] }}</span></template></el-table-column></el-table></el-tab-pane></el-tabs></el-card></div></div></div></el-tab-pane><el-tab-pane label="视频检测" name="second"><h3>视频名称</h3><img :src="vidoedectetion"> </el-tab-pane><el-tab-pane label="视频流检测" name="third"></el-tab-pane><el-tab-pane label="多路视频流检测" name="fourth"></el-tab-pane></el-tabs></template><script>
import axios from "axios";export default {name: "Content",data() {return {vidoedectetion:"http://127.0.0.1:5003" + "/video_start",server_url: "http://127.0.0.1:5003",activeName: "first",active: 0,centerDialogVisible: true,url_1: "",url_2: "",textarea: "",srcList: [],srcList1: [],feature_list: [],feature_list_1: [],feat_list: [],url: "",visible: false,wait_return: "等待上传",wait_upload: "等待上传",loading: false,table: false,isNav: false,showbutton: true,percentage: 0,fullscreenLoading: false,opacitys: {opacity: 0,},dialogTableVisible: false,};},created: function () {document.title = "Yolov5安全帽检测web推理部署";},methods: {true_upload() {this.$refs.upload.click();},true_upload2() {this.$refs.upload2.click();},next() {this.active++;},// 获得目标文件getObjectURL(file) {var url = null;if (window.createObjcectURL != undefined) {url = window.createOjcectURL(file);} else if (window.URL != undefined) {url = window.URL.createObjectURL(file);} else if (window.webkitURL != undefined) {url = window.webkitURL.createObjectURL(file);}return url;},// 上传文件update(e) {this.percentage = 0;this.dialogTableVisible = true;this.url_1 = "";this.url_2 = "";this.srcList = [];this.srcList1 = [];this.wait_return = "";this.wait_upload = "";this.feature_list = [];this.feat_list = [];this.fullscreenLoading = true;this.loading = true;this.showbutton = false;let file = e.target.files[0];this.url_1 = this.$options.methods.getObjectURL(file);let param = new FormData(); //创建form对象param.append("file", file, file.name); //通过append向form对象添加数据var timer = setInterval(() => {this.myFunc();}, 30);let config = {headers: { "Content-Type": "multipart/form-data" },}; //添加请求头axios.post(this.server_url + "/upload", param, config).then((response) => {this.percentage = 100;clearInterval(timer);this.url_1 = response.data.image_url;this.srcList.push(this.url_1);this.url_2 = response.data.draw_url;this.srcList1.push(this.url_2);this.fullscreenLoading = false;this.loading = false;this.feat_list = Object.keys(response.data.image_info);for (var i = 0; i < this.feat_list.length; i++) {response.data.image_info[this.feat_list[i]][2] = this.feat_list[i];this.feature_list.push(response.data.image_info[this.feat_list[i]]);}this.feature_list.push(response.data.image_info);this.feature_list_1 = this.feature_list[0];this.dialogTableVisible = false;this.percentage = 0;this.notice1();});},myFunc() {if (this.percentage + 33 < 99) {this.percentage = this.percentage + 33;} else {this.percentage = 99;}},drawChart() {},notice1() {this.$notify({title: "预测成功",message: "点击图片可以查看大图",duration: 0,type: "success",});},},mounted() {this.drawChart();},
};
</script><style>
.el-button {padding: 12px 20px !important;
}#hello p {font-size: 15px !important;/*line-height: 25px;*/
}.n1 .el-step__description {padding-right: 20%;font-size: 14px;line-height: 20px;/* font-weight: 400; */
}
</style><style scoped>
* {box-sizing: border-box;margin: 0;padding: 0;
}.dialog_info {margin: 20px auto;
}.text {font-size: 14px;
}.item {margin-bottom: 18px;
}.clearfix:before,
.clearfix:after {display: table;content: "";
}.clearfix:after {clear: both;
}.box-card {width: 680px;height: 200px;border-radius: 8px;margin-top: -20px;
}.divider {width: 50%;
}#CT {display: flex;height: 100%;width: 100%;flex-wrap: wrap;justify-content: center;margin: 0 auto;margin-right: 0px;max-width: 1800px;
}#CT_image_1 {width: 90%;height: 40%;margin: 0px auto;padding: 0px auto;margin-right: 180px;margin-bottom: 0px;border-radius: 4px;
}#CT_image {margin-bottom: 60px;margin-left: 30px;margin-top: 5px;
}.image_1 {width: 275px;height: 260px;background: #ffffff;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}.img_info_1 {height: 30px;width: 275px;text-align: center;background-color: #21b3b9;line-height: 30px;
}.demo-image__preview1 {width: 250px;height: 290px;margin: 20px 60px;float: left;
}.demo-image__preview2 {width: 250px;height: 290px;margin: 20px 460px;/* background-color: green; */
}.error {margin: 100px auto;width: 50%;padding: 10px;text-align: center;
}.block-sidebar {position: fixed;display: none;left: 50%;margin-left: 600px;top: 350px;width: 60px;z-index: 99;
}.block-sidebar .block-sidebar-item {font-size: 50px;color: lightblue;text-align: center;line-height: 50px;margin-bottom: 20px;cursor: pointer;display: block;
}div {display: block;
}.block-sidebar .block-sidebar-item:hover {color: #187aab;
}.download_bt {padding: 10px 16px !important;
}#upfile {width: 104px;height: 45px;background-color: #187aab;color: #fff;text-align: center;line-height: 45px;border-radius: 3px;box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1), 0 2px 2px 0 rgba(0, 0, 0, 0.2);color: #fff;font-family: "Source Sans Pro", Verdana, sans-serif;font-size: 0.875rem;
}.file {width: 200px;height: 130px;position: absolute;left: -20px;top: 0;z-index: 1;-moz-opacity: 0;-ms-opacity: 0;-webkit-opacity: 0;opacity: 0; /*css属性&mdash;&mdash;opcity不透明度,取值0-1*/filter: alpha(opacity=0);cursor: pointer;
}#upload {position: relative;margin: 0px 0px;
}#Content {width: 85%;height: 800px;background-color: #ffffff;margin: 15px auto;display: flex;min-width: 1200px;
}.divider {background-color: #eaeaea !important;height: 2px !important;width: 100%;margin-bottom: 50px;
}.divider_1 {background-color: #ffffff;height: 2px !important;width: 100%;margin-bottom: 20px;margin: 20px auto;
}.steps {font-family: "lucida grande", "lucida sans unicode", lucida, helvetica,"Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;color: #21b3b9;text-align: center;margin: 15px auto;font-size: 20px;font-weight: bold;text-align: center;
}.step_1 {/*color: #303133 !important;*/margin: 20px 26px;
}#info_patient {margin-top: 10px;margin-right: 160px;
}
</style>

6、参考资料

yolov5-flask-web - 知乎 (zhihu.com)

Flask部署YOLOv5 - 知乎 (zhihu.com)

https://zhuanlan.zhihu.com/p/104273184

特别感谢作者

GitHub - Sharpiless/Yolov5-Flask-VUE: 基于Flask+VUE前后端,在阿里云公网WEB端部署YOLOv5目标检测模型

7、代码分享 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

字符串常量池位于JVM哪里

Java6 和6之前&#xff0c;常量池是存放在方法区&#xff08;永久代&#xff09;中的。Java7&#xff0c;将常量池是存放到了堆中。Java8 之后&#xff0c;取消了整个永久代区域&#xff0c;取而代之的是元空间。运行时常量池和静态常量池存放在元空间中&#xff0c;而字符串常…

c语言:通讯录管理系统(增删查改)

前言&#xff1a;在大多数高校内&#xff0c;都是通过设计一个通讯录管理系统来作为c语言课程设计&#xff0c;通过一个具体的系统设计将我们学习过的结构体和函数等知识糅合起来&#xff0c;可以很好的锻炼学生的编程思维&#xff0c;本文旨在为通讯录管理系统的设计提供思路和…

雷达散射截面(RCS)相关概念

一、雷达散射截面(RCS) RCS被指定为直径为1.128 m的完美导电球体的倍数。该球体的可见表面为1 m,但仅具有较小的反向散射有效面积。因此,更好的反射表面可以具有比其几何尺寸大得多的RCS。 雷达截面积 二、简单目标的RCS 简单目标的RCS如下表所示: 三、瑞利、米氏和光学…

基于SSM的家庭财务管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

SpringBoot banner 样式 自动生成

目录 SpringBoot banner 样式 自动生成 图案网站&#xff1a; 1.第一步创建banner.txt文件 2.访问网站Ascii艺术字实现个性化Spring Boot启动banner图案&#xff0c;轻松修改更换banner.txt文件内容&#xff0c;收集了丰富的banner艺术字和图&#xff0c;并且支持中文banner下…

echarts

1 type值汇总 不同的type的值对应的图表类型如下&#xff1a; type: ‘bar’&#xff1a;柱状/条形图 type: ‘line’&#xff1a;折线/面积图 type: ‘pie’&#xff1a;饼图 type: ‘scatter’&#xff1a;散点&#xff08;气泡&#xff09;图 type: ‘effectScatter’&…

ansible - Role

1、简介&#xff1a; Ansible 中的角色&#xff08;Role&#xff09;是一种组织和封装Playbook的方法&#xff0c;用于管理和组织 Ansible代码。它可以将任务和配置逻辑模块化&#xff0c;以便在不同的Playbook中共享和重用。 2、通过 role 远程部署并配置 nginx (1) 准备目…

数组(数据结构)

优质博文&#xff1a;IT-BLOG-CN 一、简介 数组Array是一种线性表数据结构&#xff0c;它用一组连续的内存空间&#xff0c;存储一组具有相同类型的数据。 数组因具有连续的内存空间的特点&#xff0c;数据拥有非常高效率的“随机访问”&#xff0c;时间复杂度为O(1)。但因要保…

ubuntu使用whisper和funASR-语者分离-二值化

文章目录 一、选择系统1.1 更新环境 二、安装使用whisper2.1 创建环境2.1 安装2.1.1安装基础包2.1.2安装依赖 3测试13测试2 语着分离创建代码报错ModuleNotFoundError: No module named pyannote报错No module named pyannote_whisper 三、安装使用funASR1 安装1.1 安装 Conda&…

黑豹程序员-架构师学习路线图-百科:Database数据库

文章目录 1、什么是Database2、发展历史3、数据库排行网4、总结 1、什么是Database 当今世界是一个充满着数据的互联网世界&#xff0c;各处都充斥着大量的数据。即这个互联网世界就是数据世界。 支撑这个数据世界的基石就是数据库&#xff0c;数据库也可以称为数据的仓库。 …

typescript开发环境搭建

typescript是基于javascript的强类型标记性语言&#xff0c;使用typescript语言可开发出不同规模的、易于扩展的web前端页面应用&#xff0c;本文主要描述typescript的开发环境搭建。 npm install -g typescript 如上所示&#xff0c;在本地开发环境中&#xff0c;使用nodejs…

基于Redis实现消息队列的实践

为什么要基于Redis实现消费队列&#xff1f; 消息队列是一种典型的发布/订阅模式&#xff0c;是专门为异步化应用和分布式系统设计的&#xff0c;具有高性能、稳定性及可伸缩性的特点&#xff0c;是开发分布式系统和应用系统必备的技术之一。目前&#xff0c;针对不同的业务场…

localhost和127.0.0.1都可以访问项目,但是本地的外网IP不能访问

使用localhost和127.0.0.1都可以访问接口&#xff0c;比如&#xff1a; http://localhost:8080/zhgl/login/login-fy-list或者 http://127.0.0.1:8080/zhgl/login/login-fy-list返回json {"_code":10000,"_msg":"Success","_data":…

Pytorch目标分类深度学习自定义数据集训练

目录 一&#xff0c;Pytorch简介&#xff1b; 二&#xff0c;环境配置&#xff1b; 三&#xff0c;自定义数据集&#xff1b; 四&#xff0c;模型训练&#xff1b; 五&#xff0c;模型验证&#xff1b; 一&#xff0c;Pytorch简介&#xff1b; PyTorch是一个开源的Python机…

淘宝商品数据分析接口,淘宝商品详情数据接口

淘宝商品数据分析接口可以通过淘宝API进行获取。 淘宝API是一种程序接口&#xff0c;通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问淘宝平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而实现淘宝平台的数据开放。 通过淘宝API提供的…

外卖小程序源码的安全性和隐私考虑

外卖小程序源码的使用正在成为数字餐饮业的主流选择之一。然而&#xff0c;随着外卖业务的增长&#xff0c;安全性和隐私保护变得至关重要。在本文中&#xff0c;我们将探讨外卖小程序源码的安全性和隐私问题&#xff0c;并提供一些代码示例&#xff0c;以帮助开发者确保其应用…

回顾C++

大一的时候学过C&#xff0c;当时学得也不深&#xff0c;考试也是糊弄过去的&#xff0c;最近刷力扣的时候&#xff0c;决定一边刷题&#xff0c;一边复习和学习C&#xff0c;在此记录一些C的知识点。反正遇到一点就记录一点&#xff0c;会一直更新。

c++解压压缩包文件

功能实现需要依赖相关头文件和库文件&#xff0c;我这里的是64位的。需要的可以在这下载&#xff1a;https://download.csdn.net/download/bangtanhui/88403596 参考代码如下&#xff1a; #include <zip.h> #pragma comment(lib,"libzip.lib")//解压压缩包 /…

性能测试笔记

一、性能测试的概念 性能测试的概念 使用自动化工具&#xff0c;模拟不同的场景&#xff0c;对软件各项性能指标进行测试和评估的过程 性能测试的目的 评估当前系统能力&#xff0c;出现性能bug后&#xff0c;优化性能&#xff1a;预测未来的性能需求是否满足 例如&#xf…

Web:前端常用的几种Http请求GET和POST样例

1、简述 在Web开发过程中&#xff0c;少不了发起Http请求服务端的接口数据&#xff0c;在不同的框架中使用了不同的Http请求方式&#xff0c;常用的请求有fetch、 ajax、 axios、XMLHttpRequest、request&#xff0c;以下样例仅供参考。 2、Fetch Fetch API 是一种 JavaScr…