图片分类模型训练及Web端可视化预测(下)——Web端实现可视化预测

Web端实现可视化预测

基于Flask搭建Web框架,实现HTML登录页面,编写图片上传并预测展示页面。后端实现上一篇文章所训练好的模型,进行前后端交互,选择一张图片,并将预测结果展示到页面上。

文章目录

  • Web端实现可视化预测
    • 1. 配置Flask环境
    • 2. 登录页面
    • 3. 预测页面
    • 4. 分类模型、权重及类别
    • 5. 主程序搭建及运行
      • 5.1 主程序
      • 5.2 运行
    • 6. 项目打包

1. 配置Flask环境

进入上一篇所创建的环境

conda activate pyweb
pip install flask
pip install flask_cors

下载static文件,并按以下文件夹列表进行放置
链接:https://pan.baidu.com/s/1_c6pIk8RTN-46QFm6W_O8g
提取码:i2kd
在这里插入图片描述

2. 登录页面

login.html,并放置到templates文件夹里

<!DOCTYPE html>
<html>
<head><title>Login</title><meta charset="utf-8"><link href="../static/css/style.css" rel='stylesheet' type='text/css' /><meta name="viewport" content="width=device-width, initial-scale=1"><script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
</head>
<body><!-----start-main----><div class="main"><div class="login-form"><h1>登录</h1><div class="head"><img src="../static/images/user.png" alt=""/></div><form action="/login" method="get"> <!-- 添加 action 属性并设置为登录路由 --><input type="text" class="text" name="username" value="USERNAME" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'USERNAME';}" ><input type="password" name="password" value="Password" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Password';}"><div class="submit"><input type="submit" onclick="myFunction()" value="LOGIN" ></div><p><a href="#">Forgot Password ?</a></p></form></div><!--//End-login-form--><!-----start-copyright----><div class="copy-right"><p>HHXC浩瀚星辰<a target="_blank" href=""></a></p></div><!-----//end-copyright----></div><!-----//end-main----><div style="display:none"><script src='http://v7.cnzz.com/stat.php?id=155540&web_id=155540' language='JavaScript' charset='gb2312'></script></div>
</body>
</html>

效果如下:
在这里插入图片描述

3. 预测页面

predict.html,同样放置到templates文件夹中

<!DOCTYPE html>
<html>
<head><title>Web上传图片并进行预测</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script src="{{ url_for('static', filename='js/jquery.min.js') }}"></script>
</head>
<body>
<div style="text-align: center"><h1 class="hfont">图像分类模型预测及可视化</h1></div>
<!--<h3>请选择图片文件:PNG/JPG/JPEG/SVG/GIF</h3>-->
<div style="text-align: left;margin-left:500px;margin-top:100px;" ><div style="float:left;"><a href="javascript:;" class="file">选择文件<input type="file" name="file" id="file0"><br></a><img src="" id="img0" style="margin-top:20px;width: 35rem;height: 30rem;"></div><div style="float:left;margin-left:50px;"><select id="modelSelect"><option value="AlexNet">AlexNet</option><option value="MobileNetV2">MobileNetV2</option><option value="DenseNet121">DenseNet121</option><option value="ResNet34">ResNet34</option></select><input type="button" id="b0" onclick="test()" value="预测"><pre  id="out" style="width:320px;height:50px;line-height: 50px;margin-top:20px;"></pre></div>
</div><script type="text/javascript">{#监听 file0 按钮, 并获取文件的URL #}$("#file0").change(function(){var objUrl = getObjectURL(this.files[0]) ;//获取文件信息console.log("objUrl = "+objUrl);{#将获取的图片显示到img0中#}if (objUrl) {$("#img0").attr("src", objUrl);}});function test() {var fileobj = $("#file0")[0].files[0];console.log(fileobj);var model = $("#modelSelect").val(); // 获取选择的模型名称var form = new FormData();form.append("file", fileobj);form.append("model", model); // 将选择的模型名称添加到form对象中var out='';var flower='';$.ajax({type: 'POST',url: "predict",data: form,async: false,       //同步执行processData: false, // 告诉jquery要传输data对象contentType: false, //告诉jquery不需要增加请求头对于contentType的设置success: function (arg) {console.log(arg)out = arg.result;{#console.log("out:--"+out)#}},error:function(){console.log("后台处理错误");}});out.forEach(e=>{flower+=`<div style="border-bottom: 1px solid #CCCCCC;line-height: 60px;font-size:16px;">${e}</div>`});//   out.slice(0,1).forEach(e=>{//     flower+=`<div style="border-bottom: 1px solid #CCCCCC;line-height: 60px;font-size:16px;">${e}</div>`// }); 只显示最大概率的类别document.getElementById("out").innerHTML=flower;}function getObjectURL(file) {var url = null;if(window.createObjectURL!=undefined) {url = window.createObjectURL(file) ;}else if (window.URL!=undefined) { // mozilla(firefox)url = window.URL.createObjectURL(file) ;}else if (window.webkitURL!=undefined) { // webkit or chromeurl = window.webkitURL.createObjectURL(file) ;}return url ;}
</script>
<style>.hfont{font-size: 50px; // 大小font-weight: 400; // 加粗font-family: Miscrosoft Yahei; // 字体}.file {position: relative;/*display: inline-block;*/background: #CCC ;border: 1px solid #CCC;padding: 4px 4px;overflow: hidden;text-decoration: none;text-indent: 0;width:100px;height:30px;line-height: 30px;border-radius: 5px;color: #333;font-size: 13px;}.file input {position: absolute;font-size: 13px;right: 0;top: 0;opacity: 0;border: 1px solid #333;padding: 4px 4px;overflow: hidden;text-indent: 0;width:100px;height:30px;line-height: 30px;border-radius: 5px;color: #FFFFFF;}#b0{background: #1899FF;border: 1px solid #CCC;padding: 4px 10px;overflow: hidden;text-indent: 0;width:60px;height:28px;line-height: 20px;border-radius: 5px;color: #FFFFFF;font-size: 13px;}/*.gradient{*//*filter:alpha(opacity=100 finishopacity=50 style=1 startx=0,starty=0,finishx=0,finishy=150) progid:DXImageTransform.Microsoft.gradient(startcolorstr=#fff,endcolorstr=#ccc,gradientType=0);*//*-ms-filter:alpha(opacity=100 finishopacity=50 style=1 startx=0,starty=0,finishx=0,finishy=150) progid:DXImageTransform.Microsoft.gradient(startcolorstr=#fff,endcolorstr=#ccc,gradientType=0);!*IE8*!*//*background:#1899FF; !* 一些不支持背景渐变的浏览器 *!*//*background:-moz-linear-gradient(top, #fff, #1899FF);*//*background:-webkit-gradient(linear, 0 0, 0 bottom, from(#fff), to(#ccc));*//*background:-o-linear-gradient(top, #fff, #ccc);*//*}*/
</style>
</body>
</html>

效果如下:
在这里插入图片描述

4. 分类模型、权重及类别

将上一篇训练好的模型权重,及模型代码和类别文件放置到models文件夹中

  • class_indices.json
  • mobilenet_v2.py
  • MobileNetV2.pth

如下:
在这里插入图片描述

5. 主程序搭建及运行

5.1 主程序

main.py

import os
import io
import json
import torch
import torchvision.transforms as transforms
from PIL import Image
from models.mobilenet_v2 import MobileNetV2
from flask import Flask, jsonify, request, render_template, redirect, url_for, session
from flask_cors import CORSapp = Flask(__name__)
CORS(app)  # 解决跨域问题
app.secret_key = 'super_secret_key'  # 设置一个密钥用于 session 加密@app.route("/", methods=["GET", "POST"])
def root():return render_template("login.html")@app.route("/login", methods=["GET"])
def login():print(request.args)username = request.args.get('username')password = request.args.get('password')# 简单验证用户名和密码if username == "admin" and password == "123456":return render_template("predict.html")else:return "用户名或者密码错误!重新操作!!!"# select device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
class_json_path = "models/class_indices.json"
# load class info
json_file = open(class_json_path, 'rb')
class_indict = json.load(json_file)def load_model(model_name):weights_path = "./models/{}.pth".format(model_name)assert os.path.exists(weights_path), "weights path does not exist..."assert os.path.exists(class_json_path), "class json path does not exist..."print(device)# create modelmodel = MobileNetV2(num_classes=5).to(device)# load model weightsmodel.load_state_dict(torch.load(weights_path, map_location=device))return modeldef transform_image(image_bytes):my_transforms = transforms.Compose([transforms.Resize(255),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])image = Image.open(io.BytesIO(image_bytes))if image.mode != "RGB":raise ValueError("input file does not RGB image...")return my_transforms(image).unsqueeze(0).to(device)def get_prediction(image_bytes, model_name):try:model = load_model(model_name)model.eval()tensor = transform_image(image_bytes=image_bytes)outputs = torch.softmax(model.forward(tensor).squeeze(), dim=0)prediction = outputs.detach().cpu().numpy()template = "class:{:<15} probability:{:.3f}"index_pre = [(class_indict[str(index)], float(p)) for index, p in enumerate(prediction)]# sort probabilityindex_pre.sort(key=lambda x: x[1], reverse=True)text = [template.format(k, v) for k, v in index_pre]return_info = {"result": text}except Exception as e:return_info = {"result": [str(e)]}return return_info@app.route("/predict", methods=["POST"])
@torch.no_grad()
def predict():image = request.files["file"]model_name = request.form.get('model')img_bytes = image.read()info = get_prediction(image_bytes=img_bytes, model_name=model_name)return jsonify(info)if __name__ == '__main__':app.run(debug=True)

5.2 运行

python main.py

输入用户名: admin
密码: 123456
注:这个可以在main.py中进更改,代码中又注释
在这里插入图片描述
选择图片
在这里插入图片描述
点击预测
在这里插入图片描述
预测结果展示
在这里插入图片描述

6. 项目打包

PyWeb整体项目已打包,获取方式如下:关注回复 PyWeb
在这里插入图片描述

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

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

相关文章

【Spring Security系列】权限之旅:SpringSecurity小程序登录深度探索

作者&#xff1a;后端小肥肠 创作不易&#xff0c;未经允许严禁转载。 姊妹篇&#xff1a; 【Spring Security系列】Spring SecurityJWTRedis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客 1. 前言 欢迎来到【Spring Security系列】&#xff01;在当今数字化…

海外媒体发稿的关键步骤和投稿策略:如何撰写高质量的新闻稿?国外软文发布平台有哪些?

发布国外新闻稿件是一个涉及多步骤的过程&#xff0c;旨在确保您的新闻稿能够有效覆盖目标受众。以下是一些关键步骤和实用的技巧&#xff0c;帮助你实现海外媒体发稿。 1. 明确目标和受众 首先&#xff0c;明确您发布新闻稿的目标&#xff0c;是为了增加品牌曝光、推出新产品…

【NVM】持久内存的架构

1 内存数据持久化 1.1 数据持久化 持久内存系统包含如下关键组件&#xff1a;微处理器、连接微处理器内存总线上的持久内存模组&#xff08;Persistent MemoryModule&#xff0c;PMM&#xff09;及持久内存上的非易失性存储介质。 使用持久内存来实现数据的持久化&#xff0c…

蓝牙(2):BR/EDR的连接过程;查询(发现)=》寻呼(连接)=》安全建立=》认证=》pair成功;类比WiFi连接过程。

4.2.1 BR/EDR 流程&#xff1a; 查询&#xff08;发现&#xff09;》寻呼&#xff08;连接&#xff09;》安全建立》认证》pair成功 4.2.1.1 查询&#xff08;发现&#xff09;流程Inquiry (discovering) 类比WiFi的probe request/response 蓝牙设备使用查询流程来发现附近的…

【Docker实操】启动redis服务

一、步骤 1、获取redis镜像 执行获取redis镜像命令&#xff1a;docker pull redis。打印镜像清单&#xff0c;可以看到新拉到的redis镜像。 2、创建redis.conf配置文件 linux主机 mkdir -p /root/www/redis/conf touch /root/www/redis/conf/redis.conf cat << EOF &…

vue contextPath的思考

先说我这边的情况&#xff0c;目前项目都是前后端分离开发的&#xff0c;上线有种部署方式&#xff0c;常见的就是前后端分开部署&#xff0c;这是比较常见的&#xff0c;我这边因客户原因&#xff0c;打包一起进行部署比较简单&#xff0c;交付技术运维部方便后期其他现场部署…

基于Matlab卷积神经网络人脸识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别作为计算机视觉领域的关键技术之一&#xff0c;具有广泛的应用前景&#xff0c;如安全…

“高考钉子户”唐尚珺决定再战2024年高考

“高考钉子户”唐尚珺决定在2024年再次参加高考&#xff0c;这个选择确实很特别也很有趣。十几年连续参加高考&#xff0c;他已经积累了大量的备考经验和应试技巧。这样的经验对于高考辅导机构来说无疑是非常宝贵的资源&#xff0c;他如果选择去辅导机构当老师&#xff0c;应该…

文章解读与仿真程序复现思路——电力系统保护与控制EI\CSCD\北大核心《基于改进粒子滤波的锂离子电池剩余寿命预测 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

vue 点击复制文本到剪贴板

一、首先在vue文件的template中定义复制按钮 <div size"small" v-if"item.prop jadeCode" class"cell-container"><span>{{ scope.row.jadeCode }}</span> <button click"handleCopy(scope.row.jadeCode)" clas…

告别硬编码:Spring条件注解优雅应对多类场景

一、背景 在当今的软件开发中&#xff0c;服务接口通常需要对应多个实现类&#xff0c;以满足不同的需求和场景。举例来说&#xff0c;假设我们是一家2B公司&#xff0c;公司的产品具备对象存储服务的能力。然而&#xff0c;在不同的合作机构部署时&#xff0c;发现每家公司底…

ABB 任务 模块 程序

1&#xff0c;任务由模块组成 &#xff0c; 2&#xff0c;模块分为程序模块和系统模块 3&#xff0c;可以通过新建程序模块和删除程序模块 4.可以在程序模块中构建程序 5&#xff0c;系统模块不能够被删除 6&#xff0c;main 程序主要体现在自动运行中

【Unity AR开发插件】四、制作热更数据-AR图片识别场景

专栏 本专栏将介绍如何使用这个支持热更的AR开发插件&#xff0c;快速地开发AR应用。 链接&#xff1a; Unity开发AR系列 插件简介 通过热更技术实现动态地加载AR场景&#xff0c;简化了AR开发流程&#xff0c;让用户可更多地关注Unity场景内容的制作。 “EnvInstaller…”支…

鸿蒙开发配置官方地图

一共需要配置 p12 p7b cer csr 四个文件 p12文件配置 注意创建文件名必须是.p12 到AGC创建项目 AppGallery Connect 添加自己的项目名称 我没有开启 暂时不需要 看个人需求 下载刚创建的cer证书 回到我的项目中 点击刚创建的项目 点击这里 四个文件齐全了 "metadata&qu…

Python爬取B站视频:封装一下

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…

跨境电商赛道,云手机到底能不能化繁为简?

当下国内电商背景&#xff1a; 从零售额的数据来看&#xff1a;随着互联网的普及和消费者购物习惯的改变&#xff0c;国内电商市场规模持续扩大。据相关数据显示&#xff0c;网络消费亮点纷呈&#xff0c;一季度全国网上零售额达到了3.3万亿元&#xff0c;同比增长12.4%。这表…

本地centos7+docker+ollama+gpu部署

1、一台有 NVIDIA GPU 驱动的机器 2、Docker CE安装 # 删除旧版本的 Docker&#xff08;如果存在&#xff09; sudo yum remove -y docker docker-common docker-selinux docker-engine # 安装必要的软件包&#xff1a; sudo yum install -y yum-utils device-mapper-persiste…

gpt-4o继续迭代考场安排程序 一键生成考场清单

接上两篇gpt-4o考场安排-CSDN博客&#xff0c;考场分层次安排&#xff0c;最终exe版-CSDN博客 当然你也可以只看这一篇。 今天又添加了以下功能&#xff0c;程序见后。 1、自动分页&#xff0c;每个考场打印一页 2、添加了打印试场单页眉 3、添加了页脚 第X页&#xff0c;…

基于 Java 的浏览器——JxBrowser使用分享

软件介绍 JxBrowser 是一个基于 Java 的浏览器&#xff0c;它使用 Chromium 引擎来提供高性能的网页渲染和丰富的功能。它支持多种 GUI 框架&#xff0c;如 Swing、JavaFX 和 SWT&#xff0c;使得在 Java 应用程序中嵌入浏览器组件变得简单。 JxBrowser 是一个适用于多种用途…