日记的ARTOOLKIT笔记(1):从流程开始看

原创作者:黑白日记 http://artoolkit.net/viewthread.php?tid=3597&extra=page=1

请尊重我的劳动,码字真的很消耗时间和精力

     不知道会坚持多久,希望我能有时间把我所会的全部都写出来吧,也希望能对大家有点点帮助。
     话说,如果只是翻译下注释,那我写跟不写都没什么意义了,但是我的水平还很有限,也没怎么写过教程,我也只能是从翻译注释入手,不过嘛 ~ 我会努力的去解释所有看到的东西,从整体出发,一直分析的每一个算法,每一个参数上,力求刨根问底。
     这篇文章算是个 ARTOOLKIT 编程的基础入门教程吧,不多啰嗦,看正文吧。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

首先,我假定你已经配置好ARTOOLKIT ,自己也跟着其它教程调试过某些例子程序了。那么你可以打开 “ARToolKit/examples/simple” 下的 “simpleTest.c” 文件,我将通过这个程序的流程来入门,以后的所有修改等操作也将以此程序为框架。

我用的是C++ 2005 ,当然你也可以使用别的版本,建议 2003 以上的版本

代码:
//头文件部分
#ifdef _WIN32
#include <windows.h>   //WINDOWS的头文件
#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>    //OpenGL实用库
#endif
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/param.h>
#include <AR/ar.h>
//头文件部分没啥可说的, 1 WINDOWS 的头文件, OPENGL 的实用库, AR 4 个头文件
// 摄像头设置


#ifdef _WIN32
//这里 *vconf 保存了摄像头配置文件, XML 中记录了设想头的 ID 等信息,如果你有多个摄像头,那就需要对它多了解一些了 ~
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.hiro"; //标识图
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 );

//主函数:每一个 C++ 程序都应该有一个主函数(模块除外)
int main(int argc, char **argv)
{
    glutInit(&argc, argv);    //初始化 OpenGL
    init();                         //基本参数初始化
    arVideoCapStart();       //摄像头开始工作
    argMainLoop( NULL, keyEvent, mainLoop );   //主循环
return (0);             //返回 0 ,必写,想知道为什么的话去看 C++ Primer 第四版
}



//键盘检测
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);
    draw();    //渲染模型
    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();      //清理以及回收资源,真的别指望WINDOWS会自动帮你释放资源
}

//绘制渲染部分,基于OpenGL框架,这部分我就不细说了,OpennGL的教程到处都是,
//我只写写跟AR有关的,想要多了解下OpenGL的东西就自己去看教程吧。
//推荐教程地址:
//  http://topic.csdn.net/u/20090817/13/13985888-b9d7-42f4-842d-c86abb0721a8.html

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();
    argDraw3dCamera( 0, 0 );
    glClearDepth( 1.0 );
    glClear(GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
   
    //加载摄像头变换矩阵
    argConvGlpara(patt_trans, gl_para);
    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);

    //模型的坐标(x,y,z)
    //想使用自己的模型,或者修改坐标,那就要操作下面这两个函数了~~
    glTranslatef( 0.0, 0.0, 25.0 );
    glutSolidCube(50.0);   //绘制一个50的正方体
    glDisable( GL_LIGHTING );
    glDisable( GL_DEPTH_TEST );
}


     这就是最简单的ARTOOLKIT基础框架,大家要做的就是看懂它,然后会用它,最后修改它,让它变成你的东西,整个流程很简单,很容易就能看懂的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值