相机标定 + 相机畸变矫正 (基于OpenCV + Matlab + Python)
前言
? ??此博客记录了利用 matlab 中 cameraCalibrator 工具箱进行相机标定求取相机参数,并利用 OpenCV 对相机畸变进行矫正。
?
一、标定前准备:采集相机原画面
? ??1. 生成 “棋盘式” 标定板,可以用 matlab 生成,代码参考如下:
image = (checkerboard(300,4,5)>0.5);
figure, imshow(image);
imwrite(image,'F:\\image\\abc.png');
? ??2. 将标定板用 A4 纸打印好或者找块屏幕显示都行,然后要测量标定板实物上实际黑白正方形的边长,后面会用到。
??3. 采集镜头各个角度大概 15~20 张图片,参考如下。 ?
二、开始标定:计算相机内参与畸变
? ?? 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。
? ?? 4.点击 “Calibrate” 开始标定。
?? 标定结束后点击 “Export Camera Parameters” 导出参数。
?? 保存成功后,打开变量,即可看到保存的参数值。
?
三、标定代码: Python 版本
? ?? 标定出的参数中:
?? 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 测距的实现方法。
|