SMPL论文及代码阅读

1. SMPL论文

因为下一篇论文的需要,对smpl及数据合成进行了研究,发现smpl模型刚上手实在有些懵,因此在学习之后将一些学习笔试放在本文中。因此本文不会有太多原文,而是自己在学习过程中刚开始不易理解的部分进行介绍,可以结合论文原文观看。

1.1 基础知识

在开始阅读SMPL的论文之前,有一些计算机图形学的知识需要了解:

  1. blend shape:在动画制作中常用关键帧,然后通过插值的方式补充关键帧之间的过渡,而这个插值的过程就称为blend shape。
  2. blend skinning:骨骼蒙皮也是在动画制作中,因为物体是由很多的顶点及顶点组成的面片(三角形)组成的,而我们在制作动画的时候不可能一个点一个点去调整,所以会设置几个控制点,比如人体的骨骼。对一个顶点来说,骨骼蒙皮设定了不同控制点的运动对该顶点的影响,然后通过调整控制点就可以带动整个物体一起运动了。
  3. Linear BS:线性骨骼蒙皮就是通过一个线性矩阵规定了对一个顶点而已,不同控制点运动对该点的关联程度。

1.2 模型组成

首先要知道,SMPL模型是一个加性模型,就是说其中包含的不同参数(beta和theta),对最后模型的贡献是通过相加进行融合的,使得smpl是比较简单的。

SMPL模型包含的组件如下:

  • N=6890个顶点和K=23个人体关键点。
  • 模板姿态表示为 \bar{T}\in\mathbb{R}^{3N},对应每个顶点的三维坐标。每个姿态对应一个姿态参数表示为\theta,而模板姿态的姿态参数表示为\vec{\theta}^*
  • blend weights \mathcal{W}\in\mathbb{R}^{N\times K}w_{i,j} 表示对顶点 i ,关键点 j 的运动对它的影响程度。

然后是影响人体的姿态和形体的参数:

  • shape 参数及函数 B_S(\vec{\beta}),说是函数其实就是一个矩阵的加权求和,将shape参数映射到每个顶点的偏移量。
  • \mathcal{J}(\vec{\beta}):由于人体的shape变化之后,其关键点也会发送偏移,这个函数就是在调整了shape之后对关键点进行位置调整用的。
  • B_P(\vec{\theta}):由于不同的姿态下,人体的外观也会发生一些改变,所以该函数就是在不同pose参数 \theta 下对人体顶点做一些修正用的。

需要注意几个地方:

1. pose参数和beta参数的区别:beta参数控制的是无关人体当前姿态的人体,就是说包括这个人的高矮胖瘦等,也可以理解是在模板姿态上先对人体的形态进行调整,参考文中图8:

从图中可以看到对beta参数而已,每一个元素其实对应了一种类型的人体体型;而pose参数则不同,它本身指定的只是人体关键点之间的关系,能够表示一个由人体关键点组成的姿态,与人体体型并没有对应关系。smpl是通过一个函数B_P(\vec{\theta})将这个参数映射到每个顶点的偏移的。

综上,可以认为beta是smpl引入的参数,而theta是本来就有的,只不过smpl将其考虑了进来。

2. 上述组成部分和骨骼蒙皮函数 W(\cdot):虽然上面使用\vec{\theta}对形体进行了修正,但是使用了上面提到的那些参数和函数后,人体还是处于模板姿态下的。要将模板姿态变换到目标姿态,需要使用骨骼蒙皮函数,而这个函数的选择是可以修改的,对于smpl模型来说是一个黑盒。在论文中使用了lbs或者dual-quaternion。

有了上面这两点的认识之后,可以就能看明白文中的图3了。

图(a)指定了模板姿态和骨骼蒙皮权重;图(b)通过调整shape参数调整了人体的体型,然后根据调整后的体型修正了关键点的位置;图(c)就是指定了目标姿态,不过还未对模板姿态进行变化,而是先对变换姿态带来的人体体型变换进行处理;图(d)则是在上一步之后,使用一个骨骼蒙皮函数进行姿态变换。

1.3 公式

首先需要明白文中公式(2)-(4),这部分就是对骨骼蒙皮的计算,即通过pose参数将模板姿态变换到目标姿态的过程,这里有几个地方可能需要注意:

1. 公式(2)中:这里的\bar{t}_i表示模板姿态上的顶点,通过各顶点运动的加权求和进行变换得到最后所在的位置。

2. 公式(3)中:在计算机图形学中,我们对顶点的旋转都是定义在以原点为中心的旋转矩阵,因此在对\bar{t}_i进行变换时,也得先进行逆变换将其中模板姿态中变换为以原点为中心的位置。

3. 公式(4)中:由于每个关键点的旋转矩阵都是针对其父节点而言的,因此对远端关节,他的旋转是有一个层层递进的关系的,所以这里有一个累乘。

1.4 训练

对pose参数相关的学习就是通过逐顶点与真实扫描的人体表面进行差值计算作为损失函数,需要学习的参数计算如下:

1. \mathcal{P}:除了根关键点之外的23个关键点的旋转矩阵映射至N个顶点的偏移,数量为23 * 9 * 3 * 6890

2. \mathcal{W}:为了保持稀疏,减少参数量文中规定了每个顶点至多被四个关键点影响,因此数量为4 * \mathbf{3} * 6890,这里的3比较奇怪,因为按照前文公式这里应该没有3,可能对xyz的三个维度有不同的权重?我又去对比了代码实现中,发现代码里是 24 * 6890的矩阵,每一行有四个非零值。

 3. \mathcal{J}:将经过shape参数调整后的顶点映射到关键点上,数量为23 * 3 * 6890 * 3

对shape参数的学习则是通过PCA方法,先以上面pose参数学习过程中得到的平均人体为基准,拟合shape参数学习数据集中的人体后,进行PCA降维得到300个主成分。

 2. 代码

主要是smpl官网的实例代码

其实主要是两个地方的代码,都在serialization.py中。首先是load_model中的ready_arguments函数,该函数中定义了在模板姿态上进行pose、shape参数的调整。

101-106行对应了图三(b)、107行对应了图三(c)。

然后就是load_model中的verts_core函数,其中使用了LBS(verts.py)进行骨骼蒙皮。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值