您的位置:首页 > 其它

关于camera calibration以后三维空间和二维图像之间的映射关系的讨论

2012-12-26 20:12 281 查看
多对一的映射

在三维空间内,任意曲面都可以通过摄像头的映射,投影到一个二维的图像之间。平行的三维空间的曲面重叠映射到同一个二维图像上,通过透明和重叠,形成一组实际的画面。平行的曲面上对应的无穷多个点映射到二维图像上一个相同的点,形成多对一的映射关系。

所以实际的三维空间在经过摄像头投影到图像上的变换,是一组无穷多的三维点映射到一个二维点的变换。据此,当摄像头标定好以后(摄像头的标定在此不再赘述,实例已经很丰富了),一个已知的三维点可以通过变换求得唯一确定对应的二维点,但是一个已知的二维点,必须在已知三维点之间的一个关系时(最基本的就是要锁定三维空间中一个确定的曲面),才能求得一个唯一确定对应的三维点。

三维点到二维点的映射

根据张正友前辈的论文,摄像头的基本工作原理如下

s[x1 x2 1]T=A[R1 R2 R3 t][X1 X2 X3 1]T

x1 x2为二维点的坐标,X1 X2 X3为三维点的坐标,A(3×3)为intrinsic matrix,[R1(3×1) R2(3×1) R3(3×1)]为rotation matrix, t(3×1)为translation vector。[]T为矩阵的旋转。

化简为s[x1 x2 1]T = A([R1 R2 R3][X1 X2 X3 ]T+t)

将三维点的坐标X1 X2 X3带入右边的矩阵算式,运算结果为[sX1 sX2 s]。s的值会随着选取三维点的不同而变化,不是一个常量,但是可以通过这个等式求出来特定的三维点的特定的s值。这样x1=sx1/s, x2=sx2/s便可求出来三维点对应的二维点的坐标。

用opencv的矩阵运算的方程cvGEMM()可以进行如下的编程:

cvGEMM(rotation_matrix,3D_point,1,translation_vector,1,output_vector,0);

cvGEMM(intrinsic_matrix,output_vector,1,0,0,2D_point,0);

x1 = cvGetReal2D(2D_point,0,0);

x2 = cvGetReal2D(2D_point,1,0);

s = cvGetReal2D(2D_point,2,0);

x1 = x1 / s;

x2 = x2 / s;

output_vector为[R1 R2 R3][X1 X2 X3 ]T+t的运算结果。

2D_point, 3D_point, output_vector为3×1的矩阵。

Intrinsic_matrix内矩阵,rotation_matrix旋转矩阵,translation_vector平移向量。

x1 x2即为3D_point对应的图像中二维点的坐标,x3为参数s的值。

二维点到三维点的映射

首先要在选定的三维空间中确定一个唯一的对应曲面(广义的曲面,包括平面),唯一的曲面确定后,三维点坐标可以化简如下:

3D_point=[X1 X2 f(X1,X2)]

则[R1 R2 R3][X1 X2 X3 ]T+t的运算结果为:

[(R11X1+R12X2+R13f(X1,X2)+t11)

(R21X1+R22X2+R23f(X1,X2)+t21)

(R31X1+R32X2+R33f(X1,X2)+t31)]

可以写成矩阵形式[B1 B2 Bt][X1 X2 1]T (B=[B1 B2 Bt])

在已知X3点的坐标时(比较常见的情况),f(X1 X2)=X3 可以写成一个常函数,这个时候,就可以求出在已知X3的坐标时B1 B2 Bt对应的值。

B1=R1 B2=R2 Bt=R3+t

s[x1 x2 1]T=A[R1 R2 R3 t][X1 X2 X3 1]T可以化简为

s[x1 x2 1]T=AB[X1 X2 1]

可以求出[X1/s X2/s 1/s]=(AB)-1[x1 x2 1]。将二维点带入右边算式,即可求出已知X3坐标的对应的三维的点。

用opencv编程为

cvGEMM(intrinsic_matrix,rotation_tanslation_matrix,1,0,0,fundamental_matrix,0);

cvInvert(fundamental_matrix,fundamental_matrix,CV_LU);

cvGEMM(fundamental_matrix,2D_point,1,0,0,3D_point,0);

X1 = cvGetReal2D(3D_point,0,0);

X2 = cvGetReal2D(3D_point,1,0);

s = cvGetReal2D(3D_point,2,0);

X1 = X1 / s;

X2 = X2 / s;

rotation_translation_matrix即为矩阵B,即[R1 R2 (X3R3+t)],可以单一赋值完成。

Fundamental_matrix(3×3) 为AB相乘的逆矩阵,

X1 X2 X3为2D_point对应的显示世界中三维点的坐标,X3坐标已知。

至此完成了

已知三维点3D_point = [X1 X2 X3]的情况下求解二维对应点2D_point = [x1 x2 s]的算法和

已知二维点 2D_point=[x1 x2 1]和X3的具体坐标,求解三维对应映射点3D_point = [X1 X2 X3]的算法,希望能对大家有所帮助。

http://www.opencv.org.cn/forum/viewtopic.php?f=10&t=9790&p=45344&hilit=%E6%97%8B%E8%BD%AC%E7%9F%A9%E9%98%B5#p45344
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐