从点云中检测一组平面

Ahm*_*leh 2 c++ image-processing computer-vision point-clouds

我有一套点云,我想测试3D房间是否有角落.所以我想讨论我的方法,如果在速度方面有更好的方法,因为我想在手机上测试它.

我将尝试使用hough tranform来检测线条,然后我将尝试查看是否有三条相交的线条,它们也构成了一条相交的两个平面.

kil*_*gre 6

如果点云数据来自深度传感器,那么您的墙壁采样相对密集.我发现与深度传感器(例如Kinect或DepthSense)配合良好的一件事是@MartinBeckett建议的RANSAC程序的强大版本.不是随机挑选3个点,而是随机选择一个点,并获得云中的相邻点.有两种方法可以做到这一点:

  1. 正确的方法:使用3D最近邻居查询数据结构(如KD树)来获取距查询点一小段距离内的所有点.
  2. 草率但更快的方式:使用随机选择的像素的像素网格邻域.这可能包括3D中远离它的点,因为它们位于不同的平面/对象上,但这没关系,因为这个像素不会得到数据的大量支持.

下一步是从该组3D点生成平面方程.您可以在其3D坐标上使用PCA来获得两个最重要的特征向量,这些特征向量定义平面(最后一个特征向量应该是法线).

从那里开始,RANSAC算法照常进行:检查数据中有多少其他点靠近该平面,并找到具有最大支持的平面.我发现最好找到最大的支撑平面,移除支撑的3D点,然后再次运行算法以找到其他"较小"的平面.通过这种方式,您可以获得房间内的所有墙壁.

编辑:

为了阐明上述内容:假设平面的支持是所有3D点的集合,其与该平面的距离最多为某个阈值(例如10cm,应取决于深度传感器的测量误差模型).在每次运行RANSAC算法之后,选择具有最大支持的平面.通过在支持集上执行PCA /线性回归,可以使用支持该平面的所有点来细化平面方程(这比仅使用相邻点更稳健).

为了继续并找到其他平面,应该从3D点集中移除前一次迭代的支持,以便剩余的点位于其他平面上.只要有足够的点并且最佳平面拟合误差不是太大,这可以重复.在你的情况下(寻找角落),你需要至少3个垂直平面.如果你发现两个大支撑的平面大致平行,那么它们可能是地板和一些柜台,或两个平行的墙.房间没有可见的角落,或者您需要继续寻找具有较小支撑的垂直平面.