Example #1
0
template <typename PointT, typename Scalar> inline unsigned int
pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
                              const pcl::PointIndices &indices,
                              Eigen::Matrix<Scalar, 3, 3> &covariance_matrix)
{
  return (computeCovarianceMatrix (cloud, indices.indices, covariance_matrix));
}
Example #2
0
template<typename PointT, typename PointNT> double
pcl::CovarianceSampling<PointT, PointNT>::computeConditionNumber ()
{
  Eigen::Matrix<double, 6, 6> covariance_matrix;
  if (!computeCovarianceMatrix (covariance_matrix))
    return (-1.);

  Eigen::EigenSolver<Eigen::Matrix<double, 6, 6> > eigen_solver;
  eigen_solver.compute (covariance_matrix, true);

  Eigen::MatrixXcd complex_eigenvalues = eigen_solver.eigenvalues ();

  double max_ev = -std::numeric_limits<double>::max (),
      min_ev = std::numeric_limits<double>::max ();
  for (size_t i = 0; i < 6; ++i)
  {
    if (real (complex_eigenvalues (i, 0)) > max_ev)
      max_ev = real (complex_eigenvalues (i, 0));

    if (real (complex_eigenvalues (i, 0)) < min_ev)
      min_ev = real (complex_eigenvalues (i, 0));
  }

  return (max_ev / min_ev);
}
Example #3
0
/*!

  Constructs a robust multiresolution estimator by implementing
  the iterative reweighted least squares (IRLS) technique.

*/
CMotion2DEstimator::CMotion2DEstimator()
{
  if (DEBUG_LEVEL1)
    cout << "Debut CMotion2DEstimator::CMotion2DEstimator()" << endl;
  rapport_poids = 0.0;
  sigma2res     = 0.0;
  verbose	= false;

  setRobustEstimator(true);
  setNIterationMaxLevel(7);

  setLastEstimationLevel(0);
  setFirstEstimationLevel(3);
  setLevelParameterIntroduction(-1, -1, -1);

  setRobustFunction(Tukey);
  setCConstant(CConst_Fixed, 8.0);
  setNIterationMaxIRLS(8);
  setReliableSupportRate(0.4f);

  computeSupportSize(true, 0.2f);
  computeResidualVariance(false);
  computeCovarianceMatrix(false);
  nrows = 0;
  ncols = 0;
  pyr_level_max = 0;

  init_mem_weightsIsDone = false;
  init_mem_estIsDone = false;

  if (DEBUG_LEVEL1)
    cout << "Fin CMotion2DEstimator::CMotion2DEstimator()" << endl;
}
Example #4
0
template <typename PointInT, typename PointOutT> void
pcl::TBB_NormalEstimationTBB<PointInT, PointOutT>::operator () (const tbb::blocked_range <size_t> &r) const
{
  float vpx, vpy, vpz;
  feature_->getViewPoint (vpx, vpy, vpz);
  // Iterating over the entire index vector
  for (size_t idx = r.begin (); idx != r.end (); ++idx)
  {
    std::vector<int> nn_indices (feature_->getKSearch ());
    std::vector<float> nn_dists (feature_->getKSearch ());

    feature_->searchForNeighbors ((*feature_->getIndices ())[idx], feature_->getSearchParameter (), nn_indices, nn_dists);

    // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
    Eigen::Vector4f xyz_centroid;
    // Estimate the XYZ centroid
    compute3DCentroid (*feature_->getSearchSurface (), nn_indices, xyz_centroid);

    // Placeholder for the 3x3 covariance matrix at each surface patch
    EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
    // Compute the 3x3 covariance matrix
    computeCovarianceMatrix (*feature_->getSearchSurface (), nn_indices, xyz_centroid, covariance_matrix);

    // Get the plane normal and surface curvature
    solvePlaneParameters (covariance_matrix,
                          output_.points[idx].normal[0], output_.points[idx].normal[1], output_.points[idx].normal[2], output_.points[idx].curvature);

    flipNormalTowardsViewpoint<PointInT> (feature_->getSearchSurface ()->points[idx], vpx, vpy, vpz,
                                          output_.points[idx].normal[0], output_.points[idx].normal[1], output_.points[idx].normal[2]);
  }
}
Example #5
0
template<typename PointT, typename PointNT> double
pcl::CovarianceSampling<PointT, PointNT>::computeConditionNumber ()
{
  Eigen::Matrix<double, 6, 6> covariance_matrix;
  if (!computeCovarianceMatrix (covariance_matrix))
    return (-1.);

  return computeConditionNumber (covariance_matrix);
}
Example #6
0
template <typename PointInT> void
pcl16::NormalEstimationOMP<PointInT, Eigen::MatrixXf>::computeFeatureEigen (pcl16::PointCloud<Eigen::MatrixXf> &output)
{
  float vpx, vpy, vpz;
  getViewPoint (vpx, vpy, vpz);
  output.is_dense = true;

  // Resize the output dataset
  output.points.resize (indices_->size (), 4);

  // GCC 4.2.x seems to segfault with "internal compiler error" on MacOS X here
#if defined(_WIN32) || ((__GNUC__ > 4) && (__GNUC_MINOR__ > 2)) 
#pragma omp parallel for schedule (dynamic, threads_)
#endif
  // Iterating over the entire index vector
  for (int idx = 0; idx < static_cast<int> (indices_->size ()); ++idx)
  {
    // Allocate enough space to hold the results
    // \note This resize is irrelevant for a radiusSearch ().
    std::vector<int> nn_indices (k_);
    std::vector<float> nn_dists (k_);

    if (!isFinite ((*input_)[(*indices_)[idx]]) ||
        this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
    {
      output.points (idx, 0) = output.points (idx, 1) = output.points (idx, 2) = output.points (idx, 3) = std::numeric_limits<float>::quiet_NaN ();
      output.is_dense = false;
      continue;
    }

    // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
    Eigen::Vector4f xyz_centroid;
    // Estimate the XYZ centroid
    compute3DCentroid (*surface_, nn_indices, xyz_centroid);

    // Placeholder for the 3x3 covariance matrix at each surface patch
    EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
    // Compute the 3x3 covariance matrix
    computeCovarianceMatrix (*surface_, nn_indices, xyz_centroid, covariance_matrix);

    // Get the plane normal and surface curvature
    solvePlaneParameters (covariance_matrix,
                          output.points (idx, 0), output.points (idx, 1), output.points (idx, 2), output.points (idx, 3));

    flipNormalTowardsViewpoint (input_->points[(*indices_)[idx]], vpx, vpy, vpz,
                                output.points (idx, 0), output.points (idx, 1), output.points (idx, 2));
  }
}
Example #7
0
template <typename PointT> void
pcl::SampleConsensusModelPlane<PointT>::optimizeModelCoefficients (
      const std::vector<int> &inliers, const Eigen::VectorXf &model_coefficients, Eigen::VectorXf &optimized_coefficients)
{
  // Needs a valid set of model coefficients
  if (model_coefficients.size () != 4)
  {
    PCL_ERROR ("[pcl::SampleConsensusModelPlane::optimizeModelCoefficients] Invalid number of model coefficients given (%lu)!\n", (unsigned long)model_coefficients.size ());
    optimized_coefficients = model_coefficients;
    return;
  }

  // Need at least 3 points to estimate a plane
  if (inliers.size () < 4)
  {
    PCL_ERROR ("[pcl::SampleConsensusModelPlane::optimizeModelCoefficients] Not enough inliers found to support a model (%lu)! Returning the same coefficients.\n", (unsigned long)inliers.size ());
    optimized_coefficients = model_coefficients;
    return;
  }

  Eigen::Vector4f plane_parameters;

  // Use Least-Squares to fit the plane through all the given sample points and find out its coefficients
  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  Eigen::Vector4f xyz_centroid;

  // Estimate the XYZ centroid
  compute3DCentroid (*input_, inliers, xyz_centroid);
  xyz_centroid[3] = 0;

  // Compute the 3x3 covariance matrix
  computeCovarianceMatrix (*input_, inliers, xyz_centroid, covariance_matrix);

  // Compute the model coefficients
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
  pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  // Hessian form (D = nc . p_plane (centroid here) + p)
  optimized_coefficients.resize (4);
  optimized_coefficients[0] = eigen_vectors (0, 0);
  optimized_coefficients[1] = eigen_vectors (1, 0);
  optimized_coefficients[2] = eigen_vectors (2, 0);
  optimized_coefficients[3] = 0;
  optimized_coefficients[3] = -1 * optimized_coefficients.dot (xyz_centroid);
}
Example #8
0
template <typename PointInT, typename PointOutT> void
pcl16::NormalEstimationOMP<PointInT, PointOutT>::computeFeature (PointCloudOut &output)
{
  float vpx, vpy, vpz;
  getViewPoint (vpx, vpy, vpz);

  output.is_dense = true;
  // Iterating over the entire index vector
#pragma omp parallel for schedule (dynamic, threads_)
  for (int idx = 0; idx < static_cast<int> (indices_->size ()); ++idx)
  {
    // Allocate enough space to hold the results
    // \note This resize is irrelevant for a radiusSearch ().
    std::vector<int> nn_indices (k_);
    std::vector<float> nn_dists (k_);

    if (!isFinite ((*input_)[(*indices_)[idx]]) ||
        this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
    {
      output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = output.points[idx].curvature = std::numeric_limits<float>::quiet_NaN ();
  
      output.is_dense = false;
      continue;
    }

    // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
    Eigen::Vector4f xyz_centroid;
    // Estimate the XYZ centroid
    compute3DCentroid (*surface_, nn_indices, xyz_centroid);

    // Placeholder for the 3x3 covariance matrix at each surface patch
    EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
    // Compute the 3x3 covariance matrix
    computeCovarianceMatrix (*surface_, nn_indices, xyz_centroid, covariance_matrix);

    // Get the plane normal and surface curvature
    solvePlaneParameters (covariance_matrix,
                          output.points[idx].normal[0], output.points[idx].normal[1], output.points[idx].normal[2], output.points[idx].curvature);

    flipNormalTowardsViewpoint (input_->points[(*indices_)[idx]], vpx, vpy, vpz,
                                output.points[idx].normal[0], output.points[idx].normal[1], output.points[idx].normal[2]);
  }
}
Example #9
0
template <typename PointT> void
pcl::SampleConsensusModelLine<PointT>::optimizeModelCoefficients (
      const std::vector<int> &inliers, const Eigen::VectorXf &model_coefficients, Eigen::VectorXf &optimized_coefficients)
{
  // Needs a valid set of model coefficients
  if (!isModelValid (model_coefficients))
  {
    optimized_coefficients = model_coefficients;
    return;
  }

  // Need at least 2 points to estimate a line
  if (inliers.size () <= 2)
  {
    PCL_ERROR ("[pcl::SampleConsensusModelLine::optimizeModelCoefficients] Not enough inliers found to support a model (%zu)! Returning the same coefficients.\n", inliers.size ());
    optimized_coefficients = model_coefficients;
    return;
  }

  optimized_coefficients.resize (6);

  // Compute the 3x3 covariance matrix
  Eigen::Vector4f centroid;
  compute3DCentroid (*input_, inliers, centroid);
  Eigen::Matrix3f covariance_matrix;
  computeCovarianceMatrix (*input_, inliers, centroid, covariance_matrix);
  optimized_coefficients[0] = centroid[0];
  optimized_coefficients[1] = centroid[1];
  optimized_coefficients[2] = centroid[2];

  // Extract the eigenvalues and eigenvectors
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Vector3f eigen_vector;
  pcl::eigen33 (covariance_matrix, eigen_values);
  pcl::computeCorrespondingEigenVector (covariance_matrix, eigen_values [2], eigen_vector);
  //pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  //optimized_coefficients.template tail<3> () = eigen_vector;
  optimized_coefficients[0] = eigen_vector[0];
  optimized_coefficients[1] = eigen_vector[1];
  optimized_coefficients[2] = eigen_vector[2];  
}
Example #10
0
/**
 * ComputeNormal
 */
float ZAdaptiveNormals::computeNormal(const v4r::DataMatrix2D<Eigen::Vector3f> &cloud, std::vector<int> &indices, Eigen::Matrix3f &eigen_vectors)
{
  if (indices.size()<4)
    return NaN;

  Eigen::Vector3f mean;
  mean.setZero();
  for (unsigned j=0; j<indices.size(); j++)
    mean += cloud.data[indices[j]];
  mean /= (float)indices.size();

  Eigen::Matrix3f cov;
  computeCovarianceMatrix (cloud, indices, mean, cov);

  Eigen::Vector3f eigen_values;
  v4r::eigen33 (cov, eigen_vectors, eigen_values);
  float eigsum = eigen_values.sum();
  if (eigsum != 0)
    return fabs (eigen_values[0] / eigsum );
  
  return NaN;
}
Example #11
0
template<typename PointT, typename PointNT> void
pcl::CovarianceSampling<PointT, PointNT>::applyFilter (std::vector<int> &sampled_indices)
{
  Eigen::Matrix<double, 6, 6> c_mat;
  // Invokes initCompute()
  if (!computeCovarianceMatrix (c_mat))
    return;

  const Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 6, 6> > solver (c_mat);
  const Eigen::Matrix<double, 6, 6> x = solver.eigenvectors ();

  //--- Part B from the paper
  /// TODO figure out how to fill the candidate_indices - see subsequent paper paragraphs
  std::vector<size_t> candidate_indices;
  candidate_indices.resize (indices_->size ());
  for (size_t p_i = 0; p_i < candidate_indices.size (); ++p_i)
    candidate_indices[p_i] = p_i;

  // Compute the v 6-vectors
  typedef Eigen::Matrix<double, 6, 1> Vector6d;
  std::vector<Vector6d, Eigen::aligned_allocator<Vector6d> > v;
  v.resize (candidate_indices.size ());
  for (size_t p_i = 0; p_i < candidate_indices.size (); ++p_i)
  {
    v[p_i].block<3, 1> (0, 0) = scaled_points_[p_i].cross (
                                  (*input_normals_)[(*indices_)[candidate_indices[p_i]]].getNormalVector3fMap ()).template cast<double> ();
    v[p_i].block<3, 1> (3, 0) = (*input_normals_)[(*indices_)[candidate_indices[p_i]]].getNormalVector3fMap ().template cast<double> ();
  }


  // Set up the lists to be sorted
  std::vector<std::list<std::pair<int, double> > > L;
  L.resize (6);

  for (size_t i = 0; i < 6; ++i)
  {
    for (size_t p_i = 0; p_i < candidate_indices.size (); ++p_i)
      L[i].push_back (std::make_pair (p_i, fabs (v[p_i].dot (x.block<6, 1> (0, i)))));

    // Sort in decreasing order
    L[i].sort (sort_dot_list_function);
  }

  // Initialize the 6 t's
  std::vector<double> t (6, 0.0);

  sampled_indices.resize (num_samples_);
  std::vector<bool> point_sampled (candidate_indices.size (), false);
  // Now select the actual points
  for (size_t sample_i = 0; sample_i < num_samples_; ++sample_i)
  {
    // Find the most unconstrained dimension, i.e., the minimum t
    size_t min_t_i = 0;
    for (size_t i = 0; i < 6; ++i)
    {
      if (t[min_t_i] > t[i])
        min_t_i = i;
    }

    // Add the point from the top of the list corresponding to the dimension to the set of samples
    while (point_sampled [L[min_t_i].front ().first])
      L[min_t_i].pop_front ();

    sampled_indices[sample_i] = L[min_t_i].front ().first;
    point_sampled[L[min_t_i].front ().first] = true;
    L[min_t_i].pop_front ();

    // Update the running totals
    for (size_t i = 0; i < 6; ++i)
    {
      double val = v[sampled_indices[sample_i]].dot (x.block<6, 1> (0, i));
      t[i] += val * val;
    }
  }

  // Remap the sampled_indices to the input_ cloud
  for (int &sampled_index : sampled_indices)
    sampled_index = (*indices_)[candidate_indices[sampled_index]];
}
template <typename PointT> bool
pcl::isPointIn2DPolygon (const PointT &point, const pcl::PointCloud<PointT> &polygon)
{
  // Compute the plane coefficients
  Eigen::Vector4f model_coefficients;
  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  Eigen::Vector4f xyz_centroid;

  // Estimate the XYZ centroid
  compute3DCentroid (polygon, xyz_centroid);

  // Compute the 3x3 covariance matrix
  computeCovarianceMatrix (polygon, xyz_centroid, covariance_matrix);

  // Compute the model coefficients
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
  eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  model_coefficients[0] = eigen_vectors (0, 0);
  model_coefficients[1] = eigen_vectors (1, 0);
  model_coefficients[2] = eigen_vectors (2, 0);
  model_coefficients[3] = 0;

  // Hessian form (D = nc . p_plane (centroid here) + p)
  model_coefficients[3] = -1 * model_coefficients.dot (xyz_centroid);

  float distance_to_plane = model_coefficients[0] * point.x + 
    model_coefficients[1] * point.y + 
    model_coefficients[2] * point.z + 
    model_coefficients[3];
  PointT ppoint;
  // Calculate the projection of the point on the plane
  ppoint.x = point.x - distance_to_plane * model_coefficients[0];
  ppoint.y = point.y - distance_to_plane * model_coefficients[1];
  ppoint.z = point.z - distance_to_plane * model_coefficients[2];

  // Create a X-Y projected representation for within bounds polygonal checking
  int k0, k1, k2;
  // Determine the best plane to project points onto
  k0 = (fabs (model_coefficients[0] ) > fabs (model_coefficients[1])) ? 0  : 1;
  k0 = (fabs (model_coefficients[k0]) > fabs (model_coefficients[2])) ? k0 : 2;
  k1 = (k0 + 1) % 3;
  k2 = (k0 + 2) % 3;
  // Project the convex hull
  pcl::PointCloud<PointT> xy_polygon;
  xy_polygon.points.resize (polygon.points.size ());
  for (size_t i = 0; i < polygon.points.size (); ++i)
    {
      Eigen::Vector4f pt (polygon.points[i].x, polygon.points[i].y, polygon.points[i].z, 0);
      xy_polygon.points[i].x = pt[k1];
      xy_polygon.points[i].y = pt[k2];
      xy_polygon.points[i].z = 0;
    }
  PointT xy_point;
  xy_point.z = 0;
  Eigen::Vector4f pt (ppoint.x, ppoint.y, ppoint.z, 0);
  xy_point.x = pt[k1];
  xy_point.y = pt[k2];

  return (pcl::isXYPointIn2DXYPolygon (xy_point, xy_polygon));
}
template <typename PointT> void
pcl::ExtractPolygonalPrismDataDebug<PointT>::segment (pcl::PointIndices &output)
{
  output.header = input_->header;


  if (!initCompute ()) 
    {
      output.indices.clear ();
      return;
    }
  
  if ((int)planar_hull_->points.size () < min_pts_hull_)
    {
      PCL_ERROR ("[pcl::%s::segment] Not enough points (%lu) in the hull!\n", getClassName ().c_str (), (unsigned long)planar_hull_->points.size ());
      output.indices.clear ();
      return;
    }

  // Compute the plane coefficients
  Eigen::Vector4f model_coefficients;
  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  Eigen::Vector4f xyz_centroid;

  // Estimate the XYZ centroid
  compute3DCentroid (*planar_hull_, xyz_centroid);

  // Compute the 3x3 covariance matrix
  computeCovarianceMatrix (*planar_hull_, xyz_centroid, covariance_matrix);

  // Compute the model coefficients
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
  eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  model_coefficients[0] = eigen_vectors (0, 0);
  model_coefficients[1] = eigen_vectors (1, 0);
  model_coefficients[2] = eigen_vectors (2, 0);
  model_coefficients[3] = 0;

  // Hessian form (D = nc . p_plane (centroid here) + p)
  model_coefficients[3] = -1 * model_coefficients.dot (xyz_centroid);

  // Need to flip the plane normal towards the viewpoint
  Eigen::Vector4f vp (vpx_, vpy_, vpz_, 0);
  // See if we need to flip any plane normals
  vp -= planar_hull_->points[0].getVector4fMap ();
  vp[3] = 0;
  // Dot product between the (viewpoint - point) and the plane normal
  float cos_theta = vp.dot (model_coefficients);
  // Flip the plane normal
  if (cos_theta < 0)
    {                                                                
      model_coefficients *= -1;
      model_coefficients[3] = 0;
      // Hessian form (D = nc . p_plane (centroid here) + p)
      model_coefficients[3] = -1 * (model_coefficients.dot (planar_hull_->points[0].getVector4fMap ()));
    }
    
  // Project all points
  PointCloud projected_points;
  SampleConsensusModelPlane<PointT> sacmodel (input_);
  sacmodel.projectPoints (*indices_, model_coefficients, projected_points, false);

  // Create a X-Y projected representation for within bounds polygonal checking
  int k0, k1, k2;
  // Determine the best plane to project points onto
  k0 = (fabs (model_coefficients[0] ) > fabs (model_coefficients[1])) ? 0  : 1;
  k0 = (fabs (model_coefficients[k0]) > fabs (model_coefficients[2])) ? k0 : 2;
  k1 = (k0 + 1) % 3;
  k2 = (k0 + 2) % 3;
  // Project the convex hull
  pcl::PointCloud<PointT> polygon;
  polygon.points.resize (planar_hull_->points.size ());
  for (size_t i = 0; i < planar_hull_->points.size (); ++i)
    {
      Eigen::Vector4f pt (planar_hull_->points[i].x, planar_hull_->points[i].y, planar_hull_->points[i].z, 0);
      polygon.points[i].x = pt[k1];
      polygon.points[i].y = pt[k2];
      polygon.points[i].z = 0;
    }


  PointT pt_xy;
  pt_xy.z = 0;

  output.indices.resize (indices_->size ());
  int l = 0;
  int count_inside = 0;
  int count_dist = 0;
  for (size_t i = 0; i < projected_points.points.size (); ++i)
    {
      // Check the distance to the user imposed limits from the table planar model
      
      
      double distance = pointToPlaneDistanceSigned (input_->points[(*indices_)[i]], model_coefficients);
      if (distance < height_limit_min_ || distance > height_limit_max_){
	count_dist++;
	continue;
      }
      
      
      
      // Check what points are inside the hull
      Eigen::Vector4f pt (projected_points.points[i].x,
			  projected_points.points[i].y,
			  projected_points.points[i].z, 0);
      pt_xy.x = pt[k1];
      pt_xy.y = pt[k2];

      
      if (!pcl::isXYPointIn2DXYPolygon(pt_xy, polygon, vertices_)){
	count_inside++;
	continue;
      }
      

      output.indices[l++] = (*indices_)[i];
    }
  output.indices.resize (l);

  std::cout <<  count_dist <<  " Points not complying with height limits " << count_inside << "Points not inside 2D polygon" << std::endl;

  deinitCompute ();
}
Example #14
0
template <typename PointInT> void
pcl::ConvexHull<PointInT>::performReconstruction (PointCloud &hull, std::vector<pcl::Vertices> &polygons,
                                                  bool fill_polygon_data)
{
  // FInd the principal directions
  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  Eigen::Vector4f xyz_centroid;
  compute3DCentroid (*input_, *indices_, xyz_centroid);
  computeCovarianceMatrix (*input_, *indices_, xyz_centroid, covariance_matrix);
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
  pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  Eigen::Affine3f transform1;
  transform1.setIdentity ();
  int dim = 3;

  if (eigen_values[0] / eigen_values[2] < 1.0e-5)
  {
    // We have points laying on a plane, using 2d convex hull
    // Compute transformation bring eigen_vectors.col(i) to z-axis

    eigen_vectors.col (2) = eigen_vectors.col (0).cross (eigen_vectors.col (1));
    eigen_vectors.col (1) = eigen_vectors.col (2).cross (eigen_vectors.col (0));

    transform1 (0, 2) = eigen_vectors (0, 0);
    transform1 (1, 2) = eigen_vectors (1, 0);
    transform1 (2, 2) = eigen_vectors (2, 0);

    transform1 (0, 1) = eigen_vectors (0, 1);
    transform1 (1, 1) = eigen_vectors (1, 1);
    transform1 (2, 1) = eigen_vectors (2, 1);
    transform1 (0, 0) = eigen_vectors (0, 2);
    transform1 (1, 0) = eigen_vectors (1, 2);
    transform1 (2, 0) = eigen_vectors (2, 2);

    transform1 = transform1.inverse ();
    dim = 2;
  }
  else
    transform1.setIdentity ();

  PointCloud cloud_transformed;
  pcl::demeanPointCloud (*input_, *indices_, xyz_centroid, cloud_transformed);
  pcl::transformPointCloud (cloud_transformed, cloud_transformed, transform1);

  // True if qhull should free points in qh_freeqhull() or reallocation
  boolT ismalloc = True;
  // option flags for qhull, see qh_opt.htm
  char flags[] = "qhull Tc";
  // output from qh_produce_output(), use NULL to skip qh_produce_output()
  FILE *outfile = NULL;
  // error messages from qhull code
  FILE *errfile = stderr;
  // 0 if no error from qhull
  int exitcode;

  // Array of coordinates for each point
  coordT *points = (coordT *)calloc (cloud_transformed.points.size () * dim, sizeof(coordT));

  for (size_t i = 0; i < cloud_transformed.points.size (); ++i)
  {
    points[i * dim + 0] = (coordT)cloud_transformed.points[i].x;
    points[i * dim + 1] = (coordT)cloud_transformed.points[i].y;

    if (dim > 2)
      points[i * dim + 2] = (coordT)cloud_transformed.points[i].z;
  }

  // Compute convex hull
  exitcode = qh_new_qhull (dim, cloud_transformed.points.size (), points, ismalloc, flags, outfile, errfile);

  if (exitcode != 0)
  {
    PCL_ERROR ("[pcl::%s::performReconstrution] ERROR: qhull was unable to compute a convex hull for the given point cloud (%lu)!\n", 
               getClassName ().c_str (), (unsigned long) input_->points.size ());

    //check if it fails because of NaN values...
    if (!cloud_transformed.is_dense)
    {
      bool NaNvalues = false;
      for (size_t i = 0; i < cloud_transformed.size (); ++i)
      {
        if (!pcl_isfinite (cloud_transformed.points[i].x) || 
            !pcl_isfinite (cloud_transformed.points[i].y) ||
            !pcl_isfinite (cloud_transformed.points[i].z))
        {
          NaNvalues = true;
          break;
        }
      }

      if (NaNvalues)
        PCL_ERROR ("[pcl::%s::performReconstruction] ERROR: point cloud contains NaN values, consider running pcl::PassThrough filter first to remove NaNs!\n", getClassName ().c_str ());
    }

    hull.points.resize (0);
    hull.width = hull.height = 0;
    polygons.resize (0);

    qh_freeqhull (!qh_ALL);
    int curlong, totlong;
    qh_memfreeshort (&curlong, &totlong);

    return;
  }

  qh_triangulate ();

  int num_facets = qh num_facets;

  int num_vertices = qh num_vertices;
  hull.points.resize (num_vertices);

  vertexT * vertex;
  int i = 0;
  // Max vertex id
  int max_vertex_id = -1;
  FORALLvertices
  {
    if ((int)vertex->id > max_vertex_id)
    max_vertex_id = vertex->id;
  }

  ++max_vertex_id;
  std::vector<int> qhid_to_pcidx (max_vertex_id);

  FORALLvertices
  {
    // Add vertices to hull point_cloud
    hull.points[i].x = vertex->point[0];
    hull.points[i].y = vertex->point[1];

    if (dim>2)
    hull.points[i].z = vertex->point[2];
    else
    hull.points[i].z = 0;

    qhid_to_pcidx[vertex->id] = i; // map the vertex id of qhull to the point cloud index
    ++i;
  }

  if (fill_polygon_data)
  {
    if (dim == 3)
    {
      polygons.resize (num_facets);
      int dd = 0;

      facetT * facet;
      FORALLfacets
      {
        polygons[dd].vertices.resize (3);

        // Needed by FOREACHvertex_i_
        int vertex_n, vertex_i;
        FOREACHvertex_i_((*facet).vertices)
        //facet_vertices.vertices.push_back (qhid_to_pcidx[vertex->id]);
        polygons[dd].vertices[vertex_i] = qhid_to_pcidx[vertex->id];

        ++dd;
      }
    }
    else
    {