216 lines
7.0 KiB
Python
216 lines
7.0 KiB
Python
#!/usr/bin/env python
|
|
|
|
import base64
|
|
import argparse
|
|
import cv2
|
|
import flask
|
|
import getopt
|
|
import gevent
|
|
import gevent.pywsgi
|
|
import glob
|
|
import h5py
|
|
import io
|
|
import math
|
|
import moviepy
|
|
import moviepy.editor
|
|
import numpy as np
|
|
import os
|
|
import random
|
|
import re
|
|
import scipy
|
|
import scipy.io
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
import torch
|
|
import torchvision
|
|
import urllib
|
|
import zipfile
|
|
from anime_3dkenburns import KenBurnsPipeline, npyframes2video, KenBurnsConfig
|
|
|
|
##########################################################
|
|
|
|
torch.set_grad_enabled(False) # make sure to not compute gradients for computational performance
|
|
torch.backends.cudnn.enabled = True # make sure to use cudnn for computational performance
|
|
|
|
KCFG = {}
|
|
KPIPE: KenBurnsPipeline = None
|
|
|
|
objPlayback = {
|
|
'strImage': None,
|
|
'npyImage': None,
|
|
'strMode': 'automatic',
|
|
'intTime': 0,
|
|
'fltTime': np.linspace(0.0, 1.0, 75).tolist() + list(reversed(np.linspace(0.0, 1.0, 75).tolist())),
|
|
'strCache': {},
|
|
'objFrom': {
|
|
'fltCenterU': 512.0,
|
|
'fltCenterV': 384.0,
|
|
'intCropWidth': 1024,
|
|
'intCropHeight': 768
|
|
},
|
|
'objTo': {
|
|
'fltCenterU': 512.0,
|
|
'fltCenterV': 384.0,
|
|
'intCropWidth': 1024,
|
|
'intCropHeight': 768
|
|
}
|
|
}
|
|
|
|
objFlask = flask.Flask(import_name=__name__, static_url_path='', static_folder=os.path.abspath('./'))
|
|
|
|
@objFlask.route(rule='/', methods=[ 'GET' ])
|
|
def index():
|
|
return objFlask.send_static_file('naive_interface.html')
|
|
# end
|
|
|
|
@objFlask.route(rule='/load_image', methods=[ 'POST' ])
|
|
def load_image():
|
|
global KCFG
|
|
|
|
objPlayback['strImage'] = flask.request.form['strFile']
|
|
objPlayback['npyImage'] = np.ascontiguousarray(cv2.imdecode(buf=np.frombuffer(base64.b64decode(flask.request.form['strData'].split(';base64,')[1]), np.uint8), flags=-1)[:, :, 0:3])
|
|
objPlayback['strCache'] = {}
|
|
|
|
KCFG = KPIPE.generate_kenburns_config(objPlayback['npyImage'], verbose=args.verbose)
|
|
return ''
|
|
# end
|
|
|
|
# @objFlask.route(rule='/autozoom', methods=[ 'POST' ])
|
|
# def autozoom():
|
|
# objPlayback['objFrom'] = {
|
|
# 'fltCenterU': 512.0,
|
|
# 'fltCenterV': 384.0,
|
|
# 'intCropWidth': 1000,
|
|
# 'intCropHeight': 750
|
|
# }
|
|
|
|
# objPlayback['objTo'] = process_autozoom({
|
|
# 'fltShift': 100.0,
|
|
# 'fltZoom': 1.25,
|
|
# 'objFrom': objPlayback['objFrom']
|
|
# }, KCFG)
|
|
|
|
# return flask.jsonify({
|
|
# 'objFrom': objPlayback['objFrom'],
|
|
# 'objTo': objPlayback['objTo']
|
|
# })
|
|
# # end
|
|
|
|
@objFlask.route(rule='/update_mode', methods=[ 'POST' ])
|
|
def update_mode():
|
|
objPlayback['strMode'] = flask.request.form['strMode']
|
|
|
|
return ''
|
|
# end
|
|
|
|
@objFlask.route(rule='/update_from', methods=[ 'POST' ])
|
|
def update_from():
|
|
objPlayback['intTime'] = objPlayback['fltTime'].index(0.0)
|
|
objPlayback['strCache'] = {}
|
|
objPlayback['objFrom']['fltCenterU'] = float(flask.request.form['fltCenterU'])
|
|
objPlayback['objFrom']['fltCenterV'] = float(flask.request.form['fltCenterV'])
|
|
objPlayback['objFrom']['intCropWidth'] = int(flask.request.form['intCropWidth'])
|
|
objPlayback['objFrom']['intCropHeight'] = int(flask.request.form['intCropHeight'])
|
|
|
|
return ''
|
|
# end
|
|
|
|
@objFlask.route(rule='/update_to', methods=[ 'POST' ])
|
|
def update_to():
|
|
objPlayback['intTime'] = objPlayback['fltTime'].index(1.0)
|
|
objPlayback['strCache'] = {}
|
|
objPlayback['objTo']['fltCenterU'] = float(flask.request.form['fltCenterU'])
|
|
objPlayback['objTo']['fltCenterV'] = float(flask.request.form['fltCenterV'])
|
|
objPlayback['objTo']['intCropWidth'] = int(flask.request.form['intCropWidth'])
|
|
objPlayback['objTo']['intCropHeight'] = int(flask.request.form['intCropHeight'])
|
|
|
|
return ''
|
|
# end
|
|
|
|
@objFlask.route(rule='/get_live', methods=[ 'GET' ])
|
|
def get_live():
|
|
def generator():
|
|
fltFramelimiter = 0.0
|
|
|
|
while True:
|
|
for intYield in range(100): gevent.sleep(0.0)
|
|
|
|
gevent.sleep(max(0.0, (1.0 / 25.0) - (time.time() - fltFramelimiter))); fltFramelimiter = time.time()
|
|
|
|
if objPlayback['strImage'] is None:
|
|
yield b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + cv2.imencode(ext='.jpg', img=np.ones([ 768, 1024, 3 ], np.uint8) * 29, params=[ cv2.IMWRITE_JPEG_QUALITY, 80 ])[1].tobytes() + b'\r\n'; continue
|
|
# end
|
|
|
|
if objPlayback['intTime'] > len(objPlayback['fltTime']) - 1:
|
|
objPlayback['intTime'] = 0
|
|
# end
|
|
|
|
intTime = objPlayback['intTime']
|
|
fltTime = objPlayback['fltTime'][intTime]
|
|
|
|
if objPlayback['strMode'] == 'automatic':
|
|
objPlayback['intTime'] += 1
|
|
# end
|
|
|
|
if str(fltTime) not in objPlayback['strCache']:
|
|
# Debug by Francis
|
|
npyKenburns,_ = KPIPE.process_kenburns({
|
|
'fltSteps': [ fltTime ],
|
|
'objFrom': objPlayback['objFrom'],
|
|
'objTo': objPlayback['objTo'],
|
|
'boolInpaint': False
|
|
}, KCFG, inpaint=False)[0]
|
|
|
|
objPlayback['strCache'][str(fltTime)] = b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + cv2.imencode(ext='.jpg', img=npyKenburns, params=[ cv2.IMWRITE_JPEG_QUALITY, 80 ])[1].tobytes() + b'\r\n'
|
|
# end
|
|
|
|
yield objPlayback['strCache'][str(fltTime)]
|
|
# end
|
|
# end
|
|
|
|
return flask.Response(response=generator(), mimetype='multipart/x-mixed-replace; boundary=frame')
|
|
# end
|
|
|
|
@objFlask.route(rule='/get_result', methods=[ 'GET' ])
|
|
def get_result():
|
|
# strTempdir = tempfile.gettempdir() + '/kenburns-' + str(os.getpid()) + '-' + str.join('', [ random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for intCount in range(8) ]) + '-' + str(time.time()).split('.')[-1]
|
|
|
|
# os.makedirs(name=strTempdir + '/', exist_ok=False)
|
|
print('###########################################')
|
|
print(objPlayback['objFrom'])
|
|
print(objPlayback['objTo'])
|
|
|
|
# Debug by Francis
|
|
npyKenburns,_ = KPIPE.process_kenburns({
|
|
'fltSteps': np.linspace(0.0, 1.0, 75).tolist(),
|
|
'objFrom': objPlayback['objFrom'],
|
|
'objTo': objPlayback['objTo'],
|
|
'boolInpaint': True
|
|
}, KCFG)
|
|
|
|
moviepy.editor.ImageSequenceClip(sequence=[ npyFrame[:, :, ::-1] for npyFrame in npyKenburns + list(reversed(npyKenburns))[1:-1] ], fps=25).write_videofile('interface_kenburns.mp4', preset='placebo')
|
|
|
|
|
|
return ''
|
|
# objKenburns = io.BytesIO(open(strTempdir + '/kenburns.mp4', 'rb').read())
|
|
|
|
# shutil.rmtree(strTempdir + '/')
|
|
|
|
# return flask.send_file(path_or_file=objKenburns, mimetype='video/mp4', as_attachment=True, download_name='kenburns.mp4')
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
parser = argparse.ArgumentParser(description='Anime Character Instance Segmentation')
|
|
|
|
parser.add_argument('--cfg', type=str, default=None, help='KenBurns config file path')
|
|
parser.add_argument('--verbose', action='store_true')
|
|
args = parser.parse_args()
|
|
|
|
KPIPE = KenBurnsPipeline(args.cfg)
|
|
print(f'running on http://localhost:8080')
|
|
gevent.pywsgi.WSGIServer(listener=('0.0.0.0', 8080), application=objFlask).serve_forever()
|