PaddleHub是基于PaddlePaddle生态下的预训练模型管理和迁移学习工具,可以结合预训练模型更便捷地开展迁移学习工作。通过PaddleHub,可以便捷地获取PaddlePaddle生态下的所有预训练模型,涵盖了图像分类、目标检测、词法分析、语义模型、情感分析、语言模型、视频分类、图像生成、图像分割九类主流模型。
本文利用DeepLabv3+模型完成一键抠图。DeepLabv3+ 是Google DeepLab语义分割系列网络的最新作,其前作有 DeepLabv1,DeepLabv2, DeepLabv3。在最新作中,作者通过encoder-decoder进行多尺度信息的融合,同时保留了原来的空洞卷积和ASSP层, 其骨干网络使用了Xception模型,提高了语义分割的健壮性和运行速率,在 PASCAL VOC 2012 dataset取得新的state-of-art performance。
注意:需要安装PaddleHub
本文利用PaddleHub实现了图像风格迁移、AI人像抠图以及图像合成。首先对需要抠图的输入图像进行风格迁移,然后抠取图片中的人像,最后实现图像合成。
AI Studio项目链接 :PaddleHub实现图像合成
图片来自网络,如有需要侵删。
一、安装环境
!pip install paddlehub==1.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
!hub install deeplabv3p_xception65_humanseg==1.0.0
二、具体操作
1. 引入包
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from matplotlib import animation
import cv2
import paddlehub as hub
from PIL import Image, ImageSequence, ImageDraw,ImageFont
from IPython.display import display, HTML
import numpy as np
import imageio
import os
2. 风格迁移
# 查看图片
#查看输入图片
input_img_path = './cry.png'
input_img = cv2.imread(input_img_path)
input_img = cv2.cvtColor(input_img, cv2.COLOR_RGB2BGR)
plt.figure(figsize=(10,10))
plt.imshow(input_img)
plt.axis('off')
plt.show()
待抠图像如下图所示
#查看风格图片
style_img_path = 'style/style1.jpg'
style_img = cv2.cvtColor(cv2.imread(style_img_path), cv2.COLOR_RGB2BGR)
plt.figure(figsize=(10,10))
plt.imshow(style_img)
plt.axis('off')
plt.show()
加载风格迁移模型
## 加载style transfer模型
def style_transfer(input_img_path,style_img_path):
stylepro_artistic = hub.Module(name="stylepro_artistic")
result = stylepro_artistic.style_transfer(
images=[{
'content': cv2.cvtColor(cv2.imread(input_img_path), cv2.COLOR_RGB2BGR),
'styles': [cv2.cvtColor(cv2.imread(style_img_path), cv2.COLOR_RGB2BGR)]
}])
cartoon_img = result[0]['data']
plt.figure(figsize=(10, 10))
plt.imshow(cartoon_img)
plt.show()
output_img = cv2.cvtColor(cartoon_img, cv2.COLOR_BGR2RGB)
return output_img
#输出风格迁移结果
output_img=style_transfer(input_img_path,style_img_path)
cv2.imwrite('./out/bg.jpg', output_img)
风格迁移后的图片如图所示
3. 抠取人像
通过加载PaddleHub DeepLabv3+模型(deeplabv3p_xception65_humanseg)实现一键抠图
module = hub.Module(name="deeplabv3p_xception65_humanseg")
test_img_path = ['./styleout/bg.jpg']
input_dict = {"image": test_img_path}
# execute predict and print the result
results = module.segmentation(data=input_dict)
for result in results:
print(result)
# 预测结果展示
out_img_path = 'humanseg_output/' + os.path.basename(test_img_path[0]).split('.')[0] + '.png'
img = mpimg.imread(out_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()
4. 图像合成
# 合成函数
def blend_images(fore_image, base_image, output_path):
"""
将抠出的人物图像换背景
fore_image: 前景图片,抠出的人物图片
base_image: 背景图片
"""
# 读入图片
base_image = Image.open(base_image).convert('RGB')
fore_image = Image.open(fore_image).resize(base_image.size)
# 图片加权合成
scope_map = np.array(fore_image)[:,:,-1] / 255
scope_map = scope_map[:,:,np.newaxis]
scope_map = np.repeat(scope_map, repeats=3, axis=2)
res_image = np.multiply(scope_map, np.array(fore_image)[:,:,:3]) + np.multiply((1-scope_map), np.array(base_image))
#保存图片
res_image = Image.fromarray(np.uint8(res_image))
res_image.save(output_path)
return res_image
# output_path_img = output_path + 'blend_res_img.jpg'
output_path = 'result/'
output_path_img = output_path + 'blend_res_img.jpg'
# blend_images('humanseg_output/test.png', 'image/test/bg.jpg', output_path_img)
blend_images('humanseg_output/bg.png', 'image/fg.jpg', output_path_img)
# 展示合成图片
plt.figure(figsize=(10,10))
img = mpimg.imread(output_path_img)
plt.imshow(img)
plt.axis('off')
plt.show()
合成图片如下图所示