一、函数的作用
计算特征点的方向信息,并返回角度
二、源码和注释
// 这个函数用于计算特征点的方向,这里是返回角度作为方向。
static float IC_Angle(const Mat& image, Point2f pt, const vector<int> & u_max)
{
// m_01为y轴坐标加权,m_10为x轴坐标加权
int m_01 = 0, m_10 = 0;
// 获得这个特征点所在的图像块的中心点坐标灰度值的指针center
const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
// Treat the center line differently, v=0
// v = 0的时候,y方向无,只用计算x方向
for (int u = -HALF_PATCH_SIZE; u <= HALF_PATCH_SIZE; ++u)
m_10 += u * center[u];
// Go line by line in the circuI853lar patch
// 创建步长并初始化
int step = (int)image.step1(); // .step1()返回矩阵中每一行所占用的字节数
// 遍历圆上面的每个点,对其灰度加权,算出m_10和m_01
for (int v = 1; v <= HALF_PATCH_SIZE; ++v)
{
// Proceed over the two lines
int v_sum = 0;
// 获取横坐标最大范围(3,6,8,9,10,11,12,13,13,14,14,14,15,15,15,15)
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;
}
// 返回特征值的角度,类型为float型
return fastAtan2((float)m_01, (float)m_10);
}
三、传递的参数
1. const Mat& image 要进行操作的某层金字塔图像,类型为Mat类型(矩阵),&是变量引用的意思,引用可以节省空间。
2. Point2f pt 当前特征点的坐标,类型为Point2f
Point2f 是 OpenCV 中的一个用于表示二维点的类模板的特定实例,它表示二维空间中的一个点,并且每个坐标使用 float 类型的小数表示。
3. const vector<int> & u_max 灰度图像的边界,类型为vector<int>(动态数组,数组内的成员为int类型),umax在构造函数内求出。
四、函数难点
原始的FAST特征点没有方向信息,这样当图像发生旋转后,brief描述子也会发生变化,使得特征点对旋
转不鲁棒,计算特征点的方向,可以保证旋转不变性,鲁棒性更好,本函数的难点是灰度质心的定义。
本函数采用了先求0行的灰度加权,然后同时求第一行和第负一行的加权(这样可以减少一倍的计算量),
后面依次求到第15和负15行(如下图),以此求得 m_01 和 m_10 ,方法和数学里面求质量不均衡平面物体的质心一样,
只不过每个像素点为离散的点