我将在下面的答案中假设一个正交投影,但是扩展到透视投影应该很容易。对于较小的物体,正交投影看起来不错(因为我们习惯于看不到它们的透视效果)。
对于每个点 i,让 x[i],y[i],z[i] 成为对象空间中的原始坐标。
让x'[i],y'[i],z'[i] 成为旋转到相机空间的点(这可以通过将旋转变换应用于每个点来计算 - 我认为这部分对你来说很容易)。
正交投影将是:
X[i] = f*x'[i] + Cx
Y[i] = f*y'[i] + Cy
f 是一个数字,我们将计算它来处理缩放,Cx 和 Cy 是图像的中心。
这可以变得更复杂,以允许例如透视投影,非统一纵横比。参见例如我对另一个问题的回答:((3D points projected to form an image)) 处理透视投影。
由于我们将求解f,因此我们重新排列:
f = (X[i] - Cx)/x'[i]
f = (Y[i] - Cy)/y'[i]
让MaxX 成为最大可取点X 像素坐标,MaxY 最大像素坐标Y,MinX 和MinY 最小(我们取像素的中心) .
例如
MinX=0.5
MaxX=599.5
MinY=0.5
MaxY=599.5
我们希望选择一个足够小的f,以便最极端的x'[i] 或y'[i] 点映射到这些像素之一。
注意:我假设对象已经居中:如果不是,那么我们还需要计算一个好的 Cx 和 Cy(并且可以实现更紧密地拟合图像像那样)。
计算每个X 和Y 方向上的最大和最小旋转点(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
提醒:您可以通过添加透视投影、允许不同的图像中心、缩放等多种方式使此功能更加复杂。这种方法旨在成为最简单的入门方法。