欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > ORB-SLAM2源码学习:Initializer.cc:Initializer::CheckHomography地图初始化——检查单应矩阵并评分

ORB-SLAM2源码学习:Initializer.cc:Initializer::CheckHomography地图初始化——检查单应矩阵并评分

2024/11/29 14:18:17 来源:https://blog.csdn.net/2301_76831056/article/details/144024329  浏览:    关键词:ORB-SLAM2源码学习:Initializer.cc:Initializer::CheckHomography地图初始化——检查单应矩阵并评分

前言

这部分函数是要对所有的单应矩阵进行一个打分,比较得分,得分最高(误差最小)的选为最优的单应矩阵。

1.函数声明

float Initializer::CheckHomography(const cv::Mat &H21,                 const cv::Mat &H12,                vector<bool> &vbMatchesInliers,     float sigma)  

2.函数定义 

1.单应矩阵描述特征点对之间的关系 

2.定义误差(实际上,上述的等式不完全恒等于0) 

其中在代码中σ=1。

3.评分公式 (误差越大评分越低)

th表示自由度为2的卡方分布在显著性水平为0.05时对应的临界域值。 

/*对给定的homography matrix打分,需要使用到卡方检验的知识H21                       从参考帧到当前帧的单应矩阵H12                       从当前帧到参考帧的单应矩阵vbMatchesInliers          匹配好的特征点对的Inliers标记sigma                     方差,默认为1return float                        返回得分*/
float Initializer::CheckHomography(const cv::Mat &H21,                 //从参考帧到当前帧的单应矩阵const cv::Mat &H12,                 //从当前帧到参考帧的单应矩阵vector<bool> &vbMatchesInliers,     //匹配好的特征点对的Inliers标记float sigma)                        //估计误差
{// 特点匹配个数const int N = mvMatches12.size();// Step 1 获取从参考帧到当前帧的单应矩阵的各个元素const float h11 = H21.at<float>(0,0);const float h12 = H21.at<float>(0,1);const float h13 = H21.at<float>(0,2);const float h21 = H21.at<float>(1,0);const float h22 = H21.at<float>(1,1);const float h23 = H21.at<float>(1,2);const float h31 = H21.at<float>(2,0);const float h32 = H21.at<float>(2,1);const float h33 = H21.at<float>(2,2);// 获取从当前帧到参考帧的单应矩阵的各个元素const float h11inv = H12.at<float>(0,0);const float h12inv = H12.at<float>(0,1);const float h13inv = H12.at<float>(0,2);const float h21inv = H12.at<float>(1,0);const float h22inv = H12.at<float>(1,1);const float h23inv = H12.at<float>(1,2);const float h31inv = H12.at<float>(2,0);const float h32inv = H12.at<float>(2,1);const float h33inv = H12.at<float>(2,2);// 给特征点对的Inliers标记预分配空间vbMatchesInliers.resize(N);// 初始化score值float score = 0;// 基于卡方检验计算出的阈值(假设测量有一个像素的偏差)// 自由度为2的卡方分布,显著性水平为0.05,对应的临界阈值const float th = 5.991;//信息矩阵,方差平方的倒数const float invSigmaSquare = 1.0/(sigma * sigma);// Step 2 通过H矩阵,进行参考帧和当前帧之间的双向投影,并计算起加权重投影误差// H21 表示从img1 到 img2的变换矩阵// H12 表示从img2 到 img1的变换矩阵 for(int i = 0; i < N; i++){// 一开始都默认为Inlierbool bIn = true;// Step 2.1 提取参考帧和当前帧之间的特征匹配点对const cv::KeyPoint &kp1 = mvKeys1[mvMatches12[i].first];const cv::KeyPoint &kp2 = mvKeys2[mvMatches12[i].second];const float u1 = kp1.pt.x;const float v1 = kp1.pt.y;const float u2 = kp2.pt.x;const float v2 = kp2.pt.y;// Step 2.2 计算 img2 到 img1 的重投影误差// x1 = H12*x2// 将图像2中的特征点通过单应变换投影到图像1中// |u1|   |h11inv h12inv h13inv||u2|   |u2in1|// |v1| = |h21inv h22inv h23inv||v2| = |v2in1| * w2in1inv// |1 |   |h31inv h32inv h33inv||1 |   |  1  |// 计算投影归一化坐标const float w2in1inv = 1.0/(h31inv * u2 + h32inv * v2 + h33inv);const float u2in1 = (h11inv * u2 + h12inv * v2 + h13inv) * w2in1inv;const float v2in1 = (h21inv * u2 + h22inv * v2 + h23inv) * w2in1inv;// 计算重投影误差 = ||p1(i) - H12 * p2(i)||2const float squareDist1 = (u1 - u2in1) * (u1 - u2in1) + (v1 - v2in1) * (v1 - v2in1);const float chiSquare1 = squareDist1 * invSigmaSquare;// Step 2.3 用阈值标记离群点,内点的话累加得分if(chiSquare1>th)bIn = false;    else// 误差越大,得分越低score += th - chiSquare1;// 计算从img1 到 img2 的投影变换误差// x1in2 = H21*x1// 将图像2中的特征点通过单应变换投影到图像1中// |u2|   |h11 h12 h13||u1|   |u1in2|// |v2| = |h21 h22 h23||v1| = |v1in2| * w1in2inv// |1 |   |h31 h32 h33||1 |   |  1  |// 计算投影归一化坐标const float w1in2inv = 1.0/(h31*u1+h32*v1+h33);const float u1in2 = (h11*u1+h12*v1+h13)*w1in2inv;const float v1in2 = (h21*u1+h22*v1+h23)*w1in2inv;// 计算重投影误差 const float squareDist2 = (u2-u1in2)*(u2-u1in2)+(v2-v1in2)*(v2-v1in2);const float chiSquare2 = squareDist2*invSigmaSquare;// 用阈值标记离群点,内点的话累加得分if(chiSquare2>th)bIn = false;elsescore += th - chiSquare2;   // Step 2.4 如果从img2 到 img1 和 从img1 到img2的重投影误差均满足要求,则说明是Inlier pointif(bIn)vbMatchesInliers[i]=true;elsevbMatchesInliers[i]=false;}return score;
}

结束语 

以上就是我学习到的内容,如果对您有帮助请多多支持我,如果哪里有问题欢迎大家在评论区积极讨论,我看到会及时回复。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com