自然场景中的弱监督网格卷积手部重构.

目前已有的手部重构方法在非实验室环境下的样本上泛化性不好,一方面是因为公开数据集都是实验室环境下的标注,背景、光线相对单一,收集到的手部动作也相对单一;另一方面公开数据集的数据量也比较有限,这都限制了现有方法在真实场景下的表现。

本文作者提出了一套弱监督策略,用Youtube的无标注视频制作了一个数据集,并提出了一个新的模型结构。实验证明,这个模型在已有的公开数据集上性能超越了过去的工作,再加上他们的数据集训练后,取得了大幅超越前人的成果。

1. 自动数据收集系统

在手部重构任务中,过去的方法和数据大都是实验室环境下的产物,与真实场景差别太;本文作者决定自己收集制作一个符合真实世界场景的数据集。

这个数据集的来源是Youtube上的手语视频,手语视频的好处很多,既出现了各种真实世界场景,又包括了各种各样复杂的手势,同时还有很高的清晰度,唯一的问题在于这些视频是没有标注的。

Openpose2017CMU开源的一套人体姿态估计系统,可以同时对身体、面部、手部、脚部进行姿态估计,在保证较高精度的同时又保有实时处理的速度,并且发布的版本相当完善,很适合用来进行机器标注。作者使用Openpose对视频抽帧得到的图片进行了机器标注,通过置信度阈值筛选得到了很小的、标注相对精确的图片子集,得到了手部的2D关键点标注。

MANO是近年开源的一套很成熟的手部建模生成模型,只需要输入两组向量参数,就可以直接生成对应姿态的21个关键点和778个点的手部表面建模,这可以给很多遮挡、手与物体交互等过去比较困难的场景带来先验知识。

MANO的输入是两组向量参数,而现在只有Openpose生成的2D标注,因此还需要一个简单的模型来将2D标注转化成对应的向量参数。通过将标注数据作为输入,与MANO输出的关键点进行对比计算损失,就可以训练拟合得到一个参数生成矩阵。实际操作中,这里的损失设计得更复杂一点,同时计算了2D点位置的损失和手指骨骼长度比例的损失。其中骨骼损失的计算公式如下:

\[\mathcal{L}_{\text{bone}}(J, Y) = \sum_{(i,j) \in \epsilon} \left| ||J_{2D_i}-J_{2D_j}|| - ||Y_{2D_i}-Y_{2D_j}|| \right|\]

其中$J_{2D}$是模型预测的关键点,$Y_{2D}$是Ground Truth,该公式约束了每个关键点之间的空间关系,同时相当于约束了每根骨骼的长度,能帮助学习到骨头长度关系,避免预测出一些诡异的不存在的姿态。

class JointBoneLoss(nn.Module):
    def __init__(self, joint_num):
        super(JointBoneLoss, self).__init__()
        id_i, id_j = [], []
        for i in range(joint_num):
            for j in range(i+1, joint_num):
                id_i.append(i)
                id_j.append(j)
        self.id_i = id_i
        self.id_j = id_j

    def forward(self, joint_out, joint_gt):
        if len(joint_out.shape) == 4: # (b, n, h, w) heatmap-based featuremap 
            calc_dim = [2, 3]
        elif len(joint_out.shape) == 3:# (b, n, 2) or (b, n, 3) regression-based result
            calc_dim = -1
        
        J = torch.norm(joint_out[:,self.id_i,:] - joint_out[:,self.id_j,:], p=2, dim=calc_dim, keepdim=False)
        Y = torch.norm(joint_gt[:,self.id_i,:] - joint_gt[:,self.id_j,:], p=2, dim=calc_dim, keepdim=False)
        loss = torch.abs(J-Y)
        return loss.mean()

这套系统完整地将无标注视频制作成有3D标注的数据集,作者用这种方法从Youtube视频制作了4w5张图片,同时又用该系统从COCO中得到了5k张,最终形成了一个5W图片的数据集。

2. 手部重建模型

除了更好的数据集,作者也提出了一个表现更优的模型,该模型在公开数据集上的表现也超越了之前的工作。这个模型的结构很简单,由encoderdecoder两部分组成,其中encoder的部分使用的就是标准的ResNet50作为backbonedecoder则用到了螺旋卷积和上采样,通过这个模型直接学习2D图片到3D网格节点的映射。

螺旋卷积是指用顺时针的螺旋形来对一片网状节点进行排序,选取一个节点$v$作为第$0$圈,所有与$v$连接的节点作为第$1$圈,与第$1$圈中所有节点相连的点为第$2$圈,以此类推,最终就可以得到一个序列$S(v)$来描述这片网状节点。