您想要的答案将取决于您需要的结果的准确性。正如 danaid 所指出的,图像传感器的非线性和大气失真等其他因素可能会导致误差,但在不同设备上使用不同的相机等将是难以解决的问题。因此,让我们从获得一个合理的近似值开始,当需要更高的准确性时可以对其进行调整。
首先,如果您愿意,您可以忽略来自设备的方向信息。如果您有五个位置(POS1 - POS4 和相机,在一组一致的坐标基础上),您就拥有了所需的一切。事实上,您甚至不需要所有这些点。
关于一致坐标的说明。在他的尺度上,一旦你使用将经纬度转换为米,使用 cos(lat) 作为比例因子,你应该能够从“平坦地球”的角度对待每个人。然后您只需要记住相机的 x-y 平面大致是全局 x-z 平面。
概念背景
下图展示了点在图像平面上的投影。用于透视的 dz 可以直接使用远点和近点之间的视野距离与它们的物理距离的比例得出。在简单情况中,POS1 到 POS2 的线平行于 POS3 到 POS4 的线,透视因子就是两条线的缩放比例:
Scale (POS1, POS2) = pixel distance (pos1, pos2) / Physical distance (POS1, POS2)
Scale (POS3, POS4) = pixel distance (pos3, pos4) / Physical distance (POS3, POS4)
Perspective factor = Scale (POS3, POS4) / Scale (POS1, POS2)
因此,应用于矩形顶点的透视因子将是与线之间顶点的距离的比例。简化:
Factor(rect) ~= [(Rect.z - (POS3, POS4).z / ((POS1, POS2).z - (POS3, POS4).z)] * Perspective factor.
回答
透视变换相对于焦点在观察方向上的距离是线性的。下图是 X 轴平行于图像平面绘制,Y 轴指向观察方向。在该坐标系中,对于任意点 P 和距原点任意距离的图像平面,投影点 p 的 X 坐标 p.x 与 P.x/P.y 成正比。这些值可以线性插值。
在图中,tp 是目标点的期望投影。要获得 tp.x,例如使用距离调整在 pos1.x 和 pos3.x 之间进行插值,如下所示:
tp.x = pos1.x + ((pos3.x-pos1.x)*((TP.x/TP.y)-(POS1.x/POS1.y))/((POS3.x/POS3.y)-(POS1.x/POS1.y))
这种方法的优点是它不需要任何关于每个像素所看到的角度的先验知识,并且对于相机位置和方向的合理错误,它相对稳健。
进一步细化
使用更多数据意味着能够弥补更多错误。在多个视点的情况下,可以使用Tienstra method 校准摄像机的位置和方向。可以在here 找到这种方法的简明证明(使用重心坐标)。
由于所需的变换都是基于齐次坐标的线性变换,因此您可以应用 barycentric coordinates 基于任意三个或更多点进行插值,假设它们在齐次 3 空间中的 X、Y、Z、W 坐标和它们的 (x ,y) 图像空间中的坐标。点越接近目标点,非线性可能越不重要,因此在您的示例中,您将使用 POS 1 和 POS3,因为矩形在左侧,而 POS2 或 POS4 取决于相对距离.
(重心坐标可能是最常见的用于在 3D 图形中的三角形(片段)上插入颜色的方法。)
编辑:重心坐标仍然需要 W 齐次坐标因子,这是表示距焦点距离的透视校正的另一种方式。有关详细信息,请参阅 GameDev 上的this article。
两个相关的 SO 问题:perspective correction of texture coordinates in 3d 和 Barycentric coordinates texture mapping。