莱莱 发表于 2025-4-8 21:04:26

详解相机的内参和外参,以及表里参的标定方法

1 四个坐标系

要想深入搞清楚相机的内参和外参含义, 首先得清楚以下4个坐标系的定义:


[*]世界坐标系: 名字看着很唬人, 实在没什么大不了的, 这个就是你自己定义的某一个坐标系。 比如, 你把房间的某一个点定为原点, 而且定义好方向, 这就是世界坐标系。 一样平常是个三维坐标系, 单位是m
[*]相机坐标系: 以相机光心为原点, 一样平常我们把z轴指向相机前方,x向右,y向下,是个三维坐标系, 单位是m
[*]成像平面坐标系: 这个是定义在物理成像平面的坐标系,方向定义与相机坐标系同等(没有z方向), 原点是光心在物理成像平面上的投影,是个二维坐标系, 单位是m。 注意, 我们一样平常都会忽略这个坐标系, 因为它是个中间过渡状态, 很少直接使用它。
[*]像素坐标系: 这个应该是最为常用, 也最为大家认识的坐标系, 计算机视觉任务的输出的坐标表达都是在这个坐标系。 它是个二维坐标系, 原点通常在图像的左上角, x向右,y向下, 单位是像素, 没有具体的尺度。
https://i-blog.csdnimg.cn/direct/358225a5c5844a5ea17918adf723b6d1.png
2 内参和外参

除了世界坐标系, 后面三个坐标系只跟相机本身有关。 相机内参表达的就是这三个坐标之间的转换关系, 而相机外参表达的是相机与世界坐标系之间的转换关系。
成像的过程实质上是几个坐标系的转换。首先空间中的一点由世界坐标系转换到相机坐标系 ,然后再将其投影到物理成像平面 ( 成像平面坐标系 ) ,末了再将成像平面上的数据转换像素坐标系 。
https://i-blog.csdnimg.cn/direct/07a553bed99942b991725dfffda4cc24.png
从世界坐标到像素坐标总共有3步转换, 前面2个合在一起就是相机内参, 末了一个是相机外参。
上面矩阵中的参数很好理解, 也都有明确的物理含义: a 和b 表示从成像平面坐标转到像素坐标时, 分别在x和y轴上的缩放系数,                                              u                            0                                       u_0                  u0​和                                             v                            0                                       v_0                  v0​是原点的平移量。                                    r                              r                  r是扭曲因子, 一样平常为0。                                    f                              f                  f是相机的焦距。 R和T是旋转宁静移矩阵。
把前面2个合一起, 就得到了如下更为常见的内参矩阵:
                                       K                            =                                       [                                                                                                   f                                              x                                                                                                            0                                                                                                             c                                              x                                                                                                                                  0                                                                                                             f                                              y                                                                                                                            c                                              y                                                                                                                                  0                                                                                             0                                                                                             1                                                                                 ]                                          \mathbf{K} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}                     K=               ​fx​00​0fy​0​cx​cy​1​               ​
下面的解说中, 我们直接用这种形式,跳过成像平面坐标系。
注意, 实际上内参包罗2部分: 内参矩阵K和畸变系数D, 上面只讲到了内参矩阵的原理, 没有讲畸变系数。 这里简单列一下畸变系数, 不做详细先容。
D =
此中 k1、k2、k3 是径向畸变系数(radial distortion coefficients) p1、p2 是切向畸变系数(tangential distortion coefficients)。
3 常用的坐标转换

假设有某一个点, 在世界坐标下的坐标为                                             P                            w                                  =                         (                                 X                            w                                  ,                                 Y                            w                                  ,                                 Z                            w                                  )                              P_w = (X_w, Y_w, Z_w)                  Pw​=(Xw​,Yw​,Zw​), 在相机坐标系下的坐标为                                 P                         =                         (                                 X                            c                                  ,                                 Y                            c                                  ,                                 Z                            c                                  )                              P = (X_c, Y_c, Z_c)                  P=(Xc​,Yc​,Zc​), 在像素坐标系下的坐标为                                             P                                       u                               v                                          =                         (                         u                         ,                         v                         )                              P_{uv} = (u, v)                  Puv​=(u,v)。


[*] 世界坐标转到相机坐标:
                                                   P                                  =                                  R                                             P                                     w                                              +                                  t                                          P = RP_w + t                           P=RPw​+t
[*] 相机坐标转到像素坐标:
                                                                P                                                   u                                        v                                                         =                                             1                                                   Z                                        c                                                         K                                  P                                          P_{uv} =\frac 1{Z_c} KP                           Puv​=Zc​1​KP
展开就是:
                                                                [                                                                                                   u                                                                                                                                     v                                                                                                                                     1                                                                                             ]                                              =                                             1                                                   Z                                        c                                                         K                                             [                                                                                                                     X                                                    c                                                                                                                                                                        Y                                                    c                                                                                                                                                                        Z                                                    c                                                                                                                ]                                              =                                             1                                                   Z                                        c                                                                        [                                                                                                                     f                                                    x                                                                                                                            0                                                                                                                           c                                                    x                                                                                                                                                      0                                                                                                                           f                                                    y                                                                                                                                              c                                                    y                                                                                                                                                      0                                                                                                         0                                                                                                         1                                                                                             ]                                                         [                                                                                                                     X                                                    c                                                                                                                                                                        Y                                                    c                                                                                                                                                                        Z                                                    c                                                                                                                ]                                                      \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \frac 1{Z_c} \mathbf{K} \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ \end{bmatrix} = \frac 1{Z_c} \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ \end{bmatrix}                                          ​uv1​               ​=Zc​1​K               ​Xc​Yc​Zc​​               ​=Zc​1​               ​fx​00​0fy​0​cx​cy​1​               ​               ​Xc​Yc​Zc​​               ​
[*] 像素坐标转到像素坐标
这个转换是最为常用的, 因为我们通常得到的都是像素坐标系下的信息, 如目标检测、分割的效果就是像素坐标, 得到像素坐标后 ,可以转为相机坐标, 进一步再转为世界坐标。别的, 在点云目标检测中, 通常要把原始的彩色图像和深度信息转换为点云, 就必要用到这个转换。
                                                   P                                  =                                             Z                                     c                                                         K                                                   −                                        1                                                                        P                                                   u                                        v                                                                   P = Z_cK^{-1}P_{uv}                           P=Zc​K−1Puv​
展开就是:
                                                                X                                     c                                              =                                                             u                                        −                                                       c                                           x                                                                              f                                        x                                                         ∗                                             Z                                     c                                                      X_c = \frac {u-c_x}{f_x}*Z_c                           Xc​=fx​u−cx​​∗Zc​
                                                                Y                                     c                                              =                                                             v                                        −                                                       c                                           y                                                                              f                                        y                                                         ∗                                             Z                                     c                                                      Y_c = \frac {v-c_y}{f_y}*Z_c                           Yc​=fy​v−cy​​∗Zc​
注意上面有个尺度因子                                                               Z                                     c                                                      Z_c                           Zc​, 从相机坐标系的三维坐标投影到像素平面的二维坐标, 实际上丢失了z方向也就是深度信息。 以是如果不知道深度, 从像素坐标就无法恢复出正确的相机坐标。深度通常可以通过深度相机直接丈量得到, 或通过深度估计算法猜测。
4 表里参标定方法

4.1 内参标定方法

内参标定通常使用张正友标定法, 也就是常见的棋盘格标定。
代码可参考https://github.com/leo038/hand_eye_calibrate/blob/main/hand_eye_calibrate.py 中的camera_calibrate函数。
4.2 外参标定方法

外参标定的核心是:已知多个点分别在相机坐标系下的坐标和在世界坐标系下的坐标, 求它们之间的映射关系。
常用求解PnP 的方法,即已知多个点, 在像素坐标系的二维坐标, 和在世界坐标系的三维坐标,而且已知内参, 求解旋转平移矩阵。
cv2 中提供了外参标定方法, cv2.solvePnP 只需提供对应的点对即可。
完备代码实现如下:
import cv2
import numpy as np

# 定义已知的3D空间点和对应的2D图像点
objectPoints = np.array([, , , ], dtype=np.float32)
imagePoints = np.array([, , , ], dtype=np.float32)

# 定义相机的内参矩阵和畸变系数
cameraMatrix = np.array([, , ], dtype=np.float32)
distCoeffs = np.zeros((4, 1), dtype=np.float32)

# 使用solvePnP函数求解相机的位姿
ret, rvec, tvec = cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs, flags=cv2.SOLVEPNP_EPNP)

if ret:
    print("Rotation vector:\n", rvec)
    print("Translation vector:\n", tvec)
else:
    print("Failed to solve PnP.")

res, _ = cv2.Rodrigues(rvec)
print(f"旋转矩阵: {res}")


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 详解相机的内参和外参,以及表里参的标定方法