关闭

对极几何——本质矩阵E和基础矩阵F

标签: matrixlistvectorimageeach优化
12352人阅读 评论(2) 收藏 举报
分类:

(1)Essential Matrix

如上图所示,给定一个目标点P,以左摄像头光心Ol为原点。点P相对于光心Ol的观察位置为Pl,相对于光心Or的观察位置为Pr。点P在左摄像头成像平面上的位置为pl,在右摄像头成像平面上的位置为pr注意Pl、Pr、pl、pr 都处于摄像机坐标系,其量纲是与平移向量T相同的(pl、pr 在图像坐标系中对应的像素坐标为 ql、qr )。

假设右摄像头相对于左摄像头的相对位置关系由旋转矩阵R和平移向量T表示,则可得:Pr = R(Pl-T)。

现在我们要寻找由点P、Ol和Or确定的对极平面的表达式。注意到平面上任意一点x与点a的连线垂直于平面法向量n,即向量 (x-a) 与向量 n 的点积为0:(x-a)·n = 0。在Ol坐标系中,光心Or的位置为T,则P、Ol和Or确定的对极平面可由下式表示:(Pl-T)T·(Pl×T) = 0。

Pr = R(Pl-T) 和 RT=R-1 可得:(RTPr)T·(Pl×T) = 0。

另一方面,向量的叉积又可表示为矩阵与向量的乘积,记向量T的矩阵表示为S,得:Pl×T = SPl

clip_image014

图11

那么就得到:(Pr)TRSPl = 0。这样,我们就得到Essential Matrix:E = RS。

通过矩阵E我们知道Pl和Pr的关系满足:(Pr)TEPl = 0。进一步地,由 pl = fl*Pl/Zl 和 pr = fr*Pr/Zr 我们可以得到点P在左右两个摄像机坐标系中的观察点 pl 和 pr 应满足的极线约束关系为:(pr)TEpl = 0。

注意到 E 是不满秩的,它的秩为2,那么 (pr)TEpl = 0 表示的实际上是一条直线,也就是对极线。

(2)Fundamental Matrix

由于矩阵E并不包含摄像头内参信息,且E是面向摄像头坐标系的。实际上我们更感兴趣的是在图像像素坐标系上去研究一个像素点在另一视图上的对极线,这就需要用到摄像机的内参信息将摄像头坐标系和图像像素坐标系联系起来。在(1)中,pl和pr是物理坐标值,对应的像素坐标值为ql和qr,摄像头内参矩阵为M,则有:p=M-1q。从而:(pr)TEpl = 0 à qrT(Mr-1)TE Ml-1ql = 0。这里,我们就得到Fundamental Matrix:F = (Mr-1)TE Ml-1。并有 qrTFql = 0。

(3)OpenCV的相关计算

由上面的分析可见,求取矩阵E和F关键在于旋转矩阵R和平移向量T的计算,而cvStereoCalibrate的代码中大部分(cvcalibration.cpp的第1886-2180行)也是计算和优化R和T的。在cvcalibration.cpp的第1913-1925行给出了计算R和T初始估计值的基本方法:

    /*
       Compute initial estimate of pose

       For each image, compute:
          R(om) is the rotation matrix of om
          om(R) is the rotation vector of R
          R_ref = R(om_right) * R(om_left)'
          T_ref_list = [T_ref_list; T_right - R_ref * T_left]
          om_ref_list = {om_ref_list; om(R_ref)]

       om = median(om_ref_list)
       T = median(T_ref_list)
    */

具体的计算过程比较繁杂,不好理解,这里就不讨论了,下面是计算矩阵E和F的代码:

 

    if( matE || matF )
    {
        double* t = T_LR.data.db;
        double tx[] =
        {
            0, -t[2], t[1],
            t[2], 0, -t[0],
            -t[1], t[0], 0
        };
        CvMat Tx = cvMat(3, 3, CV_64F, tx);
        double e[9], f[9];
        CvMat E = cvMat(3, 3, CV_64F, e);
        CvMat F = cvMat(3, 3, CV_64F, f);
        cvMatMul( &Tx, &R_LR, &E );
        if( matE )
            cvConvert( &E, matE );
        if( matF )
        {
            double ik[9];
            CvMat iK = cvMat(3, 3, CV_64F, ik);
            cvInvert(&K[1], &iK);
            cvGEMM( &iK, &E, 1, 0, 0, &E, CV_GEMM_A_T );
            cvInvert(&K[0], &iK);
            cvMatMul(&E, &iK, &F);
            cvConvertScale( &F, matF, fabs(f[8]) > 0 ? 1./f[8] : 1 );
        }
    }


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:522272次
    • 积分:6648
    • 等级:
    • 排名:第3542名
    • 原创:100篇
    • 转载:231篇
    • 译文:42篇
    • 评论:38条
    最新评论