0

我正在尝试从平面标记的多个图像执行 3D 重建(运动结构)。我对 MVG 和 openCV 很陌生。

据我了解,我必须执行以下步骤:

  1. 识别一个图像中相应的 2D 角点。
  2. 使用 cv::solvePNP 计算第一张图像的相机姿势(假设原点是标记的中心)。
  3. 对第二张图像重复 1 和 2。
  4. 通过 Rot_relative = R2 - R1, Trans_relative = T2-T1 估计相机的相对运动。
  5. 现在假设第一个摄像机是原点,为两个视图构建 3x4 投影矩阵,P1 =[I|0]*CameraMatrix(由校准已知)和 P2 = [Rot_relative |Trans_relative]。
  6. 使用创建的投影矩阵和 2D 角点使用 cv::triangulatePoints(P1,P2,point1,point2,OutMat) 对 3D 坐标进行三角测量
  7. 可以通过将 OutMat 的每一行除以第 4 行来找到 3D 坐标。
  8. 我希望将我的“第一个视图”作为我的起源并遍历 n 个视图,重复从 1 到 7 的步骤(我想它称为 Global SFM)。

我希望通过“第一个视图作为原点”获得拐角的 (n-1)3D 点,我们可以使用 Bundle Adjustment 对其进行优化。

但是我得到的结果非常令人失望,计算出的 3D 点被一个巨大的因素所取代。

这些是问题:

1.我执行的步骤有问题吗?

2.我应该使用 cv::findHomography() 和 cv::decomposeHomographyMat() 来查找相机的相对运动吗?

3. cv::triangulatePoints(P1,P2,point1,point2,OutMat) 中的point1和point2是否应该归一化且不失真?如果是,应该如何解释“Outmat”?

请任何对该主题有见解的人,您能指出我的错误吗?

PS我在阅读“计算机视觉中的多视图几何”后得到了以上理解

请在下面找到代码片段:

cv::Mat Reconstruction::Triangulate(std::vector<cv::Point2f> 
ImagePointsFirstView, std::vector<cv::Point2f>ImagePointsSecondView)
{   
    cv::Mat rVectFirstView, tVecFristView;
    cv::Mat rVectSecondView, tVecSecondView;
    cv::Mat RotMatFirstView = cv::Mat(3, 3, CV_64F);
    cv::Mat RotMatSecondView = cv::Mat(3, 3, CV_64F);

    cv::solvePnP(RealWorldPoints, ImagePointsFirstView, cameraMatrix, distortionMatrix, rVectFirstView, tVecFristView);
    cv::solvePnP(RealWorldPoints, ImagePointsSecondView, cameraMatrix, distortionMatrix, rVectSecondView, tVecSecondView);



    cv::Rodrigues(rVectFirstView, RotMatFirstView);
    cv::Rodrigues(rVectSecondView, RotMatSecondView);


    cv::Mat RelativeRot = RotMatFirstView-RotMatSecondView ;
    cv::Mat RelativeTrans = tVecFristView-tVecSecondView ;

    cv::Mat RelativePose; 

    cv::hconcat(RelativeRot, RelativeTrans, RelativePose);


    cv::Mat ProjectionMatrix_0 = cameraMatrix*cv::Mat::eye(3, 4, CV_64F);

    cv::Mat ProjectionMatrix_1 = cameraMatrix* RelativePose;
    cv::Mat X;
    cv::undistortPoints(ImagePointsFirstView, ImagePointsFirstView, cameraMatrix, distortionMatrix, cameraMatrix);
    cv::undistortPoints(ImagePointsSecondView, ImagePointsSecondView, cameraMatrix, distortionMatrix, cameraMatrix);

    cv::triangulatePoints(ProjectionMatrix_0, ProjectionMatrix_1, ImagePointsFirstView, ImagePointsSecondView, X);
    X.row(0) = X.row(0) / X.row(3);
    X.row(1) = X.row(1) / X.row(3);
    X.row(2) = X.row(2) / X.row(3);



    return X;
}
4

0 回答 0