具有梯度下降的相机径向畸变补偿

人工智能等各类编程培训资料整理,所有资源无秘无压缩-购买会员

消费级相机和镜头既便宜又普遍。不幸的是,与它们的工业同行不同,它们的设计目的并不是作为计算机视觉应用中精确测量的工具。

在各种类型的失真中,影响低档相机和镜头的最明显的失真是径向畸变。

径向畸变是场景中对象的视角与图像中该对象出现的像素之间的非线性。在光学中心附近,这种影响很难察觉,但当我们径向远离光学中心时,失真变得更加明显。

通常,远离光学中心的像素看起来比应该的更接近中心。图像的角似乎被拉向中心。这种现象被称为桶形失真,因为相机垂直看到的矩形物体将显示为圆形的“桶”(见下图)。

失真补偿

这个文章的目的是基于一个简单的模型来描述相机镜头对的径向畸变。一旦我们知道了失真参数,我们就能够补偿对象的像素位置,并获得一个无失真的像素位置。

你可以克隆此存储库中的代码和示例图像。

https://github.com/sebastiengilbert73/tutorial_distortion_calibration

棋盘图像将为我们提供共线特征点。在没有径向畸变的情况下,场景中共线点的像素位置应该是共线的。

由于它们明显不共线,我们将构建一个参数可调的模型,它将扭曲的像素点映射到未扭曲的点上。

特征点

第一步是提取图1中的特征点。

#Findthecheckerboardintersections,whichwillbeourfeaturepointsthatbelongtoaplane

checkerboard_intersections=checkerboard.CheckerboardIntersections(

adaptive_threshold_block_side=adaptive_threshold_block_side,

adaptive_threshold_bias=adaptive_threshold_bias,

correlation_threshold=correlation_threshold,

debug_directory=output_directory

)

intersections_list=checkerboard_intersections.FindIntersections(checkerboard_img)

CheckerboardIntersections类型的对象将彩色图像转换为灰度图像,然后应用自适应阈值。结果是一个二进制图像,其中的正方形交叉点非常清晰。

阈值图像与旨在强调两种交叉点的合成模式图像相关联。

对两个相关图像进行阈值处理以获得最高峰值。

检测到阈值相关图像中的斑点,并计算每个斑点的质心,生成交点列表。

径向畸变模型

我们将考虑一个基本的径向畸变模型——尽可能简单:作为距光学中心距离的函数的二次校正因子。未失真半径将是失真半径和校正系数的乘积。

这种失真模型只有三个参数:

光学中心(cx,cy)。它不一定与图像中心重合(w/2,h/2)。

二次系数α。当α>0时,我们有桶形畸变。当α<0时,我们有枕形失真(图像角向外拉伸)。当α=0时,没有径向畸变。

模型优化

我们面临着一个非线性优化问题:找到最佳参数(cx,cy)和α,它们将以形成直线的方式投影我们找到的交点。为此,我们将创建一个存储三个失真参数的PyTorch模型。

classDistortionParametersOptimizer(torch.nn.Module):

def__init__(self,center,alpha,image_sizeHW,zero_threshold=1e-12):

super(DistortionParametersOptimizer,self).__init__()

self.center=torch.nn.Parameter(torch.tensor([center[0]/image_sizeHW[1],center[1]/image_sizeHW[0]]).float())

self.alpha=torch.nn.Parameter(torch.tensor(alpha).float())

self.image_sizeHW=image_sizeHW

self.zero_threshold=zero_threshold

这个类还需要知道图像大小,因为为了数值稳定性,像素坐标将在(-1,1)中归一化。

DistortionParametersOptimizer.forward方法返回一批均方误差,每个均方误差对应于投影在相应最佳拟合线上的一行特征点的残差。

在理想情况下,如果径向畸变得到了完美补偿,forward方法将返回一批零。

我们直接与失真补偿类RadialDistortion交互。当我们调用它的Optimize方法时,它将在内部实例化DistortionParametersOptimizer类型的对象。

#CreateaRadialDistortionobject,thatwilloptimizeitsparameters

radial_distortion=radial_dist.RadialDistortion((checkerboard_img.shape[0],checkerboard_img.shape[1]))

#Starttheoptimization

epoch_loss_center_alpha_list=radial_distortion.Optimize(intersections_list,grid_shapeHW)

Plot([epochforepoch,_,_,_inepoch_loss_center_alpha_list],

[[lossfor_,loss,_,_inepoch_loss_center_alpha_list]],[“loss”])

在100个epoch内,均方误差下降100倍:

哇!这很容易¹!

找到的参数为(cx,cy)=(334.5, 187.2)(即图像中心的东北偏北(320, 240))和α=0.119,与预期的桶形失真校正系数相对应。

去失真

既然我们已经表征了径向畸变,我们可以将校正因子应用于我们的特征点。

图8显示了补偿径向畸变后的蓝色特征点。中心点基本不变,而外围点被推离中心更远。我们可以观察到,属于棋盘上直线的场景点看起来在图像中对齐得更好。

虽然我们可能不想在实时应用程序中这样做,但我们可以通过将原始图像中的每个像素投影到其相应的无失真位置来消除整个图像的失真。

由于我们逐渐将像素径向推离光学中心,我们经常会遇到投影空间中的像素,这些像素没有被原始图像中的像素映射,从而导致图9中令人讨厌的黑色痕迹。我们可以通过用附近的中间颜色替换黑色像素来消除这些像素。

结论

我们考虑了影响大多数消费级相机和镜头的径向畸变问题。我们假设了一个简单的失真模型,根据二次定律径向推拉像素。我们通过梯度下降,使用棋盘的特征点优化了一组参数。这些参数允许我们补偿径向畸变。

重要的是要认识到畸变参数是相机镜头对固有的。一旦知道它们,我们就可以补偿任何图像的径向畸变,只要相机镜头对是固定的。

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站,本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
600学习网 » 具有梯度下降的相机径向畸变补偿