【论文解读】点云深度学习网络PointNet

        点云数据天然的存在无序性,直接将用于图像的网络结构用于点云效果很差。有一些研究将点云空间进行划分成规则的3D体素网格,再使用3D卷及等方式来进行处理。而PointNet这篇文章提出的网络结构无需对点云数据进行预处理,对输入点云进行整体的分类或者点云的分割。

        在正式介绍PointNet网络结构之前先要理解欧式空间中点云的几个特征,这也后面作者设计结构的出发点。

1). 无序性

这个比较好理解,因为点云实际上就是点的集合,并无特定顺序。假如一个点云集合中有N个点,实际它就存在着N!种排序。对于网络设计来说,对于这N!种排序应该是不变的。

2). 点云点之间存在空间关系

点云无序,但是点与点存在空间上的关系,网络设计就需要有效的利用到这种空间关系。

3). 旋转平移(transformations)不变性

点云所代表的目标对某些空间转换应该具有不变性,如旋转和平移。代表一辆汽车的点云再空间中再怎么旋转平移,它始终还是一辆车。

PointNet结构

1). 对称函数应对输入点云的无序性问题

对称函数就是指对输入顺序不敏感的函数,比如:加法,点乘,最大池化(MaxPooling)等。

2). 局部和全局信息聚合

将单点点云特征和全局点云特征进行结合(concatenate),基于结合后的点云特征再学习出新的特征。

3). 联合对齐网络,对齐输入点和点特征,解决变换不变性

为了保证点云变换下(旋转/平移等)的不变性,论文提出对输入点云和中间特征进行对齐操作。对齐操作是通过训练一个小型网络(T-net)来得到旋转矩阵。由于loss的约束,使得T矩阵训练会学习到最有利于最终分类的变换,如把点云旋转到正面。论文架构中,分别在输入数据后和第一层特征中使用了T矩阵,大小为3x3和64x64。其中第二个T矩阵由于参数过多,考虑添加正则项,使其接近于正交矩阵,减少点云的信息丢失。

def get_transform_K(inputs, is_training, bn_decay=None, K = 3):
    """ Transform Net, input is BxNx1xK gray image
        Return:
            Transformation matrix of size KxK """
    batch_size = inputs.get_shape()[0].value
    num_point = inputs.get_shape()[1].value
    """
    inputs, [batch,in_height,in_width,in_channel]
    256, filter, 卷积核
    [1,1], strides
    padding, 'SAME', 'VALID'
    """
    net = tf_util.conv2d(inputs, 256, [1,1], padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training, scope='tconv1', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 1024, [1,1], padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training, scope='tconv2', bn_decay=bn_decay)
    net = tf_util.max_pool2d(net, [num_point,1], padding='VALID', scope='tmaxpool')

    net = tf.reshape(net, [batch_size, -1])
    net = tf_util.fully_connected(net, 512, bn=True, is_training=is_training, scope='tfc1', bn_decay=bn_decay)
    net = tf_util.fully_connected(net, 256, bn=True, is_training=is_training, scope='tfc2', bn_decay=bn_decay)

    with tf.variable_scope('transform_feat') as sc:
        weights = tf.get_variable('weights', [256, K*K], initializer=tf.constant_initializer(0.0), dtype=tf.float32)
        biases = tf.get_variable('biases', [K*K], initializer=tf.constant_initializer(0.0), dtype=tf.float32) + tf.constant(np.eye(K).flatten(), dtype=tf.float32)
        transform = tf.matmul(net, weights)
        transform = tf.nn.bias_add(transform, biases)

    #transform = tf_util.fully_connected(net, 3*K, activation_fn=None, scope='tfc3')
    transform = tf.reshape(transform, [batch_size, K, K])
    return transform

主要模块

1). Transform

包含两次transform,一次是针对输入的input transform,另一次是针对特征(feature) transform。

图.输入transform

图.特征transform

2) MLP

使用共享权重的卷积。

3) MaxPooling

提取点云全局特征,再MaxPooling之前基本上都是针对单个点云的操作。

4). 分类网络

将全局特征通过mlp来预测整体最后的分类分数。

5). 分割网络

将全局特征和之前学习到的各点云的局部特征进行串联,再通过mlp得到每个点云的分类结果。

【参考】

https://github.com/charlesq34/pointnet

https://www.bilibili.com/video/BV1As411377S?from=search&seid=4881067507738319602

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值