flask数字图像处理系统开发全流程记录(基于OpenCV)

news/2024/5/6 12:41:00/文章来源:https://blog.csdn.net/qianbin3200896/article/details/127145614

目录

  • 一、环境安装
    • 1.1 安装虚拟环境
    • 1.2 安装Flask
  • 二、搭建flask项目框架
    • 2.1 创建一个简单项目
    • 2.2 渲染html页面
    • 2.3 使用Bootstrap美化页面
    • 2.4 前后端逻辑交互
      • 2.4.1 前端实现
      • 2.4.2 后端实现
    • 三、部署
      • 3.1 Waitress工业级部署
      • 3.2 项目打包

一、环境安装

1.1 安装虚拟环境

虚拟环境是Python解释器的一个副本环境,在这个环境中可以安装其它第三方Python包,在虚拟环境中安装的Python包不会影响全局环境中的包。通过虚拟环境可以有效的做到python环境隔离,适合需要不同依赖库的python项目开发。

为了能够正常的使用虚拟环境,我们首先安装虚拟环境工具virtualenv,输入下面的命令即可完成安装:

sudo apt-get install python3-virtualenv

接下来我们可以专门建立一个文件夹phdl用于创建虚拟环境,创建虚拟环境命令如下:

virtualenv envi

创建成功结果如下所示:
请添加图片描述接下来我们需要进入到我们的虚拟环境,可以使用下面的命令:

source envi/bin/activate

此时在命令行前面会出现当前虚拟环境名称,如下图所示:
请添加图片描述表明我们已经进入到名为envi的python虚拟环境中。我们可以使用命令pip list来查看当前虚拟环境中的python库,如下所示:
请添加图片描述可以看到当前虚拟环境中很简单,只有pip、pkg-resources、setuptools和wheel几个工具库。目前这个虚拟环境是一个相当“干净”的库环境。

1.2 安装Flask

Flask是一个轻量级
进入刚才创建的虚拟环境envi,然后安装flask:

pip install flask -i https://mirror.baidu.com/pypi/simple

安装完后验证下flask是否能够正常使用,先输入python进入python环境,然后输入:

import flask查看是否报错,如果没有报错命令,说明flask成功安装并可以使用了。

二、搭建flask项目框架

2.1 创建一个简单项目

相比于另一个Python Web框架Django,Flask更“Python”化一些,因为我们可以在一个.py脚本文件中写完运行整个项目的所有代码。

我们在phdl项目下新建一个app.py文件,然后在该文件中填入主运行函数如下:

from flask import Flaskapp = Flask(__name__)@app.route('/', methods=['GET'])
def index():return "<h1>我的第一个网站</h1>"if __name__ == '__main__':app.run(host='0.0.0.0', port=5000, threaded=True,debug=True)

上面的代码开发了一个最简单的网站。我们可以先不分析具体的代码,直接执行来看一下效果。我们在终端中输入命令来启动这个项目(注意要在虚拟环境中启动):

python app.py

正常情况下输出如下所示:
请添加图片描述如果没有准确输出上面的内容,那么就要检查代码,其中注意__name__和__main__两个地方,这里前后都是两个下划线。

正常启动后我们就可以在浏览器中访问我们的这个网站,网址就在上述输出的最后一行http://127.0.0.1:5000/。效果如下图所示:
请添加图片描述

2.2 渲染html页面

在项目根目录下创建一个名为templates的文件夹,在该文件夹下创建一个home.html文件,该文件内容如下:

<!doctype html>
<html><head><meta charset="utf-8"><title>欢迎</title>
</head><body><h1>我的第一个网站</h1>
</body>

然后重新编辑app.py文件:

from flask import Flask,request,render_templateapp = Flask(__name__)@app.route('/', methods=['GET'])
def home():if request.method == 'GET':return render_template('/home.html')if __name__ == '__main__':app.run(host='0.0.0.0', port=5000, threaded=True,debug=True)

保存后重新运行,效果跟前面一样。到这里我们可以实现html页面的准确渲染。

2.3 使用Bootstrap美化页面

首先在当前项目根目录下新建static文件夹,该文件夹将作为我们的静态资源文件夹使用,专门用于存放css、js、fonts等网页需要的静态资源。接下来我们找一个免费的Bootstrap模板来作为我们的起始页面。

这里给出一个免费的Bootstrap模板下载网址:https://startbootstrap.com/template/scrolling-nav
下载后将其解压,然后将assets、css、js文件夹拷贝到static文件下下面,然后将index.html中的所有代码拷贝到我们自己的home.html文件中,然后修改home.html中相关静态资源的导入,修改方法很简单,只需要在类似css/styles.css这种引用的地方统一添加一个static目录前缀,如下所示:

/static/css/styles.css

然后我们重新启动系统,重新刷新页面后效果如下:
请添加图片描述
最后我们对这个页面做一些修改,最后样式如下所示:
请添加图片描述
其中关于样式.py-5我们在styles.css文件中对其做了一些修改,使得底部footer能够固定在底部:

.py-5 {/* padding-top: 1rem !important;padding-bottom: 1rem !important; */position:absolute;color:#fff;bottom:0;width:100%;height:100px;line-height:100px;text-align:center;background-color: #000;
}

最后还有一个问题需要解决。由于Bootstrap 的所有 JavaScript 插件都依赖 jQuery,而我们下载的这个模板中并没有提供jQuery,因此我们要下载jQuery并且放到js文件夹中并引用进来。

下载地址:https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js。将这个地址打开,然后右键页面另存为jquery.min.js,将这个jquery.min.js放在static/js目录下。最后在home.html中引用这个js:

2.4 前后端逻辑交互

本文实现的前后端交互逻辑比较简单:从页面能够上传一张图像并显示,然后单击“开始处理”按钮将图像通过put接口传给后端,后端采用opencv算法对图像进行灰度化处理,处理结果图像以base64形式返回给前端并展示。

通过这样一个流程我们就可以打通前后端之间的联系,虽然实现的图像处理功能比较简单,但是一旦走通这个流程,后面我们就可以封装更多更复杂的算法逻辑。

最终实现效果如下图所示:
请添加图片描述

2.4.1 前端实现

完整前端代码如下(home.html):

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /><meta name="description" content="" /><meta name="author" content="" /><title>数字图像处理系统</title><link rel="icon" type="image/x-icon" href="/static/assets/favicon.ico" /><!-- Core theme CSS (includes Bootstrap)--><link href="/static/css/styles.css" rel="stylesheet" /><!-- Bootstrap core JS--><script src="/static/js/jquery.min.js"></script><script src="/static/js/bootstrap.min.js"></script>
</head><body id="page-top"><!-- Navigation--><nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top" id="mainNav"><div class="container px-4"><a class="navbar-brand" href="#page-top">控制台主页</a><button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive"aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"><spanclass="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarResponsive"><ul class="navbar-nav ms-auto"><li class="nav-item"><a class="nav-link" href="#">创建项目</a></li></ul></div></div></nav><!-- Header--><header class="bg-primary bg-gradient text-white"><div class="container px-4 text-center"><h1 class="fw-bolder">数字图像处理系统</h1><p class="lead">Welcome to Digital Image Processing System</p><a class="btn btn-lg btn-light" data-toggle="modal" data-target="#myModal">测试</a></div></header><!-- 模态框(Modal) --><div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h4 class="modal-title" id="myModalLabel">图像处理</h4></div><div class="modal-body"><div class="container-fluid"><div class="row"><div class="col-md-6 col-lg-6 col-xs-6"><img id="photoIn" src="/static/img/sample.png" class="img-responsive" style="max-width:200px"><input type="file" id="photo" name="photo" /></div><div class="col-md-6 col-lg-6 col-xs-6"><img id="photoOut" class="img-responsive" style="max-width:200px"></div></div></div></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button><button type="button" id="btn_process" class="btn btn-primary" onclick="ProcessImg(this);">开始处理</button></div></div><!-- /.modal-content --></div><!-- /.modal --></div><script>$(function () {$('#photo').on('change', function () {var r = new FileReader();f = document.getElementById('photo').files[0];r.readAsDataURL(f);r.onload = function (e) {document.getElementById('photoIn').src = this.result;};});});</script><script>//模型预测function ProcessImg(obj) {//提取图像数据var str_img_data = document.getElementById('photoIn').src;var dst_img_data = document.getElementById('photoOut').src;var file = document.getElementById('photo').files[0];if (file == "") {alert("请先选择要测试的图片!");return;}//封装请求var http_request;if (window.XMLHttpRequest) {http_request = new XMLHttpRequest();}else {http_request = new ActiveXObject("Microsoft.XMLHTTP");}var idx_postfix = str_img_data.indexOf("base64,");if (idx_postfix > 0) {str_img_data = str_img_data.substring(idx_postfix + 7, str_img_data.length);}//发送数据var data = { "image_data": str_img_data, };http_request.open("POST", "/compute", false);http_request.setRequestHeader("Content-type", "application/json");http_request.send(JSON.stringify(data));//解析返回数据并显示var obj_json = eval('(' + http_request.responseText + ')');var str_img = obj_json["img64"];var str_b64_type = "data:image/png;base64,";document.getElementById('photoOut').src = str_b64_type + str_img;}</script><!-- Footer--><footer class="py-5 bg-dark"><div class="container px-4"><p class="m-0 text-center text-white">Copyright &copy; 数字图像处理系统 2022</p></div></footer></body>
</html>

2.4.2 后端实现

为了能够方便的使用数字图像处理算法,我们首先安装opencv-python:

pip install opencv-python -i https://mirror.baidu.com/pypi/simple

完整的后端处理代码如下app.py:

from flask import Flask, request, render_template
import numpy as np
import cv2
import base64app = Flask(__name__)@app.route('/', methods=['GET'])
def home():if request.method == 'GET':return render_template('/home.html')@app.route('/compute', methods=['POST',])
def compute():data = request.get_json()if request.method == 'POST':# 接收数据img_data = data['image_data']img_data = base64.b64decode(img_data)img_array = np.frombuffer(img_data, np.uint8)img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)# 图像变换gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 返回数据_, buffer_img = cv2.imencode('.png', gray)img64 = base64.b64encode(buffer_img)img64 = str(img64, encoding='utf-8')ret = {}ret["img64"] = img64return retif __name__ == '__main__':app.run(host='0.0.0.0', port=5000, threaded=True, debug=True)

到这里,我们的基本开发功能就全部结束了(虽然只搭了一个框架,但是路都打通了,后面只需要在这个基础上进行二次开发和完善即可)。

三、部署

3.1 Waitress工业级部署

前面开发过程中我们使用的是flask现成的开发服务器来启动项目的,这个开发服务器启动快、支持代码热更新,非常适合在开发过程中调试和测试页面效果。但是对于实际工业部署来说,这个开发服务器性能就不够用了,它的并发和稳定性都存在问题。因此,我们需要一个更强大的工业级服务器框架用来部署flask应用。

参照flask官网部署教程,我们使用Waitress来部署我们开发的应用。

Waitress是一个纯粹的Python WSGI服务器,它具有两大优势:

  • 易配置、易安装
  • 支持Windows

其中尤其需要注意Waitress支持windows系统来部署,这对于一些windows云服务器平台来说具有非常大的吸引力。

首先来安装Waitress。由于Waitress本质上就是一个python库,因此它的安装也只需要在虚拟环境中通过pip来安装:

pip install waitress

安装完以后我们可以在虚拟环境中使用pip list看一下当前的所有依赖库:
请添加图片描述
可以看到,目前我们的虚拟环境中的库还是比较简洁的,如果要部署到其它机器上,那么也需要提前安装好这些库(或者也可以使用docker将整个环境打包部署)。

接下来我们需要利用waitress来启动flask项目。

首先我们在项目根目录下新建一个python脚本文件run.py,内容如下:

from waitress import serve
import app
serve(app.app, host='0.0.0.0', port=5001)

然后使用下面的命令来启动项目:

python run.py

这样就完成了工业级部署了。可以说整个部署工作非常简单。

3.2 项目打包

前面的方法我们基本是用源码来进行部署,这种方式对于给甲方进行私有化部署来说就显得非常不合适了,毕竟给出了项目的完整源码,别人可以轻而易举将你辛辛苦苦开发的项目整个拷贝走。还有一个问题就是,这种部署方式需要甲方提前在他们的机器上安装好所有的依赖库环境,而且启动的时候需要输出命令行python run.py来启动。我们希望最终交给用户的部署方案是更安全、更简单的。

本小节我们使用pyinstaller来完成这样的打包部署任务。

首先安装pyinstaller:

pip install pyinstaller

在项目根目录下创建一个deploy.py文件,内容如下:

from PyInstaller.__main__ import run
import platformif __name__ == '__main__':if platform.system() == "Windows":opts = ['run.py',  # 主程序文件'-n ImageProcessSys',  # 可执行文件名称'-F',  # 打包单文件# '-w', #是否以控制台黑窗口运行r'--icon=.\Creeper.ico',  # 可执行程序图标'-y','--clean','--workpath=build','--add-data=templates;templates',  # 打包包含的html页面'--add-data=static;static',  # 打包包含的静态资源'--distpath=build','--specpath=./']run(opts)elif platform.system() == "Linux":opts = ['run.py',  # 主程序文件'-nImageProcessSys', # 可执行文件名称'-F',  # 打包单文件r'--icon=./Creeper.ico','--clean','--add-data=templates:templates',  # 打包包含的html页面'--add-data=static:static',  # 打包包含的静态资源]run(opts)else:print(platform.system())

运行这个deploy.py文件,在当前项目根目录下会生成dist和bulid文件夹,其中的dist文件夹中生成的程序就是我们最终打包部署后的程序,只需要使用命令./ImageProcessSys就能启动项目了。如果是在windows下,那么会生成ImageProcessSys.exe,双击这个exe就可以直接运行。

如果要给客户部署,那么直接把这个ImageProcessSys文件交给用户就行,用户不需要安装其它的依赖库了(只需要安装好python即可)。

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

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

相关文章

以太网交换机(计算机网络)

目录 一、以太网交换机与网桥 二、交换机与集线器 三、交换式以太网 四、以太网交换机的要点 一、以太网交换机与网桥 1、交换式集线器又称为以太网交换机(switch)或二层交换 机&#xff08;表明此交换机工作在数据链路层&#xff09;&#xff0c;或直接简称 为交换机。 2…

2022/10/4——基于stm32mp157a的A7核按键中断实验

分析电路图可知三个按键对应的管脚为&#xff1a;KEY1----->PF9 KEY2----->PF7 KEY3----->PF8 本次实验采用延时函数来解决按键按下时的电平抖动问题 功能分析如下 如上图所示 1.需要分析GPIOF章节&#xff1a;设置引脚为输入模式 2.需要分析EXTI章节&#xff1…

人工智能算法一无监督学习(Kmeas聚类)

简介 在前面介绍的线性回归还有逻辑回归它们都是知道x,y然后开始训练模型&#xff0c;这也就是有监督学习的情况&#xff0c;还有如果只是知道x不知道y的情况那么这种就是无监督学习。 描述 需求引入&#xff0c;如果有一千万用户&#xff0c;我们要对用户进行分类。这里由于…

Pytorch深度学习笔记之三(构建一个完整的神经网络)

本篇笔记是基于一个印度人写的《Pytorch深度学习》一书的第二章&#xff0c;主要用来描述一个麻雀虽小五脏俱全的完整的神经网络&#xff0c;包含了建模、训练等。原书的代码基于较老版本的Pytorch&#xff0c;有多处编译不过&#xff0c;笔者都做了调整&#xff0c;并在文末给…

几种常见的概率分布表

参考:《概率论与数理统计 第四版》

Jenkins+Maven+Gitlab+Tomcat 自动化构建打包、部署

一、环境需求 本帖针对的是Linux环境&#xff0c;Windows或其他系统也可借鉴。具体只讲述Jenkins配置以及整个流程的实现。 1.JDK&#xff08;或JRE&#xff09;及Java环境变量配置&#xff0c;我用的是JDK1.8。 2.Jenkins 持续集成和持续交付项目。 3.现有项目及gitlab&#…

Redis实战 - 03 RedisTemplate 的 hash 结构

文章目录1. put(H var1, HK var2, HV var3)2. get(H var1, Object var2)3. entries(H key)4. keys(H key)5. values(H key)6. hasKey(H key, Object var2)7. size(H key)8. putAll(H key, Map<? extends HK, ? extends HV> map)1. put(H var1, HK var2, HV var3) 新增…

机器学习之验证曲线绘制-调参可视化-sklearn

验证曲线是什么&#xff1f; 验证曲线和学习曲线的区别是&#xff0c;横轴为某个超参数的一系列值&#xff0c;由此来看不同参数设置下模型的准确率(评价标准)&#xff0c;而不是不同训练集大小下的准确率。 从验证曲线上可以看到随着超参数设置的改变&#xff0c;模型可能从…

Java Web 12.1 Filter 12.1.2 Filter 快速入门

Java Web 【黑马程序员新版JavaWeb基础教程&#xff0c;Java web从入门到企业实战完整版】 12 Filter & Listener & Ajax 文章目录Java Web12 Filter & Listener & Ajax12.1 Filter12.1.2 Filter 快速入门12.1 Filter 12.1.2 Filter 快速入门 【开发步骤】…

论如何参与一个开源项目(上)

写在前面的一些话 说起开源项目&#xff0c;好像人人都懂&#xff1a;不过就是一群人一起写了些东西&#xff0c;并且这些东西是公开的&#xff0c;大家都能看。但要细说&#xff0c;可能大多数的开发者都说不出个所以然&#xff0c;甚至不知道怎么提issue。 所以我就想写这样…

这,这,是个神人,我喜欢

国庆的第三天&#xff0c;跟一个好友聊天&#xff0c;他本来是准备回老家的&#xff0c;但是因为疫情搁浅在原地了。上来就直接给我搞一个有难度的代码如果没有人跟你说这个是输出helloworld的&#xff0c;鬼知道这个代码。然后&#xff0c;我就说我想对他进行一个采访&#xf…

QX-A51智能小车实现-物联网应用系统设计项目开发

目录介绍说明展示介绍 STC89C52系列单片机是STC推出的新一代高速/低功耗/超强抗干扰/超低价的单片机&#xff0c;指令代码完全兼容传统8051单片机&#xff0c;12时钟每机器周期和6时钟每机器周期可以任意选择 QX-A51智能小车原理图 QX-A51智能小车配置 硬件组成&#xff1a;电…

QT模型索引使用QModelIndex

QT模型索引使用QModelIndex QModelIndex有三个要素&#xff1a;行row 列column 父节点索引parent 但是注意我们并不能定义一个QModelIndex QModelIndex的构造函数QModelIndex()的功能是创建一个新的空的QModelIndex QModelIdex()是一个空索引&#xff0c;它其实可以代表任意mo…

数据库-MySQL基础(9)-多表关系

目录 概述 1、一对多 2、多对多 3、一对一 多表查询概述 多表查询分类 1、连接查询 2、子查询 概述 项目开发中&#xff0c;在进行数据库表结构关系设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析设计表结构&#xff0c;由于业务之间相互关联…

5、android 数据存储(2)(数据库SQLite:SQLiteDatabase)

1、数据库管理器SQLiteDatabase SQLiteDatabase是SQLite的数据库管理类&#xff0c;它提供了若干操作数据表的API&#xff0c;常用的方法有3类&#xff1a; 1. 管理类&#xff0c;用于数据库层面的操作。 openDatabase&#xff1a;打开指定路径的数据库。 isOpen&#xff1a…

机器学习之学习曲线绘制Python-skleran

学习曲线作用&#xff1a; 学习曲线是什么&#xff1f;简单来说&#xff0c;就是用学习曲线(learning curve)来判断模型状态&#xff1a;过拟合还是欠拟合。 学习曲线定义&#xff1a; 学习曲线是根据不同训练集大小&#xff0c;模型在训练集和验证集上的得分变化曲线。 学…

虚拟机搭建Redis 远程密码可访问,并且后台运行

1、关闭系统防火墙 操作指令备注查看防火墙状态systemctl status firewalld / firewall-cmd --state暂时关闭防火墙systemctl stop firewalld永久关闭防火墙(禁用开机自启)systemctl disable firewalld下次启动,才生效暂时开启防火墙systemctl start firewalld永久开启防火墙(…

基于python+django框架+Mysql数据库的校园新生报到系统设计与实现

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于python的校园新生报到系统&#xff0c;整体网站系统基于B/S架构&#xff0c;技术上使用基于python的Django框架来实现&#xff1b;通过后台添加设置校园信息、录入和管理校园资讯、校园风光、学校分院信…

Linux 用户管理 文件目录指令 时间日期指令 搜索查找类 解压压缩类

目录 用户管理 添加用户: 指定/修改密码 删除用户 查询用户信息指令 切换用户 查看当前用户/登录用户 用户组 修改用户的组 用户和组相关文件 指定运行级别1 指定运行级别2 找回root密码 帮助指令 文件目录指令 文件目录类 pwd 指令 ls 指令 cd 指令 mkdir指…

Android Automotive(五) CarService

Android Automotive&#xff08;五&#xff09; CarService CarService是Android Automotive在系统框架层的核心服务。它类似SystemServer在服务内部管理着数十个子服务。 启动流程 CarService是由SystemServer启动的&#xff0c;启动流程如下。 SystemServer 启动CarServi…