PointCloud来自两个未失真的图像

时间:2014-03-26 16:19:41

标签: android opencv 3d-reconstruction

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

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

目前,我有以下信息:

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

我在互联网上搜索过,现在我很困惑,我该怎么办...... 有人说我需要使用stereoRectify获取Q并使用Q和reprojectImageTo3D()获取pointCloud。

其他人说我需要使用stereoRectifyUncalibrated并使用此方法中的H1和H2来填充triangulatePoints的所有参数。 在triangulatePoints中,我需要每个相机/图像的投影矩阵,但从我的理解来看,这似乎是错误的。

所以对我来说有一些问题:

  • 如何从我已有的所有信息中获得R和T(轮换和翻译)
  • 如果我使用stereoRectify,前4个参数是cameraMatrix1,distortionCoeff1,cameraMatrix2,distortionCoeff2) - 如果我没有像Kinect这样的stereoCamera,那么ameraMatrix1和cameraMatrix2等于我的设置(智能手机上的单声道相机)
  • 我如何获得Q(猜测我是否有R和T我可以从stereoRectify获得它)
  • 是否有另外一种方法可以获得每台摄像机的投影功能,因此我可以使用OpenCV提供的三角测量方法

我知道这是很多问题,但googeling让我很困惑,所以我需要直截了当。我希望有人可以帮我解决我的问题。

由于

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

2 个答案:

答案 0 :(得分:2)

我曾经写过一些关于使用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;

答案 1 :(得分:0)

这不是OpenCV,但这里有一个确切要求的例子:

http://boofcv.org/index.php?title=Example_Stereo_Single_Camera

Android演示应用程序包含以下代码:

https://play.google.com/store/apps/details?id=org.boofcv.android