相机成像原理:世界坐标系、相机坐标系、图像坐标系、像素坐标系之间的转换

此博客为转载,作者对原文细节添加了说明,原文链接为https://blog.youkuaiyun.com/u011754972/article/details/116305011 ,主要涉及图像处理领域。

本篇博客为转载,我对其中的细节添加了一些说明。
原文链接:https://blog.youkuaiyun.com/u011754972/article/details/116305011

<think> 我们正在处理世界坐标系相机坐标系图像坐标系像素坐标系之间转换。根据引用资料,转换过程主要分为两个步骤: 1. 世界坐标系相机坐标系(通过相机外参) 2. 相机坐标系图像坐标系(通过相机内参,其中图像坐标系通常指物理单位表示的图像平面坐标,然后还需要转换像素坐标系) 具体步骤: - 世界坐标系(World Coordinate System, WCS)是物体在真实世界中的坐标,用三维点表示。 - 相机坐标系(Camera Coordinate System, CCS)是以相机光心为原点的坐标系,Z轴沿光轴方向。 - 图像坐标系(Image Coordinate System)是在成像平面上的二维坐标系,通常以光心在图像平面的投影为原点(一般用物理单位,如毫米)。 - 像素坐标系(Pixel Coordinate System)是图像在计算机中存储的坐标系,原点在图像的左上角,单位为像素转换关系: 1. 世界坐标系 -> 相机坐标系:通过刚体变换(旋转矩阵R和平移向量t)。若有一个点P在世界坐标系中的坐标为$P_w = (X_w, Y_w, Z_w)^T$,在相机坐标系中的坐标为$P_c = (X_c, Y_c, Z_c)^T$,则: $$ P_c = R \cdot P_w + t $$ 或者写成齐次坐标形式: $$ \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix} = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix} $$ 2. 相机坐标系 -> 图像坐标系(物理单位):利用小孔成像模型。设相机焦距为f,则: $$ x = f \frac{X_c}{Z_c}, \quad y = f \frac{Y_c}{Z_c} $$ 这里得到的(x,y)是物理单位(例如毫米)表示的图像平面坐标。 3. 图像坐标系(物理单位)-> 像素坐标系:需要知道每个像素在x和y方向的物理尺寸(dx, dy,单位:毫米/像素)以及图像中心(即主点)在像素坐标系中的坐标(u0, v0)。则: $$ u = \frac{x}{dx} + u_0, \quad v = \frac{y}{dy} + v_0 $$ 通常,我们用一个内参矩阵K来表示这个变换: $$ K = \begin{bmatrix} f_x & 0 & u_0 \\ 0 & f_y & v_0 \\ 0 & 0 & 1 \end{bmatrix} $$ 其中,$f_x = f / dx$, $f_y = f / dy$。 因此,从相机坐标系像素坐标系的齐次坐标变换可以写为: $$ \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \frac{1}{Z_c} K \begin{bmatrix} X_c \\ Y_c \\ Z_c \end{bmatrix} $$ 注意:这里我们取齐次坐标,所以实际计算时,需要将得到的(u,v)除以第三项(即深度Z_c)来得到归一化的像素坐标。 综合起来,从世界坐标到像素坐标的变换为: $$ \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \frac{1}{Z_c} K \begin{bmatrix} R & t \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix} $$ 其中,$\begin{bmatrix} R & t \end{bmatrix}$是外参矩阵(通常为3×4矩阵,或者使用4×4齐次矩阵取前3行),K是内参矩阵(3×3)。 注意:在实际应用中,我们通常将世界坐标点表示为齐次坐标(4维向量,最后一项为1),然后左乘外参矩阵(3×4)得到相机坐标(3维向量,非齐次),再左乘内参矩阵(3×3)得到齐次像素坐标,最后除以深度(即Z_c)得到像素坐标。 代码示例(参考引用[2]): 假设我们有: - 内参矩阵K - 外参矩阵(这里外参矩阵可以用4×4的变换矩阵T表示,或者用旋转矩阵R和平移向量t表示) 以下是一个转换函数的示例: ```python import numpy as np def world_to_pixel(point_world, R, t, K): """将世界坐标系中的点转换像素坐标系 参数: point_world: 世界坐标系中的点,形状(3,)或(4,),如果是3维则自动转换为齐次坐标 R: 旋转矩阵,形状(3,3) t: 平移向量,形状(3,) K: 相机内参矩阵,形状(3,3) 返回: 像素坐标(u, v) """ # 确保point_world是齐次坐标形式(4维) if len(point_world) == 3: point_world = np.append(point_world, 1.0) # 将世界坐标点转换相机坐标系 point_camera = R @ point_world[:3] + t # 这里point_world[:3]是前三项,即非齐次部分 # 或者使用齐次变换矩阵(这里用分步计算) # 注意:上面这种写法等价于:point_camera = R @ point_world[:3] + t.reshape(3,1) 但如果t是行向量则需要转置 # 更通用的做法是构建一个3x4的变换矩阵 T = np.hstack((R, t.reshape(3,1))) point_camera = T @ point_world # 此时point_camera是3维向量 # 从相机坐标系像素坐标系 # 先进行投影(得到归一化坐标) if point_camera[2] == 0: # 避免除以0 return None x = point_camera[0] / point_camera[2] y = point_camera[1] / point_camera[2] # 转换为齐次坐标 point_image = np.array([x, y, 1]) point_pixel = K @ point_image u = point_pixel[0] v = point_pixel[1] return u, v ``` 注意:上面的代码中,我们假设输入的t是列向量,或者能够与R水平拼接(因此t应该是3×1的列向量)。在实际使用中,需要根据输入进行调整。另外,上面的转换没有考虑畸变。 此外,引用[2]中提到外参有时用四元数(qw,qx,qy,qz)和平移向量(tx,ty,tz)表示,我们需要将四元数转换为旋转矩阵。可以使用以下函数转换: ```python import numpy as np from scipy.spatial.transform import Rotation as R def quaternion_to_rotation_matrix(q): """将四元数转换为旋转矩阵 参数: q: 四元数,格式为(qw, qx, qy, qz) 返回: 旋转矩阵R,形状(3,3) """ # 使用scipy的Rotation r = R.from_quat([q[1], q[2], q[3], q[0]]) # 注意:scipy要求输入为(x,y,z,w),所以调整顺序 return r.as_matrix() ``` 这样,如果给定了四元数和平移向量,我们可以先得到旋转矩阵R,然后使用上面的转换函数。 总结: 1. 世界坐标系相机坐标系:通过外参(旋转矩阵R和平移向量t)进行刚体变换。 2. 相机坐标系图像坐标系:利用透视投影(小孔成像模型),除以Z_c得到归一化坐标。 3. 图像坐标系(归一化坐标)到像素坐标系:通过内参矩阵K进行线性变换。 注意:在实际应用中,我们通常将内参矩阵K和外参矩阵[R|t]合并成一个投影矩阵P=K[R|t],然后直接使用P将世界坐标点(齐次坐标)变换到像素坐标(齐次坐标),然后除以第三个分量得到像素坐标。 参考文献: [^1]: 计算机视觉:相机成像原理世界坐标系相机坐标系图像坐标系像素坐标系之间转换 [^2]: 世界坐标系相机坐标系像素坐标系转换 详细说明(附代码) §§相关问题§§ 1. 相机内参矩阵包含哪些参数?如何标定? 2. 相机外参矩阵的作用是什么?如何求解? 3. 在相机坐标系转换像素坐标系的过程中,为什么需要除以Z_c? 4. 如何使用OpenCV实现世界坐标系像素坐标系转换? </think>### 坐标系转换详解 在计算机视觉中,世界坐标系相机坐标系图像坐标系像素坐标系之间转换是核心基础。转换过程涉及相机内参和外参,以下是完整的转换流程: #### **1. 世界坐标系相机坐标系** - **转换公式**: $$ \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix} = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix} $$ 其中: - $(X_w, Y_w, Z_w)$:世界坐标系坐标 - $(X_c, Y_c, Z_c)$:相机坐标系坐标 - $R$:旋转矩阵(3×3) - $t$:平移向量(3×1) - **示例代码**: ```python import numpy as np def world_to_camera(point_world, R, t): point_homogeneous = np.append(point_world, 1) # 齐次坐标 T = np.vstack([np.hstack([R, t.reshape(3,1)]), [0,0,0,1]]) # 外参矩阵 point_camera = T @ point_homogeneous return point_camera[:3] # 返回非齐次坐标 ``` #### **2. 相机坐标系图像坐标系** - **转换公式**(透视投影): $$ \begin{cases} x = f_x \frac{X_c}{Z_c} \\ y = f_y \frac{Y_c}{Z_c} \end{cases} $$ 其中: - $(x, y)$:图像坐标系坐标(物理单位,如毫米) - $f_x, f_y$:焦距参数(内参) #### **3. 图像坐标系像素坐标系** - **转换公式**: $$ \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \begin{bmatrix} \frac{1}{dx} & 0 & u_0 \\ 0 & \frac{1}{dy} & v_0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} $$ 其中: - $(u, v)$:像素坐标(像素单位) - $(u_0, v_0)$:主点坐标(图像中心) - $(dx, dy)$:单个像素的物理尺寸 #### **4. 完整转换世界像素)** - **内参矩阵 $K$**: $$ K = \begin{bmatrix} f_x & 0 & u_0 \\ 0 & f_y & v_0 \\ 0 & 0 & 1 \end{bmatrix} $$ - **转换公式**: $$ Z_c \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = K \begin{bmatrix} R & t \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix} $$ - **Python实现**: ```python def world_to_pixel(point_world, K, R, t): point_cam = world_to_camera(point_world, R, t) x, y, z = point_cam # 相机坐标系→归一化坐标 x_norm = x / z y_norm = y / z # 像素坐标 uv_homogeneous = K @ np.array([x_norm, y_norm, 1]) return uv_homogeneous[:2] # 返回(u,v) ``` #### **关键参数说明** | 参数类型 | 参数示例 | 物理意义 | |----------|----------------|------------------------------| | **内参** | $f_x, f_y$ | 焦距(像素单位) | | | $u_0, v_0$ | 主点(图像中心像素坐标) | | | $k_1, k_2$ | 畸变系数(未展示) | | **外参** | $R$(旋转矩阵)| 世界坐标系相机坐标系的旋转 | | | $t$(平移向量)| 世界坐标系相机坐标系的平移 | > 注:实际应用中需先进行**相机标定**获取内参(如棋盘格标定法),外参可通过PnP算法求解[^1][^2]。 --- ### 应用示例 假设: - 内参 $K = \begin{bmatrix} 800 & 0 & 320 \\ 0 & 800 & 240 \\ 0 & 0 & 1 \end{bmatrix}$ - 外参 $R = I$(单位矩阵),$t = [0, 0, 1]^T$ - 世界点 $P_w = [0.5, 0.5, 0]^T$ 转换过程: 1. $P_c = [0.5, 0.5, 1]^T$(相机坐标) 2. $x = 800 \times 0.5/1 = 400$, $y = 800 \times 0.5/1 = 400$(图像坐标) 3. $u = 400 + 320 = 720$, $v = 400 + 240 = 640$(像素坐标) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值