如何利用像素坐标计算相机成像平面的射线向量?
准确计算穿过像素的世界坐标系射线向量方法
你可以利用相机校准得到的内参矩阵、畸变系数,以及solvePnP输出的旋转矩阵,直接计算高精度的射线向量,步骤如下:
关键原理
像素点无法直接映射到世界坐标系的某一个点,但可以得到从相机光心出发、穿过该像素的射线。核心是先把像素坐标转换为相机坐标系下的方向向量,再变换到世界坐标系,结合相机的世界位置就能完整描述这条射线。
具体步骤
对像素坐标去畸变
原始像素坐标存在镜头畸变,先用cv2.undistortPoints将其转换为相机坐标系下的归一化成像平面坐标(即z=1平面上的坐标):# 假设要计算的像素坐标为 (u, v),输入格式为Nx1x2的数组 pixel = np.array([[[u, v]]], dtype=np.float32) # 去畸变得到归一化坐标 (x, y),对应相机坐标系中z=1的点 undistorted = cv2.undistortPoints(pixel, new_mtx, dist, None, new_mtx) x, y = undistorted[0][0]构建相机坐标系下的射线方向向量
相机光心在相机坐标系的原点,所以穿过该像素的射线在相机坐标系下的方向向量就是(x, y, 1),可归一化为单位向量:cam_dir = np.array([x, y, 1.0]) cam_dir /= np.linalg.norm(cam_dir) # 归一化为单位向量转换为世界坐标系下的方向向量
solvePnP得到的旋转矩阵rmat是世界坐标系到相机坐标系的旋转矩阵,因此相机坐标系下的向量转换到世界坐标系需要用其转置矩阵(旋转矩阵的逆等于转置):world_dir = rmat.T @ cam_dir完整描述射线
射线由相机在世界坐标系的位置camera_position(你已计算得到)和世界方向向量world_dir共同定义:- 射线参数方程:
P_world = camera_position + t * world_dir,其中t > 0(射线从相机出发指向场景)
- 射线参数方程:
为什么这个方法精度更高
相比用FOV和图像尺寸计算角度的方法,这个方案:
- 考虑了镜头畸变的修正,避免畸变导致的方向偏移
- 用到了校准得到的实际主点位置(不一定在图像中心),而FOV方法通常假设主点在中心
- 直接基于校准的内参矩阵计算,完全贴合你的相机实际成像模型
内容的提问来源于stack exchange,提问作者Bvdb89
相关产品推荐
相关产品推荐

