Overview
- The gray region is the epipolar plane
- The orange line is the baseline
- the two blue lines are the epipolar lines
Basic Epipolar Geometry entities for pinhole cameras and panoramic camera sensors
Foundamental Matrix (基本矩阵)
F=K′−TEK−1
p′T⋅F⋅p=0
其中,p,p′ 为两个匹配 像素点坐标
F 的性质:
- 对其乘以 任意非零常数,对极约束依然满足(尺度等价性,up to scale)
- 具有 7个自由度: 2x11-15=7 (why)
- 奇异性约束 rank(F)=2
F 与 极线和极点 的关系:
l′=F⋅pl=FT⋅p′F⋅e=FT⋅e′=0
F 的计算:
- Compute from 7 image point correspondences
- 8点法(Eight-Point Algorithm)
Foundamental Matrix Estimation
- 类似于下面 E 的估计
Essential Matrix (本质矩阵)
- A 3×3 matrix is an essential matrix if and only if two of its singular values are equal, and the third is zero
对极约束:
E=t∧RE=K′TFKp′T⋅E⋅p=0
其中,p,p′ 为两个匹配像素点的 归一化平面坐标
E 的性质:
- 对其乘以 任意非零常数,对极约束依然满足(尺度等价性,up to scale)
- 根据 E=t∧R,E 的奇异值必定是 [σ,σ,0]T 的形式
- 具有 5个自由度:平移旋转共6个自由度 + 尺度等价性
- 奇异性约束 rank(E)=2(因为 rank(t∧)=2)
E 与 极线和极点 的关系:
l′=E⋅pl=ET⋅p′E⋅e=ET⋅e′=0
E 的计算:
- 5点法(最少5对点求解)
- 8点法(Eight-Point Algorithm)
Essential Matrix Estimation
矩阵形式:
[x′y′1]⋅⎣⎡e1e4e7e2e5e8e3e6e9⎦⎤⋅⎣⎡xy1⎦⎤=0
矩阵 E 展开,写成向量形式 e,并把所有点(n对点,n>=8)放到一个方程中,齐次线性方程组 如下:
⎣⎢⎢⎢⎡x′1x1x′2x2⋮x′nxnx′1y1x′2y2⋮x′nynx′1x′2⋮x′ny′1x1y′2x2⋮y′nxny′1y1y′2y2⋮y′nyny′1y′2⋮y′nx1x2⋮xny1y2⋮yn11⋮1⎦⎥⎥⎥⎤⋅⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡e1e2e3e4e5e6e7e8e9⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=0
即(the essential matrix lying in the null space of this matrix A)
A⋅e=0s.t.A∈Rn×9,n≥8
对上式 求解 最小二乘解(尺度等价性)
emin∥A⋅e∥2s.t.∥eTe∥=1or∥E∥F=1
SVD分解 A(或者 特征值分解 ATA)
SVD(A)=UDVT
e 正比于 V 的最后一列,得到 E
根据 奇异性约束 rank(E)=2,再 SVD分解 E
SVD(E)=UEDEVET
求出的 E 可能不满足其内在性质(奇异值是 [σ,σ,0]T 的形式),此时对 DE 进行调整,假设 DE=diag(σ1,σ2,σ3) 且 σ1≥σ2≥σ3,则令
DE′=diag(2σ1+σ2,2σ1+σ2,0)
或者,更简单的(尺度等价性)
DE′=diag(1,1,0)
最后,E 矩阵的正确估计为
E′=UEDE′VET
Rotation and translation from E
The four possible solutions for calibrated reconstruction from E
- Between the left and right sides there is a baseline reversal
- Between the top and bottom rows camera B rotates 180 about the baseline
- only in (a) is the reconstructed point in front of both cameras
Suppose that the SVD of E is Udiag(1,1,0)VT, there are (ignoring signs) two possible factorizations E=t∧R=SR as follows
t∧=S=UZUTR1=UWVTorR2=UWTVT
where
W=⎣⎡010−100001⎦⎤andZ=⎣⎡0−10100000⎦⎤
and
WZ−Z≈Rz(2π)=WT⋅diag(1,1,0)=W⋅diag(1,1,0)
Rt恢复示例代码 e2rt.cpp:
Matrix3d E;
E << -0.0203618550523477, -0.4007110038118445, -0.03324074249824097,
0.3939270778216369, -0.03506401846698079, 0.5857110303721015,
-0.006788487241438284, -0.5815434272915686, -0.01438258684486258;
cout << "E = \n" << E << endl;
// SVD and fix sigular values
JacobiSVD<MatrixXd> svd(E, ComputeThinU | ComputeThinV);
Matrix3d m3U = svd.matrixU();
Matrix3d m3V = svd.matrixV();
Vector3d v3S = svd.singularValues();
double temp = (v3S[0]+v3S[1])/2;
Matrix3d m3S(Vector3d(temp, temp, 0).asDiagonal());
Eigen::Matrix3d m3R_z_p = Eigen::AngleAxisd( M_PI/2, Eigen::Vector3d(0,0,1)).toRotationMatrix();
Eigen::Matrix3d m3R_z_n = Eigen::AngleAxisd(-M_PI/2, Eigen::Vector3d(0,0,1)).toRotationMatrix();
cout << "m3R_z_p = \n" << m3R_z_p << endl;
cout << "m3R_z_n = \n" << m3R_z_n << endl;
// set t1, t2, R1, R2
Matrix3d t_wedge1;
Matrix3d t_wedge2;
t_wedge1 = m3U * m3R_z_p * m3S * m3U.transpose();
t_wedge2 = m3U * m3R_z_n * m3S * m3U.transpose();
Matrix3d R1;
Matrix3d R2;
R1 = m3U * m3R_z_p.transpose() * m3V.transpose();
R2 = m3U * m3R_z_n.transpose() * m3V.transpose();
cout << "R1 = \n" << R1 << endl;
cout << "R2 = \n" << R2 << endl;
cout << "t1 = \n" << Sophus::SO3::vee(t_wedge1) << endl;
cout << "t2 = \n" << Sophus::SO3::vee(t_wedge2) << endl;
// check t^R=E up to scale
Matrix3d tR = t_wedge1 * R1;
cout << "t^R = \n" << tR << endl;
DecomposeE in ORB-SLAM2
void Initializer::DecomposeE(const cv::Mat &E, cv::Mat &R1, cv::Mat &R2, cv::Mat &t) {
cv::Mat u,w,vt;
cv::SVD::compute(E,w,u,vt);
u.col(2).copyTo(t);
t=t/cv::norm(t);
cv::Mat W(3,3,CV_32F,cv::Scalar(0));
W.at<float>(0,1)=-1;
W.at<float>(1,0)=1;
W.at<float>(2,2)=1;
R1 = u*W*vt;
if(cv::determinant(R1)<0)
R1=-R1;
R2 = u*W.t()*vt;
if(cv::determinant(R2)<0)
R2=-R2;
}
CheckRT in ORB-SLAM2
Homography Matrix (单应性矩阵)
- For planar surfaces, 3D to 2D perspective projection reduces to a 2D to 2D transformation
- 从零开始一起学习SLAM | 神奇的单应矩阵
单应性矩阵 通常描述处于 共同平面 上的一些点在 两张图像之间的变换关系。
p′=H⋅p
其中,p,p′ 为两个匹配像素点的 归一化平面坐标 (也可为其他点,只要 共面且3点不共线 即可)
Homography Estimation
矩阵形式:
⎣⎡x′y′1⎦⎤=⎣⎡h11h21h31h12h22h32h13h23h33⎦⎤⋅⎣⎡xy1⎦⎤
方程形式(两个约束条件):
x′=h31x+h32y+h33h11x+h12y+h13y′=h31x+h32y+h33h21x+h22y+h23
因为上式使用的是齐次坐标,所以我们可以 对 所有的 hij 乘以 任意的非0因子 而不会改变方程。
因此, H 具有 8个自由度,最少通过 4对匹配点(不能出现3点共线) 算出。
实际中,通过 h33=1 或 ∥H∥F=1 两种方法 使 H 具有 8自由度。
cont 1: H元素h33=1
线性方程:
A⋅h=b
求解:
ATA⋅h=ATb
所以
h=(ATA)−1ATb
cont 2: H的F范数|H|=1
线性方程:
A⋅h=0
求解:
ATA⋅h=0
对上式 求解 最小二乘解(尺度等价性)
hmin∥(ATA)⋅h∥2s.t.∥hTh∥=1or∥H∥F=1
SVD分解 或 特征值分解
SVD(ATA)=UΣUT
最后 h 为 Σ 中 最小特征值 对应的 U 中的列向量(单位特征向量);如果只用4对匹配点,那个特征值为0。
H in PTAM
单应性矩阵的计算
Matrix<3> HomographyInit::HomographyFromMatches(vector<HomographyMatch> vMatches)
{
unsigned int nPoints = vMatches.size();
assert(nPoints >= 4);
int nRows = 2*nPoints;
if(nRows < 9)
nRows = 9;
Matrix<> m2Nx9(nRows, 9);
for(unsigned int n=0; n<nPoints; n++)
{
double u = vMatches[n].v2CamPlaneSecond[0];
double v = vMatches[n].v2CamPlaneSecond[1];
double x = vMatches[n].v2CamPlaneFirst[0];
double y = vMatches[n].v2CamPlaneFirst[1];
// [u v]T = H [x y]T
m2Nx9[n*2+0][0] = x;
m2Nx9[n*2+0][1] = y;
m2Nx9[n*2+0][2] = 1;
m2Nx9[n*2+0][3] = 0;
m2Nx9[n*2+0][4] = 0;
m2Nx9[n*2+0][5] = 0;
m2Nx9[n*2+0][6] = -x*u;
m2Nx9[n*2+0][7] = -y*u;
m2Nx9[n*2+0][8] = -u;
m2Nx9[n*2+1][0] = 0;
m2Nx9[n*2+1][1] = 0;
m2Nx9[n*2+1][2] = 0;
m2Nx9[n*2+1][3] = x;
m2Nx9[n*2+1][4] = y;
m2Nx9[n*2+1][5] = 1;
m2Nx9[n*2+1][6] = -x*v;
m2Nx9[n*2+1][7] = -y*v;
m2Nx9[n*2+1][8] = -v;
}
if(nRows == 9)
for(int i=0; i<9; i++) // Zero the last row of the matrix,
m2Nx9[8][i] = 0.0; // TooN SVD leaves out the null-space otherwise
// The right null-space of the matrix gives the homography...
SVD<> svdHomography(m2Nx9);
Vector<9> vH = svdHomography.get_VT()[8];
Matrix<3> m3Homography;
m3Homography[0] = vH.slice<0,3>();
m3Homography[1] = vH.slice<3,3>();
m3Homography[2] = vH.slice<6,3>();
return m3Homography;
};
Rotation and translation from H
- Motion and structure from motion in a piecewise planar environment
手写笔记
2D-2D相机位姿估计
2D-2D相机位姿估计 通常利用 对极几何 进行计算,是单目SLAM初始化时的关键技术。
-
计算 基础矩阵或本质矩阵 适用于特征点不共面的情况,计算 单应矩阵 适用于特征点共面的情况
-
当 特征点共面 或者 相机发生纯旋转 时,基础矩阵 F 的自由度下降,就会出现所谓的 退化(degenerate)。为了能够避免退化现象的影响,通常会 同时估计基础矩阵 F 和 单应矩阵 H,选择重投影误差比较小的那个作为最终的运动估计矩阵。
-
平移向量t 的 尺度不确定性
-
初始化的纯旋转问题:单目初始化不能只有旋转,必须要有一定程度的平移,否则由于t趋近于0,导致无从求解R或者误差非常大
-
多于8对点:RANSAC
Ref: 2D-2D相机位姿估计
Reference
- Epipolar Geometry and the Fundamental Matrix in MVG (Chapter 9)
- 《视觉SLAM十四讲》