Mastering Opencv ch4:SFM详解(三)

本文详细介绍了使用Opencv进行三维重建过程中,如何通过SFM(结构化从运动)求解P1矩阵的过程。通过TriangulatePoints和TestTriangulation函数进行三维点的重构,并通过迭代线性重构计算三维坐标。文中还探讨了判断P1有效性条件,包括基于重投影误差和透视变换后点在摄像机前面的比例。对于为何需要两个条件,作者提出了自己的理解,认为K标定矩阵在重投影和透视变换中起到关键作用。
摘要由CSDN通过智能技术生成

前面已经利用分解本质矩阵E得到两幅图像的姿态R1,R2,t1,t2.
如何把这四个值组合成P1,得到正确的解,接下来就要分析。

1:利用三维重构求取在摄像机前面的重构点的所占比,得出最高占比的那个P1,就是要求得解。

P1 = Matx34d(R1(0,0),   R1(0,1),    R1(0,2),    t1(0),
                         R1(1,0),   R1(1,1),    R1(1,2),    t1(1),
                         R1(2,0),   R1(2,1),    R1(2,2),    t1(2));
            cout << "Testing P1 " << endl << Mat(P1) << endl;

            vector<CloudPoint> pcloud,pcloud1; vector<KeyPoint> corresp;
            double reproj_error1 = TriangulatePoints(imgpts1_good, imgpts2_good, K, Kinv, distcoeff, P, P1, pcloud, corresp);
            double reproj_error2 = TriangulatePoints(imgpts2_good, imgpts1_good, K, Kinv, distcoeff, P1, P, pcloud1, corresp);
            vector<uchar> tmp_status;
            //check if pointa are triangulated --in front-- of cameras for all 4 ambiguations
            if (!TestTriangulation(pcloud,P1,tmp_status) || !TestTriangulation(pcloud1,P,tmp_status) || reproj_error1 > 100.0 || reproj_error2 > 100.0) {
                P1 = Matx34d(R1(0,0),   R1(0,1),    R1(0,2),    t2(0),
                             R1(1,0),   R1(1,1),    R1(1,2),    t2(1),
                             R1(2,0),   R1(2,1),    R1(2,2),    t2(2));
                cout << "Testing P1 "<< endl << Mat(P1) << endl;

                pcloud.clear(); pcloud1.clear(); corresp.clear();
                reproj_error1 = TriangulatePoints(imgpts1_good, imgpts2_good, K, Kinv, distcoeff, P, P1, pcloud, corresp);
                reproj_error2 = TriangulatePoints(imgpts2_good, imgpts1_good, K, Kinv, distcoeff, P1, P, pcloud1, corresp);

                if (!TestTriangulation(pcloud,P1,tmp_status) || !TestTriangulation(pcloud1,P,tmp_status) || reproj_error1 > 100.0 || reproj_error2 > 100.0) {
                    if (!CheckCoherentRotation(R2)) {
                        cout << "resulting rotation is not coherent\n";
                        P1 = 0;
                        return false;
                    }

                    P1 = Matx34d(R2(0,0),   R2(0,1),    R2(0,2),    t1(0),
                                 R2(1,0),   R2(1,1),    R2(1,2),    t1(1),
                                 R2(2,0),   R2(2,1),    R2(2,2),    t1(2));
                    cout << "Testing P1 "<< endl << Mat(P1) << endl;

                    pcloud.clear(); pcloud1.clear(); corresp.clear();
                    reproj_error1 = TriangulatePoints(imgpts1_good, imgpts2_good, K, Kinv, distcoeff, P, P1, pcloud, corresp);
                    reproj_error2 = TriangulatePoints(imgpts2_good, imgpts1_good, K, Kinv, distcoeff, P1, P, pcloud1, corresp);

                    if (!TestTriangulation(pcloud,P1,tmp_status) || !TestTriangulation(pcloud1,P,tmp_status) || reproj_error1 > 100.0 || reproj_error2 > 100.0) {
                        P1 = Matx34d(R2(0,0),   R2(0,1),    R2(0,2),    t2(0),
                                     R2(1,0),   R2(1,1),    R2(1,2),    t2(1),
                                     R2(2,0),   R2(2,1),    R2(2,2),    t2(2));
                        cout << "Testing P1 "<< endl << Mat(P1) << endl;

                        pcloud.clear(); pcloud1.clear(); corresp.clear();
                        reproj_error1 = TriangulatePoints(imgpts1_good, imgpts2_good, K, Kinv, distcoeff, P, P1, pcloud, corresp);
                        reproj_error2 = TriangulatePoints(imgpts2_good, imgpts1_good, K, Kinv, distcoeff, P1, P, pcloud1, corresp);

                        if (!TestTriangulation(pcloud,P1,tmp_status) || !TestTriangulation(pcloud1,P,tmp_status) || reproj_error1 > 100.0 || reproj_error2 > 100.0) {
                            cout << "Shit." << endl; 
                            return false;
                        }
                    }               
                }           
            }

这里主要用了两个函数TriangulatePoints和TestTriangulation。
四种组合依次进行判断,首先给定一种组合,我们有两个由2D点匹配和P矩阵产生的关键等式:x

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值