#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef __APPLE__
#include <GL/gl.h>
#define GLUT_DISABLE_ATEXIT_HACK
#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; // 窗口 XY 尺寸
int thresh = 100; // 这个参数与摄像头检测标识图部分有关,二值化闸值
int count = 0; // 计数器,记录帧数的,后面有专门处理帧的部分
char *cparam_name = "Data/camera_para.dat"; // 摄像机特征参数
ARParam cparam;
char *patt_name = "Data/patt.yourpat"; // 标识图
int patt_id;
// 标记的大小,下面这3个都是记录标识图几何外形的,在坐标变换时用
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 keyEvent( unsigned char key, int x, int y);
static void mainLoop(void);
static void draw( void );
// 程序入口
int main(int argc, char **argv)
{
// 初始化OpenGL
glutInit(&argc, argv);
// 初始化摄像机参数和显示窗口
init();
// 启动摄像机
arVideoCapStart();
// 注册响应事件函数(分别是鼠标事件,键盘事件,帧循环)
argMainLoop( NULL, keyEvent, mainLoop );
return (0);
}
// 键盘事件响应函数
static void keyEvent( unsigned char key, int x, int y)
{
/* 点击ESC退出 */
if( key == 0x1b ) {
printf("*** %f (frame/sec)\n", (double)count/arUtilTimer());
cleanup(); // 释放资源,退出时清理使用过的内存等资源
exit(0);
}
}
/* 主循环:完成标识物的检测和位置的重定位,并渲染模型 */
static void mainLoop(void)
{
ARUint8 *dataPtr; // 图像数据
ARMarkerInfo *marker_info; // 标志信息
int marker_num; // 寻找到的标记号码
int j, k;
/* 捕捉一个输入视频帧 */
if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
arUtilSleep(2); // 调用延时,如果2毫秒内没有获取图像则程序返回
return;
}
// 定时器复位
if( count == 0 ) arUtilTimerReset();
count++; // 帧数+1
// 渲染前更新摄像头参数,主要是为渲染 2D 或 3D 对象做准备的
argDrawMode2D();
argDispImage( dataPtr, 0,0 );
// 在摄像头画面中检测标记图案,如果出错,程序退出
// 参数说明: dataPtr 帧数据,thresh 二值化闸值,&marker_info 标识特征信息
// &marker_num 标识数量
if( arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
cleanup();
exit(0);
}
// 获取下一帧图像
arVideoCapNext();
// 下面这部分是寻找标记图案的
k = -1; // 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);
printf("%f%f%f\n",patt_trans[0][3],patt_trans[1][3],patt_trans[2][3]);
draw(); // 绘图
argSwapBuffers(); // 屏幕缓冲
}
// 初始化函数
static void init( void )
{
ARParam wparam;
/* 打开视频通道,vconf包含初始视频的配置,在顶部被定义 */
if( arVideoOpen( vconf ) < 0 ) exit(0);
/* 获取视频图像大小,以像素为单位 */
if( arVideoInqSize(&xsize, &ysize) < 0 ) exit(0);
printf("Image size (x,y) = (%d,%d)\n", xsize, ysize);
/* 设置初始相机参数,cparam_name包含摄像机参数 */
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);
}
/* 打开图像窗口,第二个参数为缩放值,适应视频图像格式的值设为1.0,设为2.0时是双倍大小 */
argInit( &cparam, 1.0, 0, 0, 0, 0 );
}
/* 当退出程序时回收资源 */
static void cleanup(void)
{
/* 停止视频处理 */
arVideoCapStop();
/* 关闭视频路径 */
arVideoClose();
/* 清理以及回收资源 */
argCleanup();
}
// 绘制3D模型,这部分完全属于OpenGL的内容
static void draw( void )
{
double gl_para[16];
GLfloat mat_ambient[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash_shiny[] = {50.0};
GLfloat light_position[] = {100.0,-200.0,200.0,0.0};
GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1};
GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1};
// 3D绘图模式
argDrawMode3D(); //切换为3D渲染模式的渲染视图。
argDraw3dCamera( 0, 0 );
glClearDepth( 1.0 );//深度缓存,1.0是最大深度,整个物体都被显示
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);// 目标像素与当前像素在z方向上值大小比较,
// GL_LEQUAL:如果目标像素z值<=当前像素z值,则绘制目标像素
/* 加载摄像机转换矩阵 */
argConvGlpara(patt_trans, gl_para);//简将ARToolKit矩阵格式转换为openGL矩阵格式。
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd( gl_para );
// 灯光部分
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMatrixMode(GL_MODELVIEW);
glTranslatef( 0.0, 0.0, 25.0 );
glutSolidCube(50.0); // 绘制一个50的正方体
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
}
【学习ARTookit】——SimpleTest详解
最新推荐文章于 2024-09-15 07:17:38 发布