电影坐标到世界坐标

Posted

技术标签:

【中文标题】电影坐标到世界坐标【英文标题】:Film coordinate to world coordinate 【发布时间】:2016-12-01 04:52:14 【问题描述】:

我正在使用 OpenCV3.1 和 OpenGL 从特征匹配构建 3D 点云。

我已经实现了 1)相机校准(因此我有相机的内在矩阵)2)特征提取(因此我在像素坐标中有 2D 点)。 我浏览了几个网站,但一般都建议将 3D 对象点转换为像素点的流程,但我正在做完全的反向投影。这是解释得很好的ppt。

我已经从像素坐标(x,y)(借助固有矩阵)实现了胶片坐标(u,v)。谁能阐明我如何从胶片坐标(x,y)渲染相机坐标(X,Y,Z)的“Z”。

请指导我如何利用 OpenCV 中的函数实现预期目标,例如solvePnP、recoverPose、findFundamentalMat、findEssentialMat。

【问题讨论】:

在 openCv [doc](docs.opencv.org/2.4/modules/calib3d/doc/…findFundamentalMat(InputArray points1, InputArray points2, int method, double param1, double param2, OutputArray mask)) 处读取函数定义。这是要领悟的。对于 ex 计算基本矩阵,您需要做的就是提供在两个图像中协调的匹配像素。 好吧...你能解释一下如何从像素点重建 3d 点吗?我已经看过文档,但你能详细说明我如何利用这些功能 【参考方案1】:

在固定旋转平台上使用单个相机和旋转物体,我会实现这样的事情:

每个摄像头都有xs,ys 的分辨率和由两个角度FOVx,FOVy 定义的视野FOV,因此请查看您的摄像头数据表或进行测量。从该距离和垂直距离 (z),您可以将任何像素位置 (x,y) 转换为相对于相机 (x',y',z') 的 3D 坐标。所以首先将像素位置转换为角度:

ax = (x - (xs/2)) * FOVx / xs 
ay = (y - (ys/2)) * FOVy / ys 

然后在 3D 中计算笛卡尔位置:

x' = distance * tan(ax)
y' = distance * tan(ay)
z' = distance

这很好,但在普通图像上我们不知道distance。幸运的是,在这样的设置中,如果我们转动我们的对象,那么任何凸边都会在与相机垂直的平面相交时在侧面产生最大的ax 角度。所以检查几帧,如果检测到最大的ax,您可以假设它是位于distance 的对象的边缘(或凸块)。

如果您还知道平台的旋转角度ang(相对于您的相机),那么您可以使用rotation 围绕y 轴的公式计算未旋转位置 (@987654336 @ 链接中的矩阵)和相对于相机的已知平台中心位置(只是取消旋转之前的减法)......正如我提到的,这一切只是简单的几何形状。

简而言之:

    获取校准数据

    FOVx,FOVy,xs,ys,距离。一些相机数据表只有 FOVx,但如果像素是矩形的,您可以根据分辨率计算 FOVy

    FOVx/FOVy = xs/ys
    

    注意多分辨率相机模式下,每个分辨率的 FOV 可能不同!!!

    为每一帧提取视频中对象的轮廓

    您可以减去背景图像以简化检测

    获取每一帧的平台角度

    所以要么使用 IRC 数据,要么在旋转盘上放置已知标记并检测/插值...

    检测ax最大值

    只需检查轮廓的 x 坐标(分别针对每个 y 图像行),如果检测到峰值,请将其 3D 位置添加到您的模型。假设旋转矩形框。它的一些框架可能如下所示:

    因此检查所有帧上的一条水平线并找到最大的ax。为了提高准确性,您可以通过转动平台进行闭环调节循环,直到“准确”找到峰值。分别对所有水平线执行此操作。

    顺便说一句。如果你没有检测到ax 改变几个帧,这意味着具有相同半径的圆形......所以你可以处理每个这样的帧 ax 最大。

很容易生成 3D 点云。您可以按平台角度对其进行排序以简化转换为网格...该角度也可以用作纹理坐标...

但不要忘记,你会丢失一些隐藏在轮廓中的凹形细节!!!

如果这种方法还不够,您可以使用相同的设置进行立体 3D 重建。因为每次旋转都表现为新的(已知)相机位置。

【讨论】:

嘿,谢谢你的帮助。你的解释很容易理解,真的很有帮助。我得到了一些示例代码,它们的实现与您的解释相同。除了棋盘图案,你有什么方法可以获得校准数据吗?我可以使用一些球体(滚球)进行校准吗?如果是,那么如何? @ChiragBhuva 如果你在你的平台上放置完美的圆柱体并从左右旋转最大轴之间的中点会给你旋转轴我认为这就是你需要知道的......距离可以通过在平台上显示一些参考球来测量...您可以从像素大小估计大小...无需知道深度您只需要知道像素之间的比率和沿垂直于相机的平面的大小和去往通过旋转中心(因此将球放在平台的中心)并计算 x 和 y 比例... 感谢您的所有帮助。您可以分享您的电子邮件 ID,以便我可以与您分享更多问题吗? @ChiragBhuva 如果与此相关,为什么不在这里添加它(它也可能对其他人有所帮助)。如果不相关,您可以提出有关它的新问题(并在此处评论其链接以通知我)....【参考方案2】:

如果您只有来自该单个摄像头位置的 2D 图像,您就不能。

理论上,您可以使用启发式方法来推断 Z 堆叠。但是从数学上讲,您的问题未得到定义,并且实际上有无数不同的 Z 坐标可以评估您的约束。你必须提供一些额外的信息。例如,您可以在多个帧上移动您的相机(谷歌“运动结构”),或者您可以使用多个相机或使用具有深度传感器并为您提供完整 XYZ 元组(Kinect 或类似)的相机。

因评论而更新:

对于 2D 图像中的每个像素,都有无数个点投影到它上面。对此的技术术语称为射线。如果您有两个空间体积大致相同的 2D 图像,则每个图像的一组光线(每个像素一个)与对应于另一张图像的一组光线相交。也就是说,如果您确定图像#1 中一个像素的光线,这将映射到图像#2 中该光线所覆盖的一行像素。在图像 #2 中沿该线选择特定像素将为您提供该点的 XYZ 元组。

由于您在图像之间沿某个轴a 将对象旋转了某个角度θ,因此您实际上有很多图像可以使用。您所要做的就是通过额外的转换 (inverse(translate(-a)·rotate(θ)·translate(a)) 推导出相机位置。

然后执行以下操作:选择要开始的图像。对于您感兴趣的特定像素,确定它对应的光线。为此,只需假设像素有两个 Z 值。 0 和 1 工作得很好。将它们转换回您的对象空间,然后将它们投影到您选择使用的下一个相机的视图空间中;结果将是图像平面中的两个点(可能超出实际图像的限制,但这不是问题)。这两个点在第二个图像中定义了一条线。沿着这条线找到与您选择的第一张图像上的像素相匹配的像素,并将其投影回空间中,就像使用第一张图像一样。由于数值舍入误差,您不会在 3D 空间中获得完美的光线交点,因此请找到光线彼此最接近的点(这涉及求解二次多项式,这很简单)。

要选择要在图像之间匹配的像素,您可以使用一些特征运动跟踪算法,如用于视频压缩或类似的算法。基本思想是,对于每个像素,其周围环境的相关性都与前一张图像中的相同区域执行。相关峰值在哪里,它可能从哪里移动到哪里。

有了这个像素跟踪,您就可以推导出对象的结构。这基本上就是运动中的结构所做的。

【讨论】:

我们不能使用 kinect,但我们使用的是单摄像头,将通过将物体旋转 360 度来捕捉物体的图像。所以我们收集了二维图像。 1)您能指导我们如何从二维图像中找到深度信息(Z)吗? 对于图像中存在的每个像素,您无法找到 Z(depth) 的确切值,您只能找到所有平面特征的 Z,提供任何特征的长度等额外信息。跨度> @datenwolf.......先生,我们使用 AKAZE 进行特征匹配,我们有两张图像之间匹配的点列表......您能否进一步解释有关恢复 cameraPose 和三角测量的信息这个匹配点? @ChiragBhuva:我在答案更新中解释了这一切。 @datenwolf .....先生,我很抱歉,但我是计算机视觉和opencv的初学者......我已经附上了我的代码,直到恢复姿势......我相信你可以指导我们就可以了...链接:drive.google.com/…

以上是关于电影坐标到世界坐标的主要内容,如果未能解决你的问题,请参考以下文章

世界坐标,本地坐标的转换

顶点法向量从物体坐标系变换到世界坐标系

怎样把CAD的世界坐标恢复到初始状态?

世界坐标系怎么才能转换为用户坐标系

屏幕坐标系和世界坐标系

将世界坐标转化到屏幕坐标