Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PCL estimates wrong normal direction in some parts

I am using PCL to calculate the normal of point clouds. With Meshlab, normals are as the right one, although all normals are from outer to inner, it will be correct after I reverse them all.

But when I use PCL to do this, the direction of some normals are wrong as the left picture illustrates.

enter image description here

To make more sense, Below are reconstructed surfaces using meshlab and PCL, with the normal estimated by PCL, I cannot get the correct result. enter image description here

My code are as follow and my sample .ply data is here, and my model could be found here, I have tried to change radius, number of neighbor and the centroid position, but coundn't fix this.

cout << "begin normal estimation" << endl;
NormalEstimationOMP<PointXYZ, Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
ne.setSearchMethod(tree);
ne.setNumberOfThreads(8);
ne.setInputCloud(filtered);
ne.setKSearch(15);
ne.setRadiusSearch(5);

Eigen::Vector4f centroid;
compute3DCentroid(*filtered, centroid);
ne.setViewPoint(centroid[0], centroid[1], centroid[2]);

PointCloud<Normal>::Ptr cloud_normals (new PointCloud<Normal>());
ne.compute(*cloud_normals);
cout << "normal estimation complete" << endl;

Maybe I should adjust some other parameters? Or switch to a better methods? Thank you for your attention!

like image 360
Summer Sun Avatar asked Oct 17 '22 02:10

Summer Sun


1 Answers

Your viewpoint is in the middle of the object and not in the location from where the points were detected. All normals are oriented toward (or away from) the view point with the idea being that there is a solid object behind the point. In your case that is not the case.

You could set the view point to a location from where the points were actually detected and orient them according to that point.

If that's not an option in your case you could try to do something like this.

  1. choose a radius for neighbor search

  2. Choose a random point from where to start and check if the normal is the way you want it to be and mark it done ( perhaps remove from the cloud or pointIndices) .

  3. Then select its neighbors and check if the normals are the same way ( dot product positive ). If not, flip them and mark them done.

  4. Find the neighbors for these points and repeat to all the points.

this should do the trick. Play with the radius so that you get it right. You don't want to select the points from opposite sides of the "fingers".

AFAIK PCL doesn't have a truly robust way of determining the normal orientation for combined "complete" scans.

like image 185
Rooscannon Avatar answered Oct 23 '22 10:10

Rooscannon