Artoolkit手札之鼠标定位

本博客在simpleTest.c的基础上加以改动,实现不绘制模型,仅获取一些参数来控制鼠标移动的功能。

windows API中的mouse_event函数可以控制鼠标操作,原型如下:
VOID mouse_event(
  DWORD dwFlags, //flags specifying various  motion and click options
  DWORD dx, // horizontal position or change
  DWORD dy, // vertical mouse position or position change
  DWORD dwData, //amount of wheel movement
  ULONG_PTR dwExtraInfo //32 bits of application-defined information
  );
其中,第一个参数为代表所要模拟的鼠标消息。一般取值如下
    MOUSEEVENTF_MOVE:移动鼠标。
  MOUSEEVENTF_LEFTDOWN:模拟鼠标左键按下。
  MOUSEEVENTF_LEFTUP:模拟松开鼠标左键。
  MOUSEEVENTF_RIGHTDOWN:模拟鼠标右键按下。
  MOUSEEVENTF_RIGHTUP:模拟松开鼠标右键。
  MOUSEEVENTF_MIDDLEDOWN:模拟鼠标中键按下。
  MOUSEEVENTF_MIDDLEUP:模拟松开鼠标中键。
  MOUSEEVENTF_WHEEL:在Windows NT中如果鼠标有一个轮,表明鼠标轮被移动。移动的数量由dwData给出。
第二个参数表示鼠标的位置横坐标x,第三个参数表示鼠标的位置纵坐标y。第四和第五个参数并不重要,一般也可设为0,0.

代码如下。

#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>

//
// Camera configuration.
//
#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[0][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;
	
    /* open the video path */
    if( arVideoOpen( vconf ) < 0 ) exit(0);
    /* find the size of the window */
    if( arVideoInqSize(&xsize, &ysize) < 0 ) exit(0);
    printf("Image size (x,y) = (%d,%d)\n", xsize, ysize);

    /* set the initial camera parameters */
    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();
}
其中arUtilMat2QuatPos()函数的原型可在Artoolkit工具包自带的doc/ar_8h.html文件中找到。

arUtilMat2QuatPos()函数的原型:

int arUtilMat2QuatPos(double  m[3][4],double  q[4],double  p[3])
说明:extract a quaternion/position of matrix.//提取矩阵的四元数/位置。
     //四元数在电脑图形学中用于表示物体的旋转,由x,y,z,w 四个值表示,取值范围是[-1,1]。
    //四元数是简单的超复数,是一个四维空间,相对于复数的二维空间。一般可表示为a + bk+ cj + di,其中a、b、c 、d是实数。
   //对于i、j、k本身的几何意义可以理解为一种旋转,其中i旋转代表X轴与Y轴相交平面中X轴正向向Y轴正向的旋转,
   //j旋转代表Z轴与X轴相交平面中Z轴正向向X轴正向的旋转,
   //k旋转代表Y轴与Z轴相交平面中Y轴正向向Z轴正向的旋转,-i、-j、-k分别代表i、j、k旋转的反向旋转。
   //要是想深入理解四元数,可以去看这个博客:http://blog.csdn.net/candycat1992/article/details/41254799
  Extract a rotation (quaternion format) and a position (vector format) from a transformation matrix. The           precondition is an euclidian matrix. //从变换矩阵中提取一个旋转矩阵(四元数格式)和一个位置矩阵(向量格式)。前提是欧几里德矩阵。
  Parameters:(参数)
  m source matrix//m为源矩阵
  q a rotation represented by a quaternion.//由四元数表示的旋转
  p a translation represented by a vector.//由一个向量表示的平移
  Returns:(结果)
  0 if the extraction success, -1 otherwise (quaternion not normalize)
  //如果提取成功则返回0,否则返回- 1(说明四元数不正常)
输出结果如下图所示。(鼠标一直在动,鼠标移动时的截图不好截,我就不贴了)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值