2
votes

Estimating normals of points in a point cloud using PCL works well, but I get strange normal orientation flip at particular piece of the cloud (see screenshot, normals are yellow lines). Ofcourse I can iterate through the array of normals and correct it, but maybe there is a better way to do it directly with PCL, on the fly? Using viewpoint-oriented normals is not an option because the surface is cylinder-like, so the normals are expected to point in all directions around that axis in the end.

Here is the code for the normal estimation. Basically the snippet from official tutorial:

pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> n;
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(cloud_);
n.setInputCloud(cloud_);
n.setSearchMethod(tree);
n.setKSearch(10);
n.compute(*normals);

Point cloud triangulation with normals

1
Hi Alexander, I am having the same problem, were you able to fix it? - Bardo91
Hello. Not really. I ended up doing it "manually" with the help of OpenMesh library which I needed for other operations on mesh anyway. - Alexander
Ok! I will do the same. Thank you very much - Bardo91
Can you explain what you did using the openmesh library? Either some pointers in the comments or a self answer if you have a nice algorithm would be nice. - allo

1 Answers

0
votes

I think the code you are looking for can be found in the Difference of Normals Tutorial. Specifically, the lines

pcl::NormalEstimationOMP<PointXYZRGB, PointNormal> ne;
...
ne.setViewPoint (std::numeric_limits<float>::max (), 
                 std::numeric_limits<float>::max (), 
                 std::numeric_limits<float>::max ());
...
ne.compute (*normals_large_scale);

Where the setViewPoint function will flip the normals of the whole point cloud (rather than just an individual point) as long as it is called before the compute function.

For example, in this image the cloud on the left was computed before calling setViewPoint, and the cloud on the right was computed afterwards.

normals_orientation_vs_not

(FYI: Anyone with the reputation to do so should feel free to edit this answer and add the '!' above to embed the actual image so it's not just a link.)