未验证 提交 ac2e7e6e 编写于 作者: W wuyefeilin 提交者: GitHub

update APP by ID photo DIY (#5698)

LGTM
上级 d4622844
import codecs
import os
import sys
import time
import zipfile
import gradio as gr import gradio as gr
import numpy as np import numpy as np
import cv2
import requests
import yaml
from paddle.inference import Config as PredictConfig
from paddle.inference import create_predictor
lasttime = time.time()
FLUSH_INTERVAL = 0.1
def progress(str, end=False):
global lasttime
if end:
str += "\n"
lasttime = 0
if time.time() - lasttime >= FLUSH_INTERVAL:
sys.stdout.write("\r%s" % str)
lasttime = time.time()
sys.stdout.flush()
def _download_file(url, savepath, print_progress=True):
if print_progress:
print("Connecting to {}".format(url))
r = requests.get(url, stream=True, timeout=15)
total_length = r.headers.get('content-length')
if total_length is None:
with open(savepath, 'wb') as f:
shutil.copyfileobj(r.raw, f)
else:
with open(savepath, 'wb') as f:
dl = 0
total_length = int(total_length)
starttime = time.time()
if print_progress:
print("Downloading %s" % os.path.basename(savepath))
for data in r.iter_content(chunk_size=4096):
dl += len(data)
f.write(data)
if print_progress:
done = int(50 * dl / total_length)
progress("[%-50s] %.2f%%" %
('=' * done, float(100 * dl) / total_length))
if print_progress:
progress("[%-50s] %.2f%%" % ('=' * 50, 100), end=True)
def uncompress(path):
files = zipfile.ZipFile(path, 'r')
filelist = files.namelist()
rootpath = filelist[0]
for file in filelist:
files.extract(file, './')
class DeployConfig:
def __init__(self, path):
with codecs.open(path, 'r', 'utf-8') as file:
self.dic = yaml.load(file, Loader=yaml.FullLoader)
self._dir = os.path.dirname(path)
@property
def model(self):
return os.path.join(self._dir, self.dic['Deploy']['model'])
@property
def params(self):
return os.path.join(self._dir, self.dic['Deploy']['params'])
class Predictor:
def __init__(self, cfg):
"""
Prepare for prediction.
The usage and docs of paddle inference, please refer to
https://paddleinference.paddlepaddle.org.cn/product_introduction/summary.html
"""
self.cfg = DeployConfig(cfg)
self._init_base_config() import utils
from predict import build_predictor
self._init_cpu_config() IMAGE_DEMO = "./images/idphoto.jpg"
predictor = build_predictor()
sizes_play = utils.size_play()
self.predictor = create_predictor(self.pred_cfg)
def _init_base_config(self): def get_output(img, size, bg, download_size):
self.pred_cfg = PredictConfig(self.cfg.model, self.cfg.params)
self.pred_cfg.enable_memory_optim()
self.pred_cfg.switch_ir_optim(True)
def _init_cpu_config(self):
"""
Init the config for x86 cpu.
""" """
self.pred_cfg.disable_gpu() Get the special size and background photo.
self.pred_cfg.set_cpu_math_library_num_threads(10)
def _preprocess(self, img):
# resize short edge to 512.
h, w = img.shape[:2]
short_edge = min(h, w)
scale = 512 / short_edge
h_resize = int(round(h * scale)) // 32 * 32
w_resize = int(round(w * scale)) // 32 * 32
img = cv2.resize(img, (w_resize, h_resize))
img = (img / 255 - 0.5) / 0.5
img = np.transpose(img, [2, 0, 1])[np.newaxis, :]
return img
def run(self, img):
input_names = self.predictor.get_input_names()
input_handle = {}
for i in range(len(input_names)):
input_handle[input_names[i]] = self.predictor.get_input_handle(
input_names[i])
output_names = self.predictor.get_output_names()
output_handle = self.predictor.get_output_handle(output_names[0])
img_inputs = img.astype('float32')
ori_h, ori_w = img_inputs.shape[:2]
img_inputs = self._preprocess(img=img_inputs)
input_handle['img'].copy_from_cpu(img_inputs)
self.predictor.run() Args:
img(numpy:ndarray): The image array.
size(str): The size user specified.
bg(str): The background color user specified.
download_size(str): The size for image saving.
results = output_handle.copy_to_cpu() """
alpha = results.squeeze() alpha = predictor.run(img)
alpha = cv2.resize(alpha, (ori_w, ori_h)) res = utils.bg_replace(img, alpha, bg_name=bg)
alpha = (alpha * 255).astype('uint8')
return alpha
def model_inference(image):
# Download inference model
url = 'https://paddleseg.bj.bcebos.com/matting/models/deploy/ppmatting-hrnet_w18-human_512.zip'
savepath = './ppmatting-hrnet_w18-human_512.zip'
if not os.path.exists('./ppmatting-hrnet_w18-human_512'):
_download_file(url=url, savepath=savepath)
uncompress(savepath)
# Inference
predictor = Predictor(cfg='./ppmatting-hrnet_w18-human_512/deploy.yaml')
alpha = predictor.run(image)
return alpha size_index = sizes_play.index(size)
res = utils.adjust_size(res, size_index)
res_download = utils.download(res, download_size)
return res, res_download
def clear_all(): def download(img, size):
return None, None utils.download(img, size)
return None
with gr.Blocks() as demo: with gr.Blocks() as demo:
gr.Markdown("Objective Detection") gr.Markdown("""# ID Photo DIY""")
with gr.Column(scale=1, min_width=100):
img_in = gr.Image( img_in = gr.Image(value=IMAGE_DEMO, label="Input image")
value="https://paddleseg.bj.bcebos.com/matting/demo/human.jpg", gr.Markdown(
label="Input") """<font color=Gray>Tips: Please upload photos with good posture, center portrait, crown free, no jewelry, ears and eyebrows exposed.</font>"""
)
with gr.Row():
size = gr.Dropdown(sizes_play, label="Sizes", value=sizes_play[0])
bg = gr.Radio(
["White", "Red", "Blue"], label="Background color", value='White')
download_size = gr.Radio(
["Small", "Middle", "Large"],
label="File size (affects image quality)",
value='Large',
interactive=True)
with gr.Row(): with gr.Row():
btn1 = gr.Button("Clear") btn1 = gr.Button("Clear")
btn2 = gr.Button("Submit") btn2 = gr.Button("Submit")
img_out = gr.Image(label="Output").style(height=200) img_out = gr.Image(
label="Output image", interactive=False).style(height=300)
f1 = gr.File(label='Image download').style(height=50)
with gr.Row():
gr.Markdown(
"""<font color=Gray>This application is supported by [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg).
If you have any questions or feature requists, welcome to raise issues on [GitHub](https://github.com/PaddlePaddle/PaddleSeg/issues). BTW, a star is a great encouragement for us, thanks! ^_^</font>"""
)
btn2.click(
fn=get_output,
inputs=[img_in, size, bg, download_size],
outputs=[img_out, f1])
btn1.click(
fn=utils.clear_all,
inputs=None,
outputs=[img_in, img_out, size, bg, download_size, f1])
btn2.click(fn=model_inference, inputs=img_in, outputs=[img_out])
btn1.click(fn=clear_all, inputs=None, outputs=[img_in, img_out])
gr.Button.style(1) gr.Button.style(1)
demo.launch() demo.launch(share=True)
import os
import sys
import time
import requests
import zipfile
FLUSH_INTERVAL = 0.1
lasttime = time.time()
def progress(str, end=False):
global lasttime
if end:
str += "\n"
lasttime = 0
if time.time() - lasttime >= FLUSH_INTERVAL:
sys.stdout.write("\r%s" % str)
lasttime = time.time()
sys.stdout.flush()
def download_file(url, savepath, print_progress=True):
if print_progress:
print("Connecting to {}".format(url))
r = requests.get(url, stream=True, timeout=15)
total_length = r.headers.get('content-length')
if total_length is None:
with open(savepath, 'wb') as f:
shutil.copyfileobj(r.raw, f)
else:
with open(savepath, 'wb') as f:
dl = 0
total_length = int(total_length)
starttime = time.time()
if print_progress:
print("Downloading %s" % os.path.basename(savepath))
for data in r.iter_content(chunk_size=4096):
dl += len(data)
f.write(data)
if print_progress:
done = int(50 * dl / total_length)
progress("[%-50s] %.2f%%" %
('=' * done, float(100 * dl) / total_length))
if print_progress:
progress("[%-50s] %.2f%%" % ('=' * 50, 100), end=True)
def uncompress(path):
files = zipfile.ZipFile(path, 'r')
filelist = files.namelist()
rootpath = filelist[0]
for file in filelist:
files.extract(file, './')
import os
import codecs
import numpy as np
import cv2
import yaml
from paddle.inference import Config as PredictConfig
from paddle.inference import create_predictor
from download import download_file, uncompress
URL = 'https://paddleseg.bj.bcebos.com/matting/models/deploy/ppmatting-hrnet_w18-human_512.zip'
SAVEPATH = './ppmatting-hrnet_w18-human_512.zip'
class DeployConfig:
def __init__(self, path):
with codecs.open(path, 'r', 'utf-8') as file:
self.dic = yaml.load(file, Loader=yaml.FullLoader)
self._dir = os.path.dirname(path)
@property
def model(self):
return os.path.join(self._dir, self.dic['Deploy']['model'])
@property
def params(self):
return os.path.join(self._dir, self.dic['Deploy']['params'])
class Predictor:
def __init__(self, cfg):
"""
Prepare for prediction.
The usage and docs of paddle inference, please refer to
https://paddleinference.paddlepaddle.org.cn/product_introduction/summary.html
"""
self.cfg = DeployConfig(cfg)
self._init_base_config()
self._init_cpu_config()
self.predictor = create_predictor(self.pred_cfg)
def _init_base_config(self):
self.pred_cfg = PredictConfig(self.cfg.model, self.cfg.params)
self.pred_cfg.enable_memory_optim()
self.pred_cfg.switch_ir_optim(True)
def _init_cpu_config(self):
"""
Init the config for x86 cpu.
"""
self.pred_cfg.disable_gpu()
self.pred_cfg.set_cpu_math_library_num_threads(10)
def _preprocess(self, img):
# resize short edge to 512.
h, w = img.shape[:2]
short_edge = min(h, w)
scale = 512 / short_edge
h_resize = int(round(h * scale)) // 32 * 32
w_resize = int(round(w * scale)) // 32 * 32
img = cv2.resize(img, (w_resize, h_resize))
img = (img / 255 - 0.5) / 0.5
img = np.transpose(img, [2, 0, 1])[np.newaxis, :]
return img
def run(self, img):
input_names = self.predictor.get_input_names()
input_handle = {}
for i in range(len(input_names)):
input_handle[input_names[i]] = self.predictor.get_input_handle(
input_names[i])
output_names = self.predictor.get_output_names()
output_handle = self.predictor.get_output_handle(output_names[0])
img_inputs = img.astype('float32')
ori_h, ori_w = img_inputs.shape[:2]
img_inputs = self._preprocess(img=img_inputs)
input_handle['img'].copy_from_cpu(img_inputs)
self.predictor.run()
results = output_handle.copy_to_cpu()
alpha = results.squeeze()
alpha = cv2.resize(alpha, (ori_w, ori_h))
alpha = (alpha * 255).astype('uint8')
return alpha
def build_predictor():
# Download inference model
if not os.path.exists('./ppmatting-hrnet_w18-human_512'):
download_file(url=URL, savepath=SAVEPATH)
uncompress(SAVEPATH)
cfg = os.path.join(os.path.splitext(SAVEPATH)[0], 'deploy.yaml')
predictor = Predictor(cfg)
return predictor
...@@ -2,3 +2,4 @@ gradio ...@@ -2,3 +2,4 @@ gradio
paddlepaddle paddlepaddle
opencv-python opencv-python
pyyaml >= 5.1 pyyaml >= 5.1
pymatting
\ No newline at end of file
import os
import time
from collections import OrderedDict
import numpy as np
import pymatting
import cv2
from PIL import Image
SIZES = OrderedDict({
"1 inch": {
'physics': (25, 35),
'pixels': (295, 413)
},
"1 inch smaller": {
'physics': (22, 32),
'pixels': (260, 378)
},
"1 inch larger": {
'physics': (33, 48),
'pixels': (390, 567)
},
"2 inches": {
'physics': (35, 49),
'pixels': (413, 579)
},
"2 inches smaller": {
'physics': (35, 45),
'pixels': (413, 531)
},
"2 inches larger": {
'physics': (35, 53),
'pixels': (413, 626)
},
"3 inches": {
'physics': (55, 84),
'pixels': (649, 991)
},
"4 inches": {
'physics': (76, 102),
'pixels': (898, 1205)
},
"5 inches": {
'physics': (89, 127),
'pixels': (1050, 1500)
}
})
# R, G, B
COLOR_MAP = {
'White': [255, 255, 255],
'Blue': [0, 191, 243],
'Red': [255, 0, 0]
}
# jpg compress ratio
SAVE_SIZE = {'Small': 50, 'Middle': 75, 'Large': 95}
def delete_result():
"""clear old result in `.temp`"""
root = '.temp'
results = sorted(os.listdir(root))
for res in results:
if int(time.time()) - int(os.path.splitext(res)[0]) > 10000:
os.remove(os.path.join(root, res))
def clear_all():
delete_result()
return None, None, size_play()[0], 'White', 'Large', None
def size_play():
sizes = []
for k, v in SIZES.items():
size = ''.join([
k, '(', str(v['physics'][0]), 'x', str(v['physics'][1]), 'mm,',
str(v['pixels'][0]), 'x', str(v['pixels'][1]), 'px)'
])
sizes.append(size)
return sizes
def bg_replace(img, alpha, bg_name):
bg = COLOR_MAP[bg_name]
bg = np.array(bg)[None, None, :]
alpha = alpha / 255.
pymatting.estimate_foreground_ml(img / 255., alpha) * 255
alpha = alpha[:, :, None]
res = alpha * img + (1 - alpha) * bg
return res.astype('uint8')
def adjust_size(img, size_index):
key = list(SIZES.keys())[size_index]
w_o, h_o = SIZES[key]['pixels']
# scale
h_ori, w_ori = img.shape[:2]
scale = max(w_o / w_ori, h_o / h_ori)
if scale > 1:
interpolation = cv2.INTER_CUBIC
else:
interpolation = cv2.INTER_AREA
img_scale = cv2.resize(
img, dsize=None, fx=scale, fy=scale, interpolation=interpolation)
# crop
h_scale, w_scale = img_scale.shape[:2]
h_cen = h_scale // 2
w_cen = w_scale // 2
h_start = max(0, h_cen - h_o // 2)
h_end = min(h_scale, h_start + h_o)
w_start = max(0, w_cen - w_o // 2)
w_end = min(w_scale, w_start + w_o)
img_c = img_scale[h_start:h_end, w_start:w_end]
return img_c
def download(img, size):
q = SAVE_SIZE[size]
while True:
name = str(int(time.time()))
tmp_name = './.temp/' + name + '.jpg'
if not os.path.exists(tmp_name):
break
else:
time.sleep(1)
dir_name = os.path.dirname(tmp_name)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
im = Image.fromarray(img)
im.save(tmp_name, 'jpeg', quality=q, dpi=(300, 300))
return tmp_name
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册