|||
这篇名字听起来像是个paper,实际上内容很简单,根据以前介绍的8参数图像匹配方法得到的矩阵H,分解出对应的3D旋转矩阵R和平移矢量t,也就是说恢复出物体的6自由度的姿态信息;然后把3D空间中的虚拟物体在2D图像上渲染出来。这后一步,把虚拟世界的信息植入到真实图像中的技术,叫做增强现实(Augmented reality)。
之前讲到基于图像的实时匹配,用L-K算法,得到模板和图像坐标之间的映射关系,用所谓Homography matrix来表达:x' ~ H*x,而它们之间的这种映射关系是由模板(就是那本书)在3D空间中的姿态变化引起的:X' ~ M*X,M=[R | t] 表示3×4的变换矩阵,R是旋转,t是平移。'~ '表示变换之间有一个比例关系,就是他们总提到的up to a scale factor。空间和平面坐标点都用齐次坐标表示。
又因为空间坐标在二维平面的映射和内部参数有关: x=K*X, x'=K*X', K是内部参数矩阵,可以得到
K*X' ~ H*K*X --> X' ~ K-1*H*K*X --> X' ~ [R | t]*X
2D图像和3D空间点的关系如下图所示,其中箭头表示数据流动的方向,箭头上的H,K,R,t等表示要乘以这样的变换矩阵:
因为我们的3D物体(还是说得那本书)的坐标点可以表示为[X,Y,0,1]^T,那么变换矩阵[R | t]退化成3×3矩阵[r1,r2,t], r1,r2分别表示旋转矩阵的第一、二列, 那么我们进一步得到得到H和3D变换阵之间的关系:
K^-1*H*K ~ [r1,r2,t]
现在H已知,如果内部参数矩阵K已知的话(可通过camera calibration离线计算),r1,r2,t 就得到了,R是单位正交矩阵(R*R^T=1)可知 r3 = r1 ×r2,这样就能得到平面的空间姿态了。
我们知道通常内部参数矩阵K由5个参数组成,K=[ a*f ,s, u0; 0 ,f, v0; 0 ,0, 1 ],其中u0,v0表示光心,误差不大的情况下,取图像的中心点,我们的坐标原点也是图像中心点,所以u0=v0=0;s和a通常很小;另外我的摄像头也没有鼓形畸变,那么我们只有一个参数 f 需要估计K=[ f ,0,0; 0,f,0; 0,0,1]。
另外,根据R每列(和每行)内积为0,即< r1 , r2>=0这一事实,得到 f2 *h20*h21+ h00*h01 + h10*h11 =0 ,hij表示H矩阵i行j列的元素。实际上我们还有||r1||=||r2||=1,那就是说可以解2个未知数,如果我们得到更多的H矩阵,求解K的5个参数就不是问题了,这也是张正友的Camera Calibration的基本思路,那么上边那个关于f等参数的等式,又可以用几何观点描述成二次曲线,叫做绝对二次曲线(absolute conic)。可以看到camera calibration只和H的前两列有关,和平移矢量t无关。
空间平面对应的3D位置可以用X = K^-1 * x计算(就是得到上面那个图的左下角位置),平面上的点的z值都是0,在这个空间中的3D物体可以通过R,t变换再映射到对应的2D图像中去(就是走右边这条路X3d->X'3d->x'2d)。书的封面上那个“火柴棍”立体框架就是这样画上去的(OpenCV划线函数cvLine),如果利用OpenGL等工具可以做出更复杂的立体结构或者动画,如果你的创意足够多,还可以做出更多好玩的应用来。
------------------
2011年4月补充部分matlab实现方法
1.计算焦距f的方法,我的摄像头f=359.24
%Caculete focal length
%Ht: plannar homography matrix
fb = Ht(3,1)*Ht(3,2);
f=( Ht(1,1)*Ht(1,2)+Ht(2,1)*Ht(2,2) ) /fb ;
f = sqrt(-f);
Kcal=[1.0*f,0,0; 0,f,0; 0,0,1];
2.计算R,T的方法
%homography--->R & T
H = inv(Kcal)*Ht*Kcal;
r1 = sqrt( H(:,1)'*H(:,1) );
r2 = sqrt( H(:,2)'*H(:,2) );
R = H;
%旋转矩阵R需要单位化,实际上R前两列的模应相等
R(:,1)=R(:,1)./r1;
R(:,2)=R(:,2)./r2;
R(:,3) = cross(R(:,1),R(:,2));
%T也要除以r2,r1的均值
T = H(:,3)./((r2+r1)/2);
3. 使用R,T,并计算3d->2d映射
ptop = inv(Kcal)*ptop; %2d->3d
%set z of ptop
ptop = [ptop;ones(1,size(ptop,2))];
pd = Kcal* [R,T]*ptop;
% Z值要大于或等于零,即pd(3,:)>=0,否则画不出来
for i = 1:3 pd(i,:)= pd(i,:)./pd(3,:); end
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-25 16:04
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社