点云的一致法线计算

Consistent normal calculation of a point cloud

python 或 c++ 中是否有能够以一致的方式估计点云法线的库? 以一致的方式,我的意思是法线的方向在表面上全局保留。

例如,当我使用python open3d包时:

downpcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(
    radius=4, max_nn=300))

我得到了不一致的结果,其中一些法线指向内部,而其余的则指向外部。

非常感谢

如果您知道捕获每个点的视点,它可用于确定法线的方向。 我认为情况并非如此 - 所以考虑到你的情况,这似乎相当无懈可击且采样均匀,网格重建很有希望。

PCL 库在 surface module 中提供了许多替代方案。为了正常估计,我会从以下任一开始:

虽然简单,但它们应该足以生成一个连贯的网格。

一旦有了网格,每个三角形就定义了一条法线(叉积)。重要的是要注意网格不仅仅是独立面的集合。面是相连的,这种连通性在整个网格上强制执行一致的方向。

pcl::PolygonMesh 是一个“half edge data structure”。这意味着每个三角形面都由一组有序的顶点定义,这些顶点定义了方向: 顶点顺序 => 叉积顺序 => 明确定义的明确法线

您可以使用网格(最近邻)的法线,或计算低分辨率网格并仅使用它来定向云。

更新好消息!

切平面算法现已在 Open3D 中实现!
source code and the documentation.

你可以打电话 pcd.orient_normals_consistent_tangent_plane(k=15).
k是knn图参数。


原回答:

正如 Mark 所说,如果您的点云来自多个深度图像,那么您可以在将它们连接在一起之前调用 open3d.geometry.orient_normals_towards_camera_location(pcd, camera_loc)(假设您使用的是 Open3D 的 python 版本).


但是,如果您没有该信息,可以使用切面算法:

  1. 为您的点云构建 knn-graph。
    图节点是点。如果一个点是另一个点的 k 最近邻,则两个点相连。
  2. 为图中的边分配权重。
    与边 (i, j) 关联的权重计算为 1 - |ninj|
  3. 生成结果图的最小生成树
  4. 在初始节点处生根树, 以深度优先顺序遍历树,为每个节点分配一个 与其父级一致的方向。

其实上面的算法来自Hoppe's 1992的Section 3.3 SIGGRAPH 论文 Surface Reconstruction from Unorganized Points. The algorithm is also open sourced.

据我所知,该算法不能保证完美的方向,但应该足够好了。