前言
很烦呗,学艺不精导致在啃源码的道路上十分坎坷。
在啃码过程中,看到了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是正的就往右下走。
还是在纠结,哪里定义了就是按水平方向优先走,而不是按竖直方向。
还是说这就是一维数组存储的顺序?
诶,先这么理解着吧。
望有大神解答或肯定!