Search code examples
graphics3dpoint-cloud-librarypoint-cloudsopen3d

Consistent normal calculation of a point cloud


Is there a library in python or c++ that is capable of estimating normals of point clouds in a consistent way? In a consistent way I mean that the orientation of the normals is globally preserved over the surface.

For example, when I use python open3d package:

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

I get an inconsistent results, where some of the normals point inside while the rest point outside.

many thanksestimated normals (black lines indicate outside directed normals)


Solution

  • If you know the viewpoint from where each point was captured, it can be used to orient the normals. I assume that this not the case - so given your situation, which seems rather watertight and uniformly sampled, mesh reconstruction is promising.

    PCL library offers many alternatives in the surface module. For the sake of normal estimation, I would start with either:

    Although simple, they should be enough to produce a single coherent mesh.

    Once you have a mesh, each triangle defines a normal (the cross product). It is important to note that a mesh isn't just a collection of independent faces. The faces are connected and this connectivity enforces a coherent orientation across the mesh.

    pcl::PolygonMesh is an "half edge data structure". This means that every triangle face is defined by an ordered set of vertices, which defines the orientation: order of vertices => order of cross product => well defined unambiguous normals

    You can either use the normals from the mesh (nearest neighbor), or calculate a low resolution mesh and just use it to orient the cloud.