使用Aruco标记(OpenCV)将相机姿势映射到SceneKit

时间:2019-06-19 11:52:58

标签: opencv scenekit aruco

尝试将摄像机位置从Aruco跟踪映射回SceneKit中的摄像机位置。它几乎可以正常工作,但跟踪确实不稳定,并且似乎无法转换为SceneKit相机姿势,因为它漂浮在相机视图中的标记上并随着我移动相机而移动。在转换回sceneKit摄像机平移和位置矢量的转换中,谁能看到我在这里做错的事情?

for item in root.findall("{http://www.ca.com/spectrum/restful/schema/response}model-responses"):
     #print(item.findall('{http://www.ca.com/spectrum/restful/schema/response}model'))
     for child in item.findall('{http://www.ca.com/spectrum/restful/schema/response}model'):
         #print(child.attrib, child.tag)
         for info in child.findall('{http://www.ca.com/spectrum/restful/schema/response}attribute'):
               print(info.tag, info.attrib)
               print(info.text)

在OpenCV中完成的绘图是正确的,并且视频中可以看到我在Aruco板上的轴和框架正在精确跟踪。

非常感谢您的帮助。 这是场景的视频。应该锁定在标记位置的黄色物体看起来非常不稳定。

https://youtu.be/ZvKtZ3DNdrk

1 个答案:

答案 0 :(得分:0)

很遗憾,这不是一个完整的示例,因此不清楚错误在哪里。无论如何,您发布的内容似乎仍然可能存在问题,因此也许我通过困惑进行的谈话会有所帮助。

RotX似乎旨在解决OpenCV(右边X,向下YZ)和SceneKit(右边X,{ {1}}向上,Y结束)。

Ztvec代表相对于OpenCV摄像机的世界原点。

rvecR.t()相同,正交旋转,因此R.inv()现在是原始Rrvec的逆矩阵。

因此,R = R.t()(或更明确地说,Mat tvecConverted = -R * tvec;)是相机的世界坐标。 R * -tvec似乎与Rodrigues(R, rvecConverted);的世界框架相似。

然后,将每个值乘以rvec,以将OpenCV坐标转换为SceneKit坐标,并分配给RotX

更新:代码更新后,我们看到分配给payload的值最终会分配给payload cameraNodeposition值。由于SceneKit rotation始终沿其父项SCNCamera的负Z轴以相同的方向指向,因此对父项SCNNode进行定位和定向可以对摄像机本身进行定位和定向。这表明上面的SCNNodetvecConverted是正确的,因为摄像机的rvecConverted似乎是根节点的父级。

但是,仍然存在从ScenKit相机空间投影到显示器像素空间的问题,这似乎不在您发布的代码摘录中。我怀疑这需要匹配在OpenCV侧绘制时使用的固有相机矩阵和失真,以便它们正确对齐。

SCNCamera docs page中,projectionTransform property的描述如下:

  

此转换表示所有   相机的几何属性:投影类型(透视   或正交),视野,深度限制和正交   规模(如果适用)。 SceneKit使用此转换来   将相机节点的坐标空间中的点转换为   渲染和处理事件时,渲染器的2D空间。

     

如果您的应用需要执行以下操作,则可以直接使用此转换   在视图和渲染器坐标之间进行转换,以用于其他目的。   另外,如果您计算自己的投影变换矩阵,   您可以设置此属性以覆盖转换   根据相机的几何特性合成的。

由于您尚未发布与相机内部特性相关的代码,因此尚不清楚这是否是问题所在。但是,我怀疑在OpenCV和SceneKit之间对齐内在函数将解决此问题。此外,还会根据节点的SCNNode属性来评估SceneKit变换,因此,如果要使用该属性,则要格外小心(例如,将pivot相对于其角而不是其中心放置) )