Opencv 查找两个摄像头之间的相对位置

Opencv 查找两个摄像头之间的相对位置,opencv,camera,computer-vision,camera-calibration,Opencv,Camera,Computer Vision,Camera Calibration,我有一个Kinect摄像头和一个网络摄像头,我正在尝试使用OpenCV查找Kinect和网络摄像头之间的旋转/平移矩阵。以下是设置: 这两台摄像机正对着同一个方向。我可以得到两个相机的内在矩阵,但我不知道如何得到它们之间的相对位置 我做了一些研究,发现了findesentialmat()函数。显然,它返回一个基本矩阵(但该函数似乎不适用,因为它假设两台摄像机中的焦点和主点相同),可用于: recoverPose() decompositeEssentialMat()->如果我理解,它将返回4种

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

这两台摄像机正对着同一个方向。我可以得到两个相机的内在矩阵,但我不知道如何得到它们之间的相对位置

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

  • recoverPose()
  • decompositeEssentialMat()->如果我理解,它将返回4种不同的解决方案,我应该使用此函数吗
  • 多谢各位

    编辑:stereoCalibrate()函数如何?但我的设置与立体相机并不完全一致

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


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

    使用stereoCalibrate。您的设置与立体摄像机完全相同。

    只需将Kinect放在网络摄像机后面即可。Kinect将为您提供从深度图中平移网络摄像头的功能。相关旋转可通过Kinect从刚性连接到网络摄像机的平面计算。如果你不太在意准确度的话,这就行了,我假设立体在这种情况下是不相关的,因为Kinect已经给你提供了深度贴图


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

    如果你对深度图和对齐两幅图像感兴趣,我认为
    stereoCalibrate
    是一种工作方式(我认为这是一个重要的问题,即使我不知道你想做什么,即使你已经从kinect获得了深度图)

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

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

    通过这种方式,您将要实现的目标类似于以下图像:

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

    关于数学的详细描述,我可以向你介绍著名的

    另请参见我的上一篇文章(即热使用外部矩阵和TR矩阵,这些矩阵可以从中分解,并表示相机在世界上的位置和方向)

    出于好奇:你为什么要用普通相机加kinect?kinect为您提供了我们尝试使用2个立体摄像头实现的深度贴图。我不知道一个额外的普通相机能给你什么样的数据,比一个使用外部矩阵的校准kinect能给你更多

    PS这张图片是从这个漂亮的OpenCV中拍摄的,但我认为这篇文章与你的问题没有多大关系,因为那篇文章是关于intrisinc矩阵和失真参数的,你似乎已经知道了。我只是想澄清一下


    编辑:当你谈论外部数据的单位时,你通常是用棋盘的3D点的相同单位来测量它们,因此如果你用p(0,0)p(1,0)p(1,1)p(0,1)p(0,1)p(0)来识别3D中的正方形棋盘边缘点,并用
    solvePnP
    来使用它们,那么相机的平移将以像素为单位来测量棋盘边缘大小“。如果长度为1米,则计量单位为米。对于旋转,单位通常是以弧度表示的角度,但这取决于如何使用
    cv::Rodrigues
    提取它们,以及如何从旋转矩阵中获得3个角度的哈欠俯仰滚动。

    谢谢!我试过了,但我不太了解旋转/平移矩阵的单位。我编辑了我的问题,你发布的图片是经过校正的立体对-请注意,相应的棋盘格角靠近同一条垂直线。但是,您可能希望使用更多的图像对进行迭代,因为这些对应看起来不太准确(考虑到您发布的图像的大小,很难说)。旋转矩阵R没有比例/单位-列是单位向量。IIRC yml格式的定义使得平移向量矩阵T以校准网格的一个正方形的宽度为1进行缩放,因此您只需乘以目标的实际物理宽度。嗨!谢谢你们的回复,我现在正忙着准备一份工作的面试。下周,我将做一些测试,并给大家一些反馈。谢谢你