话不多说,先上源码。
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef __APPLE__
#include <GL/gl.h>
#include <GL/glut.h>
#else
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
#endif
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/param.h>
#include <AR/ar.h>
#ifdef _WIN32
char *vconf = "Data\\WDM_camera_flipV.xml";
#else
char *vconf = "";
#endif
int xsize, ysize;
int thresh = 100;
int count = 0;
char *cparam_name = "Data/camera_para.dat";
ARParam cparam;
char *patt_name = "Data/patt.hiro";//标识卡类型
int patt_id;
double patt_width = 80.0;
double patt_center[2] = {0.0, 0.0};
double patt_trans[3][4];
static void init(void);
static void cleanup(void);
static void mainLoop(void);
//主函数
int main(int argc, char **argv)
{
glutInit(&argc, argv);
init();
arVideoCapStart();
argMainLoop( NULL, NULL, mainLoop );
return (0);
}
//主循环
static void mainLoop(void)
{
ARUint8 *dataPtr;
ARMarkerInfo *marker_info;
int marker_num;
int j, k;
double cam_trans[3][4];//包含摄像头在标识坐标中的位置
double quat[4] ,pos[3];//添加2个数组以记录结果
if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
arUtilSleep(2);
return;
}
if( count == 0 ) arUtilTimerReset();
count++;
argDrawMode2D();
argDispImage( dataPtr, 0,0 );
if( arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
cleanup();
exit(0);
}
arVideoCapNext();
k = -1;
for( j = 0; j < marker_num; j++ ) {
if( patt_id == marker_info[j].id ) {
if( k == -1 ) k = j;
else if( marker_info[k].cf < marker_info[j].cf ) k = j;
}
}
if( k == -1 ) {
argSwapBuffers();
return;
}
arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans);//计算摄像头的转移矩阵
if(arUtilMatInv(patt_trans,cam_trans)<0)return;//可以得到摄像头在标识坐标中的位置(cam_trans[0][3],cam_trans[1][3],cam_trans[2][3])
if(arUtilMat2QuatPos(cam_trans,quat,pos)<0)return;//从变换矩阵cam_trans中提取一个旋转矩阵quat[4](四元数格式)和一个位置矩阵pos[3](向量格式)
printf("Cam Pos x: %3.1f y: %3.1f z:%3.1f\n",cam_trans[0][3], cam_trans[1][3],cam_trans[2][3]);//输出摄像头在标识坐标系中的位置
printf("Pos x: %3.1f y: %3.1f z:%3.1f\n",pos[0], pos[1], pos[2]); //输出从变换矩阵cam_trans中提取的位置矩阵pos[3](向量格式)
printf("Quat Pos x: %3.1f y: %3.1f z:%3.1f m:%3.1f\n",quat[0], quat[1], quat[2], quat[3]);//输出从变换矩阵cam_trans中提取的旋转矩阵quat[4](四元数格式)
mouse_event(MOUSEEVENTF_MOVE,pos[0],pos[1],0,0);//鼠标的位置根据(pos[0],pos[1])移动
argSwapBuffers();
}
//初始化
static void init( void )
{
ARParam wparam;
if( arVideoOpen( vconf ) < 0 ) exit(0);
if( arVideoInqSize(&xsize, &ysize) < 0 ) exit(0);
printf("Image size (x,y) = (%d,%d)\n", xsize, ysize);
if( arParamLoad(cparam_name, 1, &wparam) < 0 ) {
printf("Camera parameter load error !!\n");
exit(0);
}
arParamChangeSize( &wparam, xsize, ysize, &cparam );
arInitCparam( &cparam );
printf("*** Camera Parameter ***\n");
arParamDisp( &cparam );
if( (patt_id=arLoadPatt(patt_name)) < 0 ) {
printf("pattern load error !!\n");
exit(0);
}
argInit( &cparam, 1.0, 0, 0, 0, 0 );
}
//清除
static void cleanup(void)
{
arVideoCapStop();
arVideoClose();
argCleanup();
}
上述代码是在simpleTest.c的基础上加以改动,把绘制模型的代码去掉了。
函数1
通过arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans)获得摄像头的转移矩阵,而arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans)函数获得了标识卡的patt_center, patt_width, patt_trans这三个值分别是标识卡的中心,标识卡的宽度,转移矩阵
函数2
通过arUtilMatInv(patt_trans,cam_trans)函数获得摄像头在标识卡中的坐标,并且显示出来
函数3
通过arUtilMat2QuatPos(cam_trans,quat,pos)获得变换矩阵cam_trans中提取一个旋转矩阵quat[4](四元数格式)和一个位置矩阵pos[3](向量格式)
函数4
其中鼠标的位置移动就是根据pos[0],pos[1]来移动
void mouse_event(dwFlags,dx,dy,dwData,ULONG_PTR dwExtraInfo)函数是windows的API中控制鼠标移动的函数
其中第一个参数为代表所要模拟的鼠标消息,第二个参数表示鼠标的位置横坐标x,第三个参数表示鼠标的位置纵坐标y。第四和第五个参数并不重要,一般也可设为0,0.。在外面的代码中 本函数是mouse_event(MOUSEEVENTF_MOVE,pos[0],pos[1],0,0);
通过dx=pos[0],dy=pos[1]来进行变换