1

假设我有一个 3D 对象。我没有关于对象形式的详细信息,我拥有的唯一信息是 3 轴坐标的范围(最小/最大 x 坐标等)。

给定一个相机“方向”(基本上相机从哪个角度看物体),我如何计算相机必须有多远才能在一定尺寸的屏幕上查看整个物体。

所以基本上我有以下输入:

  • 对象边界
  • 相机“方向”
  • 屏幕尺寸

并想计算相机距离。

我该如何解决这个问题?

当知道相机在 3D 坐标中的位置时,我发现了很多关于如何将 3D 点投影到 2D 平面上的信息,但是我未能以匹配我的输入/输出的方式调整公式。

示例输入为:

  • x: (0-100), y: (0-100), z: (0-100)
  • 相机观察物体时好像它绕 Z 轴旋转 45° 和绕 X 轴旋转 45°
  • 屏幕尺寸为 600x600

提前致谢!

4

1 回答 1

1

我将在下面的答案中假设一个正交投影,但是扩展到透视投影应该很容易。对于较小的物体,正交投影看起来不错(因为我们习惯于看不到它们的透视效果)。

对于每个点,ix[i], y[i],z[i]为对象空间中的原始坐标。

x'[i],成为旋转到相机空间y'[i]z'[i]点(这可以通过将旋转变换应用于每个点来计算 - 我认为这部分对你来说很容易)。

正交投影将是:

X[i] = f*x'[i] + Cx
Y[i] = f*y'[i] + Cy

哪里f是一些数字,我们将计算它来处理缩放,并且CxCy图像的中心。这可以变得更复杂,以允许例如透视投影、非统一纵横比。例如,请参阅我对另一个问题的回答:(( 3D 点投影以形成图像)) 来处理透视投影。

由于我们将求解f,因此我们重新排列:

f = (X[i] - Cx)/x'[i]
f = (Y[i] - Cy)/y'[i]

MaxX是像素坐标中最大的理想X点,像素坐标中的最大点和MaxY最小Y的点(我们取像素的中心)。MinXMinY

例如

MinX=0.5
MaxX=599.5
MinY=0.5
MaxY=599.5

我们希望选择一个f足够小,以便最极端x'[i]y'[i]点映射到这些像素之一。

注意:我假设对象已经居中:如果不是,那么我们还需要计算一个好的CxCy太(并且可以像这样实现更紧密的图像拟合)。

计算每个XY方向上的最大和最小旋转点(min_i(x[i])表示 的x[i]所有可能值中的最小值i):

minx = min_i(x[i])
maxx = max_i(x[i])
miny = min_i(y[i])
maxy = max_i(y[i])

现在求解每个极值像素映射到每个极值点所需的焦距:

f_1 = (MinX - Cx)/minx
f_2 = (MaxX - Cx)/maxx
f_3 = (MinY - Cy)/miny
f_4 = (MaxY - Cy)/maxy

我们选择其中最小的一个,以确保整个对象都适合屏幕。

例子

如果我们假设最左边的点(旋转后)在

minx = -1.2

最右边的点:

maxx = 1.5

最高点(请注意,我假设像素坐标与空间坐标对齐):

miny = -1.3

最不利的点(请注意,我假设像素坐标与空间坐标对齐):

maxy = 1.3

我们使用您的600x600图像示例。

对于其中的每一个,我们解决f

f_1 = (0.5 - 300)/-1.2 = 249.6
f_2 = (599.5 - 300)/1.5 = 199.7
f_3 = (0.5 - 300)/-1.3 = 230.4
f_4 = (599.5 - 300)/1.3 = 230.4

现在我们选择最小的f,所以我们得到:

f=199.7

正交投影将是:

X[i] = 199.7*x'[i] + 300
Y[i] = 199.7*y'[i] + 300

提醒:您可以通过添加透视投影、允许不同的图像中心、缩放等以多种方式使其更加复杂。这种方法旨在成为最简单的入门方法。

于 2013-01-29T09:25:32.330 回答