ARToolkit中标识和摄像头的位置关系
ARToolKit 提供了标识在摄像机的坐标系统中的位置,使用 opengl 矩阵系统计算出虚拟物体的位置。我会更详细地讲解这些不同的元素及其之间的关系。
坐标系统
我们先来介绍 simpleTest 程序。打开它,把下面这句代码加在 arGetTransMat 后:
printf("%f %f %f\n",patt_trans[0][3],patt_trans[1][3],patt_trans[2][3]);
重新编译,运行程序。注意输出值。如果把标识往左移动,第一个值就会增加,往上移动,第二个值就减小,往前移动最后一个值也会增加。下面是 ARToolKit 所使用的坐标系统(CS)。
输出的值与这些坐标系统相对应。标识坐标系统有着和 opengl 坐标系统一样的方位。
因此任何应用于与标识关联的物体的转换都应遵循 opengl 的转换规则。比如说,如果不想把茶壶显示在标识坐标系统的中心,而是让它显示在顶部,可以把下面的代码:
glTranslatef(0.0,0.0,25.0);
代替为:
glTranslatef(0.0,80.0,25.0);
那么就会得到:
图 2 虚拟物体移动后的 simpleTest
图 3 exview 视频截图
图 4 摄像头的不同位置
if( arGetTransMat(marker_info, target_center,target_width, target_trans) < 0 ) return;
if( arUtilMatInv(target_trans, cam_trans) < 0 ) return;
sprintf(string," RAW: Cam Pos x: %3.1f y: %3.1f z: %3.1f",cam_trans[0][3], cam_trans[1][3], cam_trans[2][3]);
可以看到,同样调用了 arGetTransMat,又调用了 arUtilMatInv,得到转换后的位置。
标识卡和摄像机之间的关系非常重要,它们之间的转换使多个坐标系统的工作成为可能。
在这些坐标系统的基础上,同样可以得到任何两个不同的坐标系统之间的转换关系。
打开examples/relation 目录下的 relationtest.c 文件。可以得到和 simplem 一样的多个物体。主要的区别是增加了以下代码:
if( object[0].visible >= 0 && object[1].visible >= 0 ) {
double wmat1[3][4], wmat2[3][4];
arUtilMatInv(object[0].trans, wmat1);
arUtilMatMul(wmat1, object[1].trans, wmat2);
for( j = 0; j < 3; j++ ) {
for( i = 0; i < 4; i++ ) printf("%8.4f ", wmat2[j]);
printf("\n");
}
printf("\n\n");
这段代码计算了两个标识之间的相对转移矩阵。object[0].trans 是标识卡 1 在摄像机坐标系里面的转移矩阵,object[1].trans 是标识卡 2 在摄像机坐标系里面的转移矩阵.因此object[0].trans 的转置乘以 object[1].trans 就得到了标识卡 2 在标识卡 1 坐标系里面的转移矩阵。运行程序,把标识卡放在如图所示位置上:
图 5 relationtest(渲染视图和控制台输出)
尝试通过修改 relationTest 的代码做相反的操作(标识卡 1 在标识卡 2 坐标系里面的相对转移矩阵)。