## 百度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.