【问题标题】:Open CV - Several Methods for SfMOpen CV - SfM 的几种方法
【发布时间】:2012-08-13 16:07:15
【问题描述】:

我有一个任务:

我们有一个系统可以让摄像头绕着人头转半圈。我们知道相机矩阵和每一帧的旋转/平移。 (失真等等......但我想首先在没有这些参数的情况下工作)

我的任务是我只有相机矩阵,它在这个动作中是恒定的,还有图像(超过 100 个)。现在我必须逐帧获取平移和旋转,并将其与现实世界中的旋转和平移进行比较(来自我拥有但仅用于比较的系统,我也证明了!)

到目前为止我所做的第一步:

  1. 使用 OpenCV Cookbook 中的 robustMatcher -works finde - 40-70 匹配每帧 - 可见看起来非常好!
  2. 我使用 getFundamental() 获得了基础矩阵。我使用了来自 robustMatcher 和 RANSAC 的稳健点。
  3. 当我拿到 F 后,我可以使用我的 CameraMatrix K 获得 Essentialmatrix E,如下所示:

cv::Mat E = K.t() * F * K; //Found at the Bible HZ Chapter 9.12

现在我们需要使用 SVD 从 E 中提取 R 和 t。顺便说一句,camera1 的位置为零,因为我们必须从某个地方开始。

cv::SVD svd(E);
cv::SVD svd(E);

cv::Matx33d W(0,-1,0,   //HZ 9.13
          1,0,0,
          0,0,1);

 cv::Matx33d Wt(0,1,0,//W^
        -1,0,0,
        0,0,1);

 cv::Mat R1 = svd.u * cv::Mat(W)  * svd.vt; //HZ 9.19
 cv::Mat R2 = svd.u * cv::Mat(Wt) * svd.vt; //HZ 9.19

 //R1 or R2???
 R = R1; //R2

 //t=+u3 or t=-u3?
 t = svd.u.col(2); //=u3

这是我的实际状态!

我的计划是:

  1. 对所有点进行三角测量以获得 3D 点
  2. 将框架 i 与框架 i++ 连接
  3. 以某种方式可视化我的 3D 点!

现在我的问题是:

  1. 这个强大的匹配器过时了吗?还有其他方法吗?
  2. 使用我在第二步中描述的这些点是否错误?必须用失真或其他方式转换它们吗?
  3. 我在这里提取的 R 和 t 是什么?是从camera1的角度看camera1和camera2之间的旋转和平移吗?
  4. 当我阅读圣经或论文或其他地方时,我发现 R 和 t 有 4 种可能性! 'P' = [UWV^T |+u3] oder [UWV^T |−u3] oder [UW^TV^T |+u3] oder [UW^TV^T |−u3]' P´ 是第二个图像的投影矩阵。 这意味着 t 可能是 - 或 + 并且 R 可能完全不同?! 我发现我应该将一个点计算为 3D 并找出该点是否在两个摄像机的前面,然后我找到了正确的矩阵! 我在互联网上找到了其中一些代码,他只是说这没有进一步计算: cv::Mat R1 = svd.u * cv::Mat(W) * svd.vtt = svd.u.col(2); //=u3 为什么这是正确的?如果不是 - 我将如何在 OpenCV 中进行这种三角测量? 我将这个翻译与给我的翻译进行了比较。 (首先我必须将平移和旋转与 camera1 相关,但我现在得到了这个!)但它不一样。我的程序的值只是让我们称它为从正数跳到负数。但它应该更恒定,因为相机在一个恒定的圆圈中移动。 我确信某些轴可能会被切换。我知道翻译只是从 -1 到 1 但我认为我可以从我的结果中提取一个因素到我的比较值然后它应该是相似的。

以前有人做过类似的事情吗?

很多人通过使用棋盘进行相机校准,但我不能使用这种方法来获取外部参数。

我知道视觉 sfm 可以以某种方式做到这一点。 (在 youtube 上有一段视频,有人绕着一棵树走,并从这些图片中使用视觉 sfm 重建这棵树) 这和我必须做的差不多。

最后一个问题:

有人知道可视化我的 3D 点的简单方法吗?我更喜欢MeshLab。有这方面的经验吗?

【问题讨论】:

    标签: opencv computer-vision camera-calibration


    【解决方案1】:

    很多人用棋盘标定相机,但我不能用这种方法获取外参。

    棋盘或棋盘用于查找内部/内部矩阵/参数,而不是外部参数。你是说你已经有了内部矩阵,我想这就是你的意思

    我们知道相机矩阵和...

    你在 youtube 上看到的那些视频也做了同样的事情,相机已经校准,也就是说内部矩阵是已知的。

    这个强大的匹配器过时了吗?还有其他方法吗?

    我没有那本书,所以看不到代码并回答这个问题。

    使用我在第二步中描述的这些点是错误的吗?必须用失真或其他方式转换它们吗?

    你需要先取消径向畸变,见undistortPoints

    我在这里提取的 R 和 t 是什么?是从camera1看camera1和camera2之间的旋转和平移吗?

    R 是第一台摄像机坐标系中第二台摄像机的方向。 T 是第二个摄像机在该坐标系中的位置。它们有多种用途。

    当我在圣经、论文或其他地方阅读时,我发现有 4 种可能性如何......

    阅读圣经的相关部分,那里对此进行了很好的解释,三角测量是一种幼稚的方法,那里解释了更好的方法。

    有人知道可视化我的 3D 点的简单方法吗?

    要在 Meshlab 中查看它们,一种非常简单的方法是将 3D 点的坐标保存在 PLY 文件中,这是一种极其简单的格式,并且受到 Meshlab 和几乎所有其他 3D 模型查看器的支持。

    【讨论】:

    • @Shambool:谢谢你的帮助。我的研究更进一步。我真的应该使用 undistortPoints。我认为您可以通过校准获得外部数据。但看来我错了。
    • 但我对校准不感兴趣,因为我已经有了相机(内在)矩阵。重要的是要知道 R 和 t 矩阵取决于第一个相机坐标系。下一步:由于有 4 个选项,得到正确的 R 和 t。是的,它可以通过三角测量来完成。 (和 SVD 或 Horn 的封闭形式得到四个选项)
    • 但你只是说这是可能的并且在圣经中描述了数学,但我希望有人已经这样做并想要分享他的代码。最后:是的 ply 文件应该是 Meshlab 最好的。我想回到 youtubevideos:不,他们没有进行校准。他们使用来自罗马、杜布罗夫尼克或一棵树的 150.000 个 Flikrimages 并进行 sfm。所以他们绝对不能有校准!但是我的问题的意思就是解决这个 R 和 t 问题。如果有人想分享他的代码 - 这真的很有帮助。
    • 我尝试使用 OpenCV 中给定的 triangulatePoints 进行三角测量,但如果这个点真的在凸轮前面,我该如何决定?只需检查 x,y,z?这是否意味着它必须在 y(z 如果旋转)轴上为正?还是我也检查 x 和 z(y 如果旋转) 轴?感谢 Shambool 的回答,但它并没有完全解决我的卑鄙问题。您是否在某处找到了描述良好的教程?我找到了一些教程,但没有人真正用代码或准确地描述它。或者我只是看不到明显的东西。 ;-) 到目前为止谢谢你
    • 你在一个问题中问了太多问题。请在stackoverflow上的单独问题中一一提出您的问题,以便更容易回答。人们不能花太多时间回答别人的问题。
    【解决方案2】:

    在这篇文章“五点相对姿势问题的有效解决方案”中,Nistér 解释了一种非常好的方法来确定四种配置中的哪一种是正确的(谈论 R 和 T)。

    我已经尝试过强大的匹配器,我认为它很安静。这个匹配器的问题是非常慢,因为它使用 SURF,也许你应该尝试使用其他检测器和提取器来提高速度。我也相信 OpenCV 中计算基本矩阵的函数不需要 Ransac 参数,因为速率和对称性方法可以很好地去除异常值,您应该尝试使用 8 点参数。

    OpenCV 有 triangulate 功能,这只需要两个投影矩阵,即在第一张和第二张图像中的点。检查 calib3d 模块。

    【讨论】:

    • 值得注意的是,基于 Nister 的工作,最新版本的 OpenCV 现在包括三个用于恢复基本矩阵并分解它的函数。我发现对于我的数据,新的 findEssentialMat 函数比旧的 findFundamentalMat 函数更强大。我在纠正仅移动一个相机拍摄的一对图像时遇到了很多麻烦;现在我的运气更好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多