人工智能学习之使用百度大脑在线AI Studio实现人体皮影戏


前言

资源来自BaiDu大脑AI Studio,本文在弘扬传统文化同时,能让读者学习AI知识。

https://aistudio.baidu.com/aistudio/projectdetail/1907782


提示:以下是本篇文章正文内容,下面案例可供参考

一、项目背景

领略千年皮影戏魅力,传承正在消失的艺术。
皮影戏的神奇,在于小小皮影在指尖上飞舞,时而刀光剑影、时而策马扬鞭、时而缠绵悱恻,千军万马是他,单打独斗也是他。皮影戏可谓是闻名中外,它是把光影声色做到极致的一门古老艺术。

在这里插入图片描述
在这里插入图片描述

先辈门通过手艺演绎着皮影戏,同样我们也可以通过AI方式来实现。为了实现皮影戏,可以通过PaddleHub提供的人体骨骼关键点检测库完成将人体姿态检测,同时映射到皮影身上,让皮影动起来。

二、效果展示

通过PaddleHub完成人体骨骼关键点检测,将人体骨骼关键点进行连接,就可以获取到人体的肢体骨骼,在骨骼肢体上覆盖皮影素材,就可以得到皮影人了。将视频中连续帧进行转换,就可以实现“皮影戏”的效果. 下面我们一起来看一下整体效果吧:

  • 对单张图片的转换,左边是原始图片,通过人体骨骼关键点检测后标注出了关键点位置,右边就是我们实现皮影素材叠加的效果:
    在这里插入图片描述
  • 在实现单张图片转换之后,我们就可以对视频中的每一帧进行处理,通过视频中的人物运动,让皮影动起来! 我b站上找了一个可爱的小姐姐进行转换(别只看小姐姐哦!),效果如下:
    在这里插入图片描述

NOTE: 如果您在本地运行该项目示例,需要首先安装PaddleHub。如果您在线运行,需要首先fork该项目示例。之后按照该示例操作即可。

三、实现步骤

1.安装依赖库

  • aistudio默认安装了PaddleHub, 本地运行的同学需要自行安装,可以到飞桨官网查看安装步骤:https://www.paddlepaddle.org.cn PaddleHub
  • PaddleHub 的人体骨骼关键点检测库 官方地址
 ! hub install human_pose_estimation_resnet50_mpii==1.1.1
 ! mkdir work/output_pose
 #测试是否安装成功
 ! hub run human_pose_estimation_resnet50_mpii --input_path "work/imgs/body01.jpg" --visualization True --output_dir "work/output_pose"

2.目录和资源

所有资源在work目录下

  • work/imgs 目录下是从网上找的图片资源
  • work/output_pose 是人体骨骼关键点识别后的图片目录
  • work/shadow_play_material 是皮影的素材图片
  • work/mp4_img 是视频导出的图片
  • work/mp4_img_analysis 视频图片分析结果
! mkdir work/mp4_img
! mkdir work/mp4_img_analysis
! mkdir work/shadow_play_material

# 解压皮影素材
!unzip -q -o /home/aistudio/data/data53265/shadow_play_material.zip -d /home/aistudio/work/shadow_play_material/

3. 查看单张图片的人体骨骼关键点检测效果

import os
import cv2
import paddlehub as hub
import matplotlib.pyplot as plt
from matplotlib.image import imread
import numpy as np
%matplotlib inline
def show_img(img_path, size=8):
    '''
        文件读取图片显示
    '''
    im = imread(img_path)
    plt.figure(figsize=(size,size))
    plt.axis("off")
    plt.imshow(im)


def img_show_bgr(image,size=8):
    '''
        cv读取的图片显示
    '''
    image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    plt.figure(figsize=(size,size))
    plt.imshow(image)
    
    plt.axis("off")
    plt.show() 
show_img('work/imgs/body01.jpg')

在这里插入图片描述

#通过代码获取图片中的结果
pose_estimation = hub.Module(name="human_pose_estimation_resnet50_mpii")
result = pose_estimation.keypoint_detection(paths=['work/imgs/body01.jpg'], visualization=True, output_dir="work/output_pose/")
result
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pip/_vendor/packaging/version.py:130: DeprecationWarning: Creating a LegacyVersion has been deprecated and will be removed in the next major release
  DeprecationWarning,
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pip/_vendor/packaging/version.py:130: DeprecationWarning: Creating a LegacyVersion has been deprecated and will be removed in the next major release
  DeprecationWarning,
[2021-05-07 20:50:41,355] [ WARNING] - The _initialize method in HubModule will soon be deprecated, you can use the __init__() to handle the initialization of the object
image saved in work/output_pose/body01time=1620391842.jpg

[{'path': 'work/imgs/body01.jpg',
  'data': OrderedDict([('left_ankle', [192, 679]),
               ('left_knee', [203, 521]),
               ('left_hip', [213, 347]),
               ('right_hip', [291, 347]),
               ('right_knee', [307, 521]),
               ('right_ankle', [307, 672]),
               ('pelvis', [255, 347]),
               ('thorax', [255, 166]),
               ('upper_neck', [255, 120]),
               ('head_top', [255, 22]),
               ('right_wrist', [161, 354]),
               ('right_elbow', [182, 264]),
               ('right_shoulder', [192, 166]),
               ('left_shoulder', [317, 166]),
               ('left_elbow', [333, 271]),
               ('left_wrist', [348, 362])])}]

从上面可以得到每个人体骨骼关键点的具体坐标,我们通过可视化查看前面图片分析出的结果。

show_img('work/output_pose/body01.jpg')

在这里插入图片描述

4.实现思路

要实现皮影戏的效果我们首先要解析,人体各个骨骼关键点的位置信息,通过关节点的信息计算皮影的肢体位置,和旋转方向,从而达到肢体同步。

  • 首先解析某个部位骨骼关键点的,这里以手臂进行举例:

通过PaddleHub中解析结果,获取手臂具体位置,我们可以通过肩膀(shoulder)和肘(elbow)得到,那么就可以获取对应的坐标点信

  • 通过2个骨骼关键点可以确认肢体的长度和旋转角度,根据长度就可以对素材进行缩放,根据旋转角度,可以先对素材进行中心旋转,再计算旋转后图片的位移信息,就可以得到最终映射骨骼关键点位置。将各个素材图片映射到对应的肢体上,便可以达到动作映射的效果。
    在这里插入图片描述
  • 将动作映射后的“皮影”,合并到背景图像中进行输出。

5. 让皮影动起来

具体实现步骤如下:

准备素材
将视频中每一帧保存成图片
分析图片中的人体姿势, 并转换为皮影姿势,输出结果
合并图像到视频,得到最终的结果

5.1 准备素材

含有人体动作视频,需要各位自行下载,本教程已经下载好(work/001.mp4)

PS:视频素材可以到b站舞蹈区进行下载

# 素材图片位置
input_video = 'work/001.mp4'

5.2 将视频中每一帧保存成图片

def transform_video_to_image(video_file_path, img_path):
    '''
    将视频中每一帧保存成图片
    '''
    video_capture = cv2.VideoCapture(video_file_path)
    fps = video_capture.get(cv2.CAP_PROP_FPS)
    count = 0
    while(True):
        ret, frame = video_capture.read() 
        if ret:
            cv2.imwrite(img_path + '%d.jpg' % count, frame)
            count += 1
        else:
            break
    video_capture.release()
    print('视频图片保存成功, 共有 %d 张' % count)
    return fps
# 将视频中每一帧保存成图片
fps = transform_video_to_image(input_video, 'work/mp4_img/')

5.3 分析图片中的人体姿势, 并转换为皮影姿势,保存输出

def analysis_pose(input_frame_path, output_frame_path, is_print=True):
    '''
    分析图片中的人体姿势, 并转换为皮影姿势,输出结果
    '''
    file_items = os.listdir(input_frame_path)
    file_len = len(file_items)
    for i, file_item in enumerate(file_items):
        if is_print:
            print(i+1,'/', file_len, ' ', os.path.join(output_frame_path, file_item))
        combine_img = get_combine_img(os.path.join(input_frame_path, file_item))
        cv2.imwrite(os.path.join(output_frame_path, file_item), combine_img)
# 分析图片中的人体姿势, 并转换为皮影姿势,输出结果
analysis_pose('work/mp4_img/', 'work/mp4_img_analysis/', is_print=False)

5.4 合并图像到视频

def combine_image_to_video(comb_path, output_file_path, fps=30, is_print=False):
    '''
        合并图像到视频
    '''
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')    
    
    file_items = os.listdir(comb_path)
    file_len = len(file_items)
    # print(comb_path, file_items)
    if file_len > 0 :
        temp_img = cv2.imread(os.path.join(comb_path, file_items[0]))
        img_height, img_width = temp_img.shape[0], temp_img.shape[1]
        
        out = cv2.VideoWriter(output_file_path, fourcc, fps, (img_width, img_height))

        for i in range(file_len):
            pic_name = os.path.join(comb_path, str(i)+".jpg")
            if is_print:
                print(i+1,'/', file_len, ' ', pic_name)
            img = cv2.imread(pic_name)
            out.write(img)
        out.release()
# 合并图像到视频
combine_image_to_video('work/mp4_img_analysis/', 'work/mp4_analysis.mp4', fps)
# 添加音频 mp4_analysis_result.mp4为最终输出文件
! ffmpeg -i work/mp4_analysis.mp4 -i  work/001.mp4 -c:v copy -c:a copy work/mp4_analysis_result.mp4 -y

OK, 最后我们得到动起来的皮影戏了!!!
在这里插入图片描述

四、总结

本文在弘扬传统文化同时,能让读者学习AI知识,体会到 PaddleHub 的强大, 可谓一举两得!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王鸽子

你的鼓励都是我前进的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值