飛槳PaddleHub帶你環遊世界,快來試試Python一鍵視頻摳圖吧

在視頻創作過程中,有時會遇到人像摳圖的需求,最一般的做法是使用PR、AE等工具將視頻中的每一幀圖像手動摳圖。這麼繁瑣的步驟在理工男面前簡直是不可存在的,那麼有什麼簡單的方法能快速摳圖嗎?當然有啦,接下來給大家介紹如何使用PaddleHub一鍵視頻人像摳圖。

效果展示

首先展示一些摳圖完畢的小片段,上一秒我還在家裏的小房間,下一秒我就出現在了土耳其。

那順便去看看埃菲爾鐵塔唄。

到洛杉磯的海邊散散步。

到上海歡樂谷鍛鍊鍛鍊身體。

最後到東京的觀景臺上看個日落

視頻效果是不是很逼真呢,一天環遊世界不是夢哈哈哈……

其實這些人像素材都是在房間裏拍攝,然後使用PaddleHub工具庫一鍵摳圖,最後使用PR進行後期創作的,接下來介紹下如何操作吧。


這是如何實現的?

關注飛槳的小夥伴是否還記得前幾天推過的別再用PS了,我用5行Python代碼就實現了批量摳圖,視頻人像摳圖也是類似的,只要把視頻的每一幀圖像所含有的人像提取出來,然後加上背景重新合成視頻就可以啦。大體的步驟知道了,那接下來開始實踐吧。

哦對了,還得有一段含有人像的素材,小夥伴們可以自己拍攝或者從網絡蒐集。

01

安裝必要組建

需要安裝的是飛槳框架和PaddleHub工具庫,安裝步驟可以參考別再用PS了,我用5行Python代碼就實現了批量摳圖。或者直接進入飛槳官網查看安裝步驟:

https://www.paddlepaddle.org.cn

02

人像摳圖製作素材

由於目前PaddleHub人像摳圖模型API的輸入是單張圖像的路徑,故需要先將視頻的每一幀圖像分離存儲後才能進行摳圖。當然也可以通過修改模型的源碼,將API的輸入修改成圖像輸入,這樣就省去了視頻分離存儲的步驟,具體的源碼可以參考:

https://aistudio.baidu.com/aistudio/projectdetail/370260,這裏主要介紹前一種方法。

2.1 導入所有相關模塊

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

2.2 將視頻內圖像分離存儲

def CutVideo2Image(video_path, img_path):
    cap = cv2.VideoCapture(video_path)
    index = 0
    while(True):
        ret,frame = cap.read() 
        if ret:
            cv2.imwrite(img_path + '%d.jpg' % index, frame)
            index += 1
        else:
            break
    cap.release()
    print('Video cut finish, all %d frame' % index)

該步驟將會把每一幀圖像保存到本地目錄。

2.3 導入模型進行人像摳圖

def GetHumanSeg(frame_path, out_path):
    # 加載模型
    module = hub.Module(name="deeplabv3p_xception65_humanseg")
    # 配置
    test_img_path = [os.path.join(frame_path, fname) for fname in os.listdir(in_path)]
    input_dict = {"image": test_img_path}

    results = module.segmentation(data=input_dict, output_dir=out_path)
    # Tips:使用GPU加速需安裝paddlepaddle-gpu
    # results = module.segmentation(data=input_dict, use_gpu = gpu, batch_size = 10,output_dir=out_path)

該步驟將會把人像提取並保存爲png至本地

2.4 生成綠幕並與人像合成

爲什麼要使用綠幕呢,主要是爲了後續在視頻後期軟件裏方便使用素材。當然熟悉Python的同學也可以直接使用一些Python模塊進行視頻後期。但是在這裏還是推薦使用PR、AE這類專業軟件,可以方便地對素材進行縮放、變速、位置處理、以及添加特效等操作。更重要的是,可以對素材進行調色,與新的背景更好地融合。



def init_canvas(width, height, color=(255, 255, 255)):
    canvas = np.ones((height, width, 3), dtype="uint8")
    canvas[:] = color
    return canvas
# 生成綠幕

def GetGreenScreen(size, out_path):
    canvas = init_canvas(size[0], size[1], color=(0, 255, 0))
    cv2.imwrite(out_path, canvas)

def BlendImg(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)

def BlendHumanImg(in_path, screen_path, out_path):
    humanseg_png = [filename for filename in os.listdir(in_path)]
    for i, img in enumerate(humanseg_png):
        img_path = os.path.join(in_path + '%d.png' % (i))
        output_path_img = out_path + '%d.png' % i
        BlendImg(img_path, screen_path, output_path_img)



該步驟完成後將會得到類似這樣的綠幕圖片:

2.5 視頻合成

def CompVideo(in_path, out_path, size):
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter(out_path,fourcc, 30.0, size)
    files = os.listdir(in_path)


    for i in range(len(files)):
        img = cv2.imread(in_path + '%d.png' % i)
        out.write(img)    # 保存幀
    out.release()

該步驟完成後即可得到類似下圖的人體綠幕素材

2.6 主程序

# Config
Video_Path = 'video/0.mp4'
Video_Size = (1920, 1080)
FrameCut_Path = 'video/frame/'
FrameSeg_Path = 'video/frame_seg/'
FrameCom_Path = 'video/frame_com/'
GreenScreen_Path = 'video/green.jpg'
ComOut_Path = 'output.mp4'

if __name__ == "__main__":
    # 第一步:視頻->圖像
    if not os.path.exists(FrameCut_Path):
        os.mkdir(FrameCut_Path)     
        CutVideo2Image(Video_Path, FrameCut_Path)

    # 第二步:摳圖
    if not os.path.exists(FrameSeg_Path):
        os.mkdir(FrameSeg_Path) 
        GetHumanSeg(FrameCut_Path, FrameSeg_Path)

    # 第三步:生成綠幕併合成
    if not os.path.exists(GreenScreen_Path):
        GetGreenScreen(Video_Size, GreenScreen_Path)

    if not os.path.exists(FrameCom_Path):
        os.mkdir(FrameCom_Path) 
        BlendHumanImg(FrameSeg_Path, GreenScreen_Path, FrameCom_Path)

    # 第四步:合成視頻
    if not os.path.exists(ComOut_Path):
        CompVideo(FrameCom_Path, ComOut_Path, Video_Size)

OK,綠幕素材都已經制作完畢,下一步就可以導入到後期軟件內進行創作啦,這裏以PR爲例。

03

後期創作

將綠幕素材和背景素材導入PR,在綠幕素材上使用`超級鍵`效果,並將主要顏色選取爲綠幕的顏色,即可輕鬆去除綠幕顏色。

再往後的各種騷操作就看各位小夥伴的想象力啦!

這裏附上我的作品:[AI人像摳圖]|百度PaddleHub摳圖創意賽[附教程、代碼]:

https://www.bilibili.com/video/BV1cA411b7r2

目前存在的問題:

  • 頭髮、手指等細節部分還需要進一步完善。

  • 人體動作幅度大導致圖像幀模糊,會造成提取失敗。

  • 模型的API接口有待繼續豐富。

不過聽說百度飛槳後續會針對視頻流推出更高效的人像分割模型,真是讓人期待呀!

如果使用過程中遇到任何問題,大家可通過以下聯繫方式進行技術交流及問題反饋。

PaddleHub issue:

https://github.com/PaddlePaddle/PaddleHub/issues

官方QQ羣:703252161。如果您加入官方QQ羣,您將遇上大批志同道合的深度學習同學。

如果您想詳細瞭解更多飛槳的相關內容,請參閱以下文檔。

官網地址:https://www.paddlepaddle.org.cn

  • PaddleHub項目地址:

GitHub: https://github.com/PaddlePaddle/PaddleHub

Gitee:  https://gitee.com/paddlepaddle/PaddleHub

  • PaddleHub 官網:

https://www.paddlepaddle.org.cn/hub

  • PaddleHub 預訓練模型:

https://www.paddlepaddle.org.cn/hublist

  • PaddleHub 文檔:

https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.6/docs

  • PaddleHub demo:

https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.6/demo

  • PaddleHub AI Studio官方教程示例:

https://aistudio.baidu.com/aistudio/personalcenter/thirdview/79927

  • 飛槳PaddleSeg項目地址:

https://github.com/PaddlePaddle/PaddleSeg

  • 飛槳開源框架項目地址:

GitHub: https://github.com/PaddlePaddle/Paddle

Gitee:  https://gitee.com/paddlepaddle/Paddle

END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章