文章目录
前言
资源来自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 的强大, 可谓一举两得!