本文主要是介绍《Neural Pose Transfer by Spatially Adaptive Instance Normalization》,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概括: 对identity mesh 做pose transfer, 实际上是让提供目标pose的human mesh 学到identity的style。关键在于要让生成的mesh的点的顺序和identity mesh的一致而不是pose mesh。
传统的做法是学习在同一个pose下,不同identity style 之间的correspondence,利用correspondence 去算displacement。
做法:这里用PointNet提取点的特征,把每个vertex当做一个point , 但是注意,mesh和point cloud还是不同的,在mesh里我们还需要考虑face, 也就是每个面上的顶点,点与点的连接方式会影响我们的最后结果。
input data中包含identity mesh和pose mesh,用mesh = pymesh.load_mesh读出来是(6890,3) ,也就是6890个点,3通道代表坐标,mesh.faces 还可以得到这个human body的面(13776,3),一共13776个面,这里的3通道指的是组成一个面的3个连接点的index。
对于pose_mesh,文章里用到两种处理方式, 这里贴出代码可以直观一点。
class PoseFeature(nn.Module):def __init__(self, num_points = 6890):super(PoseFeature, self).__init__()self.conv1 = torch.nn.Conv1d(3, 64, 1)self.conv2 = torch.nn.Conv1d(64, 128, 1)self.conv3 = torch.nn.Conv1d(128, 1024, 1)self.norm1 = torch.nn.InstanceNorm1d(64)self.norm2 = torch.nn.InstanceNorm1d(128)self.norm3 = torch.nn.InstanceNorm1d(1024)### torch.nn.InstanceNorm1d [N,C,L] -> [N,C,L]self.num_points = num_pointsdef forward(self, x): # B, 3,6890x = F.relu(self.norm1(self.conv1(x)))x = F.relu(self.norm2(self.conv2(x)))x = F.relu(self.norm3(self.conv3(x)))
############# model_maxpoolx,_ = torch.max(x, 2) #归一化 B 1024 1x = x.view(-1, 1024)x = x.view(-1, 1024, 1).repeat(1, 1, self.num_points) # B 1024 6890return x
一种处理方式是在### model__maxpool 上面就结束了,在这一步就把x=F.relu(xxx) 作为最终结果return, 一种处理方式是加上下面三行代码,用torch.max 先对dim=2 归一化,然后再复制6890个,这样子做应该是为了证明无论所有点的Order如何,都不影响最终的结果,因为都是取最大的那个点再复制。
需要注意的是,不同于我们在图像上做2维卷积,会对图像的大小进行改变,随着叠加卷积层,特征图会越来越小(如果不考虑Padding的话),而在3d上做1维卷积,用的都是kernel=1的卷积核,不会改变大小,整个过程只改变了通道数。
后面的decoder是参考图像上spade的方法,之前也有介绍过,就不详述了。
这篇关于《Neural Pose Transfer by Spatially Adaptive Instance Normalization》的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!