优化大师官网登录入口,seo入口,网站建设规划任务书,红杉树装修公司目录 1、思路
2、代码结构
3、代码运行
4、api接口代码
5、web ui界面
6、参考资料
7、代码分享 1、思路
通过搭建flask微型服务器后端#xff0c;以后通过vue搭建网页前端。flask是第一个第三方库。与其他模块一样#xff0c;安装时可以直接使用python的pip命令实现…目录 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类
appFlask(__name__) #实例化并命名为app实例
if __name____main__:app.run(port2020,host127.0.0.1,debugTrue) #调用run方法设定端口号启动服务
路由定义
from flask import Flask
appFlask(__name__)app.route(/)
def index():return welcome to my webpage!if __name____main__:app.run(port2020,host127.0.0.1,debugTrue)
通过这种方式实现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./uploadsALLOWED_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(seconds1)# 添加header解决跨域
app.after_request
def after_request(response):response.headers[Access-Control-Allow-Origin] *response.headers[Access-Control-Allow-Credentials] trueresponse.headers[Access-Control-Allow-Methods] POSTresponse.headers[Access-Control-Allow-Headers] Content-Type, X-Requested-Withreturn 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_attachmentTrue)# 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(ftmp/{file}, rb).read()response make_response(image_data)response.headers[Content-Type] image/pngreturn response#视频检测接口
def gen(camera):Video streaming generator function.while True:frame camera.get_frame()yield (b--frame\r\nbContent-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()),mimetypemultipart/x-mixed-replace; boundaryframe)#视频流检测接口
#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(host127.0.0.1, port5003, debugTrue)5、web ui界面
templateel-tabs stretchtrue v-modelactiveName typecard tab-clickhandleClickel-tab-pane label图片检测 namefirstdiv idContentel-dialogtitleAI预测中:visible.syncdialogTableVisible:show-closefalse:close-on-press-escapefalse:append-to-bodytrue:close-on-click-modalfalse:centertrueel-progress :percentagepercentage/el-progressspan slotfooter classdialog-footer请耐心等待约3秒钟/span/el-dialogdiv idCTdiv idCT_imageel-cardidCT_image_1classbox-cardstyleborder-radius: 8px;width: 800px;height: 360px;margin-bottom: -30px;div classdemo-image__preview1divv-loadingloadingelement-loading-text上传图片中element-loading-spinnerel-icon-loadingel-image:srcurl_1classimage_1:preview-src-listsrcListstyleborder-radius: 3px 3px 0 0div sloterrordiv slotplaceholder classerrorel-buttonv-showshowbuttontypeprimaryiconel-icon-uploadclassdownload_btv-on:clicktrue_upload上传图像inputrefuploadstyledisplay: nonenamefiletypefilechangeupdate//el-button/div/div/el-image/divdiv classimg_info_1 styleborder-radius: 0 0 5px 5pxspan stylecolor: white; letter-spacing: 6px原始图像/span/div/divdiv classdemo-image__preview2divv-loadingloadingelement-loading-text处理中,请耐心等待element-loading-spinnerel-icon-loadingel-image:srcurl_2classimage_1:preview-src-listsrcList1styleborder-radius: 3px 3px 0 0div sloterrordiv slotplaceholder classerror{{ wait_return }}/div/div/el-image/divdiv classimg_info_1 styleborder-radius: 0 0 5px 5pxspan stylecolor: white; letter-spacing: 4px检测结果/span/div/div/el-card/divdiv idinfo_patient!-- 卡片放置表格 --el-card styleborder-radius: 8pxdiv slotheader classclearfixspan检测目标/spanel-buttonstylemargin-left: 35pxv-show!showbuttontypeprimaryiconel-icon-uploadclassdownload_btv-on:clicktrue_upload2重新选择图像inputrefupload2styledisplay: nonenamefiletypefilechangeupdate//el-button/divel-tabs v-modelactiveNameel-tab-pane label检测到的目标 namefirst!-- 表格存放特征值 --el-table:datafeature_listheight390borderstylewidth: 750px; text-align: centerv-loadingloadingelement-loading-text数据正在处理中请耐心等待element-loading-spinnerel-icon-loadinglazyel-table-column label目标类别 width250pxtemplate slot-scopescopespan{{ scope.row[2] }}/span/template/el-table-columnel-table-column label目标大小 width250pxtemplate slot-scopescopespan{{ scope.row[0] }}/span/template/el-table-columnel-table-column label置信度 width250pxtemplate slot-scopescopespan{{ scope.row[1] }}/span/template/el-table-column/el-table/el-tab-pane/el-tabs/el-card/div/div/div/el-tab-paneel-tab-pane label视频检测 namesecondh3视频名称/h3img :srcvidoedectetion /el-tab-paneel-tab-pane label视频流检测 namethird/el-tab-paneel-tab-pane label多路视频流检测 namefourth/el-tab-pane/el-tabs/templatescript
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();},
};
/scriptstyle
.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; */
}
/stylestyle 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(opacity0);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: 基于FlaskVUE前后端在阿里云公网WEB端部署YOLOv5目标检测模型
7、代码分享