姿态估计旨在 RGB 图片和 Video 中的人体像素映射到肢体的三维曲面(3D surface),其涉及了很多计算机视觉任务,如目标检测,姿态估计,分割,等等. 姿态估计的应用场景不仅包括关键点定位,如图形(Graphics),增强显示(Augmented Reality, AR),人机交互(Human-Computer Interaction,HCI),还包括 3D 目标识别的很多方面.
层出不穷的姿态检测深度网络模型,在最近两三年如雨后春笋般出现。今天我们选AlphaPose导出骨骼3D关键点位置,并在游戏引擎的去运行相关的模型。相关的代码都已提交到github, 我们提供算法解决视频2D到游戏3D骨骼的转换。算法不局限于抖音上的视频, 只是作者使用的视频都是从抖音上爬来的。
识别视频
首先将从抖音扒来的视频导入到模型,由AlphaPose生产识别后的运动姿势, 并使用Video3DPose中的方法渲染成视频, 如下:
使用工具将numpy格式的数据转换成二进制(bytes), 以供之后在unity里解析使用。我们输出的时候查看numpy对象shape是(x,17,3), 第一维x代表帧数, 第二维代表17个关节,第三维代表关键点(joint)的3d位置。
Unity 运行模型
将上一步Python环境里生成的关键点信息(二进制文件),导入到Unity里,使用IO接口解析出来,由于Video3DPose默认使用的[hunman3.6数据集]骨骼的标记是17个部位,这里我们创建了17个GameObject,代表17个关节节点, 并使用LineRender组件把相关的关节连接成线。在Mono的Update函数,我们更新导出模型的3d关键点位置信息,于是一个运动的骨骼人行动起来了。 关于[hunman3.6数据集]关节编号的详细介绍,见本文最后的附录。
代码如下, 在Update中插值更新17组关节的位置,pose_joint数组的顺序对应到hunman3.6数据集关节编号。
protected override void LerpUpdate(float lerp)
{
Hip.position = Vector3.Lerp(Hip.position, pose_joint[0], lerp);
RHip.position = Vector3.Lerp(RHip.position, pose_joint[1], lerp);
RKnee.position = Vector3.Lerp(RKnee.position, pose_joint[2], lerp);
RFoot.position = Vector3.Lerp(RFoot.position, pose_joint[3], lerp);
LHip.position = Vector3.Lerp(LHip.position, pose_joint[4], lerp);
LKnee.position = Vector3.Lerp(LKnee.position, pose_joint[5], lerp);
LFoot.position = Vector3.Lerp(LFoot.position, pose_joint[6], lerp);
Spine.position = Vector3.Lerp(Spine.position, pose_joint[7], lerp);
Thorax.position = Vector3.Lerp(Thorax.position, pose_joint[8], lerp);
Neck.position = Vector3.Lerp(Neck.position, pose_joint[9], lerp);
Head.position = Vector3.Lerp(Head.position, pose_joint[10], lerp);
LShoulder.position = Vector3.Lerp(LShoulder.position, pose_joint[11], lerp);
LEblow.position = Vector3.Lerp(LEblow.position, pose_joint[12], lerp);
LWrist.position = Vector3.Lerp(LWrist.position, pose_joint[13], lerp);
RShoulder.position = Vector3.Lerp(RShoulder.position, pose_joint[14], lerp);
REblow.position = Vector3.Lerp(REblow.position, pose_joint[15], lerp);
RWrist.position = Vector3.Lerp(RWrist.position, pose_joint[16], lerp);
}
怎么能使游戏的Avatar的3D模型也能像输入模型那样运动起来呢? 换句话说,如何求一种解法将上一步的人形转换为游戏的绑定顶点的骨骼。我们知道3D角色的骨骼动画都是在CPU端层级计算的,上一级关节是下一节关节的原点坐标,由于关节之间的部位长度是固定的,于是问题转换成了求父关节的旋转,即四元数。当父关节的旋转固定的时候,子关节的位置随即也确定了。
对于旋转的求法, 先根据父子关节关系求一个角度, 然后在根据关键点模型里的位置算一个角度, 使用Quaternion.FromToRotation得到一个旋转四元数, 然后在当前的基础上旋转得到目标四元数,最后在Update里由当前插值到目标四元数就行了。代码实现如下:
private void UpdateBone(AvatarTree tree, float lerp)
{
var dir1 = tree.GetDir();
var dir2 = pose_joint[tree.idx] - pose_joint[tree.parent.idx];
Quaternion rot = Quaternion.FromToRotation(dir1, dir2);
Quaternion rot1 = tree.parent.transf.rotation;
tree.parent.transf.rotation = Quaternion.Lerp(rot1, rot * rot1, lerp);
}
unity里运行效果如图所示:
如果想看更多的运行效果,参考附录视频。
TIP
一般的情况下游戏里的Avatar关节和Human3.6数据集里的骨骼不是匹配的,往往游戏或者3D Max等美术制作的工具里的骨骼设置的更多,这时候可以跟动作设计师提出跟Hum3.6数据集的骨骼蒙皮解决方案。 如果是已经导出的fbx,我们也得保证关节层级的对应,应该上述算法得到的旋转四元数是基于父节点的local坐标系的。 解决方法就是把fbx在Unity引擎转换为Prefab, 然后再更改Prefab的关节层级结构。
从上面视频我们可以看到, AlphaPose 虽然能很好的识别出骨骼节点的位置, 但这不包含手指等小关节的姿势, 所以从上而下手都是僵硬的, 但是从卡内基梅隆大学的OpenPose(最新版)已经能识别手指的动作,甚至还包含一些脸部的表情,真的是非常强大了。
附录1:
姿态估计开源深度学习模型汇总:
AlphaPose
AlphaPose 是上海交通大学开源的精确多人姿态估计,声称是第一个开源系统.
AlphaPose 可以同时对图片, videos,以及图片列表,进行姿态估计和姿态追踪(pose tracking). 可以得到很多不同的输出,包括 PNG,JPEG,AVI 格式的关键点图片,JSON 格式的关键点输出,便于很多应用场景.AlphaPose 采用区域多人姿态估计(regional multi-person pose estimation, RMPE)框架,以在人体边界框不准确的情况下,提升姿态估计. 其主要包括三部分:
- Symmetric Spatial Transformer Network (SSTN)
- Parametric Pose Non-Maximum-Suppression (NMS)
- Pose-Guided Proposals Generator (PGPG)
OpenPose
OpenPose 是 CMU Perceptual Computing Lab 开源的一个实时多人关键点检测库.
OpenPose 提供了 2D 和 3D 多人关键点检测方法,以及特定参数的姿态估计的标准化工具包.
OpenPose 可以采用很多不同的输入方式,如,图片image, 视频video,IP相机camera,等等.
OpenPose 的输出也可以是很多不同形式,如图片和关键点(PNG,JPG,AVI),可读格式的关键点(JSON,XML,YML),甚至是数组类.OpenPose 的输入和输出参数,还可以根据需要进行调整. OpenPose 提供了 C++ API,可以在 CPU 和 GPU 上运行,也兼容 AMD 显卡.
DensePose
DensePose 出自 Facebook Research,其开源了 DensePose 实现的代码,模型和数据集.
DensePose 数据集,DensePose-COCO,用于人体姿态估计的大规模数据集.
DensePose-COCO 数据集,是在 50K COCO 图片上手工标注的图片-表面(image-to-surface)对应的大规模数据集.
DensePose 论文提出了 DensePose-RCNN,是 Mask-RCNN 的一个变形,针对每秒多帧的每个人体区域,其回归密集地回归特定肢体部分的 UV 坐标.
DensePose 基于 DenseReg: Fully Convolutional Dense Shape Regression In-the-Wild - 2016.
DensePose 的目标是确定每个像素点的曲面位置(surface location),以及该肢体曲面所属的对应 2D 参数化.
DensePose 采用了基于 FPN 的 Mask R-CNN 结构,RoI-Align Pooling.
此外,DensePose 在 RoI-Pooling 的输出端加入全卷积网路.
附录2
human3.6m关节点标注顺序
序号 | 数据集标注顺序 | 关节名 | 中文名 |
---|---|---|---|
0 | 0 | hip | 臀部 |
1 | 1 | rhip | 右臀部 |
2 | 2 | rknee | 右膝盖 |
3 | 3 | rfoot | 右脚踝 |
4 | 6 | lhip | 左臀部 |
5 | 7 | lknee | 左膝盖 |
6 | 8 | lfoot | 左脚踝 |
7 | 12 | spine | 脊柱 |
8 | 13 | thorax | 胸部 |
9 | 14 | neck | 颈部 |
10 | 15 | head | 头部 |
11 | 17 | lshoulder | 左肩 |
12 | 18 | lelbow | 左手肘 |
13 | 19 | lwrist | 左手腕 |
14 | 25 | rshoulder | 右肩 |
15 | 26 | relbow | 右手肘 |
16 | 27 | rwrist | 右手腕 |
COCO数据集骨骼关节keypoint标注对应
序号 | 数据集标注顺序 | 关节名 | 中文名 |
---|---|---|---|
0 | 0 | nose | 鼻子 |
1 | 1 | L eye | 左眼 |
2 | 2 | R eye | 右眼 |
3 | 3 | L ear | 左耳 |
4 | 4 | R ear | 右耳 |
5 | 5 | L shoulder | 左肩 |
6 | 6 | R shoulder | 右肩 |
7 | 7 | L elbow | 左手肘 |
8 | 8 | R elbow | 右手肘 |
9 | 9 | L wrist | 左手腕 |
10 | 10 | R wrist | 右手腕 |
11 | 11 | L hip | 左臀部 |
12 | 12 | R hip | 右臀部 |
13 | 13 | knee | 左膝盖 |
14 | 14 | R knee | 右膝盖 |
15 | 15 | L ankle | 左脚踝 |
16 | 16 | R ankle | 右脚踝 |
Openpose-Body25数据集骨骼关节keypoint标注对应
序号 | 数据集标注顺序 | 关节名 | 中文名 |
---|---|---|---|
0 | 0 | Nose | 鼻子 |
1 | 1 | Neck | 脖子 |
2 | 2 | RShoulder | 右肩 |
3 | 3 | RElbow | 右手肘 |
4 | 4 | RWrist | 右手腕 |
5 | 5 | LShoulder | 左肩 |
6 | 6 | LElbow | 左手肘 |
7 | 7 | LWrist | 左手腕 |
8 | 8 | MidHip | 中臀 |
9 | 9 | RHip | 右臀 |
10 | 10 | RKnee | 右膝盖 |
11 | 11 | RAnkle | 右脚踝 |
12 | 12 | LHip | 左臀 |
13 | 13 | LKnee | 左膝盖 |
14 | 14 | LAnkle | 左脚踝 |
15 | 15 | REye | 右眼 |
16 | 16 | LEye | 左眼 |
17 | 17 | REar | 右耳 |
18 | 18 | LEar | 左耳 |
19 | 19 | LBigToe | 左大拇指 |
20 | 20 | LSmallToe | 左小拇指 |
21 | 21 | LHeel | 左脚跟 |
22 | 22 | RBigToe | 右大拇指 |
23 | 23 | RSmallToe | 右小拇指 |
24 | 24 | RHeel | 右脚跟 |
附录3
更多从抖音扒来的的视频姿势识别参见:
- Alphapose 模型渲染系列
- Unity Skeleton动画
- Unity Avatar动画
参考文献:
- Densepose by Facebook
- Detectron by Facebook
- DensePose-COCO 数据集
- AlphaPose 上海交大
- CMU Perceptual Computing Lab
- OpenPose by CMU
- Paper - DensePose: Dense Human Pose Estimation In The Wild-2018
- human3.6m数据集骨骼关节keypoint标注对应
- COCO数据集骨骼关节keypoint标注对应
- VideoPose3D by Facebook
- [目标检测] YOLO
- 商汤科技 AR游戏同步角色动作
- PanopticStudio 3D PointCloud Dataset
- 基于跨视角信息融合的三维人体姿态估计 微软