关于对ORB-SLAM2中计算描述子函数的理解
关于对于BRIEF描述子的代码阅读,
具体原理如下,首先明确我们的目的,我们获得的描述子是一个256 X 1的一个描述子
在ORBLSAM2中对于他的求解具体步骤如下,首先我们要比较的点都是事先设置好的点,即代码中所出现的一个256 X 4的一个大矩阵,是原作者所特意提取的点(好像是根据每次多少角度的叠加对于输入固定大小的图像我们每一真都去这样比较),每一行四个值分别代表不同的两个点的坐标XY值
static int bit_pattern_31_[256*4] =
{
8,-3, 9,5/mean (0), correlation (0)/,//平均值和相关系数
4,2, 7,-12/mean (1.12461e-05), correlation (0.0437584)/,
-11,9, -8,2/mean (3.37382e-05), correlation (0.0617409)/,
7,-12, 12,-13/mean (5.62303e-05), correlation (0.0636977)/,
2,-13, 2,12/mean (0.000134953), correlation (0.085099)/,}
//例如第一行的意思是通过比较的是点(8, -3)与 点(9,5)之间的像素值来得出大小
//下面这段代码就是计算描述子
static void computeOrbDescriptor(const KeyPoint& kpt,
const Mat& img, const Point* pattern,
uchar* desc)
{
float angle = (float)kpt.angle*factorPI; //将角度转换为弧度
float a = (float)cos(angle), b = (float)sin(angle);//a= sin a b= cos A
const uchar* center = &kpt.pt.y), cvRound(&kpt.pt.x));
//这个center的意思是图像img的(x,y)位置的元素(用char字符来代表像素暂时存疑?)
const int step = (int)img.step;
//GET——VALUE返回的是旋转后该坐标对应像素点的值
#define GET_VALUE(idx)
center[cvRound(pattern[idx].xb + pattern[idx].ya)step +
cvRound(pattern[idx].xa - pattern[idx].yb)]
//cvRound函数返回的是与该数最接近的整数
//pattern是后面的一个数组的值,在代码地458行有具体说明pattern的创建,如下
// const Point pattern0 = (const Point*)bit_pattern_31_;
std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
//point类为点的坐标,该步骤//将前面的256 x 4的矩阵转化为一个拥有256个点对的point
//持续32次
for (int i = 0; i < 32; ++i, pattern += 16)
{
int t0, t1, val;
t0 = GET_VALUE(0); t1 = GET_VALUE(1);//getvalue是得到该点对应的像素值
val = t0 < t1;
t0 = GET_VALUE(2); t1 = GET_VALUE(3);
val |= (t0 < t1) << 1;
// |= 为A与B按位或运算最终值给A,<<代表将该数位左移
t0 = GET_VALUE(4); t1 = GET_VALUE(5);
val |= (t0 < t1) << 2;
t0 = GET_VALUE(6); t1 = GET_VALUE(7);
val |= (t0 < t1) << 3;
t0 = GET_VALUE(8); t1 = GET_VALUE(9);
val |= (t0 < t1) << 4;
t0 = GET_VALUE(10); t1 = GET_VALUE(11);
val |= (t0 < t1) << 5;
t0 = GET_VALUE(12); t1 = GET_VALUE(13);
val |= (t0 < t1) << 6;
t0 = GET_VALUE(14); t1 = GET_VALUE(15);
val |= (t0 < t1) << 7;
//每次比较16对,循环32次,最终获得的是256个描述子
desc[i] = (uchar)val;//将VAL转化为字符串型来存储
//每一行存储16位的字符,共32行
}
#undef GET_VALUE
}
补充:每个特征点的描述子都不同,观察GETVALUE函数其中在返回该点对应的像素指的时候,有两个参数A,B对应sin a.,cos a,这个角度a是根据灰度质心法算出来的每个特征点模板自带属性,所以通过这样的GETVALUE相同的点对于不同特征点所附带的不同角度返回到的结果不一样