从Scaramuzza的论文出发,详细介绍该模型。
参考论文-1:A Flexible Technique for Accurate Omnidirectional Camera Calibration and Structure from Motion (2006年,mei论文是2007年)
参考论文-2:A Toolbox for Easily Calibrating Omnidirectional Cameras (2006年)
参考论文-3:Omnidirectional Camera (2008年)
这3篇paper的一作都是Davide Scaramuzza,主讲的都是Scaramuzza 全向相机模型,paper-1是介绍该模型成像原理,paper-2是详细介绍该模型的标定过程(计算相机内参/外参),paper-3是针对全向相机内参模型的一篇综述。
作者在paper中声称Scaramuzza内参模型可以同时建模两种全向相机:(1) 反射折射 catadioptric(camera + mirror)(2) 纯折射 dioptric (fisheye),主要原因在于Scaramuzza模型用泰勒多项式来建模:某个3D点到光心O的向量与该点在图像坐标系下的坐标值(u,v),省去了fx / fy。paper中Scaramuzza的建模是根据2d–>3d,这和其他模型的推导是反着的
这个公式描述了一个全向相机(omnidirectional camera)的投影模型。全向相机能够捕捉到更广阔的视野,通常用于机器人、虚拟现实和增强现实等领域。让我们逐步解释这个公式的含义:
投影函数 g g g:
全向相机模型:
λ ⋅ p = λ ⋅ g ( u ′ ′ ) = λ ⋅ g ( A u ′ + t ) = P X , λ > 0 \lambda \cdot p = \lambda \cdot g(u'') = \lambda \cdot g(Au' + t) = PX, \quad \lambda > 0 λ⋅p=λ⋅g(u′′)=λ⋅g(Au′+t)=PX,λ>0
齐次坐标:
透视投影矩阵 P P P:
总的来说,这个公式描述了全向相机如何通过投影函数 g g g和透视投影矩阵 P P P将三维场景点 X X X映射到二维传感器平面上的过程。这个过程是计算机视觉和图像处理中的基础,用于从图像中恢复三维场景信息。
投影函数 g ( u ′ , v ′ ) g(u', v') g(u′,v′):
g ( u ′ , v ′ ) = ( u ′ , v ′ , f ( u ′ , v ′ ) ) T g(u', v') = (u', v', f(u', v'))^T g(u′,v′)=(u′,v′,f(u′,v′))T
旋转对称性假设:
坐标系和变换:
多项式函数 f ( u ′ , v ′ ) f(u', v') f(u′,v′):
f ( u ′ , v ′ ) = a 0 + a 1 ρ ′ ′ + a 2 ρ ′ 2 + … + a N ρ ′ N f(u', v') = a_0 + a_1 \rho'' + a_2 \rho'^2 + \ldots + a_N \rho'^N f(u′,v′)=a0+a1ρ′′+a2ρ′2+…+aNρ′N
投影模型:
λ ⋅ [ u ′ v ′ w ′ ] = λ ⋅ g ( A u ′ + t ) = λ ⋅ [ ( A u ′ + t ) f ( u ′ , v ′ ) ] = P ⋅ X , λ > 0 \lambda \cdot \begin{bmatrix} u' \\ v' \\ w' \end{bmatrix} = \lambda \cdot g(\mathbf{A}u' + t) = \lambda \cdot \begin{bmatrix}(\mathbf{A}u' + t) \\ f(u', v') \end{bmatrix} = \mathbf{P} \cdot \mathbf{X}, \, \lambda > 0 λ⋅ u′v′w′ =λ⋅g(Au′+t)=λ⋅[(Au′+t)f(u′,v′)]=P⋅X,λ>0
这些公式共同描述了一个反射折射相机系统的投影模型,包括如何将传感器平面上的点映射到三维空间中的深度,以及如何通过多项式函数和仿射变换来处理图像坐标。这种模型在计算机视觉和机器人学中非常重要,用于从全向图像中恢复三维场景信息。
这个 MATLAB 函数 cam2world
实现了将图像平面上的二维点(像素坐标)转换为三维空间中的单位向量(即从相机中心出发的光线方向)。这个过程通常用于全向相机(如鱼眼相机或反射折射相机)的模型,目的是将图像点映射到相机的单位球面上。
2D --> 3D是用ρ来进行多项式近似
输入参数:
m
:图像平面上的二维点(像素坐标),大小为 (2 \times N),其中 (N) 是点的数量。ocam_model
:一个结构体,包含相机的内参和畸变参数,具体包括:
ss
:多项式系数,用于描述相机的畸变模型。xc
, yc
:图像中心点的坐标(主点)。width
, height
:图像的宽度和高度。c
, d
, e
:仿射变换矩阵的参数。主要步骤:
提取参数:
ss = ocam_model.ss;
xc = ocam_model.xc;
yc = ocam_model.yc;
c = ocam_model.c;
d = ocam_model.d;
e = ocam_model.e;
这些参数用于描述相机的内参和畸变模型。
仿射变换:
A = [c,d; e,1];
T = [xc;yc]*ones(1,n_points);
m = A^-1*(m-T);
这里,A
是一个仿射变换矩阵,用于将图像平面上的点从像素坐标系转换到归一化的度量坐标系。T
是平移向量,用于将图像中心点对齐到坐标系原点。
计算三维光线方向:
M = getpoint(ss,m);
调用 getpoint
函数,将归一化的二维点映射到三维空间中的光线方向。
归一化到单位球面:
M = normc(M);
将三维向量归一化,使其长度为 1,表示这些向量位于单位球面上。
getpoint
函数:
ss
),将归一化的二维点映射到三维空间中的光线方向。w = [m(1,:) ; m(2,:) ; polyval(ss(end:-1:1), sqrt(m(1,:).^2 + m(2,:).^2)) ];
m(1,:)
和 m(2,:)
是归一化的二维点的 (x) 和 (y) 坐标。polyval(ss(end:-1:1), sqrt(m(1,:).^2 + m(2,:).^2))
计算径向畸变,使用多项式 ss
来描述畸变模型。w
表示从相机中心出发的光线方向。w = [m(1,:) ; m(2,:) ; polyval(ss(end:-1:1), sqrt(m(1,:).^2 + m(2,:).^2)) ];
转换为数学公式,可以表示为:完整的数学表达式为:
w = [ u ′ v ′ a 0 + a 1 ρ ′ + a 2 ρ ′ 2 + … + a N ρ ′ N ] w = \begin{bmatrix} u' \\ v' \\ a_0 + a_1 \rho' + a_2 \rho'^2 + \ldots + a_N \rho'^N \end{bmatrix} w= u′v′a0+a1ρ′+a2ρ′2+…+aNρ′N
其中:
这个公式表示将归一化的二维点 ( u ′ , v ′ ) (u', v') (u′,v′) 映射到三维空间中的光线方向 w w w,其中第三维 f f f 由多项式畸变模型计算得出。
function M=cam2world(m, ocam_model)
n_points = size(m,2);
ss = ocam_model.ss;
xc = ocam_model.xc;
yc = ocam_model.yc;
width = ocam_model.width;
height = ocam_model.height;
c = ocam_model.c;
d = ocam_model.d;
e = ocam_model.e;
A = [c,d;
e,1];
T = [xc;yc]*ones(1,n_points);
m = A^-1*(m-T);
M = getpoint(ss,m);
M = normc(M); %normalizes coordinates so that they have unit length (projection onto the unit sphere)
function w=getpoint(ss,m)
% Given an image point it returns the 3D coordinates of its correspondent optical
% ray
w = [m(1,:) ; m(2,:) ; polyval(ss(end:-1:1),sqrt(m(1,:).^2+m(2,:).^2)) ];
这个函数的主要功能是将图像平面上的二维点(像素坐标)转换为三维空间中的单位向量(光线方向)。具体步骤包括:
这种转换通常用于全向相机的几何校正和三维重建任务中。
3D --> 2D是用θ来进行多项式近似,θ是入射光线和图像平面的夹角,这个和泰勒(Kannala-Brandt模型)很像(θ是入射光线和Z轴的夹角),只不过多项式阶数更高(190度的鱼眼相机:一般为12阶以上)。这个比较简单,我就不多介绍了。可以看出,Scaramuzza的作者Davide Scaramuzza 想传达的思路在于2D鱼眼图片向其他坐标系转换的一种思路吗。
function m = world2cam_fast(M, ocam_model)
ss = ocam_model.ss;
xc = ocam_model.xc;
yc = ocam_model.yc;
width = ocam_model.width;
height = ocam_model.height;
c = ocam_model.c;
d = ocam_model.d;
e = ocam_model.e;
pol = ocam_model.pol;
npoints = size(M, 2);
theta = zeros(1,npoints);
NORM = sqrt(M(1,:).^2 + M(2,:).^2);
ind0 = find( NORM == 0); %these are the scene points which are along the z-axis
NORM(ind0) = eps; %this will avoid division by ZERO later
theta = atan( M(3,:)./NORM );
rho = polyval( pol , theta ); %Distance in pixel of the reprojected points from the image center
x = M(1,:)./NORM.*rho ; % 和fisheyey一样也利用了入射光线和x轴夹角等于像素坐标系上该点的x夹角
y = M(2,:)./NORM.*rho ;
%Add center coordinates
m(1,:) = x*c + y*d + xc;
m(2,:) = x*e + y + yc;
Scaramuzza 的模型主要用于将 2D 鱼眼图像上的点 转换为 3D 空间中的光线方向(即从相机中心出发的单位向量)。这个模型的核心在于:
2D 到 3D 的映射:
高阶多项式:
目标:
Kannala-Brandt 模型也是一种经典的鱼眼相机模型,但它更侧重于 3D 到 2D 的投影:
3D 到 2D 的映射:
多项式近似:
目标:
Scaramuzza 模型的独特之处在于:
2D 到 3D 的逆向映射:
高精度拟合:
灵活性:
Scaramuzza 的模型确实传达了一种思路:通过多项式映射将鱼眼图像上的 2D 点转换为其他坐标系(如 3D 光线方向或单位球面)。这种思路的核心在于:
直接处理鱼眼图像的畸变:
为后续任务提供基础:
Scaramuzza 的模型和 Kannala-Brandt 模型都使用多项式来描述鱼眼相机的投影过程,但它们的思路和应用场景不同:
Scaramuzza 的模型通过高阶多项式和高灵活性,为鱼眼图像的处理提供了一种有效的思路,尤其是在大视角和复杂畸变的情况下。
论文 《A Toolbox for Easily Calibrating Omnidirectional Cameras》是这么设置的,设置了一个包含 6x8=48 个角点的棋盘平面。图案的尺寸为 150x210 毫米。作为相机模型,我们选择一个 4 阶多项式,其参数根据校准真实全向相机获得的参数进行设置。然后,我们将虚拟相机的图像分辨率设置为 900x1200 像素。
通过校准全向相机,我们指的是估计参数[A, t, a0, a1, a2 ,…, an ].
按照论文的步骤;
1、求解相机外部参数:
总之,校准的第一步可以找到校准模式每个姿势的外部参数 [r11,r12,r21,r22,r31,r32,t1,t2],除了平移参数 t3 。
2、求解相机内部参数:
描述模型的内部参数 [a1,a2,a3,…,an] 。为了计算最佳多项式次数 N,我们实际上从 N=2 开始。然后,我们以单位步长增加 N,并计算所有校准点的重投影误差的平均值。当找到最小误差时,该过程停止。
C. 内在和外在参数的线性细化。线性最小化步骤找出相机的内在参数,并同时估计剩余的外在 t3 。
D. 迭代中心检测
E. 非线性细化
OCamCalib: Omnidirectional Camera Calibration Toolbox for Matlab
https://blog.csdn.net/ouyangandy/article/details/107088939
https://zhuanlan.zhihu.com/p/578678136