如何获取相机的内参(Intrinsic Parameters)和畸变系数(Distortion Coefficients)
在使用相机进行视觉测量时,获取相机的**内参(Intrinsic Parameters)**和**畸变系数(Distortion Coefficients)**是核心步骤,通常需要通过**相机标定(Camera Calibration)**完成。以下是详细的获取方法及流程:---
### **1. 标定前的准备工作**
#### **标定工具**
* **标定板**:选择高精度、高对比度的标定板,如:
* **棋盘格标定板**(Chessboard Pattern):黑白交替的方格,适合角点检测(OpenCV常用)。
* **圆点标定板**(Dot Pattern):圆心中心检测更鲁棒,适用于透视变形较大的场景。
* **软件工具**:推荐使用 **OpenCV**(开源)、**MATLAB Camera Calibrator** 或专业标定软件(如Halcon)。
#### **数据采集要求**
* **图像数量**:建议拍摄 **10-20张** 不同角度、位置的标定板图像,覆盖整个视场(边缘区域必须包含)。
* **标定板姿态**:标定板需在三维空间中倾斜、旋转,避免所有图像中平面平行于相机传感器。
* **环境条件**:标定时的光照、焦距、对焦距离需与实际测量环境一致。
---
### **2. 标定流程(以OpenCV为例)**
#### **步骤1:采集标定板图像**
* 用相机拍摄多张标定板图像(如图示例):
!棋盘格标定板
#### **步骤2:检测标定板特征点**
* **棋盘格**:使用 `cv2.findChessboardCorners()` 检测角点。
* **圆点标定板**:使用 `cv2.findCirclesGrid()` 检测圆心。
* **亚像素优化**:通过 `cv2.cornerSubPix()` 提高角点精度(需输入灰度图)。
```
import cv2
# 读取图像并检测角点
image = cv2.imread("calib_image.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (cols, rows), None)
# 亚像素优化(提高精度)
if ret:
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners_refined = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
```
#### **步骤3:构建标定输入数据**
* **对象点(Object Points)**:标定板在真实世界中的3D坐标(通常假设标定板在Z=0平面)。
* **图像点(Image Points)**:标定板在图像中的2D角点坐标。
```
import numpy as np
# 标定板实际尺寸(单位:mm或任意物理单位)
square_size = 25.0# 每个方格的边长
objp = np.zeros((rows*cols, 3), np.float32)
objp[:, :2] = np.mgrid.T.reshape(-1, 2) * square_size
# 存储所有图像的对象点和图像点
objpoints = []# 3D点
imgpoints = []# 2D点
# 对每张标定图像重复此过程
objpoints.append(objp)
imgpoints.append(corners_refined)
```
#### **步骤4:计算内参和畸变系数**
调用 `cv2.calibrateCamera()` 进行标定:
```
# 标定相机
ret, K, D, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None
)
# 输出结果
print("内参矩阵 K:\n", K)
print("畸变系数 D (k1, k2, p1, p2, k3):\n", D)
print("重投影误差 (越低越好):", ret)
```
#### **参数说明**
* **内参矩阵(K)**:
```
[,
,
]
```
* `fx, fy`: 焦距(像素单位)
* `cx, cy`: 光心(图像中心坐标)
* **畸变系数(D)**:``(径向畸变 k1\~k3,切向畸变 p1\~p2)
---
### **3. 验证标定结果**
#### **关键指标**
* **重投影误差(Reprojection Error)**:
* 计算标定板角点的理论投影位置与实际检测位置的均方误差。
* **要求**:一般需 < 0.5像素,误差过大需重新标定。
#### **直观验证**
* 使用 `cv2.undistort()` 矫正图像,观察直线是否恢复平直:
```
undistorted = cv2.undistort(image, K, D)
```
---
### **4. 特殊情况处理**
#### **广角/鱼眼镜头**
* 若畸变严重(如广角镜头),需使用 **鱼眼模型**:
```
# 使用 cv2.fisheye.calibrate()
flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC
ret, K, D, rvecs, tvecs = cv2.fisheye.calibrate(...)
```
#### **无标定板的替代方法**
* **基于已知物体的标定**:利用场景中已知尺寸的物体(如A4纸、标准零件)手动输入对象点。
* **自标定(Self-Calibration)**:通过多视图几何约束估计参数(精度较低,不推荐)。
---
### **5. 保存与加载参数**
将标定结果保存为文件(如JSON、YAML),便于后续使用:
```
import json
calib_data = {
"K": K.tolist(),
"D": D.tolist(),
"reprojection_error": ret
}
with open("camera_calib.json", "w") as f:
json.dump(calib_data, f)
```
---
### **总结**
1. **标定板准备**:覆盖视场,多角度拍摄。
2. **特征点检测**:角点或圆心,亚像素优化。
3. **参数计算**:通过OpenCV或MATLAB工具。
4. **验证与优化**:重投影误差 + 直观图像矫正。
**注意事项**:
* 标定过程中需固定焦距和对焦。
* 动态环境(如温度变化大)需定期重新标定。
* 避免使用模糊、过曝或欠曝的图像。
页:
[1]