十四讲中的ch7程序部分主要讲解了关于orb提取特征点的编程实现,作为小白,在手写orb部分,关于boundary,patch的程序部分让我迷惑好久,今天貌似对其有了新的理解,顿感眼前一亮。
一、程序部分
手写orb中关于boundary、patch的代码部分
// 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;
}
二、解读部分
half_patch_size变量:ORB检测Oriented FAST关键点时选取的图像块边长,即计算质心时选取的图像块区域边长,为长、宽各为16 pixel的区域。虽然16x16=256,但并不是描述子的向量长度。
half_boundary变量:ORB计算BRIEF描述子时所选取的图像块区域,为长宽各为32 pixel的图像块。
函数中利用if语句来进行badpoints的计数,在计算BRIEF描述子时,如果以该keypoints为中心的图像块,超出了图像范围,那么,在进行随机选取像素对时,其计算出的描述子将会是错误的,即该keypoints为badpoints。而以该keypoints为中心的图像块,其长和宽应该满足什么条件时,才能够超出图像呢?主要有四种况:
1、当kp.pt.x < half_boundary时,边长为boundary的图像块将在-x轴上超出图像。
2、当kp.pt.y < half_boundary时,边长为boundary的图像块将在-y轴上超出图像。
3、当kp.pt.x >= img.cols - half_boundary时,边长为boundary的图像块将在+x轴上超出图像。
4、当kp.pt.y >= img.rows - half_boundary时,边长为boundary的图像块将在+y轴上超出图像。
举例如下:
图像块中的中心点为关键点,当关键点的坐标为(half_boundary,half_boundary)时,正好为该关键点的图像块全部在图像中的临界坐标值,该keypoints为goodpoints。
上图中,关键点的坐标为(x,half_boundary),其中x<half_boundary,属于第一种情况。在上图中我们可以看出,以该关键点为中心的图像块,超出了图像之外,当我们计算BRIEF描述子而随机选择像素对时,将会导致选取图像外的像素对,因此该关键点为badpoints,应当剔除掉。