如何找到增强现实的相机矩阵?

7

我想在离相机x、y、z米的地方增加一个虚拟对象。OpenCV有相机校准功能,但我不知道如何精确地提供以米为单位的坐标。

我尝试在Unity中模拟相机,但没有得到预期结果。

我设置了投影矩阵,然后在z = 2.415 + 0.5的位置创建了一个单位立方体。 其中2.415是眼睛和投影平面(针孔相机模型)之间的距离。 由于立方体的面位于前向裁剪平面上,尺寸为单位,它难道不应该覆盖整个视口吗?

    Matrix4x4 m = new Matrix4x4();
    m[0, 0] = 1;
    m[0, 1] = 0;
    m[0, 2] = 0;
    m[0, 3] = 0;

    m[1, 0] = 0;
    m[1, 1] = 1;
    m[1, 2] = 0;
    m[1, 3] = 0;

m[2, 0] = 0;
    m[2, 1] = 0;
    m[2, 2] = -0.01f;
    m[2, 3] = 0;

    m[3, 0] = 0;
    m[3, 1] = 0;
    m[3, 2] = -2.415f;
    m[3, 3] = 0;

如果您设置 m[3,2] = -1 / 2.415f 和 m[3,3] = 1,则投影矩阵将正常工作。 - Sumeet Jindal
3个回答

5
为了找到增强物体,需要找到相机的位置和方向。这就是找到相机外参的过程。还需要先计算相机内参(称为校准)。
OpenCV可以帮助您完成所有这些,但并不简单,需要自己付出努力。我给你一个提示,您首先需要识别场景中您知道其外观的对象,以便通过分析该对象来计算相机姿态,将其称为标记。您可以从典型的基准物开始,它们易于检测。
请查看此线程:thread

5
您校准的全局尺度(即三维空间坐标的测量单位)取决于所使用的校准物体的几何形状。例如,在OpenCV中使用平面棋盘图像进行校准时,校准过程的输入是相应的3D点P和它们的图像p的对应点(P, p),3D点的(X、Y、Z)坐标以毫米、厘米、英寸、英里等为单位表示,具体取决于您使用的目标大小(和成像它的光学系统),而图像的2D坐标则以像素为单位。校准例程的输出是一组参数(投影矩阵P和非线性畸变参数k的分量),它们将用这些度量单位表示的3D坐标转换为像素。
如果您不知道(或不想使用)校准目标的实际尺寸,则可以随意调整它们,但保持它们的比例不变(因此,例如,一个正方形保持为正方形,即使其边长的真实长度未知)。在这种情况下,您的校准将被确定到一个未知的全局尺度。实际上这是常见情况:在大多数虚拟现实应用程序中,您并不真正关心全局尺度是多少,只要结果在图像中看起来正确即可。
例如,如果您想在Angelina Jolie的视频中增加一对更蓬松的3D嘴唇,并将它们与原始视频合成在一起,使全新的假唇与她的脸部保持粘连并看起来“自然”,则只需重新调整假唇的3D模型,使其正确重叠于嘴唇图像上。无论该模型距离您渲染合成的计算机生成摄像头有1码还是1英里,都是完全无关紧要的。

1
我能够增强模型,但我希望它在米数上是精确的。我将进行立体渲染,必须给出精确的深度感知。 - Sumeet Jindal
在立体渲染的情况下,度量精度也是无关紧要的:在这种情况下,您所关心的只是以正确的左右视差量进行渲染。只要所有大小和距离比例都正确,实际的全局比例就无法被感知到。 - Francesco Callari
建议您认真考虑是否真的需要全球规模:这非常难以做到正确,特别是在需要高精度时。考虑制造一个适合您光学和深度范围的大小/形状校准装置,它可以保持足够坚固和稳定,并且不会花费太多钱。然后每次制作成功后都要申请专利。 - Francesco Callari

4

最终我手动测量了视野范围。一旦您知道了FOV,就可以轻松创建投影矩阵。不需要担心单位,因为最终的投影形式为(X * d / Z,Y * d / Z)。无论X、Y、Z的单位是什么,X/Z的比率都保持不变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接