此博客记录了利用 matlab 中 cameraCalibrator 工具箱进行相机标定求取相机参数,并利用 OpenCV 对相机畸变进行矫正。
1. 生成 “棋盘式” 标定板,可以用 matlab 生成,代码参考如下:
image = (checkerboard(300,4,5)>0.5);
figure, imshow(image);
imwrite(image,'F:\\image\\abc.png');
2. 将标定板用 A4 纸打印好或者找块屏幕显示都行,然后要测量标定板实物上实际黑白正方形的边长,后面会用到。
1.在MATLAB的命令行窗口输入 cameraCalibrator 打开标定工具。
标定窗口如图所示:
2.选择 “Add Images” 将上述准备好的图片全部导入
然后出现如下界面,输入刚才测量的标定板正方形黑白块的边长后点击确定。
3.点击 “Options” 选项,进行如下设置(使用两参数,选择错切和桶形畸变。)
注:具体原理参见OpenCV官网介绍:
http://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
对于不会科学上网的朋友可以参考以下理论解释,简单说就是对于相机的畸变从 “径向” 和 “切向” 两个方向去考虑,总共有 5 个参数,三个径向畸变(k1, k2, k3)和两个切向畸变(p1, p2),考虑到 k3 对矫正影响较大,容易产生扭曲,故仅采用 k1, k2 两参数,即令 k3 = 0。
标定结束后点击 “Export Camera Parameters” 导出参数。
标定出的参数中:
RadialDistortion 对应k1,k2(k3 默认为 0)。
TangentialDistortion 对应p1,p2。
IntrinsicMatrix 对应内参,注意其与 OpenCV 中的转置关系,参考下图对比,实际代码编写时需注意!
Python 对应畸变矫正代码(参数一 一对应),以函数形式给出,输入待矫正图形变量,返回矫正好的图形变量。
# 摄像头畸变矫正函数,输入待矫正的图形变量
def undistort(frame):
fx = 7.867891195067076e+02
cx = 6.823648074697487e+02
fy = 8.454139535337483e+02
cy = 5.185634497802844e+02
k1, k2, p1, p2, k3 = -0.327782591286664, 0.104488486639823, -9.519326514054385e-04, 2.433441734520703e-04, 0.0
# 相机坐标系到像素坐标系的转换矩阵
k = np.array([
[fx, -0.766489481509873, cx],
[0, fy, cy],
[0, 0, 1]
])
# 畸变系数
d = np.array([
k1, k2, p1, p2, k3
])
height, weight = frame.shape[:2]
mapx, mapy = cv2.initUndistortRectifyMap(k, d, None, k, (weight, height), 5)
# 返回矫正好的图形变量
return cv2.remap(frame, mapx, mapy, cv2.INTER_LINEAR)
此博客为相机标定求取内参畸变,并对其进行矫正,采用的是 120° 超广角的镜头,镜头畸变较大,效果对比明显。不过现在主流的工业镜头畸变都比较低,求取相机参数主要还是为了测算,本博客后续将整理 OpenCV 中 solvePnP 测距的实现方法。