Четвертая пуля AI-художника — использование Flask для выпуска API передачи стилей

искусственный интеллект TensorFlow
Четвертая пуля AI-художника — использование Flask для выпуска API передачи стилей

В последней статье был представлен flask — фреймворк, который часто используется в веб-разработке на python.Третий проект ИИ-художника — Flask, убийца выпускного дизайна, основная задача этой статьи — выполнить требования в конце предыдущей статьи и использовать Flask для публикации собственного API миграции стилей.

Исходный код этой статьи можно получить, ответив на «Style Migration API» в фоне общедоступной учетной записи WeChat «01 Binary».

анализ спроса

Мы знаем, что первым шагом в разработке программного обеспечения является анализ требований, и именно здесь нужно знать, на что похожи функции, которые нам нужно реализовать. Я нарисовал грубую диаграмму, чтобы описать это требование:

Это действительно простая картинка, на самом деле ее легко понять: пользователь загружает картинку, Flask получает картинку, вызывает модель передачи стиля, а затем генерирует результирующую картинку, которую можно передать обратно во внешний интерфейс.

Подготовка окружающей среды

Теперь, когда вы поняли требования, следующее, что нужно сделать, это построить среду.Как обычно, здесь мы по-прежнему используем Pipenv для создания виртуальной среды.Я не буду говорить, как построить среду pipenv.В предыстории WeChat публичный аккаунт "01 Binary" Ответить на "Style Migration API" и ввести исходный код прямо в терминалеpipenv installВот и все.

Начинать

hello world

Сначала мы создаем файл main.py в корневом каталоге проекта в качестве файла запуска всего проекта.Как мы сказали выше, чтобы упростить масштабные приложения и обеспечить централизованную регистрационную запись для расширений, мы не пишем все напрямую функции представления.В main.py метод blueprint используется для разработки модуля, поэтому нам нужно создать новый в корневом каталоге проектаapp/папка, в которой__init__.pyНапишите следующий код в:

from flask import Flask

def create_app():
    app = Flask(__name__)
    return app

Таким образом, мы можем реализовать приложение hello world, написав следующий код в main.py.

from app import create_app

app = create_app()

@app.route('/')
def hello():
    return 'hello,world'

if __name__ == '__main__':
    app.run(port=8080, debug=True)

Запустите main.py, чтобы узнать, что проект запущен, введите в браузереlocalhost:8080видетьhello,worldшрифт.

написание чертежей

Мы не должны довольствоваться маленьким приветом, мир.Раз уж мы говорим о модульной разработке, то что такое модульный подход?

Представления здесь у всех разные, единого стандарта на самом деле нет, здесь я расскажу о своей методике оценивания.

  • stylize — это корневой путь проекта.
  • приложение это проект
  • app/api — это API-часть проекта. Проект должен иметь не только API, но и контент страницы, такой как веб-сайт.
  • app/api/v1 указывает, что версия API v1, конечно, в будущем могут быть v2, v3 и т.д.
  • app/api/v1/img указывает, что все API, связанные с img, хранятся здесь.
  • app/api/v1/img/stylize.py указывает, что в этом файле хранится функция просмотра миграции стиля

Разобравшись с разделением структуры, давайте напишем наш план.

Сначала нам нужноapp/api/v1/img/__init__.pyНапишите следующий код в:

from flask import Blueprint

# 定义一个蓝图
img = Blueprint('img', __name__)

from app.api.v1.img import stylize

# 这段代码用来测试该接口是否可用
@img.route('/')
def say_hello():
    return '这里是图片处理类的接口'

Таким образом, мы определяем план под названием img, а затем используем его вapp/api/v1/__init__.pyНапишите следующий код в:

from flask import Blueprint

# 定义一个蓝图
v1 = Blueprint('v1', __name__)

from app.api.v1.img import img

Таким образом, мы реализовали написание плана v1.

Позволяет ли это использовать чертежи? Конечно нет, нам также нужно настроить этот план в приложении и загрузить его в приложение, иначе flask не распознает этот план. Метод загрузки также очень прост, мы находимся вapp/__init__.pyДобавьте в файл функцию:

def register_blueprint(app):
    from app.api.v1 import v1
    from app.api.v1.img import img

    app.register_blueprint(v1, url_prefix='/api/v1')
    app.register_blueprint(img, url_prefix='/api/v1/img')

Зарегистрируйте эти два чертежа в приложении, гдеurl_prefixЭтот параметр используется для маркировки маршрута. Кому-то может быть непонятно, вот пример и вы все поймете. После того, как мы запустим этот проект, ввод в браузере будетlocalhost:8080, если добавитьurl_prefixПосле этого параметра, когда мы обращаемся к функции просмотра под img, нам нужно изменить путь кlocalhost:8080/api/v1/img/.

затем вcreate_app()Этот метод можно вызвать в функции, код main.py выглядит следующим образом:

from flask import Flask


def create_app():
    app = Flask(__name__)

    register_blueprint(app)
    return app


def register_blueprint(app):
    from app.api.v1 import v1
    from app.api.v1.img import img

    app.register_blueprint(v1, url_prefix='/api/v1')
    app.register_blueprint(img, url_prefix='/api/v1/img')


if __name__ == '__main__':
    create_app()

Затем мы проверяем, действительно ли схема успешно зарегистрирована.Мы запускаем проект, открываем Postman и вводим:localhost:8080/api/v1/img, мы можем увидеть следующую информацию:

Указывает, что наш план зарегистрирован

Напишите класс инструмента передачи стиля

Теперь, когда схема написана, написание функции просмотра очень просто, поэтому здесь мы сначала напишем класс инструмента для миграции стиля и, наконец, напишем функцию просмотра.

В прошлой статье мы представили миграцию стиля изображения, если вы не помните, вы можете прочитать эту статью ?Вторая пуля рисования ИИ — передача стиля изображения, В этой статье представлена ​​наиболее традиционная передача стиля изображения. Скорость создания изображения очень и очень низкая, и ее определенно невозможно использовать на практике. Поэтому метод создания изображений передачи стиля, использованный в этой статье, не является статья основана на статье «Потери восприятия для Быстрая передача стиля изображения, реализованная с помощью передачи стиля в реальном времени и супер-разрешения. Здесь мы только представляем, как использовать обученную модель.Если вам интересно, скачайте эту статью, чтобы изучить ее самостоятельно.

Создаем новую папку:app/utils/stylize, эта папка содержит классы инструментов для миграции стилей.Структура проекта следующая:

Среди них output — это папка финальной генерации, src хранит файл для миграции стилей (можете игнорировать его), Assessment.py — файл, используемый для оценки производительности модели до (по сути, это файл, который генерирует image, не важно +1), файл training_model. В папке хранится модель, которую мы обучили, temp — изображения, которые мы загрузили из внешнего интерфейса, а create_stylize_photo.py содержит класс инструмента переноса стиля, который мы предоставляем извне.

Так что вся эта папка нам просто нужно сосредоточиться наcreate_stylize_photo.pyЭтого одного файла достаточно, а второй можно посмотреть после скачивания исходного кода.

Сжать изображения

# 压缩图片
def compress_image():
    im = Image.open(content_image)
    if content_image.endswith(".png"):
        im = im.convert('P')
    im.save(content_image, optimize=True)

Выберите стиль изображения, который является моделью, которую вы хотите использовать

style_list = ['la_muse', 'rain_princess', 'scream', 'udnie', 'wave', 'wreck']
style = style_list[int(image_style)]

# 模型的 checkpoint 的位置
check_point_dir = trained_models_path + style + '.ckpt'

Выполнение операций, которые генерируют изображения

# 最终生成的图片路径
result_image = path + '/output/' + 'output.jpg'

# 执行生成图片的操作
ffwd_to_img(content_image, result_image, check_point_dir)

После выполнения вышеуказанных действий мы можемutils/stylize/outputВы можете увидеть сгенерированное изображение передачи стиля в формате .

Используйте Qiniu Cloud для сохранения изображения результата

Из-за ограничения пропускной способности сервера, результат, который мы в конечном итоге возвращаем во внешний интерфейс, не должен быть URL-адресом нашего собственного сервера (ведь пропускная способность студенческого компьютера составляет всего 1М), поэтому здесь я предлагаю использовать функцию Облачное хранилище Qiniu, чтобы сохранить сгенерированные результаты в облаке Qiniu, а затем вернуть URL-адрес.

# 将生成的图片上传到七牛云
# 传入filename和filepath,返回图片的URL
def upload_pic_to_qiniu(filename, filepath):
    from app.secure import QINIU_AK
    from app.secure import QINIU_SK

    access_key = QINIU_AK
    secret_key = QINIU_SK

    q = Auth(access_key, secret_key)

    # 要上传的空间
    bucket_name = 'ytools'

    # 生成上传 Token,可以指定过期时间等
    token = q.upload_token(bucket_name, filename, 3600)

    ret, info = put_file(token, filename, filepath)
    return BASE_URL + ret['key']

Тогда мыcreate_stylize_photo.pyДобавьте к нему сохраненный код.

img_url = upload_pic_to_qiniu(filename, result_image)

Написание API передачи стилей

Теперь мы можем реализовать функцию ввода исходного изображения и возврата URL сгенерированного изображения через класс инструмента передачи стиля Теперь сосредоточимся на написании API передачи стиля.

определить маршруты

@img.route('/stylize/create', methods=['POST'])
def create_style_changed_img():

получить параметры

мы определяем функциюcreate_style_changed_img(), метод принимает метод POST, нам нужно принять два параметра, отправленных внешним интерфейсом, а именно img и type

img = request.files.get('img')
type = request.form.get('type')

Создание изображений и URL-адресов

Затем мы сохраняем полученный файл в ранее созданный временный файл, а затем вызываем метод класса инструмента, чтобы вернуть URL-адрес изображения.

img.save(path + '/temp/' + 'temp.jpg')

img_url = change_style(int(type))

Определите формат возврата

Как хороший API, мы должны не только возвращать URL-адрес изображения, нам также нужно записывать сгенерированное время, поэтому мы добавляем кусок кода в начале и в конце выполнения кода:

start = datetime.datetime.now()
end = datetime.datetime.now()

Затем мы определяем формат возврата

status = 200
msg = '图片生成成功'
info = [
    {
        'img_url': img_url,
        'created_time': get_date_now(),
        'finish_time': (end - start).seconds
    }
]

затем вернуть результат

res_json = Res(status, msg, info)

return jsonify(res_json.__dict__)

Res здесь — это класс возвращаемой информации об объекте, который я определил, который выглядит следующим образом.

class Res:
    status = 200
    msg = ''
    info = []

    def __init__(self, status, msg, info):
        self.status = status
        self.msg = msg
        self.info = info

Наконец, мы вызываем метод jsonify для flask, чтобы вернуть результат json.

контрольная работа

На этом мы завершили написание API миграции стилей. Теперь давайте протестируем наш API. Сначала запустите проект, затем откройте Postman, измените метод запроса на post и добавьте два параметра, img и type, следующим образом :

При выборе картинки старайтесь не делать качество картинки слишком большим, иначе может застрять.

Окончательный результат возврата выглядит следующим образом:

{
    "info": [
        {
            "created_time": "2019-05-15 15:17:25",
            "finish_time": 2,
            "img_url": "https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/5/15/16aba682a31521a7~tplv-t2oaga2asx-image.image"
        }
    ],
    "msg": "图片生成成功",
    "status": 200
}

Перейдите по URL-адресу, чтобы увидеть следующую картинку (она кажется довольно хорошей):

До сих пор мы реализовали API миграции стилей с помощью Flask.

Суммировать

Исходный код этой статьи можно получить, ответив на «Style Migration API» в фоне общедоступной учетной записи WeChat «01 Binary».

В конце этой статьи рассказывается, как использовать Flask для публикации API миграции стилей, в которой мы рассказываем, как использовать чертежи для модульной разработки, и даем то, что я считаю лучшим методом многоуровневого хранения, в то время как использование облачного хранилища Qiniu распаковывает наш сервер, и, наконец, использует postman для запроса API для завершения теста. В следующей статье будет рассказано, как развернуть API в облаке Tencent (Alibaba Cloud) для доступа к внешней сети. Заинтересованные друзья обратят внимание. Ваша поддержка — самая большая мотивация для моего обновления!