机器视觉初步14:相机标定原理及应用

文章介绍了相机标定的重要性,特别是在工业三维测量中的应用,以及几种常见的标定方法,包括使用棋盘格标定板、相机自标定、三维物体标定和九孔标定。这些方法旨在获取相机的内参数和外参数,提高测量精度和图像校正效果。

相机标定是指通过已知的相机参数,解算相机内部参数矩阵和外部参数矩阵。
在这里插入图片描述

1.为什么要标定?

在工业中,更多的用户青睐于它在非接触三维尺寸测量上的应用。
所谓的三维测量是广义的三维测量,它不仅包括三维物体的重构与测量,还包括在三维空间中识别任意二维平面上的尺寸以及位置。
这种技术目前已被应用在高精度的工业模具以及装配测量中,其中任意二维平面上的尺寸检测技术应用得更为广泛。

参考文章:相机标定解析
在这里插入图片描述

相机的参数包含内参1和外参2,这些参数是将空间点坐标从相机坐标系转换到像素坐标系所需的。相机标定的目标是获得这些参数,使得我们可以从像素坐标系中的坐标得到图像中的坐标。

为了获取更高的测量精度,我们需要通过标定来实现坐标平面的转换以及图像的校正。
在这里插入图片描述

2.工业场景中常见的标定方法

在工业场景中,相机标定通常采用以下几种方法:

2.1. 使用棋盘格标定板(Checkerboard Markers)

棋盘格标定板是最常见的相机标定方法,它由黑白相间的正方形组成,棋盘格的对角线交点形成一个共用角点。使用棋盘格标定板,可以通过拍摄多张带有棋盘格的图像,并在图像中标记棋盘格的角点,从而计算相机的内外参数。在这里插入图片描述

例如,可以使用一个三维棋盘格标定板(或者投影到一张二维图像上),在相机拍摄的图像中标记棋盘格的角点。然后,通过最小化相机视场中像素坐标和标定板上角点坐标之间的误差来计算相机的内外参数。

import numpy as np
import cv2

# 棋盘格尺寸
pattern_size = (9, 6)

# 准备棋盘格标定板的世界坐标
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)

# 存储棋盘格角点的世界坐标和图像坐标
objpoints = []  # 世界坐标系中的棋盘格角点
imgpoints = []  # 图像平面中的棋盘格角点

# 读取图像
images = ['image1.jpg', 'image2.jpg', 'image3.jpg']  # 替换为实际图像的文件名列表

for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 查找棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)

    # 如果找到棋盘格角点,则添加到objpoints和imgpoints中
    if ret == True
相机标定计算机视觉机器视觉领域中的一个基础性任务,其主要目标是建立三维世界坐标系与二维图像坐标系之间的几何映射关系。通过标定可以获取相机的内部参数(如焦距、主点坐标、畸变系数等)和外部参数(相机相对于世界坐标系的位置和方向),从而为图像测量、三维重建、目标跟踪等任务提供准确的数学模型支持。 ### 工作原理 相机成像的基本模型是一个透视投影模型,即针孔相机模型。该模型将三维空间中的点通过线性变换投影到二维图像平面上。在理想情况下,这种变换由相机的内参矩阵和外参矩阵共同决定。其中: - **内参矩阵**包括焦距(fx, fy)、主点坐标(cx, cy)以及可能存在的畸变参数(如径向畸变、切向畸变等)。 - **外参矩阵**描述了相机在世界坐标系中的位置和姿态,通常由旋转矩阵R和平移向量T表示[^2]。 由于实际相机镜头存在制造误差或光学特性限制,导致图像出现畸变现象(如桶形畸变、枕形畸变等)。因此,在标定过程中还需估计这些畸变参数,以提高图像校正精度。 ### 实施步骤 相机标定的具体实施流程通常包括以下几个关键步骤: #### 1. 准备标定物 使用已知结构的标定板(如棋盘格图案),并将其固定在一个平面上作为标定对象。棋盘格因其角点易于检测且分布规则而被广泛采用[^3]。 #### 2. 图像采集 从不同角度拍摄多张标定板图像(建议至少10张以上),确保覆盖不同的旋转和平移状态。这样有助于提高标定结果的鲁棒性和准确性[^4]。 #### 3. 特征提取 对每张图像进行预处理后,利用算法自动检测并提取棋盘格角点的像素坐标。OpenCV等视觉库提供了高效的角点检测函数(如`findChessboardCorners`),可快速定位角点位置。为了进一步提升精度,还可以使用亚像素级角点优化方法(如`cornerSubPix`)[^4]。 #### 4. 参数估算 基于提取出的角点坐标数据,结合已知的标定板物理尺寸,构建方程组来求解相机的内参和外参。常见的标定方法有直接线性变换(DLT)、张正友平面标定法等。其中,张正友方法因其操作简便且精度较高,在实践中应用较为广泛。该方法首先忽略畸变影响,初步估算五个内参和六个外参;随后引入最小二乘法计算径向畸变系数,并通过极大似然法进一步优化所有参数,以获得更精确的结果[^3]。 #### 5. 畸变校正 根据标定得到的畸变参数,对原始图像进行去畸变处理。这一步骤可通过调用OpenCV中的`undistort`函数实现,输入原始图像及标定所得的相机矩阵和畸变系数即可输出校正后的图像[^4]。 #### 6. 标定验证 最后,应对标定结果进行验证,检查重投影误差是否在可接受范围内。重投影误差是指将三维世界点重新投影回图像平面时,其理论位置与实际检测到的角点位置之间的差异。若误差较大,则需重新调整拍摄条件或改进特征提取过程,直至满足精度要求[^2]。 ### 示例代码:使用OpenCV进行相机标定 以下是一个简单的Python示例,展示如何使用OpenCV库执行相机标定任务: ```python import cv2 import numpy as np import glob # 棋盘格尺寸 (列数 x 行数) chessboard_size = (9, 6) # 准备对象点,如 (0,0,0), (1,0,0), ..., (8,5,0) objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32) objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) # 存储对象点和图像点的列表 objpoints = [] # 3D点 imgpoints = [] # 2D点 images = glob.glob('calibration_images/*.jpg') for fname in images: img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 寻找棋盘格角点 ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None) if ret: objpoints.append(objp) # 细化角点位置 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) imgpoints.append(corners2) # 绘制并显示找到的角点 cv2.drawChessboardCorners(img, chessboard_size, corners2, ret) cv2.imshow('img', img) cv2.waitKey(500) cv2.destroyAllWindows() # 相机标定 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) # 输出相机矩阵和畸变系数 print("Camera Matrix:\n", mtx) print("\nDistortion Coefficients:\n", dist) # 对图像进行畸变校正 img = cv2.imread('calibration_images/left12.jpg') h, w = img.shape[:2] newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h)) # 使用remap进行校正 mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w, h), 5) dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR) # 显示校正结果 cv2.imshow('calibresult', dst) cv2.waitKey(0) cv2.destroyAllWindows() ``` 上述代码展示了完整的标定流程,包括角点检测、参数估计、畸变校正等功能。用户可根据实际需求修改相关参数,并扩展至更多应用场景中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值