纯纯小白,3月导师叫我去搞个小程序的部署,算法才入门,前端后端毛也不懂的我勇敢冲冲!
其实我对模型部署的理解非常模糊,并不清楚它具体在干什么。然后通过一些网络学习,大概理一下思路:先把模型训练好以后,通过优化转化模型、使用推理引擎两步对模型进行infer。推理引擎:已知pytorch框架自带引擎pytorch-mobile,还有专用于移动端推理部署的引擎ncnn(不支持pytorch模型所以需要中间过渡转化)。
不过,在后续实践中上述引擎我啥也没用...
反正最后呢,我最终花一周时间实现了将pytorch模型在主机跑通,然后通过python的Web应用框架Flask提供后端服务——在局域网下,接收小程序发来的图片与用户选择的参数,调用模型进行推理,得到处理后的图片,再反馈给小程序端。
1、域名注册、备案、绑定公网ip
嗯..由于我只需要做个花架子小程序,能试跑展示效果即可,不用面向大众开放,所以这一步我并没有干。
2、flask
python web开发框架,用于实现主功能,接收小程序请求,调用模型infer,返回输出结果。
具体实现方式:
将存放模型的主机在局域网下的IP地址+固定端口号5000(当然也可以是其他)作为访问入口,供其他IP访问通信,并定义路由规则,使得其他用户通过对“http://IP地址:5000/model”发送网络请求时,调用对应的model函数。
@app.route('/model', methods=['POST', 'GET'])
def model():
if request.method == 'POST':
edit_attr = request.form.get("attr") # 从网络请求输入中获取参数
print("input edit_attr:", edit_attr)
# 从网络请求输入中获取base64编码后进行传输的图片
team_image = base64.b64decode(request.form.get("image"))
# 将图片存在代码同目录下的static文件夹中,存为11111.jpg
with open("static/111111.jpg", "wb") as f:
f.write(team_image)
# 调用我的数据对齐模型
align_111111()
# 调用我的图像处理模型
run_infer()
edit.main(editattr)
img_local_path ='static/edit/222.jpg'
# 将处理结束存在static中的222.jpg图片先base64编码再转为字符串
with open(img_local_path, 'rb') as f:
img_stream = f.read()
img_stream = str(base64.b64encode(img_stream))
# 将要返回小程序的数据存进列表中
info = {'result' : 'successfully edited!', 'editimg' : img_stream}
else:
info = {'result' : 'failed!'}
# 数据返回小程序
return json.dumps(info, ensure_ascii=False)
1、小程序注册
微信公众平台
在这里可以按照网页指示一步步注册好个人的微笑小程序账号。
2、微信开发工具下载
稳定版 Stable Build 更新日志 | 微信开放文档
在这里可以下载工具软件,图标和界面如图所示:
那个二维码就是用微信账户登陆一下开发者工具而已,不要扫哦(虽然应该没人这么无聊吧hh
3、入门
微信学堂 | 微信开放社区
在这里可以找到小程序开发的网课,入门很简单。
一些基础注意点:
(1)注释方法/** **/或者ctrl+/
(2)文件名不要用中文
简要介绍一下根目录下的结构:
├── app.js # 小程序的逻辑文件
├── app.json # 小程序的配置文件
├── app.wxss # 全局公共样式文件
├── pages # 存放小程序的各个页面,可以有很多个类似index的文件夹
│ ├── index # index页面,一般新建小程序已经作为第一页而存在,也可以任意改名字
│ │ ├── index.js # 页面逻辑,执行一些动态的修改、数据的初始化
│ │ ├── index.json
│ │ ├── index.wxml # 页面结构,设置页面内容
│ │ └── index.wxss # 页面样式表,对内容格式进行设置
├── project.config.json
└── utils
└── image # 自建文件夹,可以存放一些页面所需要的图标、图片等
我主要在app.json、index.js、index.wxml、index.wxss文件中改代码——
app.json对主页面逻辑进行设计(比如首页显示什么、底部菜单栏...);
index的所有文件就是服务于index这么一个页面的:wxss文件仅仅用来修改格式(比如颜色、居中、间隔...),wxml文件用来放内容组件(比如文字、图片、按键..),js文件用来搞各种花样经(页面切换,按键后调用什么功能...)。
这些设计就取决于你对小程序的功能预期了,每个人搞得都不太一样,就不提了。
4、向url发起请求
小程序向之前说的http://IP地址:5000/model发送网络请求,传送用户上传的图片和用户选择的参数,是通过调用各种官方API完成的:
# 小程序从相机/相册读入图片
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed']
sourceType: [that.data.sourceType[sourc]],
success(res) {
const tempFilePaths = res.tempFilePaths
wx.setStorageSync('tempFilePaths', tempFilePaths)
wx.showLoading({title: '处理中...',})
var img_manager =wx.getFileSystemManager()
# 将图片进行base64编码
var img_base64 =img_manager.readFileSync(tempFilePaths[0], "base64")
# 发送网络请求
wx.request({
url: 'http://IP地址:5000/model',
method: "POST",
header: {'content-type': "application/x-www-form-urlencoded",},
# 传入图片和之前选择好的参数
data: {image: img_base64,
attr: that.data.attrsele},
success: function (res) {
console.log(res.data.result);
# 对服务端base64编码、字符串化的图像数据进行处理
var base64Data = res.data.editimg.split("'")
let editimgurl ='data:image/jpg;base64,'+ base64Data[1]
wx.hideLoading()
# 得到结果图后,带着图像参数传入跳转页面至result页面
wx.navigateTo({
url:'/pages/result/result?image=' +tempFilePaths[0]+'&editimgurl='+editimgurl
})
}
})
}
})