首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >当飞桨PaddleHub遇到微信小程序,AI也能指物作诗

当飞桨PaddleHub遇到微信小程序,AI也能指物作诗

作者头像
用户1386409
发布于 2020-10-27 02:45:38
发布于 2020-10-27 02:45:38
1.1K00
代码可运行
举报
文章被收录于专栏:PaddlePaddlePaddlePaddle
运行总次数:0
代码可运行

项目构想

最近飞桨PaddleHub大火,吸引无数开发者眼球,作为俗人的我也不例外,被看图写诗和艺术风格迁移两个模型吸引。假象一下,如果把AI和指物作诗的方仲永、江南四大才子之首的唐伯虎结合,会是啥样子?

在项目实施前,先给小伙伴们稍稍科普下本文中涉及的主人公。

  • 方仲永

金溪民方仲永,世隶耕。仲永生五年,未尝识书具,忽啼求之。父异焉,借旁近与之,即书诗四句,并自为其名。其诗以养父母、收族为意,传一乡秀才观之。自是指物作诗立就,其文理皆有可观者。

  • 唐伯虎

唐寅,出生于明朝庚寅年,故名唐寅,因排行老大,又称唐伯虎。二十五岁之前的唐伯虎,过着读书、游历、吟诗作画的单纯生活。据说,他画的虾,往水里一丢,就好像全都变得鲜活了。不仅如此,唐伯虎更擅长画山水和工笔人物,尤其是仕女。许多名家都称赞他的画法潇洒飘逸,冠绝一时。

我选择使用PaddleHub的 文本生成 — 看图写诗(reading_pictures_writing_poems) module,实现如金溪方仲永指物作诗、出口成章的效果;使用PaddleHub的 图像生成 — 艺术风格迁移(stylepro_artistic) module,实现看到唐伯虎的背影并达到他的画画效果。

项目地址:

https://aistudio.baidu.com/aistudio/projectdetail/920580

PaddleHub module地址:

https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=ImageClassification

项目组成

二、

整个项目分3个部分:

  1. PaddleHub Serving服务,由于需要进行推理,需要内存较大或能力突出的显卡支持。
  2. 后台服务,使用flask提供后台进行数据输入预处理,以及serving处理后的资源调度等。
  3. 微信小程序,负责微信模块展示 。

项目效果

扫描下方二维码即可体验(我会持续优化和完善,欢迎PaddleHub爱好者一同交流)

1. PaddleHub体验小程序效果:

选择模型效果→上传图片(等待20s)→ 输出AI写诗结果。

2、开发后台效果

详细代码解析

二、

1. PaddleHub Serving服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hub serving start --config config.json
(base) root@iZ2ze74yt1daioe0s04o9kZ:~/paddlehubweixinbox# cat config.json 
{
  "modules_info": {
    "stylepro_artistic": {
      "init_args": {
        "version": "1.0.0"
      },
      "predict_args": {
        "use_gpu": false
      }
    },
    "reading_pictures_writing_poems": {
      "init_args": {
        "version": "1.0.0"
      },
      "predict_args": {
        "use_gpu": false
      }
    }
  },
  "port": 8866,
  "use_multiprocess": false,
  "workers": 1
}

该命令启用上述的两个PaddleHub module serving服务。

2. Web后台

Web后台的作用一是提供看图写诗图片上传、处理,生成的诗返回;二是提供风格画图片上传、风格选择、处理,生成风格画文件路径返回。

代码如下所示:

  • 看图写诗
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# coding:utf-8
# author: Livingbody
# date: 2020.05.06

from flask import Flask, render_template, request, jsonify, Response
from werkzeug.utils import secure_filename
import os
import requests
import paddlehub as hub
import cv2
import time
from flask import Blueprint, render_template
import requests
import json
import cv2
import base64
from flask import json

index_reading_pictures = Blueprint("reading_pictures", __name__)
# 设置允许的文件格式
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'bmp', 'jpeg'])
# 当前文件所在路径
basepath = os.path.dirname(__file__)


def cv2_to_base64(image):
    data = cv2.imencode('.jpg', image)[1]
    return base64.b64encode(data.tostring()).decode('utf8')


def allowed_file(filename):
    filename = filename.lower()
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS


# 上传并写诗
@index_reading_pictures.route('/reading_pictures', methods=['POST', 'GET'])  # 添加路由
def upload():
    print(request)
    if request.method == 'POST':
        try:
            f = request.files['file']
            print(f.filename)
            if not (f and allowed_file(f.filename)):
                # return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、jpg、bmp"})
                return render_template('404.html')
            sourcefile = os.path.join('static/images/source', secure_filename(f.filename))
            print('sourcefile: %s' % sourcefile)
            upload_path = os.path.join(basepath, sourcefile)  # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
            f.save(upload_path)
            print(upload_path)
            print('upload_path: %s' % upload_path)
            results = reading_pictures(sourcefile)
            headers = {"Content-type": "application/json", "charset": "gbk"}
            # results: [{'Poetrys': '山隈山坳山,海滨岭颠海。中有无底渊,千古不可改。'}]
            # return Response(json.dumps(results), content_type='application/json')
            return jsonify(results)
        except Exception:
            return render_template('404.html')
    return render_template('poem.html')


# 读取图片
def reading_pictures(upload_path):
    print('upload_path: %s' % upload_path)
    # 指定图片分割方法为deeplabv3p_xception65_humanseg并发送post请求
    data = {'images': [cv2_to_base64(cv2.imread(upload_path))]}
    headers = {"Content-type": "application/json"}
    url = "http://localhost:8861/predict/reading_pictures_writing_poems"
    r = requests.post(url=url, headers=headers, data=json.dumps(data))
    print('request: %s' % r)
    t = time.time()
    results = r.json()["results"]
    number = results[0]['Poetrys'].count("。") - 1
    results[0]['Poetrys'] = results[0]['Poetrys'].replace("。", "。\n", number)
    print('results: %s' % results)
    return results
  • 风格画
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# coding:utf-8
# author: Livingbody
# date: 2020.05.06

from flask import Flask, render_template, request, jsonify, Response
from werkzeug.utils import secure_filename
import os
import requests
import paddlehub as hub
import cv2
import time
import numpy as np
from flask import Blueprint, render_template
import requests
import json
import cv2
import base64
from flask import json

index_stylepro_artistic = Blueprint("stylepro_artistic", __name__)
# 设置允许的文件格式
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'bmp', 'jpeg'])
# 当前文件所在路径
basepath = os.path.dirname(__file__)


def cv2_to_base64(image):
    data = cv2.imencode('.jpg', image)[1]
    return base64.b64encode(data.tostring()).decode('utf8')


def base64_to_cv2(b64str):
    data = base64.b64decode(b64str.encode('utf8'))
    data = np.fromstring(data, np.uint8)
    data = cv2.imdecode(data, cv2.IMREAD_COLOR)
    return data


def allowed_file(filename):
    filename = filename.lower()
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS


@index_stylepro_artistic.route('/stylepro_artistic', methods=['POST', 'GET'])  # 添加路由
def upload():
    print(request)
    if request.method == 'POST':
        try:
            f = request.files['file']
            print(f.filename)
            print(request.form.get('mystyle'))
            mystyle = request.form.get('mystyle')
            if not (f and allowed_file(f.filename)):
                # return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、jpg、bmp"})
                return render_template('404.html')
            sourcefile = os.path.join('static/images/source', secure_filename(f.filename))
            print('sourcefile: %s' % sourcefile)
            upload_path = os.path.join(basepath, sourcefile)  # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
            f.save(upload_path)
            results = change_pictures(sourcefile, mystyle)
            headers = {"Content-type": "application/json", "charset": "gbk"}
            return jsonify(results)
        except Exception:
            return render_template('404.html')
    return render_template('style.html')


def change_pictures(upload_path, style):
    style = 'static/images/style/' + str(style) + '.jpg'
    data = {'images': [
        {
            'content': cv2_to_base64(cv2.imread(upload_path)),
            'styles': [cv2_to_base64(cv2.imread(style))],
            # 'use_gpu': False,
            # 'visualization': True,
            # 'output_dir': 'static/images/stylepro_artistic'
        }
    ]}
    headers = {"Content-type": "application/json"}
    url = "http://localhost/predict/stylepro_artistic"
    r = requests.post(url=url, headers=headers, data=json.dumps(data))
    print('*' * 50)
    print('stylepro_artistic OK...........')


    t = time.time()
    filename = str(t) + '.jpg'
    mypath = os.path.join(basepath, 'static/images/stylepro_artistic', filename)
    cv2.imwrite(mypath, base64_to_cv2(r.json()["results"][0]['data']))
    filepath = {'save_path': os.path.join('static/images/stylepro_artistic', filename)}
    print('filepath: %s' % filepath)
return filepath

3. 微信小程序

微信小程序不难,只是流程比较繁琐,需要下面四个关键步骤:

  1. 申请小程序账号
  2. 本地开发小程序
  3. 上传小程序,并申请审核
  4. 审核通过,申请上线

小程序开发主要把握界面布局设计和API调用,然说小程序设计也是界面、js、css这三类,但是和web略有不同,有时候难以下手。

4. 其他注意事项

https配置:

微信小程序上传图片等文件仅支持SSL域名,HTTP或IP地址都不行,要注意flask的https配置,特别是证书配置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(base) root@iZ2ze74yt1daioe0s04o9kZ:~/paddlehubweixinbox# cat app.py
from flask import Flask, render_template
from flask_bootstrap import Bootstrap

# from datetime import timedelta

app = Flask(__name__)
from reading_pictures import *

app.register_blueprint(index_reading_pictures)
from stylepro_artistic import *

app.register_blueprint(index_stylepro_artistic)

Bootstrap(app)

@app.route('/', methods=['POST', 'GET'])
def index():
    return render_template('index.html')


@app.route('/error', methods=['POST', 'GET'])
def error():
    return render_template('404.html')


if __name__ == '__main__':
    app.config['JSON_AS_ASCII'] = False
    app.run(host='0.0.0.0', port=8080, debug=True,
            ssl_context=("4543112_www.livingbody.xyz.pem", "4543112_www.livingbody.xyz.key"))

负载问题:

在开始开发过程中经常莫名其妙的掉服务,究其原因是服务器比较单薄,只有2G内存,无显卡,在推理时内存溢出,后台服务挂掉,所以出问题。解决办法是将serving单独起在条件较好的服务器上。

界面设计问题:

此次小程序是我第一次接触,所以开发经验基本为“零”。在开发时,一直查文档,原生写界面。界面布局、数据传递、处理、样式表等,都是一步一步写,有的特别难看,直到后来才发现原来有界面WeUI,可以加速设计,成品可用,初步使用效果不错,感觉在小程序领域相当于web界的bootstrap,可以省去很多麻烦。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 如果需要进行持久化安装, 需要使用持久化路径, 如下方代码示例:
# If a persistence installation is required, you need to use the persistence path as the following:
!mkdir /home/aistudio/external-libraries
!pip install beautifulsoup4 -t /home/aistudio/external-libraries

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可:
# Also add the following code, so that every time the environment (kernel) starts, just run the following code:
import sys
sys.path.append('/home/aistudio/external-libraries')
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PaddlePaddle 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
flask 富文本编辑器(flask 22)
from flask_ckeditor import CKEditor, upload_success, upload_fail
用户5760343
2019/08/13
7670
flask简单上传demo
from flask import Flask, render_template, request,Response,redirect,url_for from werkzeug.utils import secure_filename import os, numpy as np, random, shutil, json app = Flask(__name__, template_folder='./html', static_url_path='') @app.route('/', methods=
一朵灼灼华
2022/08/05
4690
flask简单上传demo
Flask 入门系列教程(四)
在 WEB 应用当中,表单是和用户交互的最常见的方式之一,学习好表单,是非常重要的,用户登录注册、撰写文章等等操作都离不开表单的功能。表单的处理并不简单,除了要创建表单,还需要做相关的验证,还有错误提示等等。这些操作如果都从头开始编写,那么就太复杂了,不过幸运的是,我们有强大的 WTForms 帮助我们解决。
周萝卜
2020/10/10
1.5K0
Flask 入门系列教程(四)
深度学习应用的服务端部署
【GiantPandaCV导读】这篇文章包含与PyTorch模型部署相关的两部分内容:
BBuf
2020/10/10
1.2K0
flask 教程_python flask快速入门与进阶
Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。
全栈程序员站长
2022/09/20
2.4K0
flask dropzone整合到form里面(flask 76)
from flask import Flask, render_template, request from flask_dropzone import Dropzone
用户5760343
2019/08/20
6850
flask dropzone整合到form里面(flask 76)
Flask中的request和response
一.request from flask import request # 请求相关信息 # request.method 提交的方法 # request.args get请求提及的数据 # request.form post请求提交的数据 # request.values post和get提交的数据总和 # request.cookies 客户端所带的cookie # request.he
小小咸鱼YwY
2020/06/19
8450
flask dropzone大文件(flask 77)
from flask import Flask, render_template, request from flask_dropzone import Dropzone
用户5760343
2019/08/20
8180
flask dropzone图片上传例子(flask 71)
from flask import Flask, render_template, request from flask_dropzone import Dropzone
用户5760343
2019/08/20
6340
flask dropzone图片上传例子(flask 71)
Flask快速入门,知识整理
一、Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来)   Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。 “微”(mic
用户1214487
2018/01/24
2.1K0
Flask快速入门,知识整理
flask dropzone加csrf(flask 74)
from flask import Flask, render_template, request from flask_dropzone import Dropzone from flask_wtf.csrf import CSRFProtect, CSRFError
用户5760343
2019/08/20
5580
7.Flask文件上传
 1.1.上传文件和访问上次的文件 upload_file_demo.py from flask import Flask,request,render_template import os from werkzeug.utils import secure_filename from flask import send_from_directory app = Flask(__name__) #新建images文件夹,UPLOAD_PATH就是images的路径 UPLOAD_PATH = os.pa
zhang_derek
2018/08/01
3920
Flask基础入门学习笔记-1
描述:Flask 官方介绍Web Develoment one drop at a time,实际上它是一个基于Python开发的Web轻量级框架; 通过Flask和各种插件的配合使用,以新的框架实现Web前后端联合开发。
全栈工程师修炼指南
2020/10/23
1.7K0
Flask基础入门学习笔记-1
python智能图片识别系统(图片切割、图片识别、区别标识)
你好! python flask图片识别系统使用到的技术有:图片背景切割、图片格式转换(pdf转png)、图片模板匹配、图片区别标识。
用户6334815
2020/08/13
16.6K1
python智能图片识别系统(图片切割、图片识别、区别标识)
从0到1,Flask全网最全教学!全文1w字,蓝图、会话、日志、部署等使用Flask搭建中小型企业级项目
Flask是一个使用Python编写的轻量级Web应用框架,它简洁而灵活,适用于开发小型至中型的Web应用。本文将介绍Flask框架的基本概念、特点以及如何使用Flask来快速搭建Web应用,争取在两周内,介绍一篇企业级响应速度的轻量级python Web框架sanic和异步数据库SQLAlchemy。
小羽网安
2024/06/27
5.5K0
从0到1,Flask全网最全教学!全文1w字,蓝图、会话、日志、部署等使用Flask搭建中小型企业级项目
flask dropzone带移除和上传 常用(flask 75)
from flask import Flask, render_template, request from flask_dropzone import Dropzone
用户5760343
2019/08/20
9120
flask dropzone带移除和上传 常用(flask 75)
Flask_RESTful之API接口编写实践记录
温馨提示: 如果指定资源类没有定义支持的请求方法, 则会在请求后显示”405 METHOD NOT ALLOWED”信息。
全栈工程师修炼指南
2022/09/29
4020
Flask_RESTful之API接口编写实践记录
flask dropzone上传之后跳转(flask 72)
from flask import Flask, render_template, request from flask_dropzone import Dropzone
用户5760343
2019/08/20
8450
flask 文件上传页面(flask 21)
from flask import Flask,flash,redirect,render_template, url_for,session,send_from_directory,request import os import uuid from flask_wtf.csrf import validate_csrf from wtforms import ValidationError from form import LoginForm,UploadForm,MultiUploadForm
用户5760343
2019/08/13
1.2K0
机器视觉基础之PaddleOCR入门
1.Python安装 官网下载较慢, 可到淘宝镜像源 https://registry.npmmirror.com/binary.html?path=python/安装3.8或3.9, windows
Zeal
2022/11/08
8680
相关推荐
flask 富文本编辑器(flask 22)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档