赞
踩
Kannala Brandt 模型 / opencv中的fisheye / kalibr中的 pinhole + equidistant 都是指该模型。
在之前的博客【鱼眼镜头1】鱼眼镜头的四种投影模型(指导镜头的设计),中央镜头综述,说明了投影模型的重要性:为了从全向相机捕获的图像中提取有用的信息,我们需要知道光线如何从三维空间映射到二维图像平面。这就是投影模型的作用。一个准确的投影模型可以帮助我们更准确地估计场景中物体的位置、姿态和其他属性。
常见的鱼眼相机基本成像模型主要有四种,它们分别是等距投影(最广泛)、等立体角投影、体视投影、正交投影。镜头的设计基本是按照上述四种投影模型而制作的,可看出鱼眼相机成像模型通用性较差。
为了解决模型通用性较差的问题,可以引入畸变模型,将鱼眼成像模型等价成理想针孔成像模型与畸变模型的叠加作用。
以上是之前对鱼眼相机的标定和投影模型的理解。鱼眼相机由于其超大的视场角(Field of View, FOV),其成像过程并不完全符合传统的针孔相机模型。因此,需要使用特定的投影模型来描述鱼眼相机的成像过程。
Equidistant模型:
rd
与入射角Θ
(光线与相机光轴的夹角)之间的关系是线性的,即rd = f * Θ
,其中f
是相机的焦距。这个模型假设在图像平面上,沿各个方向上的距离都是等比例缩放的。鱼眼相机的实际设计:
Kannala的鱼眼相机多项式近似模型:
rd
与入射角Θ
之间的关系。这种方法的优点是可以更灵活地适应不同鱼眼相机的成像特性,提高标定的准确性。奇函数和泰勒级数展开:
综上所述,使用Equidistant模型可以简化鱼眼相机的成像过程,但实际的鱼眼镜头可能无法完全遵循这个模型。为了更准确地描述鱼眼相机的成像过程,可以使用更复杂的模型或近似方法,如Kannala的多项式近似模型。同时,通过泰勒级数展开和奇函数性质的分析,可以更好地理解这些投影模型的特点和适用性。
其中使用最多的是Equidistant模型, 即rd=f*\Theta,对实际的鱼眼镜头来说,它们不可能精确地按照投影模型来设计,所以为了方便鱼眼相机的标定,Kannala提出了一种鱼眼相机的一般多项式近似模型。通过前面的四个模型,可以发现\Thetad 是 \Theta的奇函数,而且将这些式子按泰勒级数展开,发现 可以用 的奇次多项式表示
opencv中的fisheye::calibrate就是用的该模型. 也叫作kannala-brandt模型.
class SVCCalibrationSDK: def __init__(self, intrinsic_param, width, height): self.image_size = np.array([height, width]) # rows, cols self.world2cam = np.array(intrinsic_param["world2cam"]).reshape(-1, 1) self.world2cam_len = np.array(intrinsic_param["world2cam_len"]) self.svc_rotation = np.array([[1., intrinsic_param["affine_e"]], [intrinsic_param["affine_d"], intrinsic_param["affine_c"]]]) self.svc_translation = np.array(intrinsic_param["center"]) def cam_to_pixel(self, points): num_points = len(points) if num_points == 0: return np.empty((0, 3)) else: norm = np.sqrt(np.sum(points[:, 0:2] * points[:, 0:2], axis=1, keepdims=True)) theta = np.arctan(points[:, 2:3] * (-1 / norm)) poly_theta = np.power(theta, np.arange(self.world2cam_len)) rho = (poly_theta @ self.world2cam) pixels = (points[:, 0:2] * (rho / norm)) @ self.svc_rotation + self.svc_translation return pixels
https://zhuanlan.zhihu.com/p/532501102
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。