slambook2+ch7+orb_self 源码的一点小问题

2023-05-16

slambook2+ch7+orb_self 源码的一点小问题+解读

    • 源码详细解读
    • 小错误调试,有的真的属实自己菜
    • 运行结果

源码详细解读

下面是一些个人的见解内联代码片

// compute the descriptor
void ComputeORB(const cv::Mat &img, vector<cv::KeyPoint> &keypoints, vector<DescType> &descriptors) {
  const int half_patch_size = 8;
  const int half_boundary = 16;
  int bad_points = 0;
  for (auto &kp: keypoints) {//剔除在边界上的关键点
    if (kp.pt.x < half_boundary || kp.pt.y < half_boundary ||
        kp.pt.x >= img.cols - half_boundary || kp.pt.y >= img.rows - half_boundary) {
      // outside
      bad_points++;
      descriptors.push_back({});
      continue;
    }
    //这里并没有计算图像块的灰度质心,只是计算了m10,m01,然后算的角度
    float m01 = 0, m10 = 0;
    for (int dx = -half_patch_size; dx < half_patch_size; ++dx) {
      for (int dy = -half_patch_size; dy < half_patch_size; ++dy) {
        uchar pixel = img.at<uchar>(kp.pt.y + dy, kp.pt.x + dx);
        m10 += dx * pixel;
        m01 += dy * pixel;
      }
    }

    // angle should be arc tan(m01/m10);
    float m_sqrt = sqrt(m01 * m01 + m10 * m10) + 1e-18; // avoid divide by zero
    float sin_theta = m01 / m_sqrt;
    float cos_theta = m10 / m_sqrt;

    // compute the angle of this point
    DescType desc(8, 0);
    for (int i = 0; i < 8; i++) {       //8*32=256位的描述子
      uint32_t d = 0;                   //定义一个32位的数据。存储32个0,1数据
      for (int k = 0; k < 32; k++) {    //循环32次,比较p,q值,计算BRIEF描述子
        int idx_pq = i * 32 + k;        //每次循环用掉4个值,一共256行数据,一次循环32行,故乘以系数32
        cv::Point2f p(ORB_pattern[idx_pq * 4], ORB_pattern[idx_pq * 4 + 1]);
        cv::Point2f q(ORB_pattern[idx_pq * 4 + 2], ORB_pattern[idx_pq * 4 + 3]);

        // rotate with theta
        //这一部分点为double型,有点类似于插值的干法
        cv::Point2f pp = cv::Point2f(cos_theta * p.x - sin_theta * p.y, sin_theta * p.x + cos_theta * p.y)
                         + kp.pt;
        cv::Point2f qq = cv::Point2f(cos_theta * q.x - sin_theta * q.y, sin_theta * q.x + cos_theta * q.y)
                         + kp.pt;
        //这里再强制类型转换,取最近邻像素坐标的灰度值用于计算
        if (img.at<uchar>(pp.y, pp.x) < img.at<uchar>(qq.y, qq.x)) {
          d |= 1 << k;
        }
      }
      desc[i] = d;
    }//至此,计算出一个点的描述子
    descriptors.push_back(desc);
  }
  cout << "bad/total: " << bad_points << "/" << keypoints.size() << endl;
}

// brute-force matching
void BfMatch(const vector<DescType> &desc1, const vector<DescType> &desc2, vector<cv::DMatch> &matches) {
  const int d_max = 40;

  for (size_t i1 = 0; i1 < desc1.size(); ++i1) {
    if (desc1[i1].empty()) continue;//如果vector是空就为真
    //这里前面俩参数都是代表的描述子的number,一个的A图的,一个是B图的,最后一个是用于记录描述子的距离
    cv::DMatch m{int(i1), 0, 256};//源码这里有问题,需要强制类型转换
    for (size_t i2 = 0; i2 < desc2.size(); ++i2) {//依次比对,寻找最接近那个,所以暴力匹配才需要匹配i1*i2次
      if (desc2[i2].empty()) continue;
      int distance = 0;
      for (int k = 0; k < 8; k++) {
        distance += _mm_popcnt_u32(desc1[i1][k] ^ desc2[i2][k]);//SSE指令集,计算变量中1的个数
      }
      if (distance < d_max && distance < m.distance) {
        m.distance = distance;
        m.trainIdx = i2;
      }
    }
    if (m.distance < d_max) {
      matches.push_back(m);
    }
  }
}

小错误调试,有的真的属实自己菜

比如,传入图片路径不对,就会有这种错误
在这里插入图片描述

运行结果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

slambook2+ch7+orb_self 源码的一点小问题 的相关文章

随机推荐