1. 为什么需要相机标定第一次接触相机标定的朋友可能会疑惑为什么手机拍照直接就能用而工业相机、机器人视觉却需要复杂的标定流程这就像用尺子测量物体前需要先确认尺子本身的刻度是否准确。相机标定的本质就是给数字世界里的尺子做质检。我去年帮一个做机械臂分拣的团队调试视觉系统时就遇到过标定不准导致的惨案。机械臂总是抓偏2-3厘米排查半天才发现是相机畸变参数没校准。这让我深刻体会到在需要精确测量的场景中标定质量直接决定整个视觉系统的可靠性。2. 相机标定全流程实战2.1 准备标定棋盘格棋盘格就像视觉领域的标准砝码OpenCV推荐使用不对称数量的角点图案比如8x6。我习惯用A3纸打印并贴在平整的亚克力板上这样既保证刚度又方便携带。有个小技巧用手机闪光灯从背面打光可以显著提升图案对比度。# 生成虚拟棋盘格图像 pattern_size (9, 6) # 注意是角点数量而非方格数 square_size 0.025 # 单位米 img np.zeros((800, 1200), dtypenp.uint8) for i in range(pattern_size[1]): for j in range(pattern_size[0]): if (i j) % 2 0: start_x j * 100 150 start_y i * 100 100 img[start_y:start_y100, start_x:start_x100] 255 cv2.imwrite(chessboard.png, img)2.2 采集标定图像在实际项目中我通常会采集20-30张不同角度的图像。特别注意棋盘格要占画面1/3以上面积包含不同倾斜角度俯仰/偏转/旋转确保棋盘格出现在画面各个区域避免强光反射导致的过曝最近用工业相机时发现自动曝光可能造成不同图像亮度差异过大建议改为手动模式固定曝光参数。2.3 角点检测与优化OpenCV的findChessboardCorners()虽然智能但在低对比度场景容易失败。这时可以先做直方图均衡化调整角点搜索窗口大小使用自适应阈值替代全局阈值gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray cv2.equalizeHist(gray) # 增强对比度 ret, corners cv2.findChessboardCorners( gray, pattern_size, flagscv2.CALIB_CB_ADAPTIVE_THRESH cv2.CALIB_CB_NORMALIZE_IMAGE )亚像素优化时我习惯将搜索窗口设为11x11这对高分辨率图像更有效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. 参数解析与验证3.1 内参矩阵的物理意义标定得到的相机矩阵K通常长这样[[fx 0 cx] [ 0 fy cy] [ 0 0 1]]去年调试双目相机时我发现fx和fy差值超过5%就会导致深度计算误差。后来发现是镜头安装倾斜导致的调整机械结构后问题解决。这说明内参不仅能用于计算还能反映硬件状态。3.2 畸变参数实战指南常见的畸变系数包含5个参数(k1,k2,p1,p2,k3)。在无人机视觉项目中广角镜头的k1可能达到-0.3以上。这时如果直接用undistort()函数边缘区域会出现黑洞。我的解决方案是使用initUndistortRectifyMap()预计算映射采用ROI参数保留有效区域对边缘区域做智能填充new_camera_matrix, roi cv2.getOptimalNewCameraMatrix( camera_matrix, dist_coeffs, (w,h), 1, (w,h) ) mapx, mapy cv2.initUndistortRectifyMap( camera_matrix, dist_coeffs, None, new_camera_matrix, (w,h), cv2.CV_32FC1 ) dst cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)3.3 重投影误差分析标定质量的金标准是重投影误差理想值应小于0.5像素。但要注意单张图像误差突然增大可能是该帧标定失败整体误差过大需要检查标定板测量精度误差分布不均匀可能提示镜头偏心我曾遇到误差始终在1.2像素徘徊的情况最后发现是标定板方格尺寸测量有0.1mm误差。改用游标卡尺精确测量后误差立即降到0.3像素。4. 标定结果的应用技巧4.1 三维重建中的参数使用在结构光三维扫描项目中相机参数直接影响点云精度。特别要注意内参用于将像素坐标转换到归一化平面外参决定多视角点云的拼接精度畸变参数影响特征点匹配质量有个实用技巧将标定结果保存为YAML文件方便不同程序调用fs cv2.FileStorage(calibration.yaml, cv2.FILE_STORAGE_WRITE) fs.write(camera_matrix, camera_matrix) fs.write(dist_coeffs, dist_coeffs) fs.release()4.2 实时系统的优化策略对于需要30fps以上处理的场景直接使用undistort()可能成为性能瓶颈。我的优化方案是预计算畸变映射表使用查找表(LUT)加速对低畸变镜头考虑近似计算在AGV导航项目中通过这种优化将图像校正时间从15ms降到了2ms。4.3 标定参数的长期稳定性工业环境下我建议每三个月重新标定一次。温度变化、机械振动都可能导致参数漂移。有次工厂昼夜温差导致镜头焦距变化0.1%虽然人眼难以察觉但使得测量误差增加了1.2mm。现在我们在关键工位都配备了温控箱。