本博客在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(说明四元数不正常)
输出结果如下图所示。(鼠标一直在动,鼠标移动时的截图不好截,我就不贴了)