ORB-SLAM2
代码
利用F矩阵来进行恢复,主要用于非平面
return ReconstructF(vbMatchesInliersF,F,mK,R21,t21,vP3D,vbTriangulated,1.0,50);
进入ReconstructF()函数
bool Initializer::ReconstructF(vector<bool> &vbMatchesInliers, cv::Mat &F21, cv::Mat &K,
cv::Mat &R21, cv::Mat &t21, vector<cv::Point3f> &vP3D, vector<bool> &vbTriangulated, float minParallax, int minTriangulated)
//传参:匹配好的点对应的inlier的标记、从参考帧到当前帧的基础矩阵、相机内参、旋转阵、平移向量、三角化后特征点的空间坐标,三角化成功标志、最小三角化成功视差、最小三角化的数量
{
int N=0;
for(size_t i=0, iend = vbMatchesInliers.size() ; i<iend; i++)
if(vbMatchesInliers[i])
N++;//查看存储匹配中有多少个有用的点
// Compute Essential Matrix from Fundamental Matrix
cv::Mat E21 = K.t()*F21*K;//计算E矩阵本质矩阵
cv::Mat R1, R2, t;
```// Recover the 4 motion hypotheses
DecomposeE(E21,R1,R2,t);
cv::Mat t1=t;
cv::Mat t2=-t;
// Reconstruct with the 4 hyphoteses and check//本质矩阵会有四组解,算出最佳的组合
vector<cv::Point3f> vP3D1, vP3D2, vP3D3, vP3D4;
vector<bool> vbTriangulated1,vbTriangulated2,vbTriangulated3, vbTriangulated4;
float parallax1,parallax2, parallax3, parallax4;
int nGood1 = CheckRT(R1,t1,mvKeys1,mvKeys2,mvMatches12,vbMatchesInliers,K, vP3D1, 4.0*mSigma2, vbTriangulated1, parallax1);//使用同样的匹配点分别检查四组解
int nGood2 = CheckRT(R2,t1,mvKeys1,mvKeys2,mvMatches12,vbMatchesInliers,K, vP3D2, 4.0*mSigma2, vbTriangulated2, parallax2);
int nGood3 = CheckRT(R1,t2,mvKeys1,mvKeys2,mvMatches12,vbMatchesInliers,K, vP3D3, 4.0*mSigma2, vbTriangulated3, parallax3);
int nGood4 = CheckRT(R2,t2,mvKeys1,mvKeys2,mvMatches12,vbMatchesInliers,K, vP3D4, 4.0*mSigma2, vbTriangulated4, parallax4);
int maxGood = max(nGood1,max(nGood2,max(nGood3,nGood4)));//选取最大可三角化的点的数目
R21 = cv::Mat();
t21 = cv::Mat();
int nMinGood = max(static_cast<int>(0.9*N),minTriangulated);//确定最小可三角化点的数目
int nsimilar = 0;//统计四组解中有效点个数>0.7*maxgood
if(nGood1>0.7*maxGood)
nsimilar++;
if(nGood2>0.7*maxGood)
nsimilar++;
if(nGood3>0.7*maxGood)
nsimilar++;
if(nGood4>0.7*maxGood)
nsimilar++;
// If there is not a clear winner or not enough triangulated points reject initialization//没有足够的点认为失败//没有明显的最优结果,认为失败
if(maxGood<nMinGood || nsimilar>1)
{
return false;
}
// If best reconstruction has enough parallax initialize//得到最佳结果并记录//查看在那种情况下
if(maxGood==nGood1)
{
if(parallax1>minParallax)//视差大于给定的最小值
{
vP3D = vP3D1;
vbTriangulated = vbTriangulated1;
R1.copyTo(R21);
t1.copyTo(t21);
return true;
}
}else if(maxGood==nGood2)
{
if(parallax2>minParallax)
{
vP3D = vP3D2;
vbTriangulated = vbTriangulated2;
R2.copyTo(R21);
t1.copyTo(t21);
return true;
}
}else if(maxGood==nGood3)
{
if(parallax3>minParallax)
{
vP3D = vP3D3;
vbTriangulated = vbTriangulated3;
R1.copyTo(R21);
t2.copyTo(t21);
return true;
}
}else if(maxGood==nGood4)
{
if(parallax4>minParallax)
{
vP3D = vP3D4;
vbTriangulated = vbTriangulated4;
R2.copyTo(R21);
t2.copyTo(t21);
return true;
}
}
return false;
}