点云补全概念
点云补全就是希望基于观察到的残缺不全的点云生成完整的 3D 点云。由于扫描或者距离的原因导致点云局部缺失,对其进行补全,传统算法可能会补不完整,也可能会补的过于完整。
点云补全(PF-Net)
今天这里要讲的是PF-Net: Point Fractal Network for 3D Point Cloud Completion,整体网络模型:
点云补全网络模型
骨骼点逐级恢复点云
最远点采样
- 利用骨骼点来逐级恢复点云
- 在构建标签时依旧选择最远点采样
特征提取
- 特征提取,融合多尺度特征,信息更丰富
PF-Net特征提取代码实现如下:
def forward(self,x):
print(x.shape)
x = torch.unsqueeze(x,1)
print(x.shape)
x = F.relu(self.bn1(self.conv1(x)))
print(x.shape)
x = F.relu(self.bn2(self.conv2(x)))
print(x.shape)
x_128 = F.relu(self.bn3(self.conv3(x)))
print(x_128.shape)
x_256 = F.relu(self.bn4(self.conv4(x_128)))
x_512 = F.relu(self.bn5(self.conv5(x_256)))
x_1024 = F.relu(self.bn6(self.conv6(x_512)))
print(x_1024.shape)
x_128 = torch.squeeze(self.maxpool(x_128),2)
print(x_128.shape)
x_256 = torch.squeeze(self.maxpool(x_256),2)
x_512 = torch.squeeze(self.maxpool(x_512),2)
x_1024 = torch.squeeze(self.maxpool(x_1024),2)
print(x_1024.shape)
L = [x_1024,x_512,x_256,x_128]
x = torch.cat(L,1)
print(x.shape)
return x
- 输出各阶段预测点,还考虑骨骼之间的关系
分层预测
PF-Net分层预测代码实现如下:
def forward(self,x):
print(np.array(x).shape)
x = self.latentfeature(x)
print(x.shape)
x_1 = F.relu(self.fc1(x)) #1024
print(x_1.shape)
x_2 = F.relu(self.fc2(x_1)) #512
print(x_2.shape)
x_3 = F.relu(self.fc3(x_2)) #256
print(x_3.shape)
pc1_feat = self.fc3_1(x_3)
print(pc1_feat.shape)
pc1_xyz = pc1_feat.reshape(-1,64,3) #64x3 center1
print(pc1_xyz.shape)
pc2_feat = F.relu(self.fc2_1(x_2))
print(pc2_feat.shape)
pc2_feat = pc2_feat.reshape(-1,128,64)
print(pc2_feat.shape)
pc2_xyz =self.conv2_1(pc2_feat) #6x64 center2
print(pc2_xyz.shape)
pc3_feat = F.relu(self.fc1_1(x_1))
print(pc3_feat.shape)
pc3_feat = pc3_feat.reshape(-1,512,128)
print(pc3_feat.shape)
pc3_feat = F.relu(self.conv1_1(pc3_feat))
print(pc3_feat.shape)
pc3_feat = F.relu(self.conv1_2(pc3_feat))
print(pc3_feat.shape)
pc3_xyz = self.conv1_3(pc3_feat) #12x128 fine
print(pc3_xyz.shape)
pc1_xyz_expand = torch.unsqueeze(pc1_xyz,2)
print(pc1_xyz_expand.shape)
pc2_xyz = pc2_xyz.transpose(1,2)
print(pc2_xyz.shape)
pc2_xyz = pc2_xyz.reshape(-1,64,2,3)
print(pc2_xyz.shape)
pc2_xyz = pc1_xyz_expand+pc2_xyz
print(pc2_xyz.shape)
pc2_xyz = pc2_xyz.reshape(-1,128,3)
print(pc2_xyz.shape)
pc2_xyz_expand = torch.unsqueeze(pc2_xyz,2)
print(pc2_xyz_expand.shape)
pc3_xyz = pc3_xyz.transpose(1,2)
print(pc3_xyz.shape)
pc3_xyz = pc3_xyz.reshape(-1,128,int(self.crop_point_num/128),3)
print(pc3_xyz.shape)
pc3_xyz = pc2_xyz_expand+pc3_xyz
print(pc3_xyz.shape)
pc3_xyz = pc3_xyz.reshape(-1,self.crop_point_num,3)
print(pc3_xyz.shape)
return pc1_xyz,pc2_xyz,pc3_xyz #center1 ,center2 ,fine
Chamfer Distance
- Chamfer Distance来衡量预测效果与GT之间的差异
GAN
- 整体架构还是GAN形式
BCELoss损失模块
BCELoss模块代码实现如下:
import math
r11 = 0 * math.log(0.8707) + (1-0) * math.log((1 - 0.8707))
r12 = 1 * math.log(0.7517) + (1-1) * math.log((1 - 0.7517))
r13 = 1 * math.log(0.8162) + (1-1) * math.log((1 - 0.8162))
r21 = 1 * math.log(0.3411) + (1-1) * math.log((1 - 0.3411))
r22 = 1 * math.log(0.4872) + (1-1) * math.log((1 - 0.4872))
r23 = 1 * math.log(0.6815) + (1-1) * math.log((1 - 0.6815))
r31 = 0 * math.log(0.4847) + (1-0) * math.log((1 - 0.4847))
r32 = 0 * math.log(0.6589) + (1-0) * math.log((1 - 0.6589))
r33 = 0 * math.log(0.5273) + (1-0) * math.log((1 - 0.5273))
r1 = -(r11 + r12 + r13) / 3
#0.8447112733378236
r2 = -(r21 + r22 + r23) / 3
#0.7260397266631787
r3 = -(r31 + r32 + r33) / 3
#0.8292933181294807
bceloss = (r1 + r2 + r3) / 3
print(bceloss)
判别模块代码实现如下:
def forward(self, x):
x = F.relu(self.bn1(self.conv1(x)))
x_64 = F.relu(self.bn2(self.conv2(x)))
x_128 = F.relu(self.bn3(self.conv3(x_64)))
x_256 = F.relu(self.bn4(self.conv4(x_128)))
x_64 = torch.squeeze(self.maxpool(x_64))
x_128 = torch.squeeze(self.maxpool(x_128))
x_256 = torch.squeeze(self.maxpool(x_256))
Layers = [x_256,x_128,x_64]
x = torch.cat(Layers,1)
x = F.relu(self.bn_1(self.fc1(x)))
x = F.relu(self.bn_2(self.fc2(x)))
x = F.relu(self.bn_3(self.fc3(x)))
x = self.fc4(x)
return x
点云补全项目应用
如果需要本文完整代码,以上算法论文或者点云数据资源的小伙伴可以私信我哦!