点云的一致法线计算
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 版本).
但是,如果您没有该信息,可以使用切面算法:
- 为您的点云构建 knn-graph。
图节点是点。如果一个点是另一个点的 k 最近邻,则两个点相连。
- 为图中的边分配权重。
与边 (i, j) 关联的权重计算为 1 - |ni ⋅ nj|
- 生成结果图的最小生成树。
- 在初始节点处生根树,
以深度优先顺序遍历树,为每个节点分配一个
与其父级一致的方向。
其实上面的算法来自Hoppe's 1992的Section 3.3
SIGGRAPH 论文 Surface Reconstruction from Unorganized Points. The algorithm is also open sourced.
据我所知,该算法不能保证完美的方向,但应该足够好了。
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 版本).
但是,如果您没有该信息,可以使用切面算法:
- 为您的点云构建 knn-graph。
图节点是点。如果一个点是另一个点的 k 最近邻,则两个点相连。 - 为图中的边分配权重。
与边 (i, j) 关联的权重计算为 1 - |ni ⋅ nj| - 生成结果图的最小生成树。
- 在初始节点处生根树, 以深度优先顺序遍历树,为每个节点分配一个 与其父级一致的方向。
其实上面的算法来自Hoppe's 1992的Section 3.3 SIGGRAPH 论文 Surface Reconstruction from Unorganized Points. The algorithm is also open sourced.
据我所知,该算法不能保证完美的方向,但应该足够好了。