如何从从上方观看的图像中计算以世界单位表示的距离

How to calculate distance in world units from an image viewed from above

提问人:Gaël Koch 提问时间:10/25/2023 最后编辑:WoodfordGaël Koch 更新时间:10/25/2023 访问量:42

问:

我目前正在Unity中处理一个项目,我正在从上面截取3D环境的屏幕截图以创建地图。通过这些地图图像和网站,用户可以绘制矩形来“选择世界内部的区域”(见下图)

区域选择地图示例:

Example of map with area selection

所有这些都为我提供了以下信息:

  • 地图图像的尺寸(例如 500 像素 x 500 像素)
  • 在地图上绘制的区域尺寸(顶部、左侧、宽度、高度)(例如 157 像素、342 像素、98 像素、25 像素)
  • 在世界中拍摄地图图像的高度(例如 5 个单位)

地图图像是使用设置为 (0,height,0) 的正交照相机拍摄的。相机的高度也用作正交尺寸。

我现在需要使用 Unity 单位将这些区域选择(以图像中的像素为单位)转换为 3D 世界中的区域。

我目前有这段代码:

dist_top = top-(img_height/2.0)
dist_left = left-(img_width/2.0)
dist_top = (top/2.0)/(distance_from_map) 
dist_left = (left/2.0)/(distance_from_map) 
dist_width = (width/2.0)/(distance_from_map) 
dist_height = (height/2.0)/(distance_from_map) 

这是我能做的最接近的,但尺寸有点偏离并且位置错误(如下图所示)。我希望矩形的放置方式与第一张图像中一样,但现在在 3D 世界中

错误转换示例:

Example of the wrong conversion

有关信息,这里是将这些正方形放置在 3D 世界中的代码(但我认为问题不在那里)

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = new Vector3((float)config.distances[i].left, 0.1f, (float)config.distances[i].top);
cube.transform.localScale = new Vector3((float)config.distances[i].width, 0.1f, (float)config.distances[i].height);
Python C# unity-游戏引擎 数学

评论

0赞 Absinthe 10/25/2023
不完全是你所追求的,但它可能会有所帮助:docs.unity3d.com/Manual/FrustumSizeAtDistance.html

答:

2赞 Gaël Koch 10/25/2023 #1

我想通了!

我正在拍摄相机的高度,该高度将与我正在拍摄的地图图像的宽度和高度(以 Unity 单位表示)相对应。

float camera_height = 2f * cam.orthographicSize;

然后,我可以使用图像的大小和我刚才描述的相机高度来计算像素和世界单位之间的纵横比。

aspect_ratio = camera_height/img_height

然后,我可以将图像上的任何“像素尺寸”转换为真实世界的单位

dist_top = dist_top*aspect_ratio
dist_left = dist_left*aspect_ratio

dist_width = float(width)*aspect_ratio
dist_height = float(height)*aspect_ratio

希望这会有所帮助