C++ 用一台摄像机从多幅图像进行三维重建

C++ 用一台摄像机从多幅图像进行三维重建,c++,opencv,3d,C++,Opencv,3d,所以,我一直在尝试从一个物体的一系列图像中获得一个3D云点。我已经成功地获得了一个体面的点云与两个图像。我通过匹配两幅图像上的特征,找到基本矩阵,然后从中提取P'(第二个视图的摄影机矩阵)。对于第一个视图,我设置P=K(I | 0),其中K是相机内部的矩阵。但我还没能将这种方法扩展到几个图像。我的想法是在图像序列中滑动两个图像窗口(例如,将image1与image2匹配,查找3d点,将image2与image3匹配,然后查找更多3d点,等等)。对于下面的图像对,P将由一个累积旋转矩阵和一个累积平

所以,我一直在尝试从一个物体的一系列图像中获得一个3D云点。我已经成功地获得了一个体面的点云与两个图像。我通过匹配两幅图像上的特征,找到基本矩阵,然后从中提取P'(第二个视图的摄影机矩阵)。对于第一个视图,我设置P=K(I | 0),其中K是相机内部的矩阵。但我还没能将这种方法扩展到几个图像。我的想法是在图像序列中滑动两个图像窗口(例如,将image1与image2匹配,查找3d点,将image2与image3匹配,然后查找更多3d点,等等)。对于下面的图像对,P将由一个累积旋转矩阵和一个累积平移向量组成(这将允许我不断将点带到第一个摄影机坐标系)。但这根本不起作用。我正在使用OpenCV。我想知道的是这种方法是否有意义。 在代码中,P_prev是P,Pl是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);
Mat组合点云;
Mat P_prev;

P_prev=(Mat_(3,4))我一直在尝试做类似的事情,也遇到了类似的问题。你找到了解决方案吗?不是真的。我们无法让它正常工作,但我们得到了一些结果。如果你想了解更多,请看一下我们的项目。