【SLAM学习笔记2】关于ORB-SLAM2中计算ORB特征点方向的IC_Angle()函数的问题与理解


前言

很烦呗,学艺不精导致在啃源码的道路上十分坎坷。
在啃码过程中,看到了IC_Angle()函数,对其中的center[]的指代很是不解,经过了一天的摸索,目前有一个让爱钻牛角尖的我妥协的解释。
故书写此文,记下此问题,希望能有dalao给出更为合理的解释,或给将成为dalao的你提供一点参考。


一、IC_Angle()的源码

const int HALF_PATCH_SIZE = 15;

static float IC_Angle(const Mat& image, Point2f pt,  const vector<int> & u_max)
{
    int m_01 = 0, m_10 = 0;

    const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));

    // Treat the center line differently, v=0
    for (int u = -HALF_PATCH_SIZE; u <= HALF_PATCH_SIZE; ++u)
        m_10 += u * center[u];

    // Go line by line in the circular patch
    int step = (int)image.step1();
    for (int v = 1; v <= HALF_PATCH_SIZE; ++v)
    {
        // Proceed over the two lines
        int v_sum = 0;
        int d = u_max[v];
        for (int u = -d; u <= d; ++u)
        {
            int val_plus = center[u + v*step], val_minus = center[u - v*step];
            v_sum += (val_plus - val_minus);
            m_10 += u * (val_plus + val_minus);
        }
        m_01 += v * v_sum;
    }
    
    return fastAtan2((float)m_01, (float)m_10);
}


二、疑问

如代码所示,
center指针指代特征点的像素灰度值,那center[]这个数组各个元素指代的是哪个像素点的灰度值?


三、个人理解(寻求更合理的解释)

我查了很多帖子,问过很多人都没有很好的结果,无法解释,csdn很多大神也没有对此有所注解。

然后经过询问他人,给了我一个思路:试着将center[-1]等价于当前特征点的前一个像素点,则下面的center[u + v*step]也能解释得通了。

将我将该函数摘出来,在新建程序里进行调试验证。

1. 主函数:

int main(int argc, char* argv[])
{
	const Mat& image = imread("ocv.jpg", 1);
	if (!image.data)
	{
		cout << "Please ensure the correctness of the image!" << endl;
		return -1;
	}

	Mat Gray;
	cvtColor(image, Gray, 10);

	Ptr<ORB> orb = ORB::create(500, 1.2, 8, 31, 0, 2, ORB::FAST_SCORE, 31, 20);

	vector<KeyPoint> Keypoints;
	orb->detect(Gray, Keypoints);

	Point2f pt = Keypoints[0].pt;
	cout << pt << endl;

	const vector<int>& u_max = { 15,15,15,15,14,14,14,13,13,12,11,10,9,8,6,3 };

	const uchar* center = &Gray.at<uchar>(cvRound(pt.y), cvRound(pt.x));
	cout << "center value: " << (int)*center << endl;
	for (int i = -HALF_PATCH_SIZE; i <= HALF_PATCH_SIZE; i++)
	{
		cout << "i=" << i << endl;
		cout << "value: " << (int)center[i] << endl;
	}
	//int step = (int)Gray.step1();
	//for (int v = 1; v <= HALF_PATCH_SIZE; ++v)
	//{
	//	int d = u_max[v];
	//	cout << "v:" << v << endl;
	//	cout << "d:" << d << endl;
	//	for (int u = -d; u <= d; ++u)
	//	{
	//		int val_plus = center[u + v * step], val_minus = center[u - v * step];
	//		cout << "u:" << u << endl;
	//		cout << "val_plus: " << (int)val_plus << endl;
	//		cout << "val_minus:" << (int)val_minus << endl;
	//	}
	//	cout << endl;
	//}
	system("pause");
	return 0;
}

2. 验证

首先验证v=0,即u轴上各像素点的灰度值。
在程序窗口中输出:
当前特征点的坐标:(465,482);
当前特征点的灰度值:129;
value为center[i]所指代像素点的灰度值。
输出的数值如下:

[465, 482]
center value: 129
i=-15
value: 2
i=-14
value: 12
i=-13
value: 14
i=-12
value: 8
i=-11
value: 16
i=-10
value: 33
i=-9
value: 35
i=-8
value: 36
i=-7
value: 29
i=-6
value: 12
i=-5
value: 1
i=-4
value: 12
i=-3
value: 46
i=-2
value: 77
i=-1
value: 118
i=0
value: 129
i=1
value: 107
i=2
value: 42
i=3
value: 9
i=4
value: 51
i=5
value: 43
i=6
value: 60
i=7
value: 84
i=8
value: 94
i=9
value: 104
i=10
value: 134
i=11
value: 143
i=12
value: 132
i=13
value: 142
i=14
value: 145
i=15
value: 148

在这里插入图片描述
对照着灰度图上的灰度值进行核对验证,可以发现我上述的猜想是对的。

接着继续验证v≠0时,各点的灰度值(由于数据较多,此处取v=1、2时进行验证):
v=1时,输出的数值如下:

v=1
v:1
d:15
u:-15
val_plus: 9
val_minus:0
u:-14
val_plus: 12
val_minus:3
u:-13
val_plus: 10
val_minus:12
u:-12
val_plus: 4
val_minus:18
u:-11
val_plus: 8
val_minus:26
u:-10
val_plus: 20
val_minus:34
u:-9
val_plus: 23
val_minus:27
u:-8
val_plus: 34
val_minus:22
u:-7
val_plus: 41
val_minus:11
u:-6
val_plus: 32
val_minus:4
u:-5
val_plus: 11
val_minus:14
u:-4
val_plus: 1
val_minus:47
u:-3
val_plus: 8
val_minus:91
u:-2
val_plus: 24
val_minus:122
u:-1
val_plus: 76
val_minus:136
u:0
val_plus: 94
val_minus:126
u:1
val_plus: 88
val_minus:97
u:2
val_plus: 39
val_minus:44
u:3
val_plus: 17
val_minus:15
u:4
val_plus: 59
val_minus:47
u:5
val_plus: 45
val_minus:39
u:6
val_plus: 58
val_minus:70
u:7
val_plus: 91
val_minus:78
u:8
val_plus: 100
val_minus:83
u:9
val_plus: 106
val_minus:90
u:10
val_plus: 131
val_minus:125
u:11
val_plus: 139
val_minus:141
u:12
val_plus: 132
val_minus:133
u:13
val_plus: 145
val_minus:142
u:14
val_plus: 149
val_minus:144
u:15
val_plus: 148
val_minus:149

v=2时,输出的数值如下:

v=2
v:2
d:15
u:-15
val_plus: 10
val_minus:6
u:-14
val_plus: 2
val_minus:0
u:-13
val_plus: 2
val_minus:12
u:-12
val_plus: 7
val_minus:32
u:-11
val_plus: 7
val_minus:38
u:-10
val_plus: 5
val_minus:33
u:-9
val_plus: 9
val_minus:16
u:-8
val_plus: 22
val_minus:8
u:-7
val_plus: 40
val_minus:1
u:-6
val_plus: 48
val_minus:3
u:-5
val_plus: 37
val_minus:27
u:-4
val_plus: 17
val_minus:66
u:-3
val_plus: 6
val_minus:104
u:-2
val_plus: 6
val_minus:126
u:-1
val_plus: 32
val_minus:135
u:0
val_plus: 42
val_minus:106
u:1
val_plus: 51
val_minus:77
u:2
val_plus: 39
val_minus:45
u:3
val_plus: 34
val_minus:26
u:4
val_plus: 64
val_minus:48
u:5
val_plus: 39
val_minus:39
u:6
val_plus: 56
val_minus:81
u:7
val_plus: 78
val_minus:92
u:8
val_plus: 91
val_minus:87
u:9
val_plus: 100
val_minus:84
u:10
val_plus: 130
val_minus:116
u:11
val_plus: 144
val_minus:135
u:12
val_plus: 141
val_minus:131
u:13
val_plus: 152
val_minus:140
u:14
val_plus: 152
val_minus:140
u:15
val_plus: 149
val_minus:149

对照图:
在这里插入图片描述

3. 结论

center[X] 对应的位置从当前特征点center[0]开始,水平方向以右为正方向,垂直方向以下为正方向(像素坐标系的正方向),以此对应特征点周围的像素点。

感觉有点像我们看书的顺序,从左到右,从上到下。X是负的就往左走,走到了这一行的尽头就往上走,X是正的就往右下走。

还是在纠结,哪里定义了就是按水平方向优先走,而不是按竖直方向。
还是说这就是一维数组存储的顺序?
诶,先这么理解着吧。

望有大神解答或肯定!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_z在造梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值