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.
To make more sense, Below are reconstructed surfaces using meshlab and PCL, with the normal estimated by PCL, I cannot get the correct result.
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!
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.
choose a radius for neighbor search
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) .
Then select its neighbors and check if the normals are the same way ( dot product positive ). If not, flip them and mark them done.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With