目录

一、前言

二、项目介绍

1.目的

2.技术要点

(1)读取文件

(2)标记关键节点

(3)读取每一帧图像中关键节点的坐标

(4)Unity中创建3D角色

(5)将人物动作3D化

3.需要做的准备

(1)第三方库

(2)Unity安装与使用

(3)C#了解

三、项目实现步骤

1.Python 部分

(1)读取人物动作并标记关键节点

(2)将坐标值写入文件中保存

2.Unity 部分

(1)创建项目

(2)创建空白来存储 3D 结构部位

(3)创建球体

(4)关键节点和模型的连接

(5)将分散的球体进行连接

四、总体代码

1.Python 代码

2.C# 脚本

(1)球体动画

(2)线条

五、结束语


一、前言

《功夫熊猫》、《忍者神龟》等一些大片想必大家都有了解过,里面的一个个建模角色能够出色的完成人类的动作,那么这些都是怎么实现的呢?今天我就和大家一起从零开始实现对一个视频中的人物的动作进行捕捉并将其添加到建模角色上,让建模出来的虚拟角色也可以像人类一样实现多种多样的行为动作,本次的项目实现起来有点麻烦,感兴趣的小伙伴可以一步步尝试下来,完成之后会学到很多东西呢。

二、项目介绍

1.目的

本次项目的名称为3D运动捕捉,不难猜到是需要对视频或者是摄像头中的运动的人物的姿势进行抓取并以3D的形式展现出来。简单来说就是让人物的动作能够被提取出来,方便后续的研究和观察,也可以用来进行虚拟视频的创作,给观众带来视觉上的刺激。

2.技术要点

(1)读取文件

既然是叫做3D运动捕捉的,那么肯定需要对视频或者摄像头中的人物姿势进行捕捉,第一步当然得需要读取文件,读取到的文件只要是完整的人物运动视频即可,因此如果拍摄视频的摄像头是固定的,那么将会极大地提高我们项目的准确率。

(2)标记关键节点

得到了视频文件,接下来就要标记视频中人物的身体的各个关键节点部位了,这对于Python中的第三方库 cvzone 来说就是小菜一碟。该库对人体的33个关键节点做了记录,读取视频后就能对人物的关键节点进行标记,通过节点坐标的变化我们就可以实现对人物运动姿势的把握了。

(3)读取每一帧图像中关键节点的坐标

我们已经得到了33个关键节点的坐标,每一帧图像中它们的值都会发生变化,因此我们需要将每一帧图像中的坐标值记录下来。记录下来的坐标值我们可以创建一个文件来进行存放,在后续的过程中将会使用到这些坐标点。具体的记录实现方式我将在下面的实现步骤中讲解,希望大家能够耐住性子继续往下看!!

(4)Unity中创建3D角色

使用 Unity 创建一个简单的由33个球体和几条线段组成的角色,Unity 的下载和安装我就不在这里赘述了,大家可以在网上找找,一搜一大堆!!创建3D角色的步骤将会在下面的实现步骤中详细介绍。

(5)将人物动作3D化

主要是在 Unity 中使用 C# 脚本将我们的坐标点的变化连接到创建的3D角色身上,其他的就是调整Unity 中的相机的一些参数使我们的3D形象更加合理‘上镜’即可。

3.需要做的准备

(1)第三方库

在本次项目中我们使用 Python 主要是完成人物运动的捕捉和关键节点的标记,并记录一下简单的坐标点的变化,所以只需要一些基础的视觉库即可:

import cv2
from cvzone.PoseModule import PoseDetector

在使用 cvzone 时我本人出现过一些问题并记录了下来,如果有小伙伴遇到同样的问题应该能简单的帮到你:cvzone 中 PoseDetector 读取视频坐标信息问题

(2)Unity安装与使用

这个软件的下载和安装没太大的什么问题,我是使用 vx公众号 伙伴神 下载的,但它提供的2020版有问题,下载并安装2019版就可以了。至于使用的话现学现卖吧,反正也不是很难。

(3)C#了解

使用C#语言我们需要编写脚本来连接坐标点和3D模型,可能大家会觉得没学过啊、很难啊啥的,但不用怕,我们也不需要掌握全部,就简单使用几个语法,创建几个列表,能达到我们的目标就好。

三、项目实现步骤

1.Python 部分

我们本次的项目是需要结合多种工具才能完成的,利用 Python 我们可以得到视频文件中的人物的运动状态并标记身上的33个关键节点,随后将这些关键节点的坐标值存储到一个文件中。

(1)读取人物动作并标记关键节点

读取视频文件后需要对视频中的人物的身体上的关键节点进行标记,这里我们只要使用下面的函数

img = detector.findPose(img)#标记姿势关键节点

就可以标记出我们需要的坐标点了,如下:

但我们也仅仅是标记出了节点,并没有记录每一个节点的坐标值,所以我们接下来要创建一个列表专门来存储每一帧图像中的关键点的坐标值,来方便我们后续将这些点保存到文件中,当然我们也可以打印我们存储的列表的长度,来判断我们的视频的帧数。我们需要用到下面的函数来帮我们读取每一个坐标点的坐标值:

lmList, bboxInfo = detector.findPosition(img) #获取视频中的姿势信息

有了上面的步骤我们就能检测视频中人物的运动状态了,阶段性的代码如下(仅用来参考,总体代码文章后面会发):

cap = cv2.VideoCapture('Video.mp4')
detector = PoseDetector()
posList = []
while True:success, img = cap.read()img = detector.findPose(img)#标记姿势关键节点lmList, bboxInfo = detector.findPosition(img) #获取视频中的姿势信息if bboxInfo:            #判断是否检测到一个身体lmString = ''       #创建一个空的字符串for lm in lmList:   #'lm'为'landmark'的缩写,即33个关键节点lmString += f'{lm[1]},{img.shape[0] - lm[2]},{lm[3]},' #最后一个逗号保留,这样每一个坐标值才能分离开来posList.append(lmString)print(len(posList))#打印视频帧数

(2)将坐标值写入文件中保存

上面已经将我们的坐标值存储在了列表中,但为了后续的3D转换,我们需要将这些坐标值存储到一个 .txt 文件中。代码如下:

    if key == ord('s'):   #将坐标点写入一个 .txt文件with open("AnimationFile.txt", 'w') as f:f.writelines(["%s\n" % item for item in posList])

当我们在视频结束时按下 's',就会将我们得到的所有坐标点存储到 ‘AnimationFile.txt’ 文件中,通过前面的得到的帧数我们可以判断我们的文件中的坐标点存储情况。

比如,我们读取到的帧数如下:

然后得到的文件的数据行数如下:

比视频帧数少了几行,但可以接受,因为我们也没办法在视频的最后一帧处按下 's' 。

2.Unity 部分

使用 Python 实现对人物关键节点坐标值的记录后,我们需要将记录下来的那些坐标点应用到3D模型中去,这里就要使用到 Unity 来进行创建了,总体来说比较简单,大胆尝试就好。

(1)创建项目

首先我们需要创建一个新的项目,然后在该项目中右键创建一个空白,命名为 manager,这个空白文件夹是比较重要的,后面我们需要用到它来存储我们的一些 C# 脚本。

(2)创建空白来存储 3D 结构部位

要完成一个3D建模,我们得需要一些线条,球体等物件,而我们创建的该空白文件夹就是用来存储这些部位的,至于该文件夹的命名方式可以自己考虑,我这边是命名为 body ,用来存放我们的球体和线条。

(3)创建球体

我们需要33个球体来代表得到的33个关键节点,因此接下来应该要做的就是右键点击 body 并创建一个 sphere, 在下方的空白处点击右键创建 material 将颜色选为自己喜欢的颜色,并拖动刚刚创建好的 material 到 body 下的 sphere 上,这样就可以创建一个自定义颜色的球体了,如果需要的话还可以点击 sphere 并在右边展开的栏目中修改 size ,最后复制 body 中的 sphere 并粘贴到 body 下,一共粘贴 32 次即可,至于命名可以自己考虑。

(4)关键节点和模型的连接

我们需要将之前在 Python 部分得到的关键节点坐标值文件复制到我们的项目下面,并创建一个 C# 脚本来关联,这个 C# 文件我们要拖到 manager 文件下进行管理。

上面两幅图就是我们创建的脚本文件以及添加到 manager 下的视图。

接下来我们需要将 body 类的 size 改为 33 并将下面的 sphere 按顺序拖动到对应的对象中,然后我们编写 C# 脚本进行关联,脚本代码我会放在文章后面部分。

(5)将分散的球体进行连接

通过前面的步骤,我们已经能够让那 33 个点完成简单的一些动作了,但我们还是尝试一下将那些分散的点连接起来,这样我们的项目才算比较完整。

首先我们需要在 body 下面创建一个空白并命名为 Lins(因为在该空白下我们要用来存储其他的所有线条,因此命为复数形式),然后按照前面的创建 sphere 的步骤我们可以在 Lines 下面创建一个 line 并选择合适的材料。

接下来我们需要再次创建一个脚本,主要目的是为每一个线条选择起点和终点(其实就是每一个之前创建的球体),脚本的代码还是会发布在文章后面,通过该脚本我们就可以实现对线条的位置的设定。

该怎么连接这些线条呢?我们可以观察 mediapipe 中的人体节点,结合下面这张图,我们就可以设置每一个线条的起点和终点:

然后我们复制之前的第一个线条,并粘贴到 Lines,接下来进行简单枯燥的拖动就可以了(将对应的 sphere 拖动到线条的起点和终点上,一一对应即可):

然后我们点击运行,应该就能看见我们的项目成功了。

四、总体代码

1.Python 代码

"""
Author:XiaoMa
CSDN Address:一马归一码
"""
import cv2
from cvzone.PoseModule import PoseDetectorcap = cv2.VideoCapture('Video.mp4')
detector = PoseDetector()
posList = []
while True:success, img = cap.read()img = detector.findPose(img)#标记姿势关键节点lmList, bboxInfo = detector.findPosition(img) #获取视频中的姿势信息if bboxInfo:            #判断是否检测到一个身体lmString = ''       #创建一个空的字符串for lm in lmList:   #'lm'为'landmark'的缩写,即33个关键节点lmString += f'{lm[1]},{img.shape[0] - lm[2]},{lm[3]},' #最后一个逗号保留,这样每一个坐标值才能分离开来posList.append(lmString)print(len(posList))cv2.imshow("Image", img)key = cv2.waitKey(1)if key == ord('s'):   #将坐标点写入一个文件with open("AnimationFile.txt", 'w') as f:f.writelines(["%s\n" % item for item in posList])

2.C# 脚本

(1)球体动画

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System.Threading;public class AnimationCode : MonoBehaviour
{public GameObject[] Body;List<string> lines;int counter = 0;void Start(){lines = System.IO.File.ReadLines("Assets/AnimationFile.txt").ToList();}void Update(){string[] points = lines[counter].Split(',');for (int i =0; i<=32;i++){float x = float.Parse(points[0 + (i * 3)]) / 100;float y = float.Parse(points[1 + (i * 3)]) / 100;float z = float.Parse(points[2 + (i * 3)]) / 300;Body[i].transform.localPosition = new Vector3(x, y, z);}counter += 1;if (counter == lines.Count) { counter = 0; }Thread.Sleep(30);}
}

(2)线条

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class LineCode : MonoBehaviour
{LineRenderer lineRenderer;public Transform origin;public Transform destination;void Start(){lineRenderer = GetComponent<LineRenderer>();lineRenderer.startWidth = 0.1f;lineRenderer.endWidth = 0.1f;}void Update(){lineRenderer.SetPosition(0, origin.position);lineRenderer.SetPosition(1, destination.position);}
}

五、结束语

本次项目的实现不算很难,尤其是 Python 部分,但复现起来较为繁琐,一步步地跟着做应该没啥问题。合抱之木,生于毫末,加油!

3D Motion Capture(3D运动捕捉)相关推荐

  1. Sketch-Based Skeleton-Driven 2D Animation and Motion Capture 翻译

    本文发表于2011年. Abstract 我们提出了一种新颖的基于草图的2D动画技术,该技术允许用户有效地产生2D角色动画.它由两部分组成:基于草图的骨架驱动2D动画制作和2D运动捕捉.用户输入角色的 ...

  2. 科学怪物!3D人体全身运动捕捉系统,港中文联合Facebook出品

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者 | VVingerfly 编辑 | 陈大鑫 3D人体姿态和形状估计在最近几年是一个重要的研究热点 ...

  3. gMOP3D,MOtion Path 3D 运动仿真软件

    https://sourceforge.net/projects/gmop3d/ gmop3d是一款机械手臂(轴旋转运动)或工业机器人的运动仿真软件,他仅仅提供算法,不依赖任何第三方软件包,不依赖G代 ...

  4. After Effects Guru: Time-Lapse 3D Motion and Compositing After Effects Guru:延时3D运动和合成 Lynda课程中文字幕

    After Effects Guru: Time-Lapse 3D Motion and Compositing 中文字幕 After Effects Guru:延时3D运动和合成 中文字幕After ...

  5. Android Motion Stills实现AR即时运动捕捉

    为视频短片增加有趣的3D对象,通过Android Motion Stills就可以实现.近日,Google宣布对Motion Stills增加了AR功能.本文由LiveVideoStack摘译,点击『 ...

  6. 全身捕捉vr_在VR内部制作动画:混合运动捕捉和关键帧

    全身捕捉vr In the Unity Labs Authoring Tools Group, we explore the future of content creation, namely ar ...

  7. Facial Motion Capture 调研

    开源 Regressing Robust and Discriminative 3D Morphable Models with a very Deep Neural Network(2017 CVP ...

  8. 旋转or跳跃?基于互联网视频的人体运动捕捉

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 基于图像的人体姿势估计的最新进展使从单个RGB视频捕捉3D人体运动成为可能.但是,单视图固有的深度不确定性和自遮挡问题导致其恢复的结果无 ...

  9. CMU运动捕捉数据处理 MOCAP(一)——数据介绍

    MOCAP(一) 研究生期间做了很长时间的运动捕捉数据方向的,由于运动通过运动捕捉采集的数据比较抽象,现将数据格式的介绍和一些预处理记录下. 常用的运动捕捉数据集有: CMU运动捕捉数据库 HDM05 ...

  10. CMU运动捕捉数据库MOCAP

    MOCAP(一) 常用的运动捕捉数据集有: CMU运动捕捉数据库 HDM05数据库 常用的数据格式有: ASF/AMC BVH C3D 其中,ASF/AMC是由骨架数据文件(ASF)和运动数据文件(A ...

最新文章

  1. 2022-2028年中国氨基酸表面活性剂行业研究及发展前瞻报告
  2. elementui select组件选中后无法自动刷新更新值渲染到页面中
  3. git submodule获取子模块
  4. 总体参数的估计(概念)
  5. [译文]c#扩展方法(Extension Method In C#)
  6. 超图三维GIS在线示例
  7. OpenCASCADE:形状愈合之通用拆分工具
  8. mysql查询 百万_MySQL百万级数据分页查询优化
  9. 【Flink】Flink 操作HDFS报错 hadoop is not in the classpath/dependencies
  10. php 对象转xml字符串_php方法simplexml_load_string()解析xml转数组失败
  11. sql server 死锁排查
  12. DataGear 1.13.1 发布,数据可视化分析平台
  13. Linux编译Ralink无线网卡驱动
  14. 190502 Expressing Belief
  15. Java 处理资源的try语句 (try-with-resources, TWR)
  16. OpenJ_Bailian 2748
  17. 网上关于'好人卡'的定义
  18. BMC Eaglestream利用PECI计算CPU、Memory功耗
  19. mysql删除不彻底,mysql删除不彻底的解决方法
  20. 【玩转ms17-010】mysql数据库-脱裤实践

热门文章

  1. dbutils mysql_mysql dbutils
  2. 九歌创作诗词计算机系统,人工智能辅助古诗词学习:以清华大学“九歌”诗词写作系统为例...
  3. 【CGAL_网格处理】平滑处理
  4. XUI -Android原生UI框架的配置
  5. 什么样的人适合学编程?
  6. Mac 通过adb安装apk文件
  7. net-java-php-python-社会福利保障系统计算机毕业设计程序
  8. 1023组成最小数(20分) - 用不到20行代码破解20分的题目
  9. 从零开始搭建ABP框架(Asp .Net Boilerplate)+Oracle(11 g)
  10. python语言的多行注释以什么开头和结尾_python多行注释