Skip to main content

Traditional Point Cloud Object Segmentation

传统方法实现点云分割

参考 Fast range image-based segmentation of sparse 3D laser scans for online operation (pdf) 中的方法在 range image 中实现目标分割

复现过程

  • 构建 range image

文中直接从 velodyne 传感器的数据构建 range image,但是我能使用的数据是已经转换为 sensor_msgs/pointcloud2 的点云数据,所以这里要从点云数据中构建 range image

首先要知道所使用传感器的一些参数,测试代数据包所使用的传感器是 velodyne HDL-64E ,在官网上有给出该传感器的一些参数(如下图),后续将会用到

将点云数据转换到 range image 的方法参考了这个仓库中的方法

需要用到的参数如下

/*-- range image shape 4500x64 --*/
int n_beams_ = 64;
int range_img_cols_ = 4500; // 360 / 0.08

double min_range_ = 0.0;
double max_range_ = 120.0;

double min_angle_ = -(26.9*0.5); // -1/2 Vertical FOV
double max_angle_ = (26.9*0.5); // 1/2 Vertical FOV

double angular_resolution_h_ = 0.08; // azimuth
double angular_resolution_v_ = 0.4; // altitude

通过点云中每个点的位置信息 $(x,y,z)$ 可以求出每个点相对于传感器的位置在 range image 中的对应点

  • 计算点 $p$ 的 $arctan(\frac{z}{\sqrt{x^2 + y^2}})$ 可以求出 $p$ 相对于 xy 平面的角度,即垂直方向的角度
  • 点 $p$ 的 $arctan(\frac{y}{x})$ 则表示水平方向的角度,这里要把角度转换到 $[0, 2\pi]$ 之间,即当 $y<0$ 的时 $angle = angle + 2\pi$
  • 计算点到传感器的距离 $range = \sqrt{x^2 + y^2 + z^2}$

clustering

参考文章开源的代码进行聚类,仓库地址

这篇文章使用的方法是使用广度优先搜索(BFS)来对一个 range image 进行聚类,在源码中,这个 range imageOpenCV Mat 的形式表示,也就是一个二维的矩阵,文中的方法一次遍历就能完成聚类,相当于遍历了所有点云的点,复杂度为 $O(N)$

遍历时进行 BFS 操作,先将起始点填入队列中,如果这个队列非空,那么就创建一个队首点的复制,然后执行 pop 操作,判断这个点的 N4领域(即上下左右相邻的四个点) 上的点是否与当前点满足一定的条件,并将满足条件的相邻点添加到队列中,如此循环,当循环结束时图像中对应的点已经打上了相同的标签,遍历过程会跳过已经被标记过的点,并更新标签,如此在遍历结束时,整张图像都已经被打上了不同的标签,即完成了聚类

判断相邻点是否满足的条件在文中有详细说明,通过手动设定一个阈值,并通过传感器返回的深度值,计算出两个点所连直线与第一个点的传感器光束直线的夹角,看这个夹角是否满足阈值

references