我有一个非常简单的数学问题,但似乎无法解决。我需要计算从安装了无人机的摄像机观看时可以看到地面的哪一部分。我相信我已经解决了笔直看的问题,但是相机在万向架上,并且在所有轴上都有完整的运动范围。
问题的输入将是高度(m),相机焦距(mm),相机传感器x长度(mm),相机传感器y长度(mm)和每个平面中的倾斜角度。
这是当我将相机笔直指向下方时的功能(注意:这给了我地面覆盖范围的每一侧的长度。理想情况下,我希望每个点(在这种情况下,是矩形的四个角) 。)
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
轴是相机向上(*平面向前)的方向*
方向用于底视图(相机未旋转)
看这里:transform matrix anatomy如何做
从摄像机投射的光线覆盖整个屏幕
例如,使网格8x8
在从相机焦点到观看方向的方向上均匀地照射屏幕上的空间。如果光线在中间,则其方向将与相机的Z
轴相同。所有其余部分将旋转以覆盖整个FOV
计算与曲面的交集
对于平面,它只是平面和半轴之间的交点。对于椭球,它有点复杂,请参见:
这将为您提供一组相机可见的表面点。如果在相机/飞机空间中需要它,则将其转换为它。 GCS到LCS的转换通过以下方式完成:camera_LCS_point =反(camera_matrix)* surface_GCS_point;
对于平面局部点,您可以创建表示平面的单独变换矩阵...
现在可以从相机/平面LCS点中提取出最小和最大x,y
坐标
这些是相机视图覆盖的区域的边缘,为增加精度,您可以找到光线边缘。因此,如果您的2条相邻光线仅击中表面一次,则在它们之间投射中间光线。可以递归执行几次以提高精度,而不会增加太多复杂性。您还可以根据高度和观察方向在计算区域中添加/划分一些安全区域
看看这个非常相似的质量检查: