ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer::ComputeF21 (OpenCV 细节)

ORB_SLAM2 计算 F21 的代码是这样的。

cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1,const vector<cv::Point2f> &vP2)
{
    const int N = vP1.size();

    cv::Mat A(N,9,CV_32F);

    for(int i=0; i<N; i++)
    {
        const float u1 = vP1[i].x;
        const float v1 = vP1[i].y;
        const float u2 = vP2[i].x;
        const float v2 = vP2[i].y;

        A.at<float>(i,0) = u2*u1;
        A.at<float>(i,1) = u2*v1;
        A.at<float>(i,2) = u2;
        A.at<float>(i,3) = v2*u1;
        A.at<float>(i,4) = v2*v1;
        A.at<float>(i,5) = v2;
        A.at<float>(i,6) = u1;
        A.at<float>(i,7) = v1;
        A.at<float>(i,8) = 1;
    }

    cv::Mat u,w,vt;

    cv::SVDecomp(A,w,u,vt,cv::SVD::MODIFY_A | cv::SVD::FULL_UV);

    cv::Mat Fpre = vt.row(8).reshape(0, 3);

    cv::SVDecomp(Fpre,w,u,vt,cv::SVD::MODIFY_A | cv::SVD::FULL_UV);

    w.at<float>(2)=0;

    return  u*cv::Mat::diag(w)*vt;
}

F21 的真正意思是:

\[x_2^TF_{21}x_1^T=0
\]

而写成克罗内克积的形式应该是这样的:

\[(x_1 \otimes x_2)^TF_{21}^s = 0
\]

\[(x_1 \otimes x_2)^T = [ u_1 u_2, u_1 v_2, u_1, v_1 u_2, v_1 v_2, v_1, u_2, v_2, 1 ]^T
\]

这样上面的代码不是写错了吗?

不,OpenCV 是“ROW stack”,而数学公式里面写的是“COL stack”。

OpenCV:

\[F_{21}^s = [f_{11}, f_{12}, f_{13}, …, f_{31}, f_{32}, f_{33}]^T
\]

数学公式:

\[F_{21}^s = [f_{11}, f_{21}, f_{31}, …, f_{13}, f_{23}, f_{33}]^T
\]

总结

“ROW stack”用$ (x_2 \otimes x_1)^T $ 计算 \(F_{21}\)。“COL stack”用$ (x_1 \otimes x_2)^T $,计算 \(F_{21}\)

原文链接: https://www.cnblogs.com/JingeTU/p/6519120.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer::ComputeF21 (OpenCV 细节)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/250509

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午4:33
下一篇 2023年2月14日 上午4:35

相关推荐