使用一台摄像机从多个图像进行三维重建

时间:2015-05-16 12:47:45

标签: c++ opencv 3d

所以,我一直试图从一系列物体的图像中获取一个3D云点。我已经成功获得了一个有两个图像的体面点云。我通过匹配两个图像上的特征得到了这一点,找到了基本矩阵,并从中提取了P' (第二个视图的相机矩阵)。对于第一个视图,我设置P = K(I | 0),其中K是相机内在函数的矩阵。但我还没有能够将这种方法扩展到几个图像。我的想法是通过图像序列滑动两个图像窗口(例如,将image1与image2匹配,找到3d点,将image2与image3匹配,然后找到更多的3d点,依此类推)。对于以下图像对,P将由累积旋转矩阵和累积平移向量组成(这将允许我继续将点带到第一个摄像机坐标系)。但这根本不起作用。我正在使用OpenCV。我想知道的是这种方法是否有意义。 在代码中,P_prev是P而P1是P'。这只是我认为相关的部分。

Mat combinedPointCloud;
Mat P_prev;
P_prev = (Mat_<double>(3,4) <<  cameraMatrix.at<double>(0,0), cameraMatrix.at<double>(0,1), cameraMatrix.at<double>(0,2), 0,
                                cameraMatrix.at<double>(1,0), cameraMatrix.at<double>(1,1), cameraMatrix.at<double>(1,2), 0,
                                cameraMatrix.at<double>(2,0), cameraMatrix.at<double>(2,1), cameraMatrix.at<double>(2,2), 0);

for(int i = 1; i < images.size(); i++) {

    Mat points3D;

    image1 = images[i-1];
    image2 = images[i];

    matchTwoImages(image1, image2, imgpts1, imgpts2);
    P = findSecondProjectionMatrix(cameraMatrix, imgpts1, imgpts2);

    P.col(0).copyTo(R.col(0));
    P.col(1).copyTo(R.col(1));
    P.col(2).copyTo(R.col(2));
    P.col(3).copyTo(t.col(0));

    if(i == 1) {
        Pl = P;
        triangulatePoints(P_prev, Pl, imgpts1, imgpts2, points3D); //points3D is 4xN

        //Transforming to euclidean by hand, because couldn't make 
        // opencv's convertFromHomogeneous work
        aux.create(3, points3D.cols, CV_64F);// aux is 3xN
        for(int i = 0; i < points3D.cols; i++) {
            aux.at<float>(0, i) = points3D.at<float>(0, i)/points3D.at<float>(3, i);
            aux.at<float>(1, i) = points3D.at<float>(1, i)/points3D.at<float>(3, i);
            aux.at<float>(2, i) = points3D.at<float>(2, i)/points3D.at<float>(3, i);
        }

        points3D.create(3, points3D.cols, CV_64F);
        aux.copyTo(points3D);

    }
    else {
        R_aux = R_prev * R;
        t_aux = t_prev + t;

        R_aux.col(0).copyTo(Pl.col(0));
        R_aux.col(1).copyTo(Pl.col(1));
        R_aux.col(2).copyTo(Pl.col(2));
        t_aux.col(0).copyTo(Pl.col(3));

        triangulatePoints(P_prev, Pl, imgpts1, imgpts2, points3D);

        //Transforming to euclidean by hand, because couldn't make 
        // opencv's convertFromHomogeneous work
        aux.create(3, points3D.cols, CV_64F);// aux is 3xN
        for(int i = 0; i < points3D.cols; i++) {
            aux.at<float>(0, i) = points3D.at<float>(0, i)/points3D.at<float>(3, i);
            aux.at<float>(1, i) = points3D.at<float>(1, i)/points3D.at<float>(3, i);
            aux.at<float>(2, i) = points3D.at<float>(2, i)/points3D.at<float>(3, i);
        }

        points3D.create(3, points3D.cols, CV_64F);
        aux.copyTo(points3D);
    }   
    Pl.col(0).copyTo(R_prev.col(0));
    Pl.col(1).copyTo(R_prev.col(1));
    Pl.col(2).copyTo(R_prev.col(2));
    Pl.col(3).copyTo(t_prev.col(0));
    P_prev = Pl;

    if(i==1) {
        points3D.copyTo(combinedPointCloud);
    } else {
        hconcat(combinedPointCloud, points3D, combinedPointCloud);
    }
}
show3DCloud(comninedPointCloud);

0 个答案:

没有答案