镜头畸变校正
本文最后更新于:2023年4月11日 晚上
之前介绍了镜头畸变,本文记录校正畸变的模型和方法。
背景
- 对于常见的镜头径向畸变和切向畸变,在硬件已经无法继续优化时,需要后处理进行校正
模型
一些针孔摄像机会对图像产生严重的畸变,主要有两种畸变: 径向畸变和切向畸变。
径向畸变
- 径向畸变导致直线看起来弯曲。点距图像中心越远,径向畸变越大。例如,下图显示了一个棋盘的两个边缘用红线标记的图像。但是,你可以看到棋盘的边界不是一条直线,与红线不匹配。所有预期的直线都凸出。
- 径向畸变可以表示为以下模型
切向畸变
- 类似地,切向畸变发生是因为摄像透镜没有与成像平面完全平行。因此,图像中的某些区域看起来可能比预期的要近。切向扭曲的数量可表示如下:
叠加畸变
利用上面两组式子就可对畸变进行较好的修正。同时对径向、切向畸变消除就是将两组式子合并。
$$ \begin{aligned} x_{\text {distorted }} & =x\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right)+2 p_{1} x y+p_{2}\left(r^{2}+2 x^{2}\right) \\ y_{\text {distorted }} & =y\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right)+p_{1}\left(r^{2}+2 y^{2}\right)+2 p_{2} x y\end{aligned} $$自变量为理想坐标,等式左边的结果为畸变坐标,反过来该公式不成立。
畸变系数
- 简而言之,我们需要找到五个参数,即畸变系数:
$$
Distortion ; coefficients=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3)
$$
相机参数
- 除了畸变模型参数之外,还需要一些其他的信息,比如相机的内部参数和外部参数。
内参
- 摄像机的固有参数是特定的。它们包括像焦距 $(f_x,f_y)$和光学中心 $(c_x,c_y)$ 这样的信息。所述焦距和光学中心可用于创建摄像机矩阵,该矩阵可用于消除由于特定摄像机的镜头而产生的畸变。相机矩阵对于特定的相机来说是独一无二的,所以一旦计算出来,就可以在同一个相机拍摄的其他图像上重复使用。它表示为一个 $3 \times 3$ 的矩阵:
外参
-
外部参数对应于将 3D 点的坐标转换为坐标系的旋转和平移向量。
-
为了找到这些参数,我们必须提供一些定义良好的示例图像(例如棋盘)。如果已经知道相对位置的特定点(例如棋盘上的方角),并且知道这些点在真实空间中的坐标,也知道图像中的坐标,在这种情况下就可以求出畸变系数。
为了获得更好的结果,至少需要10组对应点的数据。
Python 实现
- 测试图像:
可以直接下载图像,命名为
undistort.png
-
示例代码(需要安装 mtutils)
1
pip install mtutils
-
核心步骤使用 OpenCV 库实现
1 |
|
- 配置好图像,运行程序可以看到标记的图和校正结果
- 使用映射矩阵直接映射得到矫正图像结果,速度可以快十几倍
C++ 实现
1 |
|
- image watch 中显示的矫正结果
参考资料
-
https://www.zywvvd.com/notes/study/camera-imaging/photo-distortion/photo-distortion/
-
https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html
文章链接:
https://www.zywvvd.com/notes/study/camera-imaging/distort-corr/distort-corr/