我想使用OpenCV从Motion做一些结构。这应该在Android上发生。
目前,我正在使用cameraMatrix(固有参数)和来自摄像机校准的失真系数。

用户现在应该从建筑物中拍摄2张图像,并且该应用程序应生成一个点云。
注意:用户在沿着建筑物的一侧移动时,可能还会稍微旋转智能手机的摄像头...

目前,我有以下信息:

  • 左图像未失真
  • 正确的右图
  • 使用SIFT的良好匹配列表
  • 单应矩阵
  • 基本矩阵

  • 我已经搜索过互联网,现在我很困惑应该如何进行...
    有人说我需要使用stereoRectify来获取Q,并将Q与reprojectImageTo3D()一起使用来获取pointCloud。

    其他人则说我需要使用stereoRectifyUncalibrated,并使用此方法中的H1和H2来填充triangulatePoints的所有参数。
    在triangulatePoints中,我需要每个摄像机/图像的projectionMatrix,但是从我的理解来看,这显然是错误的。

    所以对我来说有一些问题:
  • 如何从我已有的
  • 信息中获得R和T(旋转和翻译)
  • 如果我使用stereoRectify,则前4个参数是cameraMatrix1,畸变Coeff1,cameraMatrix2,畸变Coeff2)-如果我没有像Kinect这样的stereoCamera,则ameraMatrix1和cameraMatrix2等于我的设置(智能手机上的单摄像头)
  • 如何获取Q(如果我有R和T,我可以从stereoRectify获得它)
  • 是否有另一种获取每个摄像机的projectioMatrices的方法,所以我可以使用OpenCV提供的三角测量方法

  • 我知道这是很多问题,但是googeling使我感到困惑,所以我需要弄清楚这一点。我希望有人可以帮助我解决我的问题。

    谢谢

    PS,因为这是更多理论上的问题,我没有发布一些代码。如果您想/需要查看代码或相机校准的值,请询问,我将其添加到我的帖子中。

    最佳答案

    之前,我曾写过有关使用Farneback的光流进行“运动中的结构”的文章。您可以在此处阅读详细信息。

    但是这是代码片段,虽然有些奏效,但不是很好的实现。希望您可以将其用作参考。

    /* Try to find essential matrix from the points */
    Mat fundamental = findFundamentalMat( left_points, right_points, FM_RANSAC, 0.2, 0.99 );
    Mat essential   = cam_matrix.t() * fundamental * cam_matrix;
    
    /* Find the projection matrix between those two images */
    SVD svd( essential );
    static const Mat W = (Mat_<double>(3, 3) <<
                         0, -1, 0,
                         1, 0, 0,
                         0, 0, 1);
    
    static const Mat W_inv = W.inv();
    
    Mat_<double> R1 = svd.u * W * svd.vt;
    Mat_<double> T1 = svd.u.col( 2 );
    
    Mat_<double> R2 = svd.u * W_inv * svd.vt;
    Mat_<double> T2 = -svd.u.col( 2 );
    
    static const Mat P1 = Mat::eye(3, 4, CV_64FC1 );
    Mat P2 =( Mat_<double>(3, 4) <<
             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));
    
    /*  Triangulate the points to find the 3D homogenous points in the world space
        Note that each column of the 'out' matrix corresponds to the 3d homogenous point
     */
    Mat out;
    triangulatePoints( P1, P2, left_points, right_points, out );
    
    /* Since it's homogenous (x, y, z, w) coord, divide by w to get (x, y, z, 1) */
    vector<Mat> splitted = {
        out.row(0) / out.row(3),
        out.row(1) / out.row(3),
        out.row(2) / out.row(3)
    };
    
    merge( splitted, out );
    
    return out;
    

    08-25 23:13