Creating mesh from a simple point cloud
Hi,
I am trying to create mesh from a point cloud, and currently having trouble finding the right parameters/methods to get good result. I have created point cloud (sampled from a, plane extracted from, kinect scan) in a structured way where the points are in a grid.
When I generate a mesh using pcl::GreedyProjectionTriangulation, I see that points are beng used just once, and hence the mesh I am getting is simply set of triangels all separated. Please see the two pics, pointCloud:
and Mesh (I want a mesh where there are no gaps. I can easily create a ply format file for this since this is a plane, but it would be difficult to create it for complex point clouds. I am sure there already is a method to do so.
, where mesh is being displayed in meshlab (I convereted vtk to ply by using a custom code).
Please let me know what parameters to use.
My i/p point cloud have two points separated by 0.025 meters. The parameter for mesh are: (I am not able to see any difference on changing these)
p_setKSearch: 20
p_setSearchRadius: 0.1
p_setMu: 5
p_neighbours: 100
p_maxSurfAnglePiDiv: 4
p_minAnglePiDiv: 18
p_maxAnglePiDiv: 1.5
p_normal_consist: true
The code I am using to convertPointCLoud to Mehs is:
void CreateWorld::createMeshFromCloud(pcl::PointCloud<pointrgb>::Ptr &ipCloudI){
//Let's first convert it to PointXYZ
pcl::PointCloud<pointType>::Ptr cloud = getXYZfromRGB(ipCloudI); //pointType is pointXYZ
pcl::NormalEstimation<pointType, 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 (ParamValue::p_setKSearch); //It was 20
n.compute (*normals); //Normals are estimated using standard method.
// Concatenate the XYZ and normal fields*
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>);
pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
//* cloud_with_normals = cloud + normals
// Create search tree*
pcl::search::KdTree<pcl::PointNormal>::Ptr tree2 (new pcl::search::KdTree<pcl::PointNormal>);
tree2->setInputCloud (cloud_with_normals);
// Initialize objects
pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
pcl::PolygonMesh triangles;
// Set the maximum distance between connected points (maximum edge length)
gp3.setSearchRadius (ParamValue::p_setSearchRadius); //It was 0.025
// Set typical values for the parameters
gp3.setMu (ParamValue::p_setMu); //It was 2.5
gp3.setMaximumNearestNeighbors (ParamValue::p_neighbours); //It was 100
gp3.setMaximumSurfaceAngle(M_PI/ParamValue::p_maxSurfAnglePiDiv); // 45 degrees //it was 4
gp3.setMinimumAngle(M_PI/ParamValue::p_minAnglePiDiv); // 10 degrees //It was 18
gp3.setMaximumAngle(M_PI/ParamValue::p_maxAnglePiDiv); // 120 degrees //it was 1.5
gp3.setNormalConsistency(ParamValue::p_normal_consist); //It was false
// Get result
gp3.setInputCloud (cloud_with_normals);
gp3.setSearchMethod (tree2);
gp3.reconstruct (triangles);
// Additional vertex information
std::vector<int> parts = gp3.getPartIDs();
std::vector<int> states = gp3.getPointStates();
//pcl::io::
pcl::io::saveVTKFile (ParamValue::planeMeshVTK, triangles);
std::cout<<"\n\n\t Calling conversion from VTK to PLY";
convertVtkToPly(ParamValue::planeMeshVTK, ParamValue::planeMeshPLY);
}
Any help/pointer is greatly appreciated.
Thanks
Nirala A K