Beispiel #1
0
template <typename PointT, typename PointNT> bool
pcl::SurfelSmoothing<PointT, PointNT>::initCompute ()
{
  if (!PCLBase<PointT>::initCompute ())
    return false;

  if (!normals_)
  {
    PCL_ERROR ("SurfelSmoothing: normal cloud not set\n");
    return false;
  }

  if (input_->points.size () != normals_->points.size ())
  {
    PCL_ERROR ("SurfelSmoothing: number of input points different from the number of given normals\n");
    return false;
  }

  // Initialize the spatial locator
  if (!tree_)
  {
    if (input_->isOrganized ())
      tree_.reset (new pcl::search::OrganizedNeighbor<PointT> ());
    else
      tree_.reset (new pcl::search::KdTree<PointT> (false));
  }

  // create internal copies of the input - these will be modified
  interm_cloud_ = PointCloudInPtr (new PointCloudIn (*input_));
  interm_normals_ = NormalCloudPtr (new NormalCloud (*normals_));

  return (true);
}
template <typename PointT, typename PointNT> bool
pcl::SurfelSmoothing<PointT, PointNT>::initCompute ()
{
  if (!PCLBase<PointT>::initCompute ())
    return false;

  if (!normals_)
  {
    PCL_ERROR ("SurfelSmoothing: normal cloud not set\n");
    return false;
  }

  if (input_->points.size () != normals_->points.size ())
  {
    PCL_ERROR ("SurfelSmoothing: number of input points different from the number of given normals\n");
    return false;
  }

  if (!tree_)
  {
    PCL_ERROR ("SurfelSmoothing: kd-tree not set\n");
    return false;
  }

  // create internal copies of the input - these will be modified
  interm_cloud_ = PointCloudInPtr (new PointCloudIn (*input_));
  interm_normals_ = NormalCloudPtr (new NormalCloud (*normals_));

  return true;
}
template <typename PointT, typename PointNT> void
pcl::SurfelSmoothing<PointT, PointNT>::smoothCloudIteration (PointCloudInPtr &output_positions,
                                                             NormalCloudPtr &output_normals)
{
  PCL_INFO ("SurfelSmoothing: cloud smoothing iteration starting ...\n");
  tree_->setInputCloud (interm_cloud_);

  output_positions = PointCloudInPtr (new PointCloudIn);
  output_positions->points.resize (interm_cloud_->points.size ());
  output_normals = NormalCloudPtr (new NormalCloud);
  output_normals->points.resize (interm_cloud_->points.size ());

  std::vector<int> nn_indices;
  std::vector<float> nn_distances;

  std::vector<float> diffs (interm_cloud_->points.size ());
  Eigen::Vector4f total_residual = Eigen::Vector4f::Zero ();

  for (size_t i = 0; i < interm_cloud_->points.size (); ++i)
  {
    Eigen::Vector4f smoothed_point  = Eigen::Vector4f::Zero ();
    Eigen::Vector4f smoothed_normal = Eigen::Vector4f::Zero (); 

    // get neighbors
    tree_->radiusSearch (i, scale_, nn_indices, nn_distances);

    float theta_normalization_factor = 0.0;
    Eigen::Vector4f e_residual = Eigen::Vector4f::Zero ();
    for (std::vector<int>::iterator nn_index_it = nn_indices.begin (); nn_index_it != nn_indices.end (); ++nn_index_it)
    {
      float dist = pcl::squaredEuclideanDistance (interm_cloud_->points[i], interm_cloud_->points[*nn_index_it]);
      float theta_i = exp ( (-1) * dist / scale_squared_);
      theta_normalization_factor += theta_i;

      smoothed_normal += theta_i * interm_normals_->points[*nn_index_it].getNormalVector4fMap ();
      e_residual += theta_i * (interm_cloud_->points[i].getVector4fMap () - interm_cloud_->points[*nn_index_it].getVector4fMap ());
    }
    smoothed_normal /= theta_normalization_factor;
    e_residual /= theta_normalization_factor;
    smoothed_point = interm_cloud_->points[i].getVector4fMap () - e_residual.dot (smoothed_normal) * smoothed_normal;
///    smoothed_point = interm_cloud_->points[point_i].getVector3fMap () - e_residual;

    total_residual += e_residual;

    output_positions->points[i].getVector4fMap () = smoothed_point;
    output_normals->points[i].getNormalVector4fMap () = smoothed_normal;

    // Calculate difference
    diffs[i] = smoothed_normal.dot (smoothed_point - interm_cloud_->points[i].getVector4fMap ());
  }

  std::cerr << "Total residual after an iteration: " << total_residual << std::endl;
  PCL_INFO("SurfelSmoothing done iteration\n");
}
Beispiel #4
0
template <typename PointT, typename PointNT> float
pcl::SurfelSmoothing<PointT, PointNT>::smoothCloudIteration (PointCloudInPtr &output_positions,
                                                             NormalCloudPtr &output_normals)
{
//  PCL_INFO ("SurfelSmoothing: cloud smoothing iteration starting ...\n");

  output_positions = PointCloudInPtr (new PointCloudIn);
  output_positions->points.resize (interm_cloud_->points.size ());
  output_normals = NormalCloudPtr (new NormalCloud);
  output_normals->points.resize (interm_cloud_->points.size ());

  std::vector<int> nn_indices;
  std::vector<float> nn_distances;

  std::vector<float> diffs (interm_cloud_->points.size ());
  float total_residual = 0.0f;

  for (size_t i = 0; i < interm_cloud_->points.size (); ++i)
  {
    Eigen::Vector4f smoothed_point  = Eigen::Vector4f::Zero ();
    Eigen::Vector4f smoothed_normal = Eigen::Vector4f::Zero (); 

    // get neighbors
    // @todo using 5x the scale for searching instead of all the points to avoid O(N^2)
    tree_->radiusSearch (interm_cloud_->points[i], 5*scale_, nn_indices, nn_distances);

    float theta_normalization_factor = 0.0;
    std::vector<float> theta (nn_indices.size ());
    for (size_t nn_index_i = 0; nn_index_i < nn_indices.size (); ++nn_index_i)
    {
      float dist = pcl::squaredEuclideanDistance (interm_cloud_->points[i], input_->points[nn_indices[nn_index_i]]);//interm_cloud_->points[nn_indices[nn_index_i]]);
      float theta_i = exp ( (-1) * dist / scale_squared_);
      theta_normalization_factor += theta_i;

      smoothed_normal += theta_i * interm_normals_->points[nn_indices[nn_index_i]].getNormalVector4fMap ();

      theta[nn_index_i] = theta_i;
    }

    smoothed_normal /= theta_normalization_factor;
    smoothed_normal(3) = 0.0f;
    smoothed_normal.normalize ();


    // find minimum along the normal
    float e_residual;
    smoothed_point = interm_cloud_->points[i].getVector4fMap ();
    while (1)
    {
      e_residual = 0.0f;
      smoothed_point(3) = 0.0f;
      for (size_t nn_index_i = 0; nn_index_i < nn_indices.size (); ++nn_index_i)
      {
        Eigen::Vector4f neighbor = input_->points[nn_indices[nn_index_i]].getVector4fMap ();//interm_cloud_->points[nn_indices[nn_index_i]].getVector4fMap ();
        neighbor(3) = 0.0f;
        float dot_product = smoothed_normal.dot (neighbor - smoothed_point);
        e_residual += theta[nn_index_i] * dot_product;// * dot_product;
      }
      e_residual /= theta_normalization_factor;
      if (e_residual < 1e-5) break;

      smoothed_point = smoothed_point + e_residual * smoothed_normal;
    }

    total_residual += e_residual;

    output_positions->points[i].getVector4fMap () = smoothed_point;
    output_normals->points[i].getNormalVector4fMap () = normals_->points[i].getNormalVector4fMap ();//smoothed_normal;
  }

//  std::cerr << "Total residual after iteration: " << total_residual << std::endl;
//  PCL_INFO("SurfelSmoothing done iteration\n");
  return total_residual;
}