예제 #1
0
파일: test_poisson.cpp 프로젝트: 2php/pcl
TEST (PCL, Poisson)
{
  Poisson<PointNormal> poisson;
  poisson.setInputCloud (cloud_with_normals);
  PolygonMesh mesh;
  poisson.reconstruct (mesh);


//  io::saveVTKFile ("bunny_poisson.vtk", mesh);

  ASSERT_EQ (mesh.polygons.size (), 1051);
  // All polygons should be triangles
  for (size_t i = 0; i < mesh.polygons.size (); ++i)
    EXPECT_EQ (mesh.polygons[i].vertices.size (), 3);

  EXPECT_EQ (mesh.polygons[10].vertices[0], 121);
  EXPECT_EQ (mesh.polygons[10].vertices[1], 120);
  EXPECT_EQ (mesh.polygons[10].vertices[2], 23);

  EXPECT_EQ (mesh.polygons[200].vertices[0], 130);
  EXPECT_EQ (mesh.polygons[200].vertices[1], 119);
  EXPECT_EQ (mesh.polygons[200].vertices[2], 131);

  EXPECT_EQ (mesh.polygons[1000].vertices[0], 521);
  EXPECT_EQ (mesh.polygons[1000].vertices[1], 516);
  EXPECT_EQ (mesh.polygons[1000].vertices[2], 517);
}
예제 #2
0
void FSModel::convertPointCloudToSurfaceMesh3()
{
    /*pcl::MovingLeastSquares<PointXYZRGB, PointXYZ> mls;
    mls.setInputCloud (pointCloud);
    mls.setSearchRadius (0.01);
    mls.setPolynomialFit (true);
    mls.setPolynomialOrder (2);
    mls.setUpsamplingMethod (pcl::MovingLeastSquares<PointXYZRGB, PointXYZ>::SAMPLE_LOCAL_PLANE);
    mls.setUpsamplingRadius (0.005);
    mls.setUpsamplingStepSize (0.003);

    pcl::PointCloud<PointXYZ>::Ptr cloud_smoothed (new pcl::PointCloud<PointXYZ> ());
    mls.process (*cloud_smoothed);*/

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    cloud->points.resize(pointCloud->size());
    for (size_t i = 0; i < pointCloud->points.size(); i++) {
        cloud->points[i].x = pointCloud->points[i].x;
        cloud->points[i].y = pointCloud->points[i].y;
        cloud->points[i].z = pointCloud->points[i].z;
    }

    pcl::NormalEstimation<pcl::PointXYZ, Normal> ne;
    //ne.setNumberOfThreads(8);
    ne.setInputCloud (cloud);
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
    ne.setSearchMethod (tree);
    ne.setRadiusSearch (0.01);
    Eigen::Vector4f centroid;
    compute3DCentroid (*cloud, centroid);
    ne.setViewPoint (centroid[0], centroid[1], centroid[2]);
    qDebug() << "Centroid:"<<centroid[0] <<centroid[1]<<centroid[2];
    PointCloud<Normal>::Ptr cloud_normals (new PointCloud<Normal> ());
    ne.compute (*cloud_normals);
    //invert all normals, primarly they all point to the centroid
    for (size_t i = 0; i < cloud_normals->size (); ++i) {
        cloud_normals->points[i].normal_x *= -1;
        cloud_normals->points[i].normal_y *= -1;
        cloud_normals->points[i].normal_z *= -1;
    }
    PointCloud<PointNormal>::Ptr cloud_smoothed_normals (new PointCloud<PointNormal> ());
    concatenateFields (*cloud, *cloud_normals, *cloud_smoothed_normals);
    //concatenateFields (*cloud_smoothed, *cloud_normals, *cloud_smoothed_normals);*/

    Poisson<PointNormal> poisson;
    poisson.setScale(1.0);
    poisson.setDepth (9);
    poisson.setDegree(2);
    poisson.setSamplesPerNode(3);
    poisson.setIsoDivide(8);
    poisson.setConfidence(0);
    poisson.setManifold(0);
    poisson.setOutputPolygons(0);
    poisson.setSolverDivide(8);
    poisson.setInputCloud(cloud_smoothed_normals);
    poisson.reconstruct(surfaceMeshPoisson);
    //pcl::io::savePLYFile("meshPoisson.ply", surfaceMeshPoisson);
    FSController::getInstance()->meshComputed=true;
}
예제 #3
0
void PoissonReconstruction::perform(int ksearch)
{
    PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
    PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
    search::KdTree<PointXYZ>::Ptr tree;
    search::KdTree<PointNormal>::Ptr tree2;

    cloud->reserve(myPoints.size());
    for (Points::PointKernel::const_iterator it = myPoints.begin(); it != myPoints.end(); ++it) {
        if (!boost::math::isnan(it->x) && !boost::math::isnan(it->y) && !boost::math::isnan(it->z))
            cloud->push_back(PointXYZ(it->x, it->y, it->z));
    }

    // Create search tree
    tree.reset (new search::KdTree<PointXYZ> (false));
    tree->setInputCloud (cloud);

    // Normal estimation
    NormalEstimation<PointXYZ, Normal> n;
    PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
    n.setInputCloud (cloud);
    //n.setIndices (indices[B);
    n.setSearchMethod (tree);
    n.setKSearch (ksearch);
    n.compute (*normals);

    // Concatenate XYZ and normal information
    pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);

    // Create search tree
    tree2.reset (new search::KdTree<PointNormal>);
    tree2->setInputCloud (cloud_with_normals);

    // Init objects
    Poisson<PointNormal> poisson;

    // Set parameters
    poisson.setInputCloud (cloud_with_normals);
    poisson.setSearchMethod (tree2);
    if (depth >= 1)
        poisson.setDepth(depth);
    if (solverDivide >= 1)
        poisson.setSolverDivide(solverDivide);
    if (samplesPerNode >= 1.0f)
        poisson.setSamplesPerNode(samplesPerNode);

    // Reconstruct
    PolygonMesh mesh;
    poisson.reconstruct (mesh);

    MeshConversion::convert(mesh, myMesh);
}
예제 #4
0
int main (int argc, char **argv)
{
   /* if (argc != 1)
    {
        PCL_ERROR ("Syntax: %s input.pcd output.ply\n", argv[0]);
         return -1;
    }*/

    PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ> ());
    io::loadPCDFile (argv[1], *cloud);
    MovingLeastSquares<PointXYZ, PointXYZ> mls;
    mls.setInputCloud (cloud);
    mls.setSearchRadius (4);
    mls.setPolynomialFit (true);
    mls.setPolynomialOrder (1);
    mls.setUpsamplingMethod (MovingLeastSquares<PointXYZ, PointXYZ>::SAMPLE_LOCAL_PLANE);
    mls.setUpsamplingRadius (1);
    mls.setUpsamplingStepSize (0.03);

    PointCloud<PointXYZ>::Ptr cloud_smoothed (new PointCloud<PointXYZ> ());
    mls.process (*cloud_smoothed);

    NormalEstimationOMP<PointXYZ, Normal> ne;
    ne.setNumberOfThreads (8);
    ne.setInputCloud (cloud_smoothed);
    ne.setRadiusSearch (0.8);
    Eigen::Vector4f centroid;
    compute3DCentroid (*cloud_smoothed, centroid);
    ne.setViewPoint (centroid[0], centroid[1], centroid[2]);

    PointCloud<Normal>::Ptr cloud_normals (new PointCloud<Normal> ());
    ne.compute (*cloud_normals);
    for (size_t i = 0; i < cloud_normals->size (); ++i)
        {
            cloud_normals->points[i].normal_x *= -1;
            cloud_normals->points[i].normal_y *= -1;
            cloud_normals->points[i].normal_z *= -1;
        }
    PointCloud<PointNormal>::Ptr cloud_smoothed_normals (new PointCloud<PointNormal> ());
    concatenateFields (*cloud_smoothed, *cloud_normals, *cloud_smoothed_normals);

    Poisson<pcl::PointNormal> poisson;
    poisson.setDepth (9);
    poisson.setInputCloud  (cloud_smoothed_normals); 
    PolygonMesh mesh_poisson;
    poisson.reconstruct (mesh_poisson);
    pcl::io::savePLYFile("mesh.ply", mesh_poisson);
    return 0;
}
예제 #5
0
void PoissonReconstruction::perform(const std::vector<Base::Vector3f>& normals)
{
    if (myPoints.size() != normals.size())
        throw Base::RuntimeError("Number of points doesn't match with number of normals");

    PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
    search::KdTree<PointNormal>::Ptr tree;

    cloud_with_normals->reserve(myPoints.size());
    std::size_t num_points = myPoints.size();
    const std::vector<Base::Vector3f>& points = myPoints.getBasicPoints();
    for (std::size_t index=0; index<num_points; index++) {
        const Base::Vector3f& p = points[index];
        const Base::Vector3f& n = normals[index];
        if (!boost::math::isnan(p.x) && !boost::math::isnan(p.y) && !boost::math::isnan(p.z)) {
            PointNormal pn;
            pn.x = p.x;
            pn.y = p.y;
            pn.z = p.z;
            pn.normal_x = n.x;
            pn.normal_y = n.y;
            pn.normal_z = n.z;
            cloud_with_normals->push_back(pn);
        }
    }

    // Create search tree
    tree.reset (new search::KdTree<PointNormal>);
    tree->setInputCloud (cloud_with_normals);

    // Init objects
    Poisson<PointNormal> poisson;

    // Set parameters
    poisson.setInputCloud (cloud_with_normals);
    poisson.setSearchMethod (tree);
    if (depth >= 1)
        poisson.setDepth(depth);
    if (solverDivide >= 1)
        poisson.setSolverDivide(solverDivide);
    if (samplesPerNode >= 1.0f)
        poisson.setSamplesPerNode(samplesPerNode);

    // Reconstruct
    PolygonMesh mesh;
    poisson.reconstruct (mesh);

    MeshConversion::convert(mesh, myMesh);
}
예제 #6
0
void
compute (const sensor_msgs::PointCloud2::ConstPtr &input, PolygonMesh &output,
         int depth, int solver_divide, int iso_divide)
{
  PointCloud<PointNormal>::Ptr xyz_cloud (new pcl::PointCloud<PointNormal> ());
  fromROSMsg (*input, *xyz_cloud);

	Poisson<PointNormal> poisson;
	poisson.setDepth (depth);
	poisson.setSolverDivide (solver_divide);
	poisson.setIsoDivide (iso_divide);
  poisson.setInputCloud (xyz_cloud);


  TicToc tt;
  tt.tic ();

  print_highlight ("Computing ");
  poisson.reconstruct (output);

  print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms]\n");
}