相机坐标系到图像坐标系是计算机视觉中的重要概念。相机坐标系指的是描述相机位置和姿态的坐标系,而图像坐标系指的是相机拍摄到的图像上的坐标系。在许多计算机视觉应用中,需要将3D点投影到2D图像上,因此需要了解相机坐标系到图像坐标系的转换。
一、坐标系的介绍
在计算机视觉中,我们通常使用右手坐标系。右手坐标系的三个坐标轴用手指表示,x轴用大拇指,y轴用食指,z轴用中指。当大拇指、食指和中指方向分别为x、y、z轴正方向时,拇指和食指的方向的螺旋转向就是z轴正方向。
相机坐标系是一个右手坐标系。与相机平行且过原点的为z轴,垂直于相机平面的为y轴,与z轴和y轴方向成直角的为x轴。
图像坐标系是一个左手坐标系,其中x轴从左到右,y轴从上至下,原点在左上角。
二、相机内参和外参
相机内参是相机固有的属性,包括相机的焦距、主点等参数。用矩阵K描述相机内参:
K = [ f_x 0 c_x ] [ 0 f_y c_y ] [ 0 0 1 ]
其中f_x、f_y是相机的焦距,c_x、c_y是相机的主点。
相机外参指的是相机在3D空间中的位置和朝向。用矩阵R、t描述相机外参:
[R t] = [ r_1 r_2 r_3 t ] [ 0 0 0 1 ]
其中r_1、r_2、r_3分别是相机的朝向向量,t是相机的位置向量。
三、相机坐标系到图像坐标系的转换
将3D点P通过K、R、t矩阵投影到2D图像上的过程可以表示为:
p = K * [R t] * P
其中,p表示图像上的点,P表示3D空间中的点,*表示矩阵乘法。
将p的齐次坐标归一化后可得到图像坐标系下的坐标:
[x, y, w] = p u = x / w v = y / w
其中,u、v分别是图像坐标系下的坐标,w是一个常量,通常为1。
四、代码示例
1. 相机内参、外参定义
import numpy as np # 相机内参 fx = 500 # 焦距 fy = 500 cx = 320 # 主点 cy = 240 K = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]]) # 相机外参 R = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) # 旋转矩阵 t = np.array([0, 0, 0]) # 平移向量
2. 将3D点P投影到2D图像中
# 3D点P P = np.array([1, 2, 3]) # 投影到2D图像 P_homogeneous = np.hstack((P, 1)) p_homogeneous = K @ np.hstack((R, t.reshape(3,1))) @ P_homogeneous.reshape(4,1) p = p_homogeneous[:2] / p_homogeneous[2] print("P: ", P) print("p: ", p)
3. 将多个3D点P投影到2D图像中
# 多个3D点P P_list = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 投影到2D图像 P_homogeneous = np.hstack((P_list, np.ones((P_list.shape[0], 1)))) p_homogeneous = K @ np.hstack((R, t.reshape(3,1))) @ P_homogeneous.T p = p_homogeneous[:2] / p_homogeneous[2] print("P_list: ", P_list) print("p: ", p.T)