给定相机参数,如何找到从视图 space 到像素坐标的变换?我的矩阵有什么问题?

Given camera parameters, how do I find the transform from view space to pixel coordinates? What is wrong with my matrix?

对于包含已知 3d obj 模型的特定图像,我有相应的模型矩阵和相机参数 fx、fy、cx、cy。将模型矩阵应用于 3d 模型顶点后,我想找到将顶点精确投影到图像中相应对象的投影矩阵。我使用这个投影矩阵:

2 * fx / w,       0,           1-2*cx/w,         0,
 0,           -2 * fy / h,     -(1-2*cy/h),         0,
 0,                 0,         (f + n) / (n - f), (2 * f * n) / (n - f),
 0,                 0,               -1,             0 

w是图像的宽度,h是高度,f是远裁剪平面,n是近裁剪平面。根据我的发现,我们在使用真实相机时忽略了裁剪平面,因此我们可以将投影矩阵写为:

2 * fx / w,       0,           1-2*cx/w,         0,
 0,           -2 * fy / h,     -(1-2*cy/h),         0,
 0,                 0,          -1,              0,
 0,                 0,          -1,              0 

在 3D 点上应用投影矩阵后,我想将 x 和 y 转换为像素坐标。为此,我执行以下操作。应用模型和投影变换后,设 p 为 3d 模型在齐次坐标系中的一个点:

float x=p.x/p.w; 
float y=p.y/p.w;
// x and y are now in the range [-1,1]
x=(x+1)*(w/2);
y=(y+1)*(h/2);
// x and y are now in pixel coordinates. 

尽管我很接近,但你可以看到结果不正确:

哪里错了

您使用的是一种相当奇怪的投影方法。标准的是:

# python, numpy
K = np.array([[fx 0 cx], [0, fy, cy], [0, 0, 1]])
# xyz is a 3d point in camera coordinates
xyz = getMyXYZ()
# project into homogeneous image coordinates
uvw = K.dot(xyz)
# pixel coordinates
uv = uvw[:2] / uvw[2]

以上假设:

  • 没有镜头畸变。
  • 相机坐标系的 Z 从 (cx, cy) 图像像素朝向场景,X 向右(平行于图像行),Y 向下,原点远离 fx 像素图片后面。
  • 图片坐标系原点在左上角像素中心,x轴向右增加,y轴向下。