3

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

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

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

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

非常感谢估计法线(黑线表示外部定向法线)

4

2 回答 2

5

更新好消息!

切平面算法现在在 Open3D 中实现!源代码
文档

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


原答案:

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


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

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

实际上,上述算法来自Hoppe 1992 年 SIGGRAPH 论文Surface Reconstruction from Unorganized Points的第 3.3 节。该算法也是开源的

AFAIK 该算法不能保证完美的方向,但它应该足够好。

于 2020-03-15T04:52:44.113 回答
1

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

PCL 库在表面模块中提供了许多替代方案。为了正常估计,我将从以下任一开始:

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

一旦你有了一个网格,每个三角形都会定义一个法线(叉积)。需要注意的是,网格不仅仅是独立面的集合。面是连接的,并且这种连接在网格上强制执行一致的方向。

pcl::PolygonMesh是一个“半边数据结构”。这意味着每个三角形面都由一组有序的顶点定义,它定义了方向: 顶点的顺序 => 叉积的顺序 => 明确定义的明确法线

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

于 2020-02-28T22:44:10.237 回答