相机参数与图像处理技术解析

01. 相机内参和外参的含义?如果将图像放大两倍,内外参如何变化?

  • 相机有两个最基础的数据:内参(Instrinsics)和外参(Extrinsics),内参主要描述的是相机的CCD/CMOS感光片尺寸/分辨率以及光学镜头的系数,外参主要描述的是相机在世界坐标系下的摆放位置和朝向角度。

  • 参考:https://zhuanlan.zhihu.com/p/646310465

  • 相机的内参和外参是用于描述相机如何捕捉三维世界并将其投影到二维图像平面上的参数。

    1. 内参(Intrinsic Parameters):

      • 内参是相机自身的属性,与场景无关。它包括焦距(focal length)、主点(principal point,图像中心的坐标)、畸变系数(distortion coefficients,描述镜头畸变如径向和切向畸变)等。

      • 焦距和图像传感器的尺寸共同决定了视场角(Field of View, FOV)。

      • 主点通常接近图像中心。

      • 内参矩阵一般形式为:

        [
        K = [ f x 0 c x 0 f y c y 0 0 1 ] K = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} K= fx000fy0cxcy1

        ]

        其中 KaTeX parse error: Can't use function '\(' in math mode at position 1: \̲(̲f_x, f_y) 是焦距在图像平面上的x轴和y轴的比例,( c x , c y c_x, c_y cx,cy) 是主点的坐标。

    2. 外参(Extrinsic Parameters):

      • 外参描述的是相机相对于世界坐标系的位置和方向。它由旋转矩阵(Rotation matrix)和平移向量(Translation vector)组成,这些参数定义了从世界坐标系到相机坐标系的转换。

      • 外参矩阵通常表示为:
        KaTeX parse error: Undefined control sequence: \[ at position 2: \̲[̲ \begin{bmatrix...

        其中 ( R R R) 是一个3x3的旋转矩阵,( t t t) 是一个3x1的平移向量。

    如果将图像放大两倍,内外参的变化如下:

    • 内参变化:

      • 焦距 ( f x , f y f_x, f_y fx,fy) 通常不会改变,因为它是基于相机的物理属性。但是,图像坐标系的比例变化了,因此主点 KaTeX parse error: Can't use function '\(' in math mode at position 1: \̲(̲c_x, c_y) 需要调整以反映新的图像中心。如果原图中 KaTeX parse error: Can't use function '\(' in math mode at position 1: \̲(̲c_x, c_y) 是原点,放大后它们将变为原来的两倍。

      • 新的内参矩阵将是:

        [
        K ′ = [ f x 0 2 c x 0 f y 2 c y 0 0 1 ] K' = \begin{bmatrix} f_x & 0 & 2c_x \\ 0 & f_y & 2c_y \\ 0 & 0 & 1 \end{bmatrix} K′= fx000fy02cx2cy1

        ]

    • 外参变化:

      • 外参(旋转矩阵和平移向量)不会因为图像尺寸的改变而改变,因为它们描述的是相机与世界坐标系之间的物理关系,与图像的尺寸无关。

    LSS(Lift, Splat, Shoot)

    https://github.com/nv-tlabs/lift-splat-shoot

    是一个用于三维环境感知和环境表示的视觉感知系统,主要应用于自动驾驶领域。这个方法是一种用于从二维图像直接构建三维环境表示的深度学习算法。它主要通过以下三个步骤来实现:

    1. Lift(提升):

      • 这一步涉及到将二维像素"提升"到三维空间中。算法使用从图像中提取的深度信息将每个像素点映射到一个三维点上。这种映射通常依赖于相机的内参和外参,通过这些参数,可以将二维图像坐标转换为三维世界坐标。
    2. Splat(喷洒):

      • 在"喷洒"步骤中,所提升的三维点被映射到一个离散的三维空间(通常是体素网格)中。这一步是一种数据结构转换,它把连续的三维点云转换为离散的体素表示,这种表示更适合用于随后的处理步骤如卷积神经网络。
    3. Shoot(射击):

      • 最后一步是"射击",这里利用三维卷积神经网络处理提升和喷洒后的数据,从而提取用于任务的特征。例如,自动驾驶车辆可能需要识别和分类不同的道路用户(如行人、车辆)、道路标记和其他关键的环境特征。

    LSS方法的一个主要优势是它能够直接从图像数据中构建出三维场景的表示,这有助于自动驾驶系统更好地理解和导航其周围的环境。此外,它通过利用卷积神经网络,可以在保持高度准确性的同时实现高效的处理速度。这种方法在自动驾驶技术中具有重要的应用前景,尤其是在需要精确和实时的三维环境感知和决策支持的情况下。

02. 坐标系的变换

  • BEV训练数据集的世界坐标系, 比如nuScenes地图,它的世界坐标系是图片坐标系,原点在图片左下角,单位是米。数据集中会根据时间序列给出车辆的瞬时位置,也就是在这个图片上的XY。

  • BEV里,这个Ego是特指车辆本身,它是用来描述摄像机/激光雷达(Lidar,light detection and ranging)/毫米波雷达(一般代码里就简称为Radar)/IMU在车身上的安装位置(单位默认都是米)和朝向角度,坐标原点一般是车身中间,外参(Extrinsics Matrix)主要就是描述这个坐标系的。

  • 相机坐标系,坐标原点在CCD/CMOS感光片的中央,单位是像素,内参(Intrinsics Matrix)主要就是描述这个坐标系的。

  • 照片坐标系,坐标原点在图片的左上角,单位是像素,横纵坐标轴一般不写成XY,而是uv。

  • 照片中的像素位置转换到世界坐标系时,要经历:Image_to_Camera, Camera_to_Ego, Ego_to_World;Camera_to_Image通常就是Intrinsics参数矩阵,Ego_to_Camera就是Extrinsics参数矩阵。

03. 放射变换与逆投影变换分别是什么

  • 仿射变换: 仿射变换是一种线性变换,保持了直线的平行性和比例关系。它可以用于将一个二维平面上的点映射到另一个二维平面上。仿射变换可以通过一个矩阵乘法和一个平移向量来表示。它包括平移、旋转、缩放和剪切等操作。在计算机视觉领域,仿射变换常用于图像的平移、旋转、缩放和仿射校正等操作。

  • 逆投影变换: 逆投影变换是指通过相机内参和外参,将图像上的点投影到三维空间中的过程。它是相机成像过程的逆过程。逆投影变换可以用于将图像上的点转换为三维空间中的点坐标。逆投影变换的计算需要相机的内参矩阵、外参矩阵和图像上的点坐标。在计算机视觉和计算机图形学中,逆投影变换常用于三维重建、相机姿态估计和虚拟现实等应用。

python 复制代码
import numpy as np
import cv2

# 定义相机内参矩阵 K
K = np.array([[1000, 0, 500], [0, 1000, 300], [0, 0, 1]], dtype=np.float32)

# 定义相机外参的旋转矩阵 R(在此为单位矩阵)
R = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32)

# 定义相机外参的平移向量 T
T = np.array([1, 2, 3], dtype=np.float32)

# 定义图像上的点坐标 uv(二维点)
uv = np.array([[200, 300], [400, 500]], dtype=np.float32)

# 计算 Rc2w * K 的逆矩阵
Rc2w_invK = np.linalg.inv(np.dot(R, K))

# 将 uv 点扩展成齐次坐标,并进行逆投影变换
H = np.dot(Rc2w_invK, np.append(uv, np.ones((uv.shape[0], 1)), axis=1).T)

# 计算世界坐标 Pxyz(假设深度为 T[2])
Pxyz = H * (T[2] / H[2]) - T[:2]

# 定义仿射变换矩阵 M
M = np.array([[1, 0, 100], [0, 1, 50]], dtype=np.float32)

# 加载图像(假设 image 是事先加载的图像)
# image = cv2.imread('path_to_your_image.jpg')  # 替换为实际图像路径

# 进行仿射变换
# output = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))  # 假设 image 是加载的图像

# 将每一步结果打印出来以进行验证(可选)
print("相机内参矩阵 K:\n", K)
print("旋转矩阵 R:\n", R)
print("平移向量 T:\n", T)
print("图像点坐标 uv:\n", uv)
print("逆 Rc2w * K:\n", Rc2w_invK)
print("齐次坐标 H:\n", H)
print("世界坐标 Pxyz:\n", Pxyz)
print("仿射变换矩阵 M:\n", M)
相关推荐
神秘的土鸡1 分钟前
神经网络图像隐写术:用AI隐藏信息的艺术
人工智能·深度学习·神经网络
数据分析能量站2 分钟前
神经网络-LeNet
人工智能·深度学习·神经网络·机器学习
Jaly_W11 分钟前
用于航空发动机故障诊断的深度分层排序网络
人工智能·深度学习·故障诊断·航空发动机
小嗷犬13 分钟前
【论文笔记】Cross-lingual few-shot sign language recognition
论文阅读·人工智能·多模态·少样本·手语翻译
夜幕龙20 分钟前
iDP3复现代码数据预处理全流程(二)——vis_dataset.py
人工智能·python·机器人
吃个糖糖37 分钟前
36 Opencv SURF 关键点检测
人工智能·opencv·计算机视觉
AI慧聚堂1 小时前
自动化 + 人工智能:投标行业的未来是什么样的?
运维·人工智能·自动化
盛世隐者1 小时前
【pytorch】循环神经网络
人工智能·pytorch
cdut_suye1 小时前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
开发者每周简报1 小时前
微软的AI转型故事
人工智能·microsoft