template <typename PointSource, typename PointTarget, typename NormalT, typename Scalar> void pcl::registration::CorrespondenceEstimationBackProjection<PointSource, PointTarget, NormalT, Scalar>::determineReciprocalCorrespondences ( pcl::Correspondences &correspondences, double max_distance) { if (!initCompute ()) return; typedef typename pcl::traits::fieldList<PointTarget>::type FieldListTarget; // Set the internal point representation of choice if(!initComputeReciprocal()) return; correspondences.resize (indices_->size ()); std::vector<int> nn_indices (k_); std::vector<float> nn_dists (k_); std::vector<int> index_reciprocal (1); std::vector<float> distance_reciprocal (1); float min_dist = std::numeric_limits<float>::max (); int min_index = 0; pcl::Correspondence corr; unsigned int nr_valid_correspondences = 0; int target_idx = 0; // Check if the template types are the same. If true, avoid a copy. // Both point types MUST be registered using the POINT_CLOUD_REGISTER_POINT_STRUCT macro! if (isSamePointType<PointSource, PointTarget> ()) { PointTarget pt; // Iterate over the input set of source indices for (std::vector<int>::const_iterator idx_i = indices_->begin (); idx_i != indices_->end (); ++idx_i) { tree_->nearestKSearch (input_->points[*idx_i], k_, nn_indices, nn_dists); // Among the K nearest neighbours find the one with minimum perpendicular distance to the normal min_dist = std::numeric_limits<float>::max (); // Find the best correspondence for (size_t j = 0; j < nn_indices.size (); j++) { float cos_angle = source_normals_->points[*idx_i].normal_x * target_normals_->points[nn_indices[j]].normal_x + source_normals_->points[*idx_i].normal_y * target_normals_->points[nn_indices[j]].normal_y + source_normals_->points[*idx_i].normal_z * target_normals_->points[nn_indices[j]].normal_z ; float dist = nn_dists[j] * (2.0f - cos_angle * cos_angle); if (dist < min_dist) { min_dist = dist; min_index = static_cast<int> (j); } } if (min_dist > max_distance) continue; // Check if the correspondence is reciprocal target_idx = nn_indices[min_index]; tree_reciprocal_->nearestKSearch (target_->points[target_idx], 1, index_reciprocal, distance_reciprocal); if (*idx_i != index_reciprocal[0]) continue; corr.index_query = *idx_i; corr.index_match = nn_indices[min_index]; corr.distance = nn_dists[min_index];//min_dist; correspondences[nr_valid_correspondences++] = corr; } } else { PointTarget pt; // Iterate over the input set of source indices for (std::vector<int>::const_iterator idx_i = indices_->begin (); idx_i != indices_->end (); ++idx_i) { tree_->nearestKSearch (input_->points[*idx_i], k_, nn_indices, nn_dists); // Among the K nearest neighbours find the one with minimum perpendicular distance to the normal min_dist = std::numeric_limits<float>::max (); // Find the best correspondence for (size_t j = 0; j < nn_indices.size (); j++) { PointSource pt_src; // Copy the source data to a target PointTarget format so we can search in the tree pcl::for_each_type <FieldListTarget> (pcl::NdConcatenateFunctor <PointSource, PointTarget> ( input_->points[*idx_i], pt_src)); float cos_angle = source_normals_->points[*idx_i].normal_x * target_normals_->points[nn_indices[j]].normal_x + source_normals_->points[*idx_i].normal_y * target_normals_->points[nn_indices[j]].normal_y + source_normals_->points[*idx_i].normal_z * target_normals_->points[nn_indices[j]].normal_z ; float dist = nn_dists[j] * (2.0f - cos_angle * cos_angle); if (dist < min_dist) { min_dist = dist; min_index = static_cast<int> (j); } } if (min_dist > max_distance) continue; // Check if the correspondence is reciprocal target_idx = nn_indices[min_index]; tree_reciprocal_->nearestKSearch (target_->points[target_idx], 1, index_reciprocal, distance_reciprocal); if (*idx_i != index_reciprocal[0]) continue; corr.index_query = *idx_i; corr.index_match = nn_indices[min_index]; corr.distance = nn_dists[min_index];//min_dist; correspondences[nr_valid_correspondences++] = corr; } } correspondences.resize (nr_valid_correspondences); deinitCompute (); }
template <typename PointSource, typename PointTarget, typename NormalT, typename Scalar> void pcl::registration::CorrespondenceEstimationNormalShooting<PointSource, PointTarget, NormalT, Scalar>::determineReciprocalCorrespondences ( pcl::Correspondences &correspondences, double max_distance) { if (!initCompute ()) return; typedef typename pcl::traits::fieldList<PointSource>::type FieldListSource; typedef typename pcl::traits::fieldList<PointTarget>::type FieldListTarget; typedef typename pcl::intersect<FieldListSource, FieldListTarget>::type FieldList; // setup tree for reciprocal search // Set the internal point representation of choice if (!initComputeReciprocal ()) return; correspondences.resize (indices_->size ()); std::vector<int> nn_indices (k_); std::vector<float> nn_dists (k_); std::vector<int> index_reciprocal (1); std::vector<float> distance_reciprocal (1); double min_dist = std::numeric_limits<double>::max (); int min_index = 0; pcl::Correspondence corr; unsigned int nr_valid_correspondences = 0; int target_idx = 0; // Check if the template types are the same. If true, avoid a copy. // Both point types MUST be registered using the POINT_CLOUD_REGISTER_POINT_STRUCT macro! if (isSamePointType<PointSource, PointTarget> ()) { PointTarget pt; // Iterate over the input set of source indices for (std::vector<int>::const_iterator idx_i = indices_->begin (); idx_i != indices_->end (); ++idx_i) { tree_->nearestKSearch (input_->points[*idx_i], k_, nn_indices, nn_dists); // Among the K nearest neighbours find the one with minimum perpendicular distance to the normal min_dist = std::numeric_limits<double>::max (); // Find the best correspondence for (size_t j = 0; j < nn_indices.size (); j++) { // computing the distance between a point and a line in 3d. // Reference - http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html pt.x = target_->points[nn_indices[j]].x - input_->points[*idx_i].x; pt.y = target_->points[nn_indices[j]].y - input_->points[*idx_i].y; pt.z = target_->points[nn_indices[j]].z - input_->points[*idx_i].z; const NormalT &normal = source_normals_->points[*idx_i]; Eigen::Vector3d N (normal.normal_x, normal.normal_y, normal.normal_z); Eigen::Vector3d V (pt.x, pt.y, pt.z); Eigen::Vector3d C = N.cross (V); // Check if we have a better correspondence double dist = C.dot (C); if (dist < min_dist) { min_dist = dist; min_index = static_cast<int> (j); } } if (min_dist > max_distance) continue; // Check if the correspondence is reciprocal target_idx = nn_indices[min_index]; tree_reciprocal_->nearestKSearch (target_->points[target_idx], 1, index_reciprocal, distance_reciprocal); if (*idx_i != index_reciprocal[0]) continue; // Correspondence IS reciprocal, save it and continue corr.index_query = *idx_i; corr.index_match = nn_indices[min_index]; corr.distance = nn_dists[min_index];//min_dist; correspondences[nr_valid_correspondences++] = corr; } } else { PointTarget pt; // Iterate over the input set of source indices for (std::vector<int>::const_iterator idx_i = indices_->begin (); idx_i != indices_->end (); ++idx_i) { tree_->nearestKSearch (input_->points[*idx_i], k_, nn_indices, nn_dists); // Among the K nearest neighbours find the one with minimum perpendicular distance to the normal min_dist = std::numeric_limits<double>::max (); // Find the best correspondence for (size_t j = 0; j < nn_indices.size (); j++) { PointSource pt_src; // Copy the source data to a target PointTarget format so we can search in the tree pcl::for_each_type <FieldListTarget> (pcl::NdConcatenateFunctor <PointSource, PointTarget> ( input_->points[*idx_i], pt_src)); // computing the distance between a point and a line in 3d. // Reference - http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html pt.x = target_->points[nn_indices[j]].x - pt_src.x; pt.y = target_->points[nn_indices[j]].y - pt_src.y; pt.z = target_->points[nn_indices[j]].z - pt_src.z; const NormalT &normal = source_normals_->points[*idx_i]; Eigen::Vector3d N (normal.normal_x, normal.normal_y, normal.normal_z); Eigen::Vector3d V (pt.x, pt.y, pt.z); Eigen::Vector3d C = N.cross (V); // Check if we have a better correspondence double dist = C.dot (C); if (dist < min_dist) { min_dist = dist; min_index = static_cast<int> (j); } } if (min_dist > max_distance) continue; // Check if the correspondence is reciprocal target_idx = nn_indices[min_index]; tree_reciprocal_->nearestKSearch (target_->points[target_idx], 1, index_reciprocal, distance_reciprocal); if (*idx_i != index_reciprocal[0]) continue; // Correspondence IS reciprocal, save it and continue corr.index_query = *idx_i; corr.index_match = nn_indices[min_index]; corr.distance = nn_dists[min_index];//min_dist; correspondences[nr_valid_correspondences++] = corr; } } correspondences.resize (nr_valid_correspondences); deinitCompute (); }