PaddleHub人像分割模型:AI人像抠图及图像合成

news/2024/11/28 22:42:11/

点击上方“AI搞事情”关注我们


本项目根据DeepLabv3+模型一键抠图示例,主要采用PaddleHub DeepLabv3+模型(deeplabv3p_xception65_humanseg)和python图像处理库opencv、PIL等完成。在最新作中,作者通过encoder-decoder进行多尺度信息的融合,同时保留了原来的空洞卷积和ASSP层, 其骨干网络使用了Xception模型,提高了语义分割的健壮性和运行速率,在 PASCAL VOC 2012 dataset取得新的state-of-art performance,该PaddleHub Module使用百度自建数据集进行训练,可用于人像分割,支持任意大小的图片输入。在完成一键抠图之后,通过图像合成,实现扣图比赛任务。

PaddleHub 是基于 PaddlePaddle 开发的预训练模型管理工具,可以借助预训练模型更便捷地开展迁移学习工作,目前的预训练模型涵盖了图像分类、目标检测、词法分析、语义模型、情感分析、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型。

NOTE: 如果您在本地运行该项目示例,需要首先安装PaddleHub。如果您在线运行,需要首先fork该项目示例。之后按照该示例操作即可。

一、安装环境

!pip install paddlehub==1.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
!hub install deeplabv3p_xception65_humanseg==1.0.0

二、开始P图

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
from IPython.display import display, HTML
import numpy as np
import imageio
import os
# 测试图片路径和输出路径
test_path = 'image/test/'
output_path = 'image/blend_out/'# 待预测图片
test_img_path = ["test.jpg"]
test_img_path = [test_path + img for img in test_img_path]
img = mpimg.imread(test_img_path[0])# 展示待预测图片
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()

2. 加载预训练模型

通过加载PaddleHub DeepLabv3+模型(deeplabv3p_xception65_humanseg)实现一键抠图

module = hub.Module(name="deeplabv3p_xception65_humanseg")
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()
[32m[2020-04-01 22:40:09,064] [    INFO] - Installing deeplabv3p_xception65_humanseg module[0m
[32m[2020-04-01 22:40:09,100] [    INFO] - Module deeplabv3p_xception65_humanseg already installed in /home/aistudio/.paddlehub/modules/deeplabv3p_xception65_humanseg[0m
[32m[2020-04-01 22:40:09,814] [    INFO] - 0 pretrained paramaters loaded by PaddleHub[0m
{'origin': 'image/test/test.jpg', 'processed': 'humanseg_output/test.png'}

3. 图像合成

# 合成函数
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] / 255scope_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)
output_path_img = output_path + 'blend_res_img.jpg'
blend_images('humanseg_output/test.png', 'image/test/bg.jpg', output_path_img)# 展示合成图片
plt.figure(figsize=(10,10))
img = mpimg.imread(output_path_img)
plt.imshow(img)
plt.axis('off')
plt.show()
output_path_img = output_path + 'blend_res_img2.jpg'
blend_images('humanseg_output/test.png', 'image/test/bg1.jpg', output_path_img)# 展示合成图片
plt.figure(figsize=(10,10))
img = mpimg.imread(output_path_img)
plt.imshow(img)
plt.axis('off')
plt.show()
# 完整流程来一张
test_img_path = ["xcd.jpg"]
test_img_path = [test_path + img for img in test_img_path]
img = mpimg.imread(test_img_path[0])input_dict = {"image": test_img_path}# execute predict and print the result
results = module.segmentation(data=input_dict)output_path_img = output_path + 'blend_res_img2.jpg'
img = blend_images('humanseg_output/xcd.png', 'image/test/bg.jpg', output_path_img)ttfont = ImageFont.truetype("image/STXINGKA.TTF",100)
draw = ImageDraw.Draw(img)
draw.text((350,450), u'都市绣春刀', fill=(255 , 25, 0), font=ttfont)
img.save(output_path_img)# 展示合成图片
plt.figure(figsize=(10,10))
img = mpimg.imread(output_path_img)
plt.imshow(img)
plt.axis('off')
plt.show()
[32m[2020-04-01 22:40:28,805] [    INFO] - Installing deeplabv3p_xception65_humanseg module[0m
[32m[2020-04-01 22:40:28,821] [    INFO] - Module deeplabv3p_xception65_humanseg already installed in /home/aistudio/.paddlehub/modules/deeplabv3p_xception65_humanseg[0m
[32m[2020-04-01 22:40:29,497] [    INFO] - 0 pretrained paramaters loaded by PaddleHub[0m

三、GIF合成

GIF处理函数

def create_gif(gif_name, path, duration=0.3):'''生成gif文件,原始图片仅支持png格式gif_name :字符串,所生成的 gif 文件名,带 .gif 后缀path :      需要合成为 gif 的图片所在路径duration :  gif 图像时间间隔'''frames = []pngFiles = os.listdir(path)image_list = [os.path.join(path, f) for f in pngFiles]for image_name in image_list:frames.append(imageio.imread(image_name))# 保存为 gifimageio.mimsave(gif_name, frames, 'GIF', duration=duration)returndef split_gif(gif_name, output_path, resize=False):'''拆分gif文件,生成png格式,便于生成gif_name :gif 文件路径,带 .gif 后缀path :      拆分图片所在路径'''gif_file = Image.open(gif_name)name = gif_name.split('/')[-1].split('.')[0]if not os.path.exists(output_path):                        # 判断该文件夹是否存在,如果存在再创建则会报错os.mkdir(output_path)for i, frame in enumerate(ImageSequence.Iterator(gif_file), 1):if resize:frame = frame.resize((300, 168), Image.ANTIALIAS)frame.save('%s/%s_%d.png' % (output_path, name, i))                       # 保存在等目录的output文件夹下def plot_sequence_images(image_array):''' Display images sequence as an animation in jupyter notebookArgs:image_array(numpy.ndarray): image_array.shape equal to (num_images, height, width, num_channels)'''dpi = 72.0xpixels, ypixels = image_array[0].shape[:2]fig = plt.figure(figsize=(ypixels/dpi, xpixels/dpi), dpi=dpi)im = plt.figimage(image_array[0])def animate(i):im.set_array(image_array[i])return (im,)anim = animation.FuncAnimation(fig, animate, frames=len(image_array), interval=500, repeat_delay=1, repeat=True)display(HTML(anim.to_html5_video()))

1. 拆分GIF

# 拆GIF文件为png帧
split_gif('image/test_gif/wushu.gif', 'image/test_gif/wushu_frame', True)imgs = []
for i, fname in enumerate(os.listdir('image/test_gif/wushu_frame')):img = cv2.imread('image/test_gif/wushu_frame/' + fname)img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)imgs.append(img_rgb)
plot_sequence_images(imgs)
# 测试图片路径和输出路径
test_path = 'image/test_gif/wushu_frame/'
output_path = 'image/blend_out/'# 待预测图片
test_img_path = os.listdir(test_path)
test_img_path = [test_path + i for i in test_img_path]
img = mpimg.imread(test_img_path[0])# 展示待预测图片
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()

2. 预测分割

input_dict = {"image": test_img_path}# execute predict and print the result
results = module.segmentation(data=input_dict)# 预测结果展示
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()

3. 合成结果

# 合成图片
humanseg_wushu = [filename for filename in os.listdir('humanseg_output/') if filename.startswith("wushu")]for i, img in enumerate(humanseg_wushu):img_path = os.path.join('humanseg_output/wushu_%d.png' % (i+1))output_path_img = output_path + 'wushu/%d.png' % iblend_images(img_path, 'image/test/bg1.jpg', output_path_img)
# 合成GIF
create_gif('image/blend_out/blend_res_wushu.gif', 'image/blend_out/wushu/', duration=0.5)imgs = []
for i, fname in enumerate(os.listdir('image/blend_out/wushu/')):img = cv2.imread('image/blend_out/wushu/' + fname)img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)imgs.append(img_rgb)
plot_sequence_images(imgs)

四、视频合成

# 拆视频
cap = cv2.VideoCapture('image/video/input.mp4')imgs = []
num = 0
while(True):ret,frame = cap.read()if ret:cv2.imwrite('image/video/frame/%d.jpg'%num, frame)# img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# imgs.append(img_rgb)num += 1else:break
cap.release()#关闭相机# plot_sequence_images(imgs)
# 显示一张
out_img_path = 'image/video/frame/1.jpg'
img = mpimg.imread(out_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()

frame_path = 'image/video/frame'
test_img_path = [os.path.join(frame_path, fname) for fname in os.listdir(frame_path)]
input_dict = {"image": test_img_path}# execute predict and print the result
results = module.segmentation(data=input_dict, output_dir='image/video/frame_seg/')
# plot_sequence_images(imgs)
# 显示一张
out_img_path = 'image/video/frame_seg/1.png'
img = mpimg.imread(out_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()
# 合并输出视频
humanseg_wushu = [filename for filename in os.listdir('image/video/frame_seg/')]
for i, img in enumerate(humanseg_wushu):if i <= 145 or (i >= 250 and i <= 427) or (i >= 552 and i <= 601) or (i >= 729 and i <= 761):img_path = os.path.join('image/video/frame_seg/%d.png' % (i+1))output_path_img = output_path + 'video/%d.png' % iimg = blend_images(img_path, 'image/test/bg2.jpg', output_path_img)if (i >= 146 and i <= 249) or (i >= 428 and i<= 551) or (i >= 602 and i<= 728):img_path = os.path.join('image/video/frame_seg/%d.png' % (i+1))output_path_img = output_path + 'video/%d.png' % iimg = blend_images(img_path, 'image/test/bg3.jpg', output_path_img)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 25.0, (1280,720))
files = os.listdir('image/blend_out/video')
for i in range(len(files)):img = cv2.imread('image/blend_out/video/%d.png' % i)img = cv2.resize(img, (1280,720))out.write(img)#保存帧
out.release()

项目地址:  阅读原文

视频地址:https://www.bilibili.com/video/BV1ng4y1a77T

长按二维码关注我们

有趣的灵魂在等你

留言请摁


http://www.ppmy.cn/news/665810.html

相关文章

python爬取豆瓣影评生成词云的课程设计报告_Python爬取豆瓣影评,生成词云图,只要简单一步即可实现。...

最近看了一部电影《绣春刀》,里面的剧情感觉还不错,本文爬取的是绣春刀电影的豆瓣影评,1000个用户的短评,共5W多字。用jieba分词,对词语的出现频率进行统计,再通过wordcloud生成词云图。 今天和小伙伴们一起梳理下具体实现的流程,具体源代码已经上传到NLP小白 公众号中,…

飞鱼服 绣春刀

雨下个不停…… 下雨天音乐和什么更配&#xff1f; 作为东方华夏族的一名地道土著&#xff0c;九叔认为绝对不是小棋棋说的德芙巧克力&#xff0c;那是毛子的口味。 下雨天和音乐更配的必须是读书&#xff0c;特别是对阅读习惯据说已经连印度都不如的国人来说&#xff0c;下雨…

VIM编辑器的命令使用总结

&#xff08;该图由AI绘制 关注我 学习AI画图&#xff09; 目录 一、VIM编辑器 1、vi概述 2、vim编辑器 3、vim编辑器的安装 4、vim编辑器的四种模式&#xff08;重点&#xff09; ☆ 命令模式 ☆ 编辑模式或输入模式 ☆ 末行模式 ☆ 可视化模式&#xff08;了解&am…

conda 根目录内存满,更换新的目录

默认conda环境是在根目录&#xff0c;只需修改默认的目录即可 1 修改.condarc文件 vim ~/.condarc# 添加一行即可 envs_dirs:- /disk3/miniconda_envs/envs2 验证 创建一个conda环境 查看创建的路径 conda env list 这样以后都换把相关创建的包安装在disk3下&#xff0c;缓…

劲爆!366API免费提供微信如何打开网页下载APP

微信内无法直接下载app或者其他文件&#xff0c;是因为微信会拦截含下载文件的链接。很多朋友包括我自己想分享app下载地址的时候都会遇到这个问题&#xff0c;故特地跑去找各种解决方案&#xff0c;最终锁定了一个方便快捷的方法&#xff0c;那就是用在线api接口一键实现微信跳…

python编程 迷你世界_迷你世界迷你编程下载

迷你世界迷你编程是一款图形化编程软件&#xff0c;可以帮助青少年学习基础的编程知识&#xff0c;提高逻辑思维能力&#xff0c;迷你世界迷你编程还能让用户直观的感受到编程效果&#xff0c;对编程产生兴趣。 基本简介 迷你世界迷你编程官方版是三维图形化编程软件&#xff…

python编程 迷你世界_迷你世界迷你编程1.1最新免费版下载-迷你世界迷你编程官方版下载-Appfound...

迷你世界迷你编程是一款非常好用的编程学习辅助工具&#xff0c;软件使用中文操作界面&#xff0c;使用更加简单易上手&#xff0c;能够给孩子培养编程思维&#xff0c;通过图形化编程模式让孩子轻松学习各种编程放视&#xff0c;有需要的家长朋友们欢迎下载使用&#xff01; 基…

免费:轻松实现在微信中直接下载APK

更新&#xff1a;目前微信已不支持该功能。 —————————————————————————————————————————— 微信会故意阻碍、限制app推广通过微信平台来进行吗&#xff1f;如果你有这种看法&#xff0c;那就是有些误会微信了&#xff01; 但是你可…