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

PaddleHub官网:PaddleHub官网

PaddleHub项目地址:PaddleHub github

更多PaddleHub预训练模型应用可见:教程合集课程

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] / 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)
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]) 

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)

output_path_img = output_path + ‘blend_res_img2.jpg‘
blend_images(‘humanseg_output/xcd.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()
[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))
    # 保存为 gif
    imageio.mimsave(gif_name, frames, ‘GIF‘, duration=duration)
    return

def 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 notebook

    Args:
        image_array(numpy.ndarray): image_array.shape equal to (num_images, height, width, num_channels)
    ‘‘‘
    dpi = 72.0
    xpixels, 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‘ % i
    blend_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)

四、视频合成

有时间再写……

> 项目地址:
https://aistudio.baidu.com/aistudio/projectdetail/362432

原文地址:https://www.cnblogs.com/fahaihappy/p/12616795.html

时间: 2024-10-29 18:00:05

PaddleHub人像分割模型:AI人像抠图及图像合成的相关文章

人工智能必须要知道的语义分割模型:DeepLabv3+

图像分割是计算机视觉中除了分类和检测外的另一项基本任务,它意味着要将图片根据内容分割成不同的块.相比图像分类和检测,分割是一项更精细的工作,因为需要对每个像素点分类,如下图的街景分割,由于对每个像素点都分类,物体的轮廓是精准勾勒的,而不是像检测那样给出边界框. 图像分割可以分为两类:语义分割(Semantic Segmentation)和实例分割(Instance Segmentation),其区别如图所示. 可以看到语义分割只是简单地对图像中各个像素点分类,但是实例分割更进一步,需要区分开不同

Python - AI自动抠图

一.简介 抠图是用PS? 用魔棒和快速选择工具? 遇到复杂背景怎么办? 最近发现一个神奇的工具——Remove Image Background https://www.remove.bg/zh 它是基于Python.Ruby和深度学习技术开发,通过强大的AI人工智能算法实现自动识别出前景主体与背景图,秒秒种完成抠图. 这款抠图工具有两种简单方式: 1.在线抠图 2.API代码抠图 二.在线抠图 1.打开remove.bg网站首页,可以上传本地图片,也可以选择网络图片的URL链接. 2.上传几秒

学习笔记之Java Annotation学习总结 [ 光影人像 东海陈光剑 的博客 ]

?? 按照自己定的学习计划,今天是该写点什么了. ? 在上篇文章里提到的是JUnit的学习,其中就涉及到了一些内置的annotation,如@Test.@Ignore等.现在我就结合个人的理解谈下如何自定义自己的annotation. ? annotation能被用来为某个程序元素(类.方法.成员变量等)关联任何的信息,但annotaion不能影响程序代码的执行,无论增加.删除annotation,代码都始终如一的执行.另外,尽管一些annotation通过java的反射api方法在运行时被访问

起底区块链人脸识别黑马,一个没有人像的人脸识别:iFace Chain(爱妃链)

近几年来,人脸识别技术可谓在移动互联网中得到了空前广泛应用,从银行APP免密转账,人脸快捷支付到证券人脸开户,人脸识别技术已经应用到了移动互联的诸多应用场景.互联网无处不在的今天,便捷与安全貌似是一个非常难以调和的矛盾体,你在享受便捷的同时,你无意识的忽略了是否安全. 那么这些大家熟知的人脸识别技术,其实存在严重的风险.这些人脸识别无一例外是通过手机或者计算机摄像头拍摄人脸,并将人像照片传输至服务器中进行处理.这些处理流程大致如下: 大家可能已经注意到了这里面有个关键性的环节,就是服务器会将这些

牛径哲学 [ 光影人像 东海陈光剑 的博客 ]

??????? 牛径即牛走出来的路,我记得有一幅图是这样描绘的,几只牛被围在一堆有半人高的草从中,这些牛把中间的草吃出了一块空地,但吃完草,牛就开始找水喝,在离他们不远的地方就有一条小河(直线距离只有几米远),但牛看不到这条河,于是,有一天,一只牛不小心走出了一条弯弯曲曲的路(这条路的距离,远远大于直线的距离),并且成功到达了小河,喝到了水,于是,这只牛把这个消息告诉了被围住的其它牛,其它牛也顺着这条弯弯曲曲的小路找到了水喝,后来所有的牛都是顺着这条弯弯曲曲的小路达到河边喝水,从来没有其他牛去探

[ 光影人像 东海陈光剑 的博客 ]

关于"Deming第三原则:不要依赖于海量的检查"的思考 ????? 传统的想法认为检查可以排除糟糕的质量.当难于确定在过程中一个缺陷在哪边产生的时候,一个好的方法是关注于我们做的如何,而不应针对最终的产品.质量应当是内在的,而不是依赖于无数的检查获得的. ????? 为了使用该原则,一个质量保证组织可以: 1.在整个开发生命周期中,提高并使用技术评审.走读和检视来获取质量. 2.在整个组织中灌输质量意识,并把它作为一个切实的,可度量的工作产品 3.需要信息技术质量的统计证据 ????

临时需求如何安排发布? [ 光影人像 东海陈光剑 的博客 ]

?淘宝的发布工作是有严格的发布计划的,一旦非计划的发布需求出现时,需要评估才能决定何时能够发布. 这周在处理一个临时需求的发布计划时,有以下的感想: 在临时需求提出后,由PDM进行协调,这时发现和一个项目发布有冲突,经过和项目经理确认可以一起发布.但当项目发布前做计划时才发现,可能一起发会存在风险,比如任何一个进度延迟,另一个就不能发.一个上线有问题,如果严重,就会影响到另一个的质量.临时改变计划,并通知需求方. 通知需求方后,需求方坚持按原计划日期上线.经过了多轮沟通,采取了临时的计划. 这次

如何促进买家、卖家的交易提升 [ 光影人像 东海陈光剑 的博客 ]

1.如何让买家更方便的买到满意的宝贝? ????????现在网站的信息量越来越大,可以说是"海量",这当然是好事,但有时候却会给买家带去"被淹没在信息的海洋中"般的困惑.当然,为了买家能找到满意的宝贝,我们也提供了搜索引擎的功能,不过,我的感觉是这功能有时候并不能满足大家的要求. 淘宝网对买卖双方的需求有两个链接入口:"我要买"."我要卖".但对于"我要买"的功能,目前仍只是简单的链接到需要搜索的信息海洋中

Project web Access 2007工时更新 [ 光影人像 东海陈光剑 的博客 ]

2007-11-15添加: l? 设置任务跟踪方法 管理员可以在服务器端设置任务跟踪方法:见下图: 完成设置后,此时去打开我的任务时,跟踪方法并没有被改进,仍然是修改设置之前的跟踪方法,这时,需要在project客户端打开该项目,并做一定的操作,比如:更新任务的工时.调整计划等,总时,需要有所改动,因为只有这样,才可以重新发布计划,只有重新发布计划之后,新的跟踪方法才会生效. ?l? 项目成员如何在WEB端更新任务的完成情况? n? 跟踪方法为"工时完成百分比"的任务更新方法: 项目成