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

本文主要是介绍人工智能学习之使用百度大脑在线AI Studio实现人体皮影戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、项目背景
  • 二、效果展示
  • 三、实现步骤
    • 1.安装依赖库
    • 2.目录和资源
    • 3. 查看单张图片的人体骨骼关键点检测效果
    • 4.实现思路
    • 5. 让皮影动起来
      • 5.1 准备素材
      • 5.2 将视频中每一帧保存成图片
      • 5.3 分析图片中的人体姿势, 并转换为皮影姿势,保存输出
      • 5.4 合并图像到视频
  • 四、总结


前言

资源来自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 releaseDeprecationWarning,
/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 releaseDeprecationWarning,
[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 = 0while(True):ret, frame = video_capture.read() if ret:cv2.imwrite(img_path + '%d.jpg' % count, frame)count += 1else:breakvideo_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 的强大, 可谓一举两得!

这篇关于人工智能学习之使用百度大脑在线AI Studio实现人体皮影戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/202635

相关文章

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

springboot filter实现请求响应全链路拦截

《springbootfilter实现请求响应全链路拦截》这篇文章主要为大家详细介绍了SpringBoot如何结合Filter同时拦截请求和响应,从而实现​​日志采集自动化,感兴趣的小伙伴可以跟随小... 目录一、为什么你需要这个过滤器?​​​二、核心实现:一个Filter搞定双向数据流​​​​三、完整代码