计算机视觉 相机标定

本文详细介绍了相机标定的基本原理,包括相机坐标系、畸变参数和标定方法,如线性标定、非线性标定以及张正友标定法。张正友标定法主要处理径向畸变,通过棋盘格图像进行相机内外参及畸变参数的估计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.相机标定基本原理
1.1 简介


        在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立摄像机成像的几何模型,这些几何模型参数就是摄像机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定。简单来说是从世界坐标系换到图像坐标系的过程,也就是求最终的投影矩阵P PP的过程。
无论是在图像测量或者机器视觉应用中,摄像机参数的标定都是非常关键的环节,其标定结果的精度及算法的稳定性直接影响摄像机工作产生结果的准确性。因此,做好摄像机标定是做好后续工作的前提,是提高标定精度是科研工作的重点所在。其标定的目的就是为了相机内参、外参、畸变参数。

1.2 基本的坐标系


世界坐标系:用户定义的三维世界的坐标系,为了描述目标物在真实世界里的位置而被引入。

相机坐标系:在相机上建立的坐标系,为了从相机的角度描述物体位置而定义,作为沟通世界坐标系和图像/像素坐标系的中间一环。

图像坐标系:为了描述成像过程中物体从相机坐标系到图像坐标系的投影透射关系而引入,方便进一步得到像素坐标系下的坐标。

一般来说,标定的过程分为两个部分:
第一步是从世界坐标系转换为相机坐标系,这一步是三维点到三维点的转换,包括 R RR,t tt(相机外参)等参数;

 

 

第二步是从相机坐标系转为图像坐标系,这一步是三维点到二维点的转换,包括 K KK(相机内参)等参数;


同步标定内部参数和外部参数,一般包括两种策略s:
光学标定: 利用已知的几何信息(如定长棋盘格)实现参数求解。
自标定: 在静态场景中利用 structure from motion估算参数

 


1. 3 畸变参数


理想的小孔成像模型,物和像满足相似三角形的关系。实际上由于相机光学系统制造工艺的误差,实际成像与理想成像存在几何失真,称为畸变。畸变主要分为径向畸变和切向畸变。
(1)径向畸变(枕形、桶形):
①透镜质量原因
②光线在远离透镜中心的地方比靠近中心的地方更加弯曲。

 

 

径向畸变可以用如下公式修正:


(2)切向畸变(薄透镜畸变和离心畸变):
切向畸变是由于透镜制造上的缺陷使得透镜本身与图像平面不平行而产生的。
切向畸变可以用如下公式修正:

 

 


其中:

 x_{dis} , y_{dis} 表示有畸变的坐标;
x_{corr} ,y _{corr}表示修复后的坐标;
k_1,k_2, k_3表示径向畸变参数;

<think>好的,我现在需要帮助用户找到关于如何使用Python进行计算机视觉相机标定的教程或示例代码。首先,用户明确提到了Python、计算机视觉相机标定以及教程或示例代码,所以我的回答需要围绕这些关键词展开。 根据用户提供的引用内容,引用[1]解释了相机标定的目的,引用[2]提到了Python OpenCV的单目相机标定和坐标转换代码,包括鱼眼相机,而引用[3]则涉及手眼标定的ROS2相关内容。我需要综合这些信息来构建回答。 首先,我应该介绍相机标定的基本概念和步骤,这样用户能有一个整体的理解。然后,分步骤说明具体操作,比如准备标定板、采集图像、检测角点、计算参数等,每个步骤都需要结合Python代码示例,尤其是使用OpenCV库,因为引用[2]中提到了OpenCV的相关函数。 接下来,我需要确保代码示例的正确性,比如使用cv2.findChessboardCorners来检测棋盘格角点,以及使用cv2.calibrateCamera进行标定。这部分需要检查语法是否正确,参数是否合理,例如图像尺寸、角点数量等。 然后,用户可能需要知道如何处理畸变矫正,这时候可以引用[2]中的cv2.undistort函数,说明如何应用标定得到的参数来矫正图像。同时,提到手眼标定的话,引用[3]中的calibrateHandeye函数也是一个相关点,不过用户主要关注的是相机标定本身,可能手眼标定可以作为扩展内容。 此外,用户可能需要了解如何验证标定结果,比如通过重投影误差来评估标定精度,这部分在引用[1]中提到的精度和鲁棒性相关。因此,在回答中加入误差计算的步骤会更有帮助。 最后,生成相关问题需要考虑用户可能进一步的需求,比如标定板的选择、不同相机标定方法、标定失败的处理,以及如何将标定参数应用到实际项目中,比如三维重建或目标跟踪,如引用[1]提到的应用场景。 需要确保回答结构清晰,分步骤说明,每个部分都有对应的代码示例和解释,并且正确引用提供的参考资料。同时,语言要使用中文,符合用户的要求。</think>### 如何使用Python进行相机标定? #### 1. 相机标定基础概念 相机标定的核心是通过分析已知空间坐标的标定板(如棋盘格)图像,求解相机的$内参矩阵$(焦距、主点坐标)和$畸变系数$,建立像素坐标与物理坐标的映射关系[^1]。标定流程分为以下步骤: - **标定板准备**:使用标准棋盘格或圆形网格图案 - **图像采集**:从不同角度拍摄多张标定板图像 - **角点检测**:提取标定板特征点的像素坐标 - **参数计算**:通过优化算法求解相机参数 #### 2. Python实现步骤(以OpenCV为例) **步骤1:安装依赖库** ```bash pip install opencv-python numpy ``` **步骤2:采集标定图像** ```python import cv2 cap = cv2.VideoCapture(0) count = 0 while True: ret, frame = cap.read() cv2.imshow('Capture', frame) key = cv2.waitKey(1) if key == ord('s'): # 按's'保存图像 cv2.imwrite(f'calib_{count}.jpg', frame) count +=1 elif key == 27: break cap.release() ``` **步骤3:检测棋盘格角点** ```python # 定义棋盘格规格(内角点数量) pattern_size = (9, 6) obj_points = [] # 三维物理坐标 img_points = [] # 二维像素坐标 # 生成标定板三维坐标(假设棋盘格单元边长为2.5cm) objp = np.zeros((pattern_size[0]*pattern_size[1],3), np.float32) objp[:,:2] = np.mgrid[0:pattern_size[0],0:pattern_size[1]].T.reshape(-1,2) * 0.025 for fname in glob.glob('calib_*.jpg'): img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 查找角点 ret, corners = cv2.findChessboardCorners(gray, pattern_size, None) if ret: obj_points.append(objp) img_points.append(corners) ``` **步骤4:计算相机参数** ```python ret, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera( obj_points, img_points, gray.shape[::-1], None, None) print(f"内参矩阵:\n{cameraMatrix}") print(f"畸变系数:\n{distCoeffs}") ``` **步骤5:畸变矫正验证** ```python # 使用标定结果矫正图像 img = cv2.imread('test.jpg') h, w = img.shape[:2] newCameraMatrix, roi = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, (w,h), 1) dst = cv2.undistort(img, cameraMatrix, distCoeffs, None, newCameraMatrix) cv2.imshow('Undistorted', dst) ``` #### 3. 关键参数说明 | 参数名称 | 数学表示 | 物理意义 | |----------------|-------------------|-------------------------| | 内参矩阵 | $\begin{bmatrix}f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1\end{bmatrix}$ | 焦距($f_x,f_y$)和主点($c_x,c_y$) | | 径向畸变系数 | $(k_1,k_2,k_3)$ | 矫正径向形变 | | 切向畸变系数 | $(p_1,p_2)$ | 矫正切向形变 | #### 4. 扩展应用示例(手眼标定) ```python # 使用calibrateHandeye实现手眼标定(需配合机器人位姿数据) R_cam2gripper, t_cam2gripper = cv2.calibrateHandEye( robot_poses_world, # 机械臂基坐标系下的位姿 marker_poses_camera, # 相机坐标系下的标定板位姿 method=cv2.CALIB_HAND_EYE_TSAI ) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值