【问题标题】:Find relative position between 2 cameras查找 2 个摄像头之间的相对位置
【发布时间】:2014-03-28 04:39:25
【问题描述】:

我有一台 Kinect 摄像头和一台网络摄像头,我正在尝试使用 OpenCV 查找 Kinect 和网络摄像头之间的旋转/平移矩阵。这是设置:

两个摄像头朝向同一个方向。我可以得到两个相机的内在矩阵,但我不确定如何得到它们之间的相对位置?

我做了一些研究,发现了 findEssentialMat() 函数。显然它返回一个基本矩阵(但这个函数似乎不合适,因为它假设两个相机的焦点和主点相同),可以用于:

  1. recoverPose()
  2. decomposeEssentialMat() -> 如果我理解了,它会返回 4 个不同的解决方案,我应该使用这个函数吗?

非常感谢!

编辑:stereoCalibrate() 函数怎么样?但我的设置并不真正对应立体相机..

EDIT2:我尝试了 openCV 提供的“stereo_calib.cpp”示例。这是我的结果,我真的不知道如何解释它?

此外,它还会生成一个“extrinsics.yml”文件,我可以在其中找到 R 和 T 矩阵,但我不知道它们以哪些单位表示?我在源代码中多次更改了 squareSize 变量,但矩阵似乎根本没有改变。

【问题讨论】:

  • 嗨!谢谢大家的回复,我现在正忙着准备面试。下周,我会做一些测试,给大家一些反馈。感谢您的帮助!!

标签: opencv camera computer-vision camera-calibration


【解决方案1】:

如果您对深度图和对齐 2 个图像感兴趣,我认为stereoCalibrate 是一种工作方式(我认为这是一个重要的问题,即使我不知道您在尝试什么做,即使你已经有来自 kinect 的深度图)。

但是,如果我正确理解了您的需求,您还想找到相机在世界上的位置。您可以通过在两个视图中使用相同的已知几何来做到这一点。这通常是通过放置在地板上的棋盘图案实现的,由两个(固定位置)摄像机发送。

一旦您有了已知的几何 3d 点和投影在图像平面中的相应 2d 点,您就可以独立地找到相机相对于 3d 世界的 3d 位置,考虑从棋盘的一个边缘开始的世界。

通过这种方式,您将要实现的效果类似于下图:

要找到相机相对于棋盘的 3d 位置,您可以使用 cv::solvePnP 单独查找每个相机的外在矩阵。这是关于相机方向的一些问题(从相机指向原点世界的光线),如果你想可视化它们(如在 OpenGL 中),你必须处理它们(相同:每个相机独立)。还有一些矩阵代数和角度处理。

关于数学的详细描述,我可以联系著名的Multiple View Geometry

另见我之前的answer on augmented reality and integration between OpenCV and OpenGL(即热使用外在矩阵和TR矩阵,可以从中分解并表示位置和方向世界上的相机)。

出于好奇:您为什么使用普通相机加上 kinect? kinect 为您提供了我们尝试使用 2 个立体相机实现的深度图。我不明白一个额外的普通相机可以给你什么样的数据,而不是一个校准过的 kinect 已经很好地利用了外部矩阵。

PS 图片取自这个漂亮的 OpenCV introductory blog,但我认为该帖子与您的问题没有太大关系,因为该帖子是关于似乎您已经拥有的内在矩阵和失真参数。只是为了澄清。

编辑:当您谈论外在数据的 单位 时,您通常以棋盘的 3D 点的相同单位来测量它们,所以如果您确定一个平方的棋盘边缘点在 3D 中使用 P(0,0) P(1,0) P(1,1) P(0,1) 并将它们与solvePnP 一起使用,相机的平移将以“棋盘边缘大小”为单位进行测量”。如果长度为 1 米,则测量单位为米。对于旋转,单位通常是以弧度为单位的角度,但这取决于您如何使用 cv::Rodrigues 提取它们以及如何从旋转矩阵中获取 3 个角度 yawn-pitch-roll。

【讨论】:

  • 您好,很抱歉回复晚了。我使用另一台相机,因为我的目标是将网络摄像头拍摄的照片映射到 kinect 创建的 3D 表面。我这样做是因为网络摄像头将进一步被红外摄像头取代(我们害怕红外摄像头和 kinect 之间的干扰)。如果我理解你的回答,solvePnp 会给我两台摄像机的 rvec 和 tvec,一旦我有了它们,我就能找到相对变换?另外,在校准步骤中,我给方格的尺寸是否重要? (因为你说如果我修改 P(0,0)..etc,单位会改变)
  • 是的,你正确理解了solvePnP的东西,但记得使用cv::Rodrigues。那么是的,正方形的大小很重要!这能回答问题吗?
  • 是的,你真的很有帮助,非常感谢。我想我现在明白了,罗德里格斯会给我旋转矩阵。至于翻译矩阵,我应该在不改变任何东西的情况下使用 tvec 吗?或者我应该使用这个:cameraPosition = -np.matrix(rotM).T * np.matrix(tvec)(我从你的问题中看到了这个:stackoverflow.com/questions/18637494/…
  • 这取决于您的坐标系。看这里:ksimek.github.io/2012/08/14/decompose
【解决方案2】:

使用立体校准。您的设置与立体相机完全一样。

【讨论】:

  • 谢谢!我试过了,但我不太了解旋转/平移矩阵使用的单位。我编辑了我的问题
  • 您发布的图像是经过校正的立体对 - 请注意,相应的棋盘角靠近同一垂直线。但是,您可能希望使用更多图像对进行迭代,因为这些对应关系看起来不太准确(考虑到您发布的图像的大小,很难分辨)。旋转矩阵 R 没有比例/单位 - 列是单位向量。 IIRC 定义了 yml 格式,以便平移向量矩阵 T 以校准网格的一个正方形的宽度为 1 进行缩放,因此您只需乘以目标的实际物理宽度。
【解决方案3】:

只需将 Kinect 放在网络摄像头后面即可。 Kinect 会根据深度图为您提供网络摄像头的转换。可以通过 Kinect 从刚性连接到网络摄像头的平面计算相关旋转。如果您不太关心准确性,这将起作用,并且我认为在这种情况下立体声是无关紧要的,因为 Kinect 已经为您提供了深度图。

如果您需要更准确的结果,则需要指定您的目标。例如,立体校准的目标是生成两个可应用于每个相机图像的单应矩阵,以便对其进行校正,或者换句话说,使像素对应关系位于同一列(用于您的设置)。这简化了对立体匹配的搜索。你的目标是什么?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-05
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多