5、ORB特征点方向计算实现旋转不变性

ORB特征点方向计算实现旋转不变性

computeOrientation分析

提取特征点后就需要计算它的描述子,前面已经根据圆的分析找出了它的计算区域,现在只需要依据对称性
计算并调用 IC_Angle函数

/**
 * @brief 计算特征点的方向
 * @param[in] image                 特征点所在当前金字塔的图像
 * @param[in & out] keypoints       特征点向量
 * @param[in] umax                  每个特征点所在图像区块的每行的边界 u_max 组成的vector
 */
static void computeOrientation(const Mat& image, vector<KeyPoint>& keypoints, const vector<int>& umax)
{
	// 遍历所有的特征点
    for (vector<KeyPoint>::iterator keypoint = keypoints.begin(),
         keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
    {
		// 调用IC_Angle 函数计算这个特征点的方向
        keypoint->angle = IC_Angle(image, 			//特征点所在的图层的图像
								   keypoint->pt, 	//特征点在这张图像中的坐标
								   umax);			//每个特征点所在图像区块的每行的边界 u_max 组成的vector
    }
}
  • IC_Angle函数分析
/**
 * @brief 这个函数用于计算特征点的方向,这里是返回角度作为方向。
 * 计算特征点方向是为了使得提取的特征点具有旋转不变性。
 * 方法是灰度质心法:以几何中心和灰度质心的连线作为该特征点方向
 * @param[in] image     要进行操作的某层金字塔图像
 * @param[in] pt        当前特征点的坐标
 * @param[in] u_max     图像块的每一行的坐标边界 u_max
 * @return float        返回特征点的角度,范围为[0,360)角度,精度为0.3°
 */
static float IC_Angle(const Mat& image, Point2f pt,  const vector<int> & u_max)
{
	//图像的矩,前者是按照图像块的y坐标加权,后者是按照图像块的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中心线的计算需要特殊对待
    //由于是中心行+若干行对,所以PATCH_SIZE应该是个奇数
    for (int u = -HALF_PATCH_SIZE; u <= HALF_PATCH_SIZE; ++u)
		//注意这里的center下标u可以是负的!中心水平线上的像素按x坐标(也就是u坐标)加权
        m_10 += u * center[u];

    // Go line by line in the circular patch  
	//这里的step1表示这个图像一行包含的字节总数。参考[https://blog.csdn.net/qianqing13579/article/details/45318279]
    int step = (int)image.step1();
	//注意这里是以v=0中心线为对称轴,然后对称地每成对的两行之间进行遍历,这样处理加快了计算速度
    for (int v = 1; v <= HALF_PATCH_SIZE; ++v)
    {
        // Proceed over the two lines
		//本来m_01应该是一列一列地计算的,但是由于对称以及坐标x,y正负的原因,可以一次计算两行
        int v_sum = 0;
		// 获取某行像素横坐标的最大范围,注意这里的图像块是圆形的!
        int d = u_max[v];
		//在坐标范围内挨个像素遍历,实际是一次遍历2个
        // 假设每次处理的两个点坐标,中心线上方为(x,y),中心线下方为(x,-y) 
        // 对于某次待处理的两个点:m_10 = Σ x*I(x,y) =  x*I(x,y) + x*I(x,-y) = x*(I(x,y) + I(x,-y))
        // 对于某次待处理的两个点:m_01 = Σ y*I(x,y) =  y*I(x,y) - y*I(x,-y) = y*(I(x,y) - I(x,-y))
        for (int u = -d; u <= d; ++u)
        {
			//得到需要进行加运算和减运算的像素灰度值
			//val_plus:在中心线下方x=u时的的像素灰度值
            //val_minus:在中心线上方x=u时的像素灰度值
            int val_plus = center[u + v*step], val_minus = center[u - v*step];
			//在v(y轴)上,2行所有像素灰度值之差
            v_sum += (val_plus - val_minus);
			//u轴(也就是x轴)方向上用u坐标加权和(u坐标也有正负符号),相当于同时计算两行
            m_10 += u * (val_plus + val_minus);
        }
        //将这一行上的和按照y坐标加权
        m_01 += v * v_sum;
    }

    //为了加快速度还使用了fastAtan2()函数,输出为[0,360)角度,精度为0.3°
    return fastAtan2((float)m_01, (float)m_10);
}

ORB(Oriented FAST and Rotated BRIEF)是一种计算机视觉领域中的特征点提取和描述算法。它结合了FAST角点检测器、BRIEF特征描述子以及旋转方向估计来提高特征点的稳定性和描述性能。 ORB特征点加速主要表现在以下几个方面。 首先,ORB算法通过引入FAST角点检测器,大大提高了特征点的检测速度。FAST角点检测器采用了快速边缘响应的方式,能够高效地检测出感兴趣点。相比于传统的Harris角点检测算法,FAST角点检测器具有更快的响应速度,并且在提取特征点时不需要计算图像的梯度,减少了计算量。 其次,ORB算法通过使用BRIEF特征描述子,加快了特征点的匹配速度。BRIEF特征描述子采用二进制方式描述特征点周围区域的灰度差异,可以快速计算特征点的特征向量。相比于传统的SIFT和SURF算法使用的浮点数描述子,BRIEF特征描述子在计算和存储上更加高效,从而提高了特征匹配的速度。 最后,ORB算法引入旋转不变性,提高了特征点的稳定性和鲁棒性。ORB算法通过计算每个特征点周围的灰度质心,确定特征点旋转方向,从而使得特征点旋转变换下保持稳定。这使得ORB算法对于具有旋转变换的图像具有较好的特征检测和匹配性能。 综上所述,ORB特征点加速体现在快速的角点检测、高效的特征描述和稳定的旋转不变性。这些优化使得ORB算法在实际应用中能够快速准确地提取和匹配图像中的特征点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值