给定相机参数,我如何找到从视图空间到像素坐标的转换?我的矩阵有啥问题?

Posted

技术标签:

【中文标题】给定相机参数,我如何找到从视图空间到像素坐标的转换?我的矩阵有啥问题?【英文标题】:Given camera parameters, how do I find the transform from view space to pixel coordinates? What is wrong with my matrix?给定相机参数,我如何找到从视图空间到像素坐标的转换?我的矩阵有什么问题? 【发布时间】:2021-11-10 22:42:48 【问题描述】:

对于包含已知 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. 

即使我很接近,你也可以看到结果不正确:

哪里出错了?

【问题讨论】:

【参考方案1】:

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

# 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 轴向下。

【讨论】:

以上是关于给定相机参数,我如何找到从视图空间到像素坐标的转换?我的矩阵有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

2021-08-16SLAM十四讲第5讲——从相机坐标到像素坐标

OpenGL获取像素的原始3d坐标

从剪辑空间到屏幕坐标的转换何时发生?

61 相机投影原理

Unity Shaderlab-从屏幕空间到世界空间的转换

第七节双目视觉之空间坐标计算