前言
在 PCL(Point Cloud Library) 和 Open3D 中,ICP(Iterative Closest Point)算法都有一个 Fitness Score,但它们的定义和意义有所不同。
1. pcl
pcl 获取 Fitness Score
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
double fitness_score = icp.getFitnessScore()
- Fitness Score 是通过计算所有源点与目标点之间的最近邻距离的平均值来衡量配准的质量。
- 距离过滤:如果距离超过
max_range
,则认为匹配无效,不计入误差。 - 返回值:越小的 Fitness Score 代表配准效果越好;如果没有点满足距离条件,返回一个非常大的值来表示配准失败。
源代码如下:
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 (std::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);
return (std::numeric_limits<double>::max ());
}
2. open3d
open3d 获取 Fitness Score
// 点到面ICP
open3d::pipelines::registration::RegistrationResult result_point2plane = open3d::pipelines::registration::RegistrationICP();
double fitness_score = result_point2plane.fitness_;
- Fitness 在 Open3D 中表示的是源点云中成功与目标点云匹配的点对的比例。
- 具体含义:
- 如果源点云中的大部分点能够与目标点云中的点成功配对(即找到匹配点),那么 Fitness 的值会接近 1。
- Fitness = 1 表示源点云中的所有点都与目标点云中的点配对成功,重叠完美。
- Fitness 越大越好,它的范围为 0 到 1,其中 1 代表完美重叠,0 代表几乎没有重叠。
源代码如下:
/// \brief Functions for ICP registration.
///
/// \param source The source point cloud.
/// \param target The target point cloud.
/// \param max_correspondence_distance Maximum correspondence points-pair
/// distance. \param init Initial transformation estimation.
/// Default value: array([[1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 1., 0.],
/// [0., 0., 0., 1.]])
/// \param estimation Estimation method.
/// \param criteria Convergence criteria.
RegistrationResult RegistrationICP(
const geometry::PointCloud &source,
const geometry::PointCloud &target,
double max_correspondence_distance,
const Eigen::Matrix4d &init = Eigen::Matrix4d::Identity(),
const TransformationEstimation &estimation =
TransformationEstimationPointToPoint(false),
const ICPConvergenceCriteria &criteria = ICPConvergenceCriteria());
/// For ICP: the overlapping area (# of inlier correspondences / # of points in target). Higher is better.
/// For RANSAC: inlier ratio (# of inlier correspondences / # of all correspondences)
double fitness_;