从双鱼眼坐标转换为equirectangular坐标

时间:2017-10-23 06:40:02

标签: c++ fisheye spherical-coordinate

以下link建议我们可以使用以下等式将双鱼眼坐标转换为等长坐标:

// 2D fisheye to 3D vector
phi = r * aperture / 2
theta = atan2(y, x)

// 3D vector to longitude/latitude
longitude = atan2(Py, Px)
latitude = atan2(Pz, (Px^2 + Py^2)^(0.5))

// 3D vector to 2D equirectangular
x = longitude / PI
y = 2 * latitude / PI

我应用于上面的等式来编写我的源代码:

const float FOV = 220.0f * PI / 180.0f;
float r = sqrt(u*u + v*v);
float theta = atan2(v, u);
float phi = r * FOV * 0.5f;
float px = u;
float py = r * sin(phi);
float pz = v;
float longitude = atan2(py, px); // theta
float latitude = atan2(pz, sqrt(px*px + py*py)); // phi
x = longitude / PI;
y = 2.0f * latitude / PI;

不幸的是我的数学不够理解这一点,不确定我是否正确编写了上述代码,我试图猜测px,py和pz的值。

假设我的相机FOV是220度,相机分辨率是2880x1440,我预计重叠区域中后置摄像头的点(358,224)和重叠区域中前置摄像头的点(2563,197)将映射到接近(2205,1009)的坐标。然而,实际的映射点分别是(515.966370,1834.647949)和(1644.442017,1853.060669),它们都非常远离(2205,1009)。请建议如何修复上述代码。非常感谢!

1 个答案:

答案 0 :(得分:2)

您正在构建equirectangular图像,因此我建议您使用逆映射。

从您正在绘制的目标图像中的像素位置开始。将2D位置转换为经度/纬度。然后将其转换为单位球体表面上的3D点。然后从3D点转换为2D鱼眼源图像中的位置。在Paul Bourke页面中,您将从最底层的方程式开始,然后是最右侧的方程式,然后是最顶层的方程式。

使用90°长0°lat等标志点来验证每一步的结果是否合理。

最终结果应该是[-1 .. + 1]范围内的源鱼眼图像中的位置。根据需要重新映射到像素或UV。由于源被分成两个眼睛图像,您还需要从目标(征服)经度到正确的源子图像的映射。