pythoncurve-fittingpoint-cloudssmoothingstructure-from-motion

Is Gaussian & Mean Curvatures Applicable for Rough Surfaces?


For a project I am working on, I have successfully performed the SFM procedure on road image data, and have been able to generate a .ply file containing point cloud coordinates (X, Y, Z), RGB values, and normals (nx, ny, nz).

Now, I am interested in calculating curvature values for each point from the data I have. I have come across Surface Curvature MATLAB Equivalent in Python, but the implementation is said to work only when X, Y, and Z are 2D arrays.

Is Gaussian and Mean curvatures applicable if the road surface is very rough? Given, the (X,Y,Z) coordinate data of size NX3 and given the (nx,ny,nz) normal data of size NX3, how should I find the curvature? Is there a current implementation in Python?


Solution

  • I'm actually writing a Python library for working with point clouds.

    Using the raw point cloud, the only "curvature" concept I'm aware of is the one computed using the eigenvalues obtained from the neighbourhood of each point.

    If that is what you mean, here is an example code:

    from pyntcloud import PyntCloud
    cloud = PyntCloud.from_file("Box.ply")
    

    This is the example point cloud inside Box.ply:

    example point cloud

    The steps to compute the curvature are:


    Get k-neighbors of each point:

    k_neighbors = cloud.get_neighbors(k=10)
    

    Compute the eigenvalues for each point using it's k (10 in this case) neighbours:

    ev = cloud.add_scalar_field("eigen_values", k_neighbors=k_neighbors)
    

    Compute the curvature from those eigenvalues:

    cloud.add_scalar_field("curvature", ev=ev)
    

    Saving the cloud with the new scalar fields:

    cloud.to_file("out.ply")
    

    Here is the point cloud inside out.ply colored according to the curvature value assigned to each point (White are higher curvature values):

    point cloud curvature


    Here is an example on how to filter the point cloud to only keep the points that have a curvature value above the mean:

    curvature = cloud.points["curvature(K(16))"]
    cloud.points = cloud.points[curvature > curvature.mean()]
    cloud.to_file("out.ply")
    

    And the new content of out.ply:

    point cloud filtered