progNewbie
progNewbie

Reputation: 4832

What unit is `getFitnessScore()` in the IterativeClosestPoint class from PCL returning?

I use the pcl::IterativeClosestPoint method from the Point-Cloud-Library. As of right now it seems that the documentation of it is offline. Here in google cache. And also a tutorial.

There is a possibility to call icp.getFitnessScore() to get the mean squared distances from the points of the two clouds. I just can't find information on what kind of unit this is indicated. Does anyone knows what the number I get there means? For example output for me was: 0,0003192. This seems to be low, but I have no clue if it is meters, centimeters, feet, or whatever.

Thank you very much.

Upvotes: 4

Views: 3715

Answers (1)

Jing Zhao
Jing Zhao

Reputation: 2682

what kind of unit is icp.getFitnessScore() used?

Like Joy said in his comment, the unit is the same as your input data.
For example, your input point cloud might comes from a obj file. And a point will be stored like v 9.322 -1.0778 0.44997. The number returned by icp.getFitnessScore() will have the same unit as the point's coordinate.


Does anyone knows what the number I get there means?

The number you get represents the mean squared distance from each point in source to its closest point in target.

That is to say, if you assume every point in source has a corresponding point in target, and the correspondence set comes from closest point data association, then the number represents the mean squared distance between all correspondences. That can be seen from the source code below.

To make more sense of the function, you might want to filter out correspondences that have a large distance between them. (The two point cloud might only partially overlap.) And the function actually has an optional parameter max_range that does this.


The method getFitnessScore() is defined in pcl::Registration, the base class of pcl::IterativeClosestPoint. The optional parameter max_range is defaulted to be std::numeric_limits<double>::max(), as you can see in the definition:

/** \brief Obtain the Euclidean fitness score (e.g., sum of squared distances from the source to the target)
  * \param[in] max_range maximum allowable distance between a point and its correspondence in the target 
  * (default: double::max)
  */
inline double 
getFitnessScore (double max_range = std::numeric_limits<double>::max ());

And the source code of this function is:

template <typename PointSource, typename PointTarget, typename Scalar> inline double
pcl::Registration<PointSource, PointTarget, Scalar>::getFitnessScore (double max_range)
{

  double fitness_score = 0.0;

  // Transform the input dataset using the final transformation
  PointCloudSource input_transformed;
  transformPointCloud (*input_, input_transformed, final_transformation_);

  std::vector<int> nn_indices (1);
  std::vector<float> nn_dists (1);

  // For each point in the source dataset
  int nr = 0;
  for (size_t i = 0; i < input_transformed.points.size (); ++i)
  {
    // Find its nearest neighbor in the target
    tree_->nearestKSearch (input_transformed.points[i], 1, nn_indices, nn_dists);

    // Deal with occlusions (incomplete targets)
    if (nn_dists[0] <= max_range)
    {
      // Add to the fitness score
      fitness_score += nn_dists[0];
      nr++;
    } 
  } 

  if (nr > 0)
    return (fitness_score / nr);
  else
    return (std::numeric_limits<double>::max ());

}

Upvotes: 5

Related Questions