关于对ORB-SLAM2中计算描述子函数的理解

这篇博客详细介绍了ORB-SLAM2中ORB特征描述子的计算过程。首先,通过比较预定义的点对来生成描述子,这些点对来自于一个256x4的矩阵。每个描述子由256个比特组成,通过比较图像上特定点的像素值来确定比特位的值。计算过程中涉及角度转换、像素值获取以及一系列位操作。每一对比较的点会根据它们的像素差异决定描述子的某一位是1还是0。整个过程重复32次,每次比较16对点,从而得到256位的ORB描述子。这个描述子对于不同特征点来说由于角度差异而各不相同,增强了描述子的区分性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于对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].x
a - 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相同的点对于不同特征点所附带的不同角度返回到的结果不一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值