IntelRealSense / librealsense

Intel® RealSense™ SDK
https://www.intelrealsense.com/
Apache License 2.0
7.55k stars 4.81k forks source link

how to create mesh in delaunay triangulation using pcl library #6225

Closed ghost closed 4 years ago

ghost commented 4 years ago

I search a lot on the internet but unable to find a suitable solution for this. my input file is input.ply

already I tried http://www.pointclouds.org/documentation/tutorials/greedy_projection.php this program but I cannot get the expected output.

so forward to Delaunay triangulation but I never noticed any PCL code for this.

now I searching the Delaunay triangulation code.

knowing persons come forward with code thanks in advance

MartyG-RealSense commented 4 years ago

I researched carefully but could not find a better guide to doing Delaunay triangulation with PCL than the one that you had already linked to.

If it is possible to consider alternatives to the PCL approach, the open source point cloud software CloudCompare has a built-in function to carry out the Delaunay process to create a mesh, either as an XY Plane or a Best Fit Plane. Page 5 of the guide in the link below illustrates the function.

http://kastner.ucsd.edu/ryan/wp-content/uploads/sites/5/2014/03/admin/palissy.pdf

CloudCompare's documentation also describes the functions:

XY Plane https://www.cloudcompare.org/doc/wiki/index.php?title=Mesh%5CDelaunay_2.5D_(XY_plane)

Best Fit Plane http://www.cloudcompare.org/doc/wiki/index.php?title=Mesh%5CDelaunay_2.5D_(best_fit_plane)

yohanb78 commented 4 years ago

Hello,

I passed a long time the previous week to test differents triangulations with PCL library.

Greedy projection has a serious problem in PCL because it randomly inverse the normal vectors in its reconstruction.

It depends of the source, the kind of object you whould like to recontruct. The fast reconstruction when you get the frame from an RSE::Pointcloud is the organizedFastMesh. I tried Greedy, Poisson, MLS, bSpline (very slow but very nice result) reconstructions, Poisson is interesting for reconstruct closed meshs, is fast ans easy to do.

  1. Convert your points to PCL pointCloud

pcl::PointCloud::Ptr points_to_pcl(const rs2::points& points,{

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// Config of PCL Cloud object
cloud->width = width;
cloud->height = height;
cloud->is_dense = false;
cloud->points.resize(points.size());

auto vertices = points.get_vertices();
// Iterating through all points and setting XYZ coordinates
for (size_t i = 0; i < points.size(); ++i)
{
    cloud->points[i].x = vertices[i].x;
    cloud->points[i].y = vertices[i].y;
    cloud->points[i].z = vertices[i].z;
}

return cloud; }

2. Fast Mesh, you can not apply PCL filter otherwise you obtain a point cloud not "organized" and can not use it:

pcl::OrganizedFastMesh::Ptr orgMesh (new pcl::OrganizedFastMesh()); pcl::PolygonMesh::Ptr triangles (new pcl::PolygonMesh); //pcl::PolygonMesh triangles ; // orgMesh.useDepthAsDistance(true); orgMesh->setTriangulationType (pcl::OrganizedFastMesh::TRIANGLE_RIGHT_CUT ); orgMesh->setInputCloud(cloud); orgMesh->reconstruct(triangles); qDebug("%i", triangles->polygons.size()); pcl::io::saveOBJFile("D:/filtered.obj", triangles);


If interested, I can add the code for the normal estimation needed to do poisson or greedy or other reconstruction.

On my side, the goal was to have an .obj with the textures. I did it on myself with some for loop and vector for the triangulation :)

Regards.
MartyG-RealSense commented 4 years ago

@yohanb78 Thanks so much for your help on this case! :)

ghost commented 4 years ago

when we do triangular meshing how to first triangulation happen in Delaunay

ghost commented 4 years ago

" a triangle whose circumradius-to-shortest edge ratio is greater than b is said to be skinny" what is mean??

in Delaunay triangulation how to I find skinny elements

MartyG-RealSense commented 4 years ago

@thambimani Wikipedia defines skinny triangles as triangles whose height is much greater than their base.

https://en.wikipedia.org/wiki/Skinny_triangle

My understanding from reading about Delaunay trinagulation is that skinny triangles do not occur often in Delaunay triangulation because the Delaunay process maximizes the minimum angle of all the angles of the triangles in the triangulation.

So you should not need to find skinny triangles because they should rarely occur in Delaunay triangulation.

ghost commented 4 years ago

@thambimani Wikipedia defines skinny triangles as triangles whose height is much greater than their base.

https://en.wikipedia.org/wiki/Skinny_triangle

My understanding from reading about Delaunay triangulation is that skinny triangles do not occur often in Delaunay triangulation because the Delaunay process maximizes the minimum angle of all the angles of the triangles in the triangulation.

So you should not need to find skinny triangles because they should rarely occur in Delaunay triangulation. Screenshot from 2020-04-20 15-08-31

@MartyG-RealSense in this picture, I do not find any skinny element as per wiki info. do you see any skinny element if you see anyone pls tell me which one and which reason

ghost commented 4 years ago

here I had another doubt what is mean by domain edge

MartyG-RealSense commented 4 years ago

@thambimani I did careful research of your question about domain edge. I could not find a single clear answer. My research suggests though that the 'domain' refers to the overall mesh, and 'domain edge' is the edge lines of the mesh (which is different from the 'domain face', the surface inside of the edges.

ghost commented 4 years ago

I search a lot on the internet but unable to find a suitable solution for this. my input file is input.ply

already I tried http://www.pointclouds.org/documentation/tutorials/greedy_projection.php this program but I cannot get the expected output.

so forward to Delaunay triangulation but I never noticed any PCL code for this.

now I searching the Delaunay triangulation code.

knowing persons come forward with code thanks in advance

if anyone give code solution for Delaunay triangulation it is helpful for me

MartyG-RealSense commented 4 years ago

I did further research. A C++ library called CGAL can do Delaunay triangulation.

https://www.cgal.org/ https://doc.cgal.org/latest/Manual/packages.html#PkgTriangulation3

ghost commented 4 years ago

Hello,

I passed a long time the previous week to test differents triangulations with PCL library.

Greedy projection has a serious problem in PCL because it randomly inverse the normal vectors in its reconstruction.

It depends of the source, the kind of object you whould like to recontruct. The fast reconstruction when you get the frame from an RSE::Pointcloud is the organizedFastMesh. I tried Greedy, Poisson, MLS, bSpline (very slow but very nice result) reconstructions, Poisson is interesting for reconstruct closed meshs, is fast ans easy to do.

1. Convert your points to PCL pointCloud

pcl::PointCloud<pcl::PointXYZ>::Ptr points_to_pcl(const rs2::points& points,{

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    // Config of PCL Cloud object
    cloud->width = width;
    cloud->height = height;
    cloud->is_dense = false;
    cloud->points.resize(points.size());

    auto vertices = points.get_vertices();
    // Iterating through all points and setting XYZ coordinates
    for (size_t i = 0; i < points.size(); ++i)
    {
        cloud->points[i].x = vertices[i].x;
        cloud->points[i].y = vertices[i].y;
        cloud->points[i].z = vertices[i].z;
    }
   return cloud;
}
1. Fast Mesh, you can not apply PCL filter otherwise you obtain a point cloud not "organized" and can not use it:
pcl::OrganizedFastMesh<pcl::PointXYZ>::Ptr orgMesh (new pcl::OrganizedFastMesh<pcl::PointXYZ>());
    pcl::PolygonMesh::Ptr triangles (new pcl::PolygonMesh);
    //pcl::PolygonMesh triangles ;
    // orgMesh.useDepthAsDistance(true);
    orgMesh->setTriangulationType (pcl::OrganizedFastMesh<pcl::PointXYZ>::TRIANGLE_RIGHT_CUT  );
    orgMesh->setInputCloud(cloud);
    orgMesh->reconstruct(*triangles);
    qDebug("%i", triangles->polygons.size());
    pcl::io::saveOBJFile("D:/filtered.obj", *triangles);

If interested, I can add the code for the normal estimation needed to do poisson or greedy or other reconstruction.

On my side, the goal was to have an .obj with the textures. I did it on myself with some for loop and vector for the triangulation :)

Regards.

@yohanb78 pls can you ADD the Whole code for greedy triangulation that is more helpful for us Thank you

ghost commented 4 years ago

include <pcl/point_types.h>

include <pcl/io/pcd_io.h>

include <pcl/kdtree/kdtree_flann.h>

include <pcl/features/normal_3d.h>

include <pcl/surface/gp3.h>

include <pcl/io/vtk_io.h>

include <pcl/io/ifs_io.h>

include <pcl/io/ply_io.h>

include <pcl/io/obj_io.h>

int main (int argc, char* argv) { // Load input file into a PointCloud with an appropriate type pcl::PointCloud::Ptr cloud (new pcl::PointCloud); pcl::PCLPointCloud2 cloud_blob; pcl::io::loadPLYFile ("2.ply", cloud_blob); pcl::fromPCLPointCloud2 (cloud_blob, cloud); //* the data should be available in cloud

// Normal estimation pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> n; pcl::PointCloud::Ptr normals(new pcl::PointCloud); pcl::search::KdTree::Ptr tree(new pcl::search::KdTree); tree->setInputCloud(cloud); n.setInputCloud(cloud); n.setSearchMethod(tree); n.setKSearch(20); // 0.1 -> 10cm // n.setRadiusSearch(5); // 0.1 -> 10cm n.compute(normals);

pcl::PointCloud::Ptr cloud_with_normals(new pcl::PointCloud); pcl::concatenateFields(cloud, normals, *cloud_with_normals);

pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZRGBNormal>);
tree2->setInputCloud(cloud_with_normals);
//Using Greedy ProjectionTriangulation
pcl::GreedyProjectionTriangulation<pcl::PointXYZRGBNormal> gp3;
pcl::PolygonMesh triangles;

gp3.setSearchRadius(0.5); // Triangle Size
gp3.setMu(2.5); // 2.5 ~ 3.0
gp3.setMaximumNearestNeighbors(150); // 100 ~ 200
gp3.setMaximumSurfaceAngle(M_PI/4); // 45 degrees
gp3.setMinimumAngle(M_PI / 18); // 10 degrees
gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
gp3.setNormalConsistency(true);
//gp3.setConsistentVertexOrdering(true);
gp3.setInputCloud(cloud_with_normals);
gp3.setSearchMethod(tree2);
gp3.reconstruct(triangles);

// Additional vertex information // std::vector parts = gp3.getPartIDs(); //std::vector states = gp3.getPointStates(); pcl::io::savePLYFile("op.ply",triangles,5); pcl::io::saveOBJFile("op.obj",triangles,5); pcl::io::saveVTKFile("op.vtk",triangles,5);

// Finish return (0); }

@yohanb78

in this code op.vtk file looks a single structure with RGB when I try to zoom I cannot find any triangulation.

what I am wrong

MartyG-RealSense commented 4 years ago

@thambimani Your images have a red error message in the log at the bottom of the window. It says:

"Mesh has no normal! You can manually compute them (select it then call "Edit > Normals > Compute)"

ghost commented 4 years ago

@thambimani Your images have a red error message in the log at the bottom of the window. It says:

"Mesh has no normal! You can manually compute them (select it then call "Edit > Normals > Compute)"

@MartyG-RealSense
give solution for my problem or direct me in the correct way solution means not my viewer "what changes i make in my code"

MartyG-RealSense commented 4 years ago

Please try going to the menu of your program and selecting "Edit > Normals > Compute" to manually compute normals, and see if that improves your image.

yohanb78 commented 4 years ago

Please attach the .obj, you can rename it suffixed with .txt. Otherwise you can open it and tell if you can find lines which begins with f (for faces/triangles), you shoud have too lines begining with v and vn (if normals have been computed). I don't know cloudcompare software and can not be sure that there is a specific vizualization of the triangles whereas it may be exists.

Your code is ok, the differences I see with mine, are:

I'm not sure but if normals have not been well computed, you will have no triangulation. And a console log after computation to display normals->points.size()

Regards

ghost commented 4 years ago

Please try going to the menu of your program and selecting "Edit > Normals > Compute" to manually compute normals, and see if that improves your image

Please try going to the menu of your program and selecting "Edit > Normals > Compute" to manually compute normals, and see if that improves your image.

I have not expected this type of output

this is not my expectation http://www.pointclouds.org/documentation/tutorials/greedy_projection.php this link contains one video that is what my expectation

guide me what changes I make in my code

MartyG-RealSense commented 4 years ago

@thambimani Please remember that it is not the responsibility of Librealsense to provide support for PCL programming questions. It is a kindness, not something that has to be done.

@yohanb78 Thanks so much again for your patient answering!

ghost commented 4 years ago

Please attach the .obj, you can rename it suffixed with .txt. Otherwise you can open it and tell if you can find lines which begins with f (for faces/triangles), you shoud have too lines begining with v and vn (if normals have been computed). I don't know cloudcompare software and can not be sure that there is a specific vizualization of the triangles whereas it may be exists.

Your code is ok, the differences I see with mine, are:

* the conversion to a pcl point cloud because I use my own.

* this way for normal computation, I don't remember why I have replaced NormaEstimation by NormalEstimationOMP class:
 pcl::NormalEstimationOMP<pcl::PointXYZRGB, pcl::Normal> n;
    pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
    pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
    tree->setInputCloud (cloud);
    n.setInputCloud (cloud);
    n.setSearchMethod (tree);
    //n.setRadiusSearch(0.1);
    n.setViewPoint(0, 0, -1);
    n.setKSearch (20);
    n.compute (*normals);

I'm not sure but if normals have not been well computed, you will have no triangulation. And a console log after computation to display normals->points.size()

Regards @yohanb78 Thank you somuch friend

yohanb78 commented 4 years ago

No pb. As i already said. There is better to do with realsense post processing. There is good tuto about this. For your hand. Start with décimation and space filters ans Alonso disparities. Save in. ply, import it in pcl and work hard until your goal. Try opencv if you want to colorize as you wish your vertices. I cant help further. It is an other level of skills

ghost commented 4 years ago

No pb. As i already said. There is better to do with realsense post processing. There is good tuto about this. For your hand. Start with décimation and space filters ans Alonso disparities. Save in. ply, import it in pcl and work hard until your goal. Try opencv if you want to colorize as you wish your vertices. I cant help further. It is an other level of skills

I can thank for your supporting

Amayess commented 2 years ago

Hello,

I passed a long time the previous week to test differents triangulations with PCL library.

Greedy projection has a serious problem in PCL because it randomly inverse the normal vectors in its reconstruction.

It depends of the source, the kind of object you whould like to recontruct. The fast reconstruction when you get the frame from an RSE::Pointcloud is the organizedFastMesh. I tried Greedy, Poisson, MLS, bSpline (very slow but very nice result) reconstructions, Poisson is interesting for reconstruct closed meshs, is fast ans easy to do.

  1. Convert your points to PCL pointCloud

pcl::PointCloud<pcl::PointXYZ>::Ptr points_to_pcl(const rs2::points& points,{

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    // Config of PCL Cloud object
    cloud->width = width;
    cloud->height = height;
    cloud->is_dense = false;
    cloud->points.resize(points.size());

    auto vertices = points.get_vertices();
    // Iterating through all points and setting XYZ coordinates
    for (size_t i = 0; i < points.size(); ++i)
    {
        cloud->points[i].x = vertices[i].x;
        cloud->points[i].y = vertices[i].y;
        cloud->points[i].z = vertices[i].z;
    }
   return cloud;
}
  1. Fast Mesh, you can not apply PCL filter otherwise you obtain a point cloud not "organized" and can not use it:
pcl::OrganizedFastMesh<pcl::PointXYZ>::Ptr orgMesh (new pcl::OrganizedFastMesh<pcl::PointXYZ>());
    pcl::PolygonMesh::Ptr triangles (new pcl::PolygonMesh);
    //pcl::PolygonMesh triangles ;
    // orgMesh.useDepthAsDistance(true);
    orgMesh->setTriangulationType (pcl::OrganizedFastMesh<pcl::PointXYZ>::TRIANGLE_RIGHT_CUT  );
    orgMesh->setInputCloud(cloud);
    orgMesh->reconstruct(*triangles);
    qDebug("%i", triangles->polygons.size());
    pcl::io::saveOBJFile("D:/filtered.obj", *triangles);

If interested, I can add the code for the normal estimation needed to do poisson or greedy or other reconstruction.

On my side, the goal was to have an .obj with the textures. I did it on myself with some for loop and vector for the triangulation :)

Regards.

Hi @yohanb78

I was able to try the Fast Organized Mesh method to generate a mesh in OBJ format. I get a result but it only contains vertices and no faces.

Do you have an explanation for this please?

How to make the method generate faces too?

Thanks for your help.