Saturday, April 9, 2016

Access point correspondences from registration method in Point Cloud Library (a.k.a. access protected member in library class without modifying library source).

This post was inspired by an answer by user D.J.Duff on StackOverflow at this post

The goal was to get point correspondences between two point clouds that were identified during registration using the Point Cloud Library (PCL). The correspondences appear to be saved, but as a protected member of the Registration class. I wasn't interested in modifying the PCL source to add a getter function, so I took the route of exposing it via inheritance. This should work with any registration method that inherits from the Registration class. I think this is considered poor form to violate the class in this manner, but I'm not sure what other options are available without modifying the source class.
/** \brief This is a mock class with the sole purpose of accessing a protected member of a class it inherits from.
*
* Some of the relevant documentation for correspondences: http://docs.pointclouds.org/trunk/correspondence_8h_source.html#l00092
*/
template <typename PointSource, typename PointTarget, typename Scalar = float>
class IterativeClosestPointNonLinear_Exposed : public pcl::IterativeClosestPointNonLinear<PointSource, PointTarget, Scalar> {
  public:
    pcl::CorrespondencesPtr getCorrespondencesPtr() {
      for (uint32_t i = 0; i < this->correspondences_->size(); i++) {
        pcl::Correspondence currentCorrespondence = (*this->correspondences_)[i];
        std::cout << "Index of the source point: " << currentCorrespondence.index_query << std::endl;
        std::cout << "Index of the matching target point: " << currentCorrespondence.index_match << std::endl;
        std::cout << "Distance between the corresponding points: " << currentCorrespondence.distance << std::endl;
        std::cout << "Weight of the confidence in the correspondence: " << currentCorrespondence.weight << std::endl;
      }
      return this->correspondences_;
    }
}

And a bit of additional content from my answer on StackOverflow:

Here are some lines drawn between corresponding points between two point clouds obtained in this manner. Notably, the pcl::Correspondence.distance value between two points doesn't always seem to be strictly less than the value of the registration method's maxCorrespondenceDistance, so you may have to check the distances to make sure you're getting only the correspondences you want.


No comments:

Post a Comment