返回

畸变校正

Distortion Correction
第二章 / 图像校正
参数面板

参数面板用于调整当前示例、算法参数和辅助操作;主区负责展示图像处理过程。

0.32
畸变图显示镜头畸变后的观测图像,校正图显示按照当前系数执行坐标校正后的结果。当前解释对象是校正图绿色框输出像素如何反向映射回畸变图采样位置;请优先观察直线边界是否恢复。
概念说明

镜头畸变为什么要校正

径向畸变会让直线在图像边缘附近产生明显弯曲。图源:OpenCV calibration docs
任务

当用广角或普通镜头拍摄时,真实场景里的直线在照片边缘可能出现弯曲,物体的形状也会被拉长或压缩。如果不校正,后续基于直线或距离的测量就会出错。

思路

常用办法是先建立畸变模型:径向畸变用多项式描述光线向边缘的弯曲,切向畸变描述镜头与传感器不平行带来的偏移。校正时根据目标像素反查它在原图中的采样位置,再把弯曲的结构重新映射回规则坐标。

观察

拖动滑块改变畸变系数,观察图像中心与边缘的变形程度有什么不同;切换径向和切向参数,看看直线从弯曲恢复平直的过程主要来自哪一类畸变。

畸变校正的本质:坐标重映射

镜头畸变会把本应保持笔直的结构扭曲或弯曲。标定得到的畸变系数并不直接修改亮度,而是先计算每个输出像素应当回到原畸变图中的哪个坐标,再由remap完成采样。

当前模式:桶形畸变校正
桶形(k₁>0)使直线向外鼓出,枕形(k₁<0)使直线向内凹陷。
畸变图120×120
畸变重映射
校正图120×120
校正图绿色框是当前正在解释的校正后输出像素。
1. 畸变图中的采样位置

畸变图是已经被镜头畸变扭曲后的观测图像。当前输出像素不会直接复制畸变图同坐标,而是先查询mapx,mapy给出的源位置。

源坐标约为 (60.00, 60.00)
当前灰度采样值:0.548
2. 由畸变系数生成映射表

映射表通常由initUndistortRectifyMap预先计算完成。当前坐标代入一次径向畸变映射后,就能得到等价的采样位置。

xd=xs,yd=ys,s=1+k1r2+k2r4
当前使用 k1=0.320,k2=0.058。
3. remap 写回校正图

校正图的当前像素位于 (60, 60),它显示的是畸变图源坐标采样后的结果(使用双线性插值),因此校正后直线会重新接近笔直。

输出灰度值:0.548
空白或暗边来自越界采样,不是图像内容本身发生变化。
畸变校正链路

畸变校正不是对像素值做卷积或增强,而是利用内参矩阵和畸变系数,为每个输出像素找到原畸变图中的采样位置。

OpenCV 的两步实现
map=initUndistortRectifyMap(K,distCoeffs),I=remap(I,map)
第一步算坐标映射,第二步按映射表取样。
径向畸变
xd=xs,yd=ys,s=1+k1r2+k2r4
x 和 y 都乘同一个径向比例项;桶形和枕形的差别,主要体现在一阶径向系数 k₁ 的正负。
当前像素如何代入映射
输出像素的归一化坐标
x=(u-cx)fx=(60-60)60=0.000,y=(v-cy)fy=(60-60)60=0.000
此处简化假设主点在图像中心(cₓ=w/2)且焦距等于半宽(fₓ=w/2),实际标定中这些值来自内参矩阵。
当前径向比例项
r2=x2+y2=0.0002+0.0002=0.000,s=1+k1r2+k2r4=1+0.3200.000+0.0580.0002=1.000
比例项决定当前点向光轴中心收缩还是向外扩张。
mapx / mapy 查询结果
us=mapx(u,v)=mapx(60,60)=60.00,vs=mapy(u,v)=mapy(60,60)=60.00
这就是 remap 要回到原畸变图中取样的位置。
写回后的像素值
I(u,v)=I(us,vs)=I(60.00,60.00)=0.548
双线性插值会综合附近 4 个源像素,因此比最近邻采样的结果更平滑。
如何判断校正是否有效
1. 观察棋盘格或边界线是否从弯曲恢复为接近直线。
2. 注意边缘黑边并不表示校正失败,而是映射后的部分像素落在原图范围之外。
3. 如果畸变系数与真实镜头不匹配,直线仍会残留弯曲或出现过校正。
学习检查
畸变校正的核心不是「改亮度」,而是「用标定参数把输出像素重新映射回原图中的正确采样位置」。