单目初始化(三):特征点归一化

本文详细介绍了在计算本质矩阵和单应矩阵时,为何需要对特征点坐标进行归一化处理。通过像素坐标去均值化、计算一阶绝对矩以及坐标除以一阶绝对矩的步骤,改善了系数矩阵的条件,减少了噪声干扰,提高了求解精度。这一过程包括计算特征点的均值,计算离均值的平均偏离程度,并进行尺度归一化,最后通过矩阵变换表示归一化过程。
摘要由CSDN通过智能技术生成

本次主要讲解计算本质矩阵和计算单应矩阵中的第一步,特征点坐标归一化Initializer::Normalize
首先我们应该明白为什么要对特征点的坐标进行归一化:根据<<计算机视觉中的多视图几何>>一书中所说,对于一个直接线性求解本质矩阵和单应矩阵构成的方程组
A x = 0 Ax=0 Ax=0
求解不稳定的原因是系数矩阵A的条件较差,也就是原始图像的像素坐标组成的矩阵A的条件较差,而造成这个的直接原因就是像素点的齐次坐标各个分量的数量级相差较大,所以在进行求解之前对像素坐标进行归一化可以大大减少噪声的干扰,提高求解精度。

像素坐标的归一化分为三个步骤

  • 像素坐标去均值化
  • 计算一阶绝对矩
  • 像素坐标除以一阶绝对矩

对应的代码分为以下几步

  • 计算特征点X,Y坐标的均值 meanX, meanY
     // Step 1 计算特征点X,Y坐标的均值 meanX, meanY
    float meanX = 0;
    float meanY = 0;
    
    //获取特征点的数量
    const int N = vKeys.size();
    
    //设置用来存储归一后特征点的向量大小,和归一化前保持一致
    vNormalizedPoints.resize(N);
    
    //开始遍历所有的特征点
    for(int i=0; i<N; i++)
    {
    	//分别累加特征点的X、Y坐标
        meanX += vKeys[i].pt.x;
        meanY += vKeys[i].pt.y;
    }
    
    //计算X、Y坐标的均值
    meanX = meanX/N;
    meanY = meanY/N;
    
  • 特征点坐标去均值并计算特征点X,Y坐标的一阶绝对矩
    // Step 2 计算特征点X,Y坐标离均值的平均偏离程度 meanDevX, meanDevY,注意不是标准差
    float meanDevX = 0;
    float meanDevY = 0;
    
    // 将原始特征点减去均值坐标,使x坐标和y坐标均值分别为0
    for(int i=0; i<N; i++)
    {
        vNormalizedPoints[i].x = vKeys[i].pt.x - meanX;
        vNormalizedPoints[i].y = vKeys[i].pt.y - meanY;
    
    	//累计这些特征点偏离横纵坐标均值的程度
        meanDevX += fabs(vNormalizedPoints[i].x);
        meanDevY += fabs(vNormalizedPoints[i].y);
    }
    
    // 求出平均到每个点上,其坐标偏离横纵坐标均值的程度;将其倒数作为一个尺度缩放因子
    meanDevX = meanDevX/N;
    meanDevY = meanDevY/N;
    float sX = 1.0/meanDevX;
    float sY = 1.0/meanDevY;
    
  • 对特征点的像素坐标除以一阶绝对矩
    // Step 3 将x坐标和y坐标分别进行尺度归一化,使得x坐标和y坐标的一阶绝对矩分别为1 
    // 这里所谓的一阶绝对矩其实就是随机变量到取值的中心的绝对值的平均值(期望)
    for(int i=0; i<N; i++)
    {
    	//对,就是简单地对特征点的坐标进行进一步的缩放
        vNormalizedPoints[i].x = vNormalizedPoints[i].x * sX;
        vNormalizedPoints[i].y = vNormalizedPoints[i].y * sY;
    }
    
  • 计算从原始坐标到归一化坐标的归一化矩阵
    // Step 4 计算归一化矩阵:其实就是前面做的操作用矩阵变换来表示而已
    // |sX  0  -meanx*sX|
    // |0   sY -meany*sY|
    // |0   0      1    |
    T = cv::Mat::eye(3,3,CV_32F);
    T.at<float>(0,0) = sX;
    T.at<float>(1,1) = sY;
    T.at<float>(0,2) = -meanX*sX;
    T.at<float>(1,2) = -meanY*sY;
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值