1.页面效果

Web 采用 flask+vue 开发,效果图如下





2.后端

import sys
import subprocess
import os
from PIL import Image
from datetime import datetime
from ASR_metrics import utils as metricsfrom werkzeug.wrappers import Request, Response
from flask import Flask, render_template, request, jsonifysys.path.append('/home/nvidia/7th_CV')
sys.path.append('/home/nvidia/7th_ASR')# ASR 路径
pathASR = "/home/nvidia/7th_ASR"# 项目路径
pathSky = '/home/nvidia'app = Flask(__name__, static_folder='')# 上传路径
uploadPath = 'uploads/'
try_model_1 = None# 主页
@app.route('/')
def index():return render_template('sky7.html', template_folder='templates')# ------------------ASR------------------
# ASR 模型加载
@app.route('/asr/load')
def asrLoad():global try_model_1if try_model_1 == None:import nemo.collections.asr as nemo_asrprint('Loading Nemo')# 加载模型try_model_1 = nemo_asr.models.EncDecCTCModel.restore_from("/home/nvidia/7th_ASR/7th_asr_model.nemo")print('Done loading Nemo')return 'ok'# POST 请求上传音频
@app.route('/asr/upload', methods=['POST'])
def asrUpload():if request.method == 'POST':f = request.files['file']if(f.headers.get('Content-Type') != 'audio/wav'):return '音频格式有错误', 400else:fileName = f'{uploadPath}audio.wav'f.save(fileName)dt = datetime.now()ts = str(int(datetime.timestamp(dt)))return jsonify(f'/{uploadPath}audio.wav?t={ts}')# 识别上传的音频
@app.route('/asr/identify', methods=['GET', 'POST'])
def asrIdentify():global try_model_1if try_model_1 == None:return '模型无效,请重新加载', 500try:asr_result = try_model_1.transcribe(paths2audio_files=["uploads/audio.wav"])s1 = request.form.get('defaultText')s2 = " ".join(asr_result)#识别结果result = {"asr_result": asr_result,"word_error_rate": metrics.calculate_cer(s1,s2),"word_accuracy_rate":1-metrics.calculate_cer(s1,s2)}return jsonify(result)except Exception as e:return '无法识别', 400# ------------------CV------------------# POST 请求上传图片
@app.route("/cv/upload", methods=['POST'])
def cvUpload():if request.method == 'POST':f = request.files['file']print('image', f, f.filename)if not 'image' in f.headers.get('Content-Type'):return '图片有错误', 400original = f'{uploadPath}original.jpg'try:# Convert image to jpegim = Image.open(f)rgb_im = im.convert('RGB')rgb_im.save(original)# Add timestampdt = datetime.now()ts = str(int(datetime.timestamp(dt)))return jsonify(original+'?t='+ts)except Exception as e:return '有错误', 400# 检测图片
@app.route("/api/detect/image")
def detectImage():cv_results = subprocess.Popen('python3 /home/nvidia/7th_CV/detection_image.py /home/nvidia/uploads/original.jpg', shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)print('code', cv_results.returncode)cv_results = str(cv_results.stdout.read()).split('\\n')[-2]dt = datetime.now()ts = str(int(datetime.timestamp(dt)))result = {"detection_result_image_path": f'/uploads/result.jpg?t={ts}'}return jsonify(result)# 获取 FPS,以 Json 格式返回前端
@app.route("/api/detect/fps")
def detectFPS():# Code herefps_results = subprocess.Popen('python3 /home/nvidia/7th_CV/cv_fps.py', shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)fps_results = str(fps_results.stdout.read()).split('\\n')[-2]fps_results = fps_results.split(" ")[-1]result = {"detection_FPS": fps_results,}return jsonify(result)# 获取 mAP
@app.route("/api/detect/map")
def detectMAP():# Code heremap_results = subprocess.Popen('python3 /home/nvidia/7th_CV/cv_map.py', shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)map_results = str(map_results.stdout.read())bytes(map_results, encoding="utf-8").decode()map_results = map_results[-9:-3]result = {"detection_mAP": map_results,}return jsonify(result)if __name__ == "__main__":app.run(debug=True)

3.前端

3.1 html

<html><meta http-equiv="content-type" content="text/html; charset=UTF-8"><head><script src="https://unpkg.com/vue@3"></script><script src="https://unpkg.com/axios/dist/axios.min.js"></script><link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css"><script src="//unpkg.com/layui@2.6.8/dist/layui.js"></script><link rel="stylesheet" type="text/css" href="/style.css"></head><body id="app"><!-- 模型加载中 --><div class="loading" v-if="loading!=''"><div class="pad">%%loading%%</div></div><h1>7th Sky Hackathon</h1><h5>team:早八睡不醒</h5><div class="content"><div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief"><ul class="layui-tab-title"><li class="layui-this"><i class="layui-icon panel-title layui-icon">&nbsp;ASR</i></li><li><i class="layui-icon panel-title layui-icon">&nbsp;CV</i></li></ul><div class="layui-tab-content"><!-- ASR 开始--><div class="layui-tab-item layui-show"><div class="layui-anim layui-anim-up"><fieldset class="asr"><legend><span class="panel-title">ASR</span></legend><div class="layui-container"><!-- 1 开始 --><div class="layui-row"><div class="layui-col-md4">1.请加载语音识别模型</div><div class="layui-col-md4"><button class="layui-btn" @click="loadModel()" v-if="!modelLoaded"><iclass="layui-icon">&nbsp;加载</i></button><div v-if="modelLoaded" class="modelLoaded">模型加载成功</div></div></div><!-- 1 结束 --><!-- 2、3 开始 --><div class="field file"><div class="newFileUpload"><!-- 2 开始 --><div class="layui-row"><div class="layui-col-md4"><label for="file">2.请选择音频文件</label><div class="note">&nbsp;&nbsp;&nbsp;仅支持 .wav 和单声道格式</div></div><div class="layui-col-md4"><div class="userdefined-file"><input type="text" name="userdefinedFile"id="userdefinedFileAudio" value="未选择任何文件" /><button type="button">选择</button></div><input type="file" name="file" id="fileAudio"@change="handleFileUploadAudio($event)" /></div></div><!-- 2 结束 --></div><!-- 3 开始 --><div class="layui-row"><div class="layui-col-md4"> 3.请上传音频文件</div><div class="layui-col-md4"><button class="layui-btn" @click="submitFile('asr')"><iclass="layui-icon">&nbsp;上传</i></button></div></div><!-- 3 结束 --></div><!-- 2、3 结束 --><!-- 4 开始 --><div class="layui-row"><div class="field"><div class="layui-col-md4"><label>4.请试听上传语音并输入正确答案</label></div><div class="layui-col-md4"><input id="answer" type="text" name="defaultText"v-model="defaultText" /></div></div></div><!-- 4 结束 --><div class="field" v-if="asrStatus=='uploaded' || asrStatus=='identified'"><!-- 试听 开始 --><div class="layui-row"><div class="audio"><div class="layui-col-md4">&nbsp;&nbsp;&nbsp; 试听 </div><div class="layui-col-md4"><audio controls :src="audioOriginal"></audio></div></div></div><!-- 试听 结束 --><!-- 5 开始 --><div class="layui-row"><div class="layui-col-md4">5.识别语音</div><div class="layui-col-md4"><div class="action"><button class="layui-btn" @click="identifyAudio()"><iclass="layui-icon">&nbsp;识别</i></button></div></div></div><!-- 5 结束 --></div><!-- 6 开始 --><div class="layui-row"><div class="field result asr" v-if="asrStatus=='identified'"><div class="layui-col-md4">6.指标</div><div class="layui-col-md4"><ul><li v-for="(value, key) in asrResult">%%key%%: %%value%%</li></ul></div></div></div><!-- 6 结束 --></div></fieldset></div></div><!-- ASR 结束 --><!-- CV 开始 --><div class="layui-tab-item"><div class="layui-anim layui-anim-up"><fieldset class="cv"><legend><span class="panel-title">CV</span></legend><div class="layui-container"><!-- 1 开始 --><div class="field"><div class="layui-row"><div class="layui-col-md4"><p>1. 获取 FPS</p><div class="item result">&nbsp;&nbsp;&nbsp; FPS: %%cvFps%%</div></div><div class="layui-col-md4"><div class="item action"><button @click="getFps()" class="inline layui-btn"><iclass="layui-icon">&nbsp;获取</i></button></div></div></div></div><!-- 1 结束 --><!-- 2 开始 --><div class="field"><div class="layui-row"><div class="layui-col-md4"><p>2. 获取 mAP</p><div class="item result">&nbsp;&nbsp;&nbsp; mAP: %%cvMap%%</div></div><div class="layui-col-md4"><div class="item"><button @click="getMap()" class="inline layui-btn"><iclass="layui-icon">&nbsp;获取</i></button></div></div></div></div><!-- 2 结束 --><!-- 3、4 开始 --><div class="field file"><!-- 3 开始 --><div class="newFileUpload"><div class="layui-row"><div class="layui-col-md4"><label for="file">3.请选择图像文件 </label><div class="note">&nbsp;</div></div><div class="layui-col-md4"><div class="userdefined-file"><input type="text" name="userdefinedFile"id="userdefinedFileImage" value="未选择任何文件" /><button type="button">选择</button></div><input type="file" name="file" ref="file" id="fileImage"@change="handleFileUploadImage($event)" /></div></div></div><!-- 3 结束 --><!-- 4 开始 --><div class="layui-row"><div class="layui-col-md4">4.请上传图像文件 </div><div class="layui-col-md4"><button @click="submitFile('cv')" class="layui-btn"><iclass="layui-icon">&nbsp;上传</i></button></div></div><!-- 4 结束 --></div><!-- 3、4 结束 --><div class="action" v-if="imageOriginal!=''"><div class="layui-row"><div class="layui-col-md4">5.识别图片</div><div class="layui-col-md4"><button class="layui-btn" @click="identifyImage()"><iclass="layui-icon">&nbsp;识别</i></button><br></div></div></div><div class="field"><div class="layui-row"><div class="image original" v-if="imageOriginal!=''"><div class="layui-col-md1"><div class="label">原图</div></div><div class="layui-col-md3"><image :src="data:imageOriginal" /></div></div><div class="image result cv" v-if="imageResult!=''"><div class="layui-col-md1"><div class="label">结果图</div></div><div class="layui-col-md3"><image :src="data:imageResult" /></div></div></div></div></div></fieldset></div></div><!-- CV 结束 --></div></div></div></body><script>const {createApp} = VuecreateApp({data() {return {file: '',defaultText: '请检测出纸箱、瓶子和果皮',modelLoaded: false,imageOriginal: '',imageResult: '',audioOriginal: '',error: '',asrResult: {},cvMap: '',cvFps: '',loading: '',asrStatus: 'pending',cvStatus: 'pending'}},// Avoid conflict with Flask delimiterscompilerOptions: {delimiters: ["%%", "%%"]},methods: {async loadModel() {if (this.loading != '') return showError('在运行中,无法执行')this.loading = '加载模型中,请耐心等待...'this.modelLoaded = falsetry {var {data,status} = await axios.get('/asr/load')if (status == 200) {this.modelLoaded = true}} catch (err) {showError(err.response.data)}this.loading = ''},async submitFile(fileType) {let formData = new FormData()formData.append('file', this.file)if (this.file == "") {showError("请选择文件");return false;}statusType = fileType + 'Status'this.loading = '上传中...'try {var {data,status} = await axios.post('/' + fileType + '/upload', formData, {headers: {'Content-Type': 'multipart/form-data'}})if (status == 200) {this[statusType] = 'uploaded'if (fileType == 'cv') {this.imageOriginal = data} else {this.audioOriginal = data}}} catch (err) {showError(err.response.data)}this.loading = ''},handleFileUploadAudio(event) {document.getElementById("userdefinedFileAudio").value = document.getElementById("fileAudio").value;this.file = event.target.files[0];},handleFileUploadImage(event) {document.getElementById("userdefinedFileImage").value = document.getElementById("fileImage").value;this.file = event.target.files[0];},async identifyAudio(event) {// if (this.loading != '') return showError('在运行中,无法执行')this.loading = '识别中...'try {let formData = new FormData()formData.append('defaultText', this.defaultText)console.log('t', this.defaultText)var result = await axios.post('/asr/identify', formData)this['asrStatus'] = 'identified'this.asrResult = result.data} catch (err) {if (err.response.status == 500) this.modelLoaded = falseshowError(err.response.data)}this.loading = ''},async identifyImage(event) {if (this.loading != '') return showError('在运行中,无法执行')this.loading = '识别中...'this.cvStatus = 'pending'try {var {data} = await axios.get('/api/detect/image')this.imageResult = data['detection_result_image_path']} catch (err) {showError(err.response.data)}this.loading = ''},async getFps(event) {if (this.loading != '') return showError('在运行中,无法执行')this.loading = '获取 FPS...'try {var {data} = await axios.get('/api/detect/fps')this.cvFps = data['detection_FPS']} catch (err) {showError(err.response.data)}this.loading = ''},async getMap(event) {// 接口路径: /api/detect/map// 方式: GETif (this.loading != '') return showError('在运行中,无法执行')this.loading = '获取 mAP...'try {var {data} = await axios.get('/api/detect/map')this.cvMap = data['detection_mAP']} catch (err) {showError(err.response.data)}this.loading = ''}}}).mount('#app')function showError(msg) {layer.msg(msg || '错误')}</script>
</html>

3.2 CSS

body {font-size: 20px;margin: 0;
}.content {padding: 10px;margin: 40px;
}fieldset {border: 1px solid #ccc;padding: 10px;
}.modelLoaded {color: green;
}.note {color: #999;margin: 5px 0;font-size: 12px;
}.field {margin: 10px 0;
}.action {margin-top: 10px;
}.loading {position: fixed;top: 0;background: #E8F9D9;text-align: center;width: 100%;
}.pad {padding: 5px;
}.inline {display: inline-block;
}.field .item {margin: 5px 0;
}.image {display: inline-block;margin-right: 10px;
}.image img {max-height: 600px;
}/* 标题 */
h1,
h5 {margin: 40px;
}/* 队名 */
h5 {margin-left: 210px;
}/* 面板title */
.panel-title {font-size: 25px;
}/* 答案输入框 */
#answer {height: 40px;width: 200px;font-size: 14px;display: inline-block;vertical-align: middle;padding-right: 14px;padding-left: 14px;
}/* 音频文件选择 */
.newFileUpload {position: relative;height: 40px;line-height: 40px;
}.newFileUpload label {display: inline-block;
}.userdefined-file {position: absolute;top: 0;/* left: 200px; */z-index: 2;width: 300px;height: 40px;line-height: 40px;font-size: 0;/*应对子元素为 inline-block 引起的外边距*/
}.userdefined-file input[type="text"] {display: inline-block;vertical-align: middle;padding-right: 14px;padding-left: 14px;width: 220px;box-sizing: border-box;border: 1px solid #ccc;height: 40px;line-height: 40px;font-size: 14px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}.userdefined-file button {display: inline-block;vertical-align: middle;width: 80px;text-align: center;height: 40px;line-height: 40px;font-size: 14px;background-color: #009688;/* background-color: #f54; */border: none;color: #fff;cursor: pointer;
}.newFileUpload input[type="file"] {position: absolute;top: 0;/* left: 200px; */z-index: 3;opacity: 0;width: 300px;height: 40px;line-height: 40px;cursor: pointer;
}

NVIDIA 7th SkyHackathon(八)使用 Flask 与 Vue 开发 Web相关推荐

  1. python django flask介绍_Python开发WEB框架Flask详细介绍

    Flask简介 Flask是一个相对于Django而言轻量级的Web框架. 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug和模 ...

  2. NVIDIA 7th SkyHackathon(五)图像数据集的处理

    1.训练环境设置 1.1 文件地址 在使用 Tao 训练模型时,需要设置两套文件地址: USER_EXPERIMENT_DIR:docker 中的实验文档存放地址 LOCAL_PROJECT_DIR: ...

  3. NVIDIA 7th SkyHackathon(四)Nemo ASR 模型训练与评估

    1.模型加载 1.1 导入 NeMo import nemo import nemo.collection.asr as nemo_asr import torch# 检查 nemo 版本 '1.4. ...

  4. NVIDIA 7th SkyHackathon(七)Tao 目标检测模型可视化推理与导出

    1.可视化推理结果 对于训练好的模型,使用 tao 套件可进行推理,各参数如下: -o:输出文件目录,即检测过的图片保存位置 -e:训练配置文件 -m:要测试的模型 -l:推理结果的标注文件目录 -k ...

  5. Python+Vue开发Web入门实例

    其实是个夭折了的练手项目,用Python写的后端,提供json格式数据给前端Vue进行渲染 代码写的比较乱,不过还是不忍扔掉,归档记录一下吧,以后再用到了也可以做个参考 数据库 文件列表 db.py ...

  6. Vue开发Web阅读器(一)

    本项目使用vue3 初始化项目后需配置vue.config.js,官方文档:https://cli.vuejs.org/zh/config/#vue-config-js 我的暂时配置: const p ...

  7. Python+Flask+SQLite+Pytorch开发Web水稻病虫害图像识别程序

    六稻 码云代码地址 介绍 本识别项目通过对于用户所上传的水稻图片进行分析,识别出相应的病虫害,通过这种方法帮助种植用户进行虫害的识别 技术栈 开发语言 python 前端 layui,jinjia2 ...

  8. vue开发web端实现列表左右联动效果

    先谈需求:左侧为分类列表,点击分类名右侧商品列表会滑动对应分类到顶部:右侧商品列表滑动到某一分类时左侧分类列表对应分类会滑动到顶部高亮显示. 再来说说思路:1,引用swiper插件,这种方法冲突和不适 ...

  9. 6篇干货带你学会用vue开发小程序——mpvue

    #第  003 期# 前段时间,美团开源了mpvue这个项目,使得我们又多了一种用来开发小程序的框架选项.由于mpvue框架是完全基于Vue框架的(重写了其runtime和compiler),因此在用 ...

最新文章

  1. 【linux】Valgrind工具集详解(八):Memcheck命令行参数详解
  2. TEASOFT软件 | 动作帮助信息定义语法
  3. 实验三 ShellShock 攻击实验
  4. php fetchall 返回值为0_PHP实现延迟执行程序
  5. NIPS 2016 Highlighted Papers
  6. Json串和java对象进行转时
  7. C# Global.asax.cs 定时任务
  8. brew卸载jenv_使用brew,cask和jenv在MacOSX上设置多个Java JRE / JDK
  9. WeUI 为微信 Web 服务量身设计-h5前端框架
  10. 数通手稿留档——Multicast
  11. sql查询月天数之和,函数相加
  12. 百度测试开发提前批一面面经
  13. Spring Aop 源码笔记和源码阅读个人技巧分享
  14. R语言快速入门课——结合各种生物信息学及医学案例,使R语言快速入门——R软件及Rstudio下载(同步课程正在更新中)
  15. 理解苏宁:互联网转型之战
  16. 深度IP转换器高匿名8级加密企业级专用IP软件
  17. 如何在股票软件画波浪?波浪原理?初级应用画线
  18. 小呆聚合支付系统免签约即时到账多商户支付系统v6.5+监控软件+教程
  19. oracle wire protocol,WMB 8.0.0.2 在linux下面怎么配置连接ORACLE数据库
  20. 泰晤士高等教育世界大学排名(400强)—前50位

热门文章

  1. 登录百度云会员账号后如何直接下载资源?
  2. 基于AM5728 DSP+ARM自动售货机智能控制单元
  3. 机器人用的是什么编程语言
  4. 集成学习——Bagging、Boosting、Stacking
  5. 稀缺的内容和亏损的平台,中视频出路在哪?
  6. 对cpu和内存的简单理解
  7. 【GlobalMapper精品教程】032:浏览地理照片及航线信息(航测应用)
  8. 阿里安全归零实验室首度揭秘真实的“黄牛软件江湖”
  9. CPU占用率控制-编程之美初学者参考文档 1.1(上)
  10. linux运行qsql,linux系统下怎么在终端运行sql语句