从源码看kalibr 角点提取原理

本文揭秘kalibr中AprilTag角点提取算法,包括目标检测策略和边缘处理规则。

从源码看kalibr 角点提取原理

因为目前涉及kalibr角点提取的代码改写,还想改成用任意标定板都可以提取角点的代码,所以想仔细想仔细研究一下他的提取原理,看看为什么标定板的行列非得大于3.
编译这套docker代码,需要在工作空间的根目录下运行:

catkin build -DCMAKE_BUILD_TYPE=Release -j4

********************************let’s start *****************************************
阅读源码可以发现,核心代码在这里:
\catkin_ws\src\kalibr\aslam_cv\aslam_cameras\src\GridDetector.cpp

bool GridDetector::findTargetNoTransformation(const cv::Mat & image, const aslam::Time & stamp,
    GridCalibrationTargetObservation & outObservation) const {
   
   
  bool success = false;

  // Extract the calibration target corner points
  Eigen::MatrixXd cornerPoints;
  std::vector<bool> validCorners;
  success = _target->computeObservation(image, cornerPoints, validCorners);

  // Set the image, target, and timestamp regardless of success.
  outObservation.setTarget(_target);
  outObservation.setImage(image);
  outObservation.setTime(stamp);

  // Set the observed corners in the observation
  for (int i = 0; i < cornerPoints.rows(); i++) {
   
   
    if (validCorners[i])
      outObservation.updateImagePoint(i, cornerPoints.row(i).transpose());
  }

  return success;
}

分析可知,_target应该包括提取的角点。找到其对应头文件,看他的私有成员可以知道_target是是GridCalibrationTargetBase::Ptr类型。

 private:
  /// the camera geometry
  boost::shared_ptr<CameraGeometryBase> _geometry;

  /// \brief the calibration target
  GridCalibrationTargetBase::Ptr _target;

  /// \brief detector options
  GridDetectorOptions _options;

前面提到,提取关键角点的代码为:

 success = _target->computeObservation(image, cornerPoints, validCorners);

找到computeObservation这个函数,位于\catkin_ws\src\kalibr\aslam_cv\aslam_cameras\include\aslam\cameras\GridCalibrationTargetBase.hpp,发现是一个虚函数:

  virtual bool computeObservation(const cv::Mat & /*image*/,
                                  Eigen::MatrixXd & /*outImagePoints*/,
                                  std::vector<bool> & /*outCornerObserved*/) const
  {
   
   
    SM_ASSERT_TRUE(Exception, true, "you need to implement this method for each target!");
    return false;
  };

这说明,应该是每一个不同的板子用不同的计算角点的方法。对于April tag,找到他的computeObservation的路径为:\catkin_ws\src\kalibr\aslam_cv\aslam_cameras_april\include\aslam\cameras\GridCalibrationTargetAprilgrid.hpp

 /// \brief extract the calibration target points from an image and write to an observation
  bool computeObservation(const cv::Mat & image,
                          Eigen::MatrixXd & outImagePoints,
                          std::vector<bool> &outCornerObserved) const;

让我们看看cpp的具体实现它干了什么:

/// \brief extract the calibration target points from an image and write to an observation
bool GridCalibrationTargetAprilgrid::computeObservation(
    const cv::Mat & image, Eigen::MatrixXd & outImagePoints,
    std::vector<bool> &outCornerObserved) const {
   
   

  bool success = true;

  // detect the tags
  std::vector<AprilTags::TagDetection> detections = _tagDetector->extractTags(image);

  /* handle the case in which a tag is identified but not all tag
   * corners are in the image (all data bits in image but border
   * outside). tagCorners should still be okay as apriltag-lib
   * extrapolates them, only the subpix refinement will fail
   */

  //min. distance [px] of tag corners from image border (tag is not used if violated)
  std::vector<AprilTags::TagDetection>::iterator iter = detections.begin();
  for (iter = detections.begin(); iter != detections.end();) {
   
   
    // check all four corners for violation
    bool remove = false;

    for (int j = 0; j < 4; j++) {
   
   
      remove |= iter->p[j].first < _options.minBorderDistance;
      remove |= iter->p[j].first > (float) (image.cols) - _options.minBorderDistance;  //width
      remove |= iter->p[j].second < _options.minBorderDistance;
      remove |= iter->p[j].second > (float) (image.rows) - _options.minBorde
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值