在机器视觉和计算机视觉领域,视觉传感器(相机)的标定是基础但至关重要的一步。无论你是在做智能驾驶、工业检测,还是机器人导航,相机标定的准确度直接决定了后续图像处理、三维重建和视觉定位的精度。我将以知乎风格,一步步带你从零开始搞定视觉传感器标定。
#为什么需要标定?
想象一下,你手里拿着一台相机,想用它来测量物体的实际位置。现实世界中的物体在三维空间里,而照片是二维的。相机标定的目的,就是建立从三维世界到二维图像的映射关系,同时消除镜头畸变(比如广角镜头的桶形畸变或长焦镜头的枕形畸变)。没有标定,你的测量数据就像没校准的尺子,误差会越来越大。
#标定前的准备
你需要准备一个标定板。最常见的是棋盘格或圆点阵列。棋盘格标定板简单易得,用A4纸打印出来,贴在一块硬板上就行。注意:棋盘格要平整,图案清晰,格子尺寸要已知(比如每个格子边长10毫米)。还需要一个稳定的三脚架和良好的光照条件,避免反光或阴影影响角点检测。
#标定流程详解
第一步:采集图像。手持标定板,在相机视野内移动,拍摄10到20张不同角度、不同距离的图像。关键点:标定板必须覆盖视野的各个角落,特别是边缘和角落区域,因为畸变在边缘最严重。确保标定板在每张图像中完整可见,且姿态多样(倾斜、旋转、平移)。
第二步:角点检测。使用OpenCV的cv2.findChessboardCorners()函数自动检测棋盘格的内角点。比如一个9x6的棋盘格,实际内角点数是8x5。如果检测失败,检查图像对比度或调整参数。
第三步:标定计算。调用cv2.calibrateCamera(),输入角点坐标和对应的世界坐标(假设标定板在Z=0平面上),它会返回相机内参矩阵(焦距、主点坐标)、畸变系数(径向畸变k1.k2.k3,切向畸变p1.p2)以及每张图像的外参(旋转和平移向量)。
第四步:评估误差。用标定结果重投影角点,计算重投影误差。通常误差小于0.5像素就算合格。如果误差大,可能是标定板不平、图像数量不足或角点检测不准,需要重新采集。
#实战代码片段
下面是一个简单的Python示例,使用OpenCV:
``python
import cv2
import numpy as np
定义棋盘格尺寸
CHECKERBOARD = (6, 9) 内角点数
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
准备世界坐标
objp = np.zeros((CHECKERBOARD[0]CHECKERBOARD[1], 3), np.float32)
objp[:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1,2)
存储
objpoints = [] 三维点
imgpoints = [] 二维点
循环处理图像
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, None)
if ret:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners2)
标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
`
运行后,mtx就是内参矩阵,dist`是畸变系数。保存后可用于后续图像去畸变。
#常见问题与技巧
1. 标定板不够大:如果视野中有大面积空白,畸变校正会不准确。建议标定板占图像面积至少三分之一。
2. 光照不均:使用均匀散射光,避免直射阳光。
3. 镜头变动:变焦镜头