【paddlepaddle】PaddleHub创意项目

写在前面

当《空山新雨后》的小姐姐遇上了《你的名字》,这将会是一场怎样的盛宴呢!

最近被《空山新雨后》疯狂洗脑,在B站看到小姐姐的歌伴舞后就有了给小姐姐换个背景的相法,
于是找来了你的名字的照片,让小姐姐在星空下配合着悦耳的歌翩翩起舞

项目AIstudio地址:https://aistudio.baidu.com/aistudio/projectdetail/765734
视频B站地址:https://www.bilibili.com/video/BV1QV41127gd/

思路

  1. 将原视频提取为1帧1帧的图片
  2. 对每一张图片做人物分割和背景合成两部分工作
  3. 将第二步得到的图片按照顺序合并成一个新的视频(注意这里的视频是没有声音的)
  4. 将原视频的bgm添加到新合成的视频上面

技术栈

  • paddlehub
  • deeplabv3p_xception65_humanseg(paddlehub提供的人物分割的模型)
  • opencv

模型介绍

DeepLabv3+ 是Google DeepLab语义分割系列网络的最新作,其前作有 DeepLabv1, DeepLabv2, DeepLabv3。在最新作中,作者通过encoder-decoder进行多尺度信息的融合,同时保留了原来的空洞卷积和ASSP层, 其骨干网络使用了Xception模型,提高了语义分割的健壮性和运行速率,在 PASCAL VOC 2012 dataset取得新的state-of-art performance。该PaddleHub Module使用百度自建数据集进行训练,可用于人像分割,支持任意大小的图片输入。点击查看详情

模型效果展示

在这里插入图片描述

核心代码

step1: 从视频中提取帧

#从视频中提取帧
def extract_images(src_video, dst_dir):
    '''
    src_video:为目标的视频文件地址
    dst_dir:为视频图片的保存路径
    '''
    video = cv2.VideoCapture(src_video)
    
    count = 0
    with tqdm(total=video.get(cv2.CAP_PROP_FRAME_COUNT)) as pbar:
        while True:
            flag, frame = video.read()
            if not flag:
                break
            cv2.imwrite(os.path.join(dst_dir, str(count) + '.png'), frame)
            count = count + 1
            pbar.update(1)
    print('extracted {} frames in total.'.format(count))

step2: 分割图像

#分割图像
def seg():
    dst_img_dir = './work/images'
    img_list = os.listdir(dst_img_dir)
    img_list = [os.path.join(dst_img_dir,str(i)+'.png') for i in range(5085)]
    print(len(img_list))
    module = hub.Module(name="deeplabv3p_xception65_humanseg")
    from tqdm import trange
    try:
        with trange(len(img_list)) as pbar:
            for i in pbar:
                tmp_list = []
                tmp_list.append(img_list[i])
                module.segmentation(data={'image':tmp_list},use_gpu=True,visualization =True,output_dir='output')
                pbar.set_description("Processing %s" % img_list[i].split('/')[-1])
    except KeyboardInterrupt:
        pbar.close()
        raise
    pbar.close()

step3: 图片转换为视频

#图片转换为视频
def img2video(dst_video_path,pic_path,size,frame):
    '''
    dst_video_path:合成视频的保存路径(包含文件名)
    pic_path:合成的所有图片的路径
    size:图片的大小,即是视频的大小
    frame:帧率

    VideoWriter_fourcc为视频编解码器
    fourcc意为四字符代码(Four-Character Codes),顾名思义,该编码由四个字符组成,下面是VideoWriter_fourcc对象一些常用的参数,注意:字符顺序不能弄混
    cv2.VideoWriter_fourcc('I', '4', '2', '0'),该参数是YUV编码类型,文件名后缀为.avi
    cv2.VideoWriter_fourcc('P', 'I', 'M', 'I'),该参数是MPEG-1编码类型,文件名后缀为.avi
    cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'),该参数是MPEG-4编码类型,文件名后缀为.avi
    cv2.VideoWriter_fourcc('T', 'H', 'E', 'O'),该参数是Ogg Vorbis,文件名后缀为.ogv
    cv2.VideoWriter_fourcc('F', 'L', 'V', '1'),该参数是Flash视频,文件名后缀为.flv
    cv2.VideoWriter_fourcc('m', 'p', '4', 'v')    文件名后缀为.mp4
    '''
    dst_video = cv2.VideoWriter(dst_video_path, cv2.VideoWriter_fourcc(*'mp4v'), frame, size, True)
    try:
        with trange(len(os.listdir(pic_path))) as pbar:
            for index in pbar:
                frame = cv2.imread(os.path.join(pic_path,'{}.png'.format(index)))
                dst_video.write(frame)
                pbar.set_description("Processing %s.png" % index)
    except KeyboardInterrupt:
        pbar.close()
        raise
    pbar.close()
    dst_video.release()

step4: 添加bgm

#给视频加声音
def add_audio(s_video_path,d_video_path,name):
    '''
    给视频加声音
    :param s_video_path: 原视频地址-含有声音的
    :param d_video_path: 目的视频地址-需要加声音的
    :return:
    '''
    video_s = VideoFileClip(s_video_path)
    video_d = VideoFileClip(d_video_path)
    audio_o = video_s.audio
    video_dd = video_d.set_audio(audio_o)
    video_dd.write_videofile(d_video_path[0:d_video_path.rfind('/')+1]+name)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值