我有一个Kinect摄像头和一个网络摄像头,我正在尝试使用OpenCV在Kinect和网络摄像头之间找到旋转/平移矩阵。这是设置:
两台摄像机朝向同一方向。我可以得到两个相机的内在矩阵,但我不确定如何获得它们之间的相对位置?
我做了一些研究,发现了 findEssentialMat()函数。显然它返回一个必要的矩阵(但这个函数似乎不合适,因为它假设两个摄像机中的焦点和原理点相同),可以用于:
非常感谢!
编辑: stereoCalibrate()功能怎么样?但我的设置并不真正对应立体相机..
EDIT2:我尝试了openCV提供的“stereo_calib.cpp”示例。这是我的结果,我真的不知道如何解释它?
此外,它产生一个“extrinsics.yml”文件,我可以找到R和T矩阵,但我不知道它们代表哪个单位?我在源代码中多次更改了squareSize变量,但似乎矩阵根本没有改变。
答案 0 :(得分:3)
使用stereoCalibrate。您的设置与立体相机完全相同。
答案 1 :(得分:2)
如果您对深度图感兴趣并对齐2张图像,我认为stereoCalibrate
是工作方式(我认为这是一个重要的问题,即使我不知道你是什么尝试做,即使你已经有了kinect的深度图。)
但是,如果我理解你需要什么,你也想找到世界上相机的位置。您可以通过在两个视图中使用相同的已知几何体来实现。这通常通过位于地板上的棋盘图案实现,由两个(固定位置)相机发送。
一旦你有一个已知的几何形状3d点和投影在图像平面上的相应的2d点,你可以独立地找到相机相对于3d世界的3d位置,考虑到从棋盘的一个边缘开始的世界。
通过这种方式你将要实现的是这样的形象:
要找到相机相对于棋盘的三维位置,您可以使用cv::solvePnP
独立地找到每个相机的外在矩阵。关于相机方向(从相机指向原始世界的光线)的一些问题,如果你想要它们(如在OpenGL中),你必须处理它们(相同:每个相机独立)。一些矩阵代数和角度处理。
有关数学的详细说明,我可以向您介绍着名的Multiple View Geometry。
另见我之前的answer on augmented reality and integration between OpenCV and OpenGL(即使用外在矩阵和 T 和 R 矩阵,可以从中分解并代表位置和世界相机的方向。)
只是为了好奇:你为什么使用普通相机加上一个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个角度的哈欠 - 俯仰 - 滚动。
答案 2 :(得分:0)
将Kinect放在网络摄像头后面。 Kinect将从深度图中为您提供网络摄像头的翻译。关联旋转可以通过Kinect从刚性连接到网络摄像机的平面计算出来。如果您不太关心准确度,这将有效,我认为在这种情况下立体声是无关紧要的,因为Kinect已经为您提供了深度图。
如果您需要更准确的结果,则需要指定目标。例如,立体校准的目标是产生两个单应矩阵,可以应用于每个摄像机图像以纠正它们,换句话说,使像素对应位于同一列(对于您的设置)。这简化了立体匹配的搜索。你的目标是什么?