2020-08-28

## 百度paddlehub创意项目 秦时明月的雪女姐姐来到了现实的飞雪玉花,氤氲了一舞倾城

很多时候,我们需要进行人像抠图,视频合成等类似的操作,可能要学很多专业的图片处理软件,视频剪辑软件等,如photoshops,Ai premiere等,当然这些软件处理后的效果很好,但在有的时候我们需要快速处理而软件又不熟悉的时候,就加大了学习成本,而在学习了百度公司基于深度学习技术开发的paddlehub组件后,就可以利用paddlehub的预训练模型,来快速的进行上述操作,只需几行代码就可以得到不错的效果。先对paddlehub做个简单介绍吧,paddlehub提供全流程、可复现的应用场景,包括图像分类,目标检测,视频分类,图像分割等计算机视觉领域以及文本生成,词法分析等nlp等还有其他领域的应用场景,提供预训练模型,让开发者轻松验证模型算法的可用性,快速完成想要的功能操作。
在这次创意项目中,想要实现一个简单的功能,秦时明月的忠实观众,最近沧海横流好像也要快了,想要把秦时明月中雪女姐姐曼妙的舞姿搬到现实的飞雪玉花场景中,下面来结合paddlehub介绍下思路吧。
先来看一组效果演示:
![飞雪玉花](https://img-blog.csdnimg.cn/20200828121102350.gif#pic_center)

首先需要在AIstudio中配置好环境

# 首先配置环境  paddlehub模块和人像抠图分割模型的安装
!pip install paddlehub==1.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
!hub install deeplabv3p_xception65_humanseg==1.0.0

当环境装好后,需要导入对于该原素材视频处理所需要的模块

import paddlehub as hub
from PIL import Image
import os
import cv2

接下来就是正式的处理过程,主要思路就是,对于原素材视频来说,我们需要将视频中的人像抠出来,那怎么扣了,在这里,我们需要将视频预先处理成每一帧数图片,这部分我们可以利用OpenCV进行完成,在得到了每一帧的图片后,我们就可以利用百度的paddlehub模型中的deeplabv3p模型进行人像抠图,得到了人像,然后再利用opencv将现实中的背景图片和人像进行图像融合,再将融合后的每一帧图片合成视频,并将原视频中的音频提取并添加进新的视频,即可完成。
提取素材视频图片

# 将所需要的的视频按帧数提取成图片,为后续的人像抠图做准备

def video2jpg(video_file,output_path):
    '''
    将视频文件video_file每一帧转成图片保存到output_path文件夹
    '''
    try:
        os.makedirs(output_path) #创建输出文件夹
    except:
        print()

    #读取视频文件
    cap = cv2.VideoCapture(video_file)
    
    num = 0
    while(True):
        ret,frame = cap.read() 
        if ret:
            cv2.imwrite('%s%d.jpg'%(output_path,num), frame)
            num += 1
        else:
            break
    cap.release()#关闭视频


video_file='video/一舞倾城1.mp4'
output_path='video/video2jpg2/'
video2jpg(video_file,output_path)

进行人像抠图

# 使用预训练模型对上述得到的图片进行人像抠图
!hub run deeplabv3p_xception65_humanseg

def humanseg(images,output_dir):
    
    #新建人像抠图后的文件夹路径
    try:
        os.makedirs(output_dir)
    except:
        print ()
    
    #装载模型
    module = hub.Module(name="deeplabv3p_xception65_humanseg")
    #执行模型segmentation命令
    result = module.segmentation(data={"image":images}, output_dir=output_dir)
    # print (result)
    return result


def file_list(listdir):
    '''
    读取文件夹listdir里的序号文件,形成im_list
    '''
    im_list=[]
    files = os.listdir(listdir)
    for i in range(len(files)) :
        im_list.append('%s%d.jpg' %(listdir,i) )
    return im_list


listdir='video/video2jpg3/'
im_list=file_list(listdir)
# print (im_list)
output_dir='video/humanseg_out2/'
humanseg(im_list,output_dir)

图片融合

# 将背景图片与扣除的人像进行图像融合
def alpha_composite(fore_image,base_image,output_dir):
    '''
    将前景图片fore_image与背景图片base_image融合,输出到文件夹output_dir
    '''
 
    base_image_op = Image.open(base_image).convert("RGBA")
    fore_image_op = Image.open(fore_image).convert("RGBA")
    # print (base_image_op)
    # print (fore_image_op)

    #调整照片的size,因为背景图片较小,所以我调整背景图片来适应前景图片
    base_image_op = base_image_op.resize(fore_image_op.size)  
    # base_image = base_image.rotate(90)  #旋转图片

    image_c = Image.alpha_composite(base_image_op, fore_image_op)
    image_c.save(output_dir + fore_image.replace('video/humanseg_out1/','') )
    # display(final2)
    return image_c



# 视频转化图片的文件夹
files_v = os.listdir('video/video2jpg2/') 
#人像抠图的文件夹
fore_path='video/humanseg_out1/'
#背景图片
base_image='video/image_base.jpg'
#合成图片输出的文件夹
output_dir='video/image_composite1/'
try:
    os.makedirs(output_dir)
except:
    print()

for i in range(len(files_v)):
    
    fore_image='%s%d.png'%(fore_path,i)
    try:    
        alpha_composite(fore_image,base_image,output_dir)
    except:
        continue

合成视频

# 将融合后的图片合成视频
def png2video(image_dir,out_video):
    '''
    将文件夹image_dir中的每一帧图片合成视频out_video
    '''
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter(out_video,fourcc, 25.0, (1280,720))
    files = os.listdir(image_dir)

    # 视频转化图片的文件夹
    files_v = os.listdir('video/video2jpg2/') 

    for i in range(len(files_v)): 
        image='%s%d.png' %(image_dir,i)
        
        try:
            img = cv2.imread(image)
            img = cv2.resize(img,(1280,720))
            out.write(img)#保存帧

        except:
            continue

    out.release()

out_video='video/out_video2.mp4'
image_dir='video/image_composite1/'

png2video(image_dir,out_video)

添加音频

# 提取音频
!ffmpeg -i video/一舞倾城1.mp4 video/video5_m.mp3 -loglevel quiet

# 添加音频合成视频
!ffmpeg -i video/out_video2.mp4 -i video/video5_m.mp3  -vcodec copy -acodec copy video/out_video_final3.mp4 -loglevel quiet

最后的视频效果

飞雪玉花,一舞倾城

最后的总结:
总的来说,完成了一次简单的视频抠图合成体验,虽然好多地方视频合成的效果还有待改善,比如人像抠图,有的图片人像估计扣得不太明显或者直接没有扣到人像,可能是动漫人物的立体感不强又或者是预训练模型,但能做到这样已经很不错了,如果再多一点类似的样本再进行训练一波模型,抠图效果可能会更好,另一方面,对于需要融合的背景图片,可以提前处理一波,比如增加图片透明度等操作,让最终合成的效果更加好看。
最后,还是很感谢paddlepaddle百度飞桨团队能提供这次机会,既是一次学习过程,也是一次深度学习应用的体验过程。
本demo参考别的大佬博主所作:
link.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值