【论文笔记】大规模点云分割网络 RangeNet++ 2019

机构:波恩大学
代码链接: https://github.com/PRBonn/lidar-bonnetal

本文解决的问题是旋转式激光雷达点云数据的语义分割问题,其在进行处理时以原始点云作为输入,不丢弃任何点的信息。

分割精度超越了现有SOTA,且速度快于激光雷达的帧率(10Hz)

RangeNet++

RangeNet++ 基于2D-3D投影的分割思路,处理流程大概可以分为4步:

  1. 将点云数据转换为range image(距离图像,应该是名称中’range’的由来)
  2. 在range image上进行2D全卷积语义分割
  3. 将2D语义信息转换到3D点云上
  4. 基于range image的3D后处理,可对所有点进行快速的基于GPU的kNN搜索,以清除undesired discretization and inference artifacts
    在这里插入图片描述

1.Range Image Point Cloud Proxy Representation

机械式激光雷达是在竖直平面上进行扫描进行成像,这种逐行曝光的方式相当于相机快门中的rolling shutter,相比于常见的所有像素点同时曝光的global shutter方式,好处是可以达到更快的帧速,坏处是会带来果冻效应:即,一旦场景中有动态物体或者相机是移动的,由于逐行曝光,运动物体的不同部位在不同时间被先后曝光,导致出现部分曝光(partial exposure)、斜坡图形(skew)、晃动(wobble) 等现象。举例:

自动驾驶场景中的激光雷达都是移动的,在高速情况下其场景点云会被拉伸为椭圆:
在这里插入图片描述

为了获得完整LiDAR点云的准确语义分割,第一步是将每个偏斜的点云转换为range image:即将每个点pi =(x,y,z)转换为球坐标,最后转换为图像坐标(u,v):
( u v ) = ( 1 2 [ 1 − arctan ⁡ ( y , x ) π − 1 ] w [ 1 − ( arcsin ⁡ ( z r − 1 ) + f u p ) f − 1 ] h ) \left(\begin{array}{l} u \\ v\end{array}\right)=\left(\begin{array}{c} \frac{1}{2}\left[1-\arctan (y, x) \pi^{-1}\right] w \\ {\left[1-\left(\arcsin \left(z r^{-1}\right)+f_{\mathrm{up}}\right) \mathrm{f}^{-1}\right] h} \end{array}\right) (uv)=(21[1arctan(y,x)π1]w[1(arcsin(zr1)+fup)f1]h)
其中h,w是range image 的尺寸,f=f_up+f_down是传感器的垂直视场,r=||pi||2是每个点的range。

得到的range-image:(5,h,w),包括(xyz,r,f),f是remission(反射强度?)
每个3D点云到其对应的(u,v)像素的分配都是按range 的降序排列,以确保图像中呈现的所有点都在传感器的当前视场中

2. Fully Convolutional Semantic Segmentation

encoder-decoder hour-glass-shaped architecture,基于Dark-net
downsampling is 32
在这里插入图片描述

损失函数:加权交叉熵:
L = − ∑ c = 1 C w c y c log ⁡ ( y ^ c ) ,  where  w c = 1 log ⁡ ( f c + ϵ ) \mathcal{L}=-\sum_{c=1}^{C} w_{c} y_{c} \log \left(\hat{y}_{c}\right), \text { where } w_{c}=\frac{1}{\log \left(f_{c}+\epsilon\right)} L=c=1Cwcyclog(y^c), where wc=log(fc+ϵ)1
类别 c的权重w_c与其出现的频率成反比,用于应对类别不平衡的情况。
为了保留垂直方向上的信息,仅在水平方向上执行下采样。这意味着在编码器中,OS(output stride)为32意味着w减小了32倍,但是在垂直方向h上仍保持64个像素不变

3. Point Cloud Reconstruction from Range Image

这里将每一个像素点的语义label分配给了该像素内的所有点云,这样可以将所有的点云都分配一个label。

4. Efficient Point Cloud Post-processing

为了加快语义分割的速度,作者选择range image作为点云的表示方式,但是图像分割网络如hour-glass-like CNNs会将输出进行模糊,一些方法尝试使用条件随机场 进行后优化:使用每个像素的softmax概率作为CRF的一元势能,并抑制相邻点之间信号和欧几里得距离的阶跃变化。
对于点云数据,这种方法是行不通的:
同一像素格中的多个点云会被给与同样的语义标签,造成"shadow":(其实就是遮挡,比如路中间的栅栏挡住了后面的点云。)
在这里插入图片描述

作者使用多线程的最近邻搜索算法解决这个问题:
在GPU上对每个点进行KNN搜索,距离度量使用的是range diffference
具体的算法描述见原论文。算法的每个主要组件都可以用并行计算原语或高度矢量化的方式表示,可使用现成的,深度学习或数据科学计算框架直接在GPU中实现。
这使其比其他最近的邻域搜索方法(例如FLANN中的方法)运行速度快几个数量级。

实验

在kitti里程计数据集上进行实验
在这里插入图片描述

性能超越了现有SOTA,同时证明了KNN cleaning 后处理步骤的有效性。

对后处理步骤的有效性进一步进行对比试验:
在这里插入图片描述

这意味着论文的方法对于标签“bieeding”或“shadowing”的情况特别有用

速度评估:
在这里插入图片描述

可以在边缘计算推理平台Jetson AGX上实时运行。

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
区域生长算法是一种点云分割方法,它通过将相邻的点聚合成区域来分割点云。以下是一个基于MATLAB的点云分割区域生长算法的实现。 首先,我们需要读取点云数据。在本例中,我们将使用一个简单的点云数据集,该数据集包含一个球形物体和一个立方体物体。 ``` % 读取点云数据 pc = pcread('example.pcd'); ``` 接下来,我们将定义一些区域生长算法的参数。这些参数包括: - `seedPoint`:种子点,用于启动区域生长算法。 - `distanceThreshold`:距离阈值,用于确定哪些点应该被聚合成一个区域。 - `normalThreshold`:法向量阈值,用于确定哪些点应该被聚合成一个区域。 - `maxNumPoints`:最大点数,用于限制每个区域的大小。 ``` % 定义区域生长算法参数 seedPoint = [0, 0, 0]; distanceThreshold = 0.01; normalThreshold = 0.8; maxNumPoints = 1000; ``` 接下来,我们将使用 `pcsegdist` 函数来执行区域生长算法。该函数需要传入点云数据、种子点、距离阈值、法向量阈值和最大点数等参数。该函数将返回一个包含每个点所属区域编号的向量。 ``` % 执行区域生长算法 labels = pcsegdist(pc, seedPoint, distanceThreshold, normalThreshold, maxNumPoints); ``` 最后,我们将使用 `pcshow` 函数来可视化点云数据和分割结果。我们将使用不同的颜色来表示不同的区域。 ``` % 可视化点云数据和分割结果 figure; pcshow(pc.Location, labels); title('Point Cloud Segmentation Using Region Growing Algorithm'); xlabel('X'); ylabel('Y'); zlabel('Z'); ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值