我有一道非常简单的数学题,但我似乎想不通。我需要计算当从安装在无人机上的摄像机上观看时,地面的哪一部分是可见的。我相信我已经解决了直接向下看的问题,但相机在万向节上,在所有轴上都有全方位的运动。
问题的输入将是海拔高度(m)、相机焦距(mm)、相机传感器x长度(mm)和相机传感器y长度(毫米),以及每个平面中的倾斜角度。
以下是当相机指向正下方时的效果(注意:这会给我地面覆盖每一侧的长度。理想情况下,我希望每个点,在这种情况下,都是矩形的四个角。)
float cameraX; // camera sensor x size (mm)
float cameraY; // camera sensor y size (mm)
float cameraF; // camera focal length (mm); common lengths: 150mm (wide angle), 300mm (normal)
float altitude; // high above ground (m)
float ax;
float ay;
void calculateGroundCoverage() {
ax = (altitude / cameraF) * cameraX;
ay = (altitude / cameraF) * cameraY;
}
void printGroundCoverage() {
System.out.print("x: " + cameraX + ", y: " + cameraY + ", f: " + cameraF + ", alt: " + altitude + "t");
System.out.println("footprint: " + ax + "m x " + ay + "m");
}
这是为了什么高度
对于小的(长达0.5公里),您可以通过平面简化地面,但前提是相机视图接近于垂直于表面的方向(视图中没有水平面!!)+/-一些安全边界,以考虑表面扭曲。对于更高的海拔,你需要考虑表面是椭球体。
我的做法与您的做法有点不同(因为我使用的是绘制在地球椭球上的DTM)
-
创建表示相机传感器的变换矩阵
芯片平面中点为原点Z
轴是观看方向(至少对我来说)X
轴为相机右(*平面右)方向Y
轴为相机向上(*平面向前)方向*
方向用于仰视(相机未旋转)看这里:变换矩阵解剖如何做到
-
摄像机投射的光线覆盖整个屏幕
例如,使栅格CCD_ 5射线在屏幕上以从相机焦点到观看方向的方向均匀分布。如果光线位于中间,则其方向与摄影机的
Z
轴相同。所有其余部分将被旋转以覆盖整个FOV -
计算与曲面的交点
对于平面来说,它只是平面和半轴的交点。对于椭球体,它有点复杂,请参见:
- 射线与椭球相交
这将为您提供一组可由相机看到的曲面点。如果您在相机/平面空间中需要它,请将其转换为它。将GCS转换为LCS的步骤如下:camera_LCS_point=反转(camera_matrix)*surface_GCS_point;
对于平面局部点,可以创建表示平面的单独变换矩阵。。。
-
现在形成相机/平面LCS点,您可以简单地提取最小和最大
x,y
坐标这些是相机视图覆盖的区域的边缘,以提高精度,您可以找到光线的边缘。所以,若你们的两条相邻光线只碰到表面一次,那个么就在它们之间投射中间光线。这可以递归地进行几次,以提高精度,而不会带来太多复杂性负担。此外,您还可以根据高度和观看方向在计算区域中添加/减少一些安全区域
看看这个非常相似的QA:
- 如何在顶部2D小地图上显示用3D透视渲染的平面世界的可见部分