日记的ARTOOLKIT笔记(1):从流程开始看
来源:互联网 发布:手机gps增强软件 编辑:程序博客网 时间:2024/04/23 14:09
原创作者:黑白日记 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, inty);
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, inty)
{
//ESC键退出
if( key == 0x1b ) {
//这句……其实没啥用,输出的东西一般无人看,测试的时候可能会用到吧
printf("***%f (frame/sec)/n", (double)count/arUtilTimer());
cleanup(); //退出时清理使用过的内存等资源
exit(0);
}
}
//主循环
static voidmainLoop(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;
}
//计算出标识图案和摄像头之间的坐标变化,这里是关键之一哦~
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("Cameraparameter 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("patternload 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基础框架,大家要做的就是看懂它,然后会用它,最后修改它,让它变成你的东西,整个流程很简单,很容易就能看懂的。
- 日记的ARTOOLKIT笔记(1):从流程开始看
- 日记的ARTOOLKIT笔记(2):使用自己的MQO模型
- 萌新的看毛片(kmp)学习日记(下标从0开始)
- 对某软件公司开发流程改造的日记 1、开始
- IOS学习日记(1)从伟大的hello world开始
- 日记从今天开始
- gradle学习笔记(三)从源码看构建流程之基本流程
- 从Zygote的启动开始看代码
- ARToolkit学习笔记-msv70d.dll的问题
- 学习日记-thinkphp 页面table id从1开始效果
- 我的Qt学习笔记 1 从QObject开始
- 新的日记开始
- 日记的开始
- 日记的开始
- ARToolkit学习笔记-exe文件一闪而过l的问题
- 从hello world看struts框架的流程
- 从Scrum开发流程看卓有成效的管理者
- 从普通交换机的转发流程看Openflow交换机
- 图灵4月书讯【黑客与画家将在4月10日左右隆重上市】
- QQ2010登录协议分析-目前可取得sessionkey
- android java.net.ConnectException: Connection 127.0.0.1:8080 refused
- C++对象布局及多态实现
- Weblogic的Machine,Server,Domain,Cluster的关系
- 日记的ARTOOLKIT笔记(1):从流程开始看
- 六种异常处理的陋习
- powerdesigner 生成sql脚本[转]
- ISO七层模型
- 日记的ARTOOLKIT笔记(2):使用自己的MQO模型
- 空接合运算符 ??--- ?:--- int? C#中的可空类型
- 尘埃落定之后,接受压力,迎接挑战
- 图像的存储
- Oracle Bug: WARNING:Could not lower the asynch I/O limit to 224 for SQL direct I/O. It is set to -1