学习ARToolkit已经快一个月了,刚刚接触时只是按照官网教程中的步骤一步一步的学习,其中遇到了许多问题,如OpenGL在64位Win7下的配置问题、ARtoolkit在64位Win7下的配置问题、如何使用VS2010创建一个自己的ARToolkit项目问题及创建过程中的出错问题等等。学习的过程中也从网上搜索的大量的论坛资料,可是大都说的比较含糊,没有一个比较系统的总结,也许大家是在同样的问题过程中不断摸索,找到了解决方案却又忘记了总结,或者只是仅仅在解决的过程中全部记录在脑子里。可是会遇到一个问题,那是已经解决的问题,可能过了几天就会把解决方案给忘的一干二净或者很模糊(总是我是这样的,可能和本人智商和记忆力有关吧,而且悲剧的是在我电脑瘫痪之后又不能不重新设置时才发现又得从头开始),好记忆不如烂笔头,也许会多话费半个小时甚至是一个小时的时间,可是总结的东西白纸黑字的放在那里永远都不会变,需要时可以直接拿来,是多么爽的一件事情。
这次应该属于终极总结,因为自己电脑瘫痪的事情,从头再来,痛定思痛,必须的这样,以后如果再次瘫痪即可安装本次总结一步一步直接实现。
好了,废话不多说了,又多“浪费”了十分钟,下面就是关于ARToolkit入门级总结,希望能够在总结中不断进步,同时也可以给大家学习和参考。首先贴出来的是内容的纲要,大家可以自主选择需要的部分。
如需转载请注明出处:
文章链接:http://blog.csdn.net/qingyang8513/article/details/45577721
作者:Qingyang8513
微博:http://blog.csdn.net/qingyang8513
纲要或者目录:
1、运行环境:Windows7(64位)+ ARToolKit-2.72.1 + VS2010(注意和自己的环境作比较)
2、资源的下载:OpenGL + ARtoolkit
3、OpenGL的安装与配置(ARToolkit配置前提)
4、ARtoolkit安装与配置
5、创建自己的ARToolkit工程
6、可能会遇到的问题
7、重要参考和链接
1、操作系统:Windows 7 (64位)
2、开发环境:Visual Studio 2010
3、ARToolkit版本:ARToolKit-2.72.1
4、OpenGL
5、摄像头:笔记本内置摄像头 / Basler工业摄像机
下载链接一:http://download.csdn.net/detail/qingyang8513/8613957(推荐链接,比较全面)
下载链接二:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip(glut下载),https://sourceforge.net/projects/glew/files/glew/1.7.0/glew-1.7.0.zip/download(glew下载)
下载链接:http://www.hitl.washington.edu/artoolkit/download/(或者直接http://sourceforge.net/projects/artoolkit/files/artoolkit/2.72.1/ARToolKit-2.72.1-bin-win32.zip/download)
下在链接:http://download.csdn.net/detail/qingyang8513/8613957(和上面OpenGL下载链接一相同,也可以自己在网上搜索)
1)将下载下来的OpenGL库解压到文件夹,拷贝文件夹中的.h文件到Visual C++ 6.0/Microsoft Visual Studio 10.0\VC的\Include\GL目录中(此处自己建立文件夹GL);
2)将.lib文件拷贝到Visual C++ 6.0/Microsoft Visual Studio 10.0\VC的\lib目录中去;
3)将.dll文件拷贝到操作系统的C:\Windows\system32目录中,如果是windows7 64位操作系统需要拷贝到C:\Windows\SysWOW64目录中去。
1)使用VS2010创建一个32位控制台程序;
2)“项目——项目属性——配置属性——C/C++— —预处理器——预处理器定义”,添加“GLUT_BUILDING_LIB”;
3)“项目——项目属性——配置属性——链接器——输入——附加依赖项”,添加“glut32.lib Opengl32.lib Glu32.lib glew32.lib”(由于没有glew32.lib文件,此处可以不添加);
1)使用VS2010创建一个32位控制台程序,名称处任意命名,假定是helloworld;
2)复制下面的代码到.cpp文件;
// OpenGL_Test1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <GL\glut.h> //#include <GL\GLU.h>//glut.h自动包含了glu.h 和 gl.h //#include <GL\gl.h> void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glBegin(GL_TRIANGLES); glVertex3f(-0.5,-0.5,0.0); glVertex3f(0.5,0.0,0.0); glVertex3f(0.0,0.5,0.0); glEnd(); glutSwapBuffers(); } int _tmain(int argc, _TCHAR* argv[]) { glutInit(&argc, (char**) argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(320,320); glutCreateWindow("Hello OpenGL"); glutDisplayFunc(renderScene); glutMainLoop();//enters the GLUT event processing loop. return 0; }
图1 OpenGL测试结果
参考:【学习OpenGL小记之一】 OpenGL开发环境配置(http://blog.csdn.net/qingyang8513/article/details/45565431)
1、解压ARToolKit-2.72.1-bin-win32.zip到目标文件夹(自己定义),直接解压到当前文件夹即可,如D:\Program Files,此时文件夹为{ARToolKit};
2、把第一个DSVL-0.0.8b.zip解压放在刚才解压的ARToolKit文件夹下,将DSVL\bin文件夹下的DSVL.dll和 DSVLd.dll放到ARToolKit\bin下
3、将OpenVRML解压后文件夹剪切至ARToolKit文件夹中,将ARToolKit\OpenVRML\bin\js32.dll复制,放进{ARToolKit}\bin里面去
4、复制 msvcp71d.dll、msvcr71d.dll到文件夹ARToolKit\bin
5、双击鼠标左键执行 ARToolKit\Configure.win32.bat 文件。
6、ARToolkit文件夹下的include和lib文件夹中的内容分别拷至Microsoft Visual Studio 10.0\VC下对应的文件夹
(如我的路径为:C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC)
7、把ARToolKit\bin下的DSVL.dll, DSVLd.dll,libARvideo.dll,libARvideod.dll复制放在C:\Windows\SysWOW64下,(如果此路径下没有msvcp71d.dll和msvpr71.dll那么需要下载一个然后放入该路径),如果是32位系统则目标文件夹为C:\Windows\System32。
8、双击{ARToolKit}目录下的ARToolKit.sln,转换版本;
9、点击生成-批生成,然后在{ARToolKit}\lib文件夹下面会生成一些lib文件,这一步必须先执行。否则直接运行包含ARToolkit的项目会出现无法解析外部符号的错误。
10、运行测试程序D:\Program Files\ARToolKit\bin\graphicsTest.exe,出现旋转茶壶如下图2所示:
图2 ARToolkit测试一
主要参考:
1)【学习ARToolkit小记之一】 ARToolkit配置设置,解决64位操作系统运行sln生成错误:(http://blog.csdn.net/qingyang8513/article/details/45192677)
2)vs2010配置ARToolkit:(http://m.blog.csdn.net/blog/dragonly945707194/34932271)
3)官网Setting up ARToolKit:(http://www.hitl.washington.edu/artoolkit/documentation/usersetup.htm)
1、打开Microsoft Visual Studio 2010,创建一个32位控制台程序;
2、输入项目名称,如这里我用的ARFirstApplication,选择项目目录,点击确定;
3、选择默认设置,完成项目创建;
4、打开ARToolKit\examples\simple\simpleTest.c文件,将全部代码复制到自己创建的项目的资源文件里,这里我的是ARFirstApplication.cpp;
代码如下:
// ARFirstApplication.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #ifdef _WIN32 #include <windows.h> #endif #include <stdio.h> #include <stdlib.h> #include <iostream> #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> using namespace std; // // 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.myren"; 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 keyEvent( unsigned char key, int x, int y); static void mainLoop(void); static void draw( void ); int main(int argc, char **argv) { glutInit(&argc, argv); init(); arVideoCapStart(); argMainLoop( NULL, keyEvent, mainLoop ); //system("pause"); return (0); } static void keyEvent( unsigned char key, int x, int y) { /* quit if the ESC key is pressed */ if( key == 0x1b ) { printf("*** %f (frame/sec)\n", (double)count/arUtilTimer()); cleanup(); exit(0); } } /* main loop */ static void mainLoop(void) { ARUint8 *dataPtr; // 图像数据,unsigned char类型 ARMarkerInfo *marker_info; // 标记块信息,结构体类型:面积、id、方向dir、自信度、中心点位置、四边的直线方程、顶点坐标4个 int marker_num; // 标记块序号 int j, k; /* grab a vide frame */ // 从摄像头获取图像数据,如果未获取图像,则2ms后返回 if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) { arUtilSleep(2); return; } if( count == 0 ) arUtilTimerReset();// 启动程序时,复位定时器 count++; // 获取图像后,计数器加一 argDrawMode2D(); // 更新摄像头参数,为渲染2D和3D对象做准备 argDispImage( dataPtr, 0,0 ); // 显示图像 /* detect the markers in the video frame */ // 在摄像头输入帧中识别标记块,过程:阈值化、标记分类、轮廓提取、线角点估计。成功返回0,否则返回-1。 if( arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 ) { cleanup(); exit(0); } arVideoCapNext(); // 获取下一帧图像 /* check for object visibility */ // 寻找可识别的标记块,按照可信度大小选择可信度最大的一个,如果没有找到则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; } /* get the transformation between the marker and the real camera */ arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans); // 获取摄像机和标记块之间的坐标变换,其中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; /* 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); } /* open the graphics window */ argInit( &cparam, 1.0, 0, 0, 0, 0 ); } /* cleanup function called when program exits */ static void cleanup(void) { arVideoCapStop(); arVideoClose(); argCleanup(); } 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}; argDrawMode3D(); // 更新摄像头参数用于3D渲染 argDraw3dCamera( 0, 0 ); // 对argDrawMode3D()的补充 glClearDepth( 1.0 ); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); /* load the camera transformation matrix */ 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 ); glutSolidCube(50.0);//绘制一个边长为50的正方体 glDisable( GL_LIGHTING ); glDisable( GL_DEPTH_TEST ); }
5、点击“生成 --- 生成解决方案”,发现程序报错,详细错误如下:
1>------ 已启动生成: 项目: ARFirstApplication, 配置: Debug Win32 ------ 1>生成启动时间为 2015/5/8 10:23:22。 1>InitializeBuildStatus: 1> 正在对“Debug\ARFirstApplication.unsuccessfulbuild”执行 Touch 任务。 1>ClCompile: 1> 所有输出均为最新。 1> 所有输出均为最新。 1>ManifestResourceCompile: 1> 所有输出均为最新。 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argMainLoop,该符号在函数 _main 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoCapStart,该符号在函数 _main 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arUtilTimer,该符号在函数 "void __cdecl keyEvent(unsigned char,int,int)" (?keyEvent@@YAXEHH@Z) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arGetTransMat,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argSwapBuffers,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoCapNext,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arDetectMarker,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argDispImage,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argDrawMode2D,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arUtilTimerReset,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arUtilSleep,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoGetImage,该符号在函数 "void __cdecl mainLoop(void)" (?mainLoop@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argInit,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arLoadPatt,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arParamDisp,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arInitCparam,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arParamChangeSize,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _arParamLoad,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoInqSize,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoOpen,该符号在函数 "void __cdecl init(void)" (?init@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argCleanup,该符号在函数 "void __cdecl cleanup(void)" (?cleanup@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoClose,该符号在函数 "void __cdecl cleanup(void)" (?cleanup@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 __imp__arVideoCapStop,该符号在函数 "void __cdecl cleanup(void)" (?cleanup@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argConvGlpara,该符号在函数 "void __cdecl draw(void)" (?draw@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argDraw3dCamera,该符号在函数 "void __cdecl draw(void)" (?draw@@YAXXZ) 中被引用 1>ARFirstApplication.obj : error LNK2019: 无法解析的外部符号 _argDrawMode3D,该符号在函数 "void __cdecl draw(void)" (?draw@@YAXXZ) 中被引用 1>G:\Learning\ARToolkit Learning\ARFirstApplication\Debug\ARFirstApplication.exe : fatal error LNK1120: 26 个无法解析的外部命令 1> 1>生成失败。 1> 1>已用时间 00:00:00.51 ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
a)将ARToolKit文件夹下lib文件夹拷贝到工程文件夹下的源文件夹中(即cpp所在文件夹);
b)同样的方法将ARToolKit\bin文件夹下的Data和Wrl两个文件夹也拷贝到工程文件夹下的源文件夹中;
c)VS2010设置:解决方视图中,右键点击工程,选择属性,弹出工程属性页,在“配置属性 --- 连接器 --- 常规 --- 附加库目录”,添加lib文件夹目录;
d)VS2010设置:解决方视图中,右键点击工程,选择属性,弹出工程属性页,在“配置属性 --- 连接器 --- 输入 --- 附加依赖项”,将lib文件夹中的后缀为.lib的文件添加上去,注意以"d"结尾的全部放在前面,而没有“d”结尾的统一放在后面
6、重新点击“生成 --- 生成解决方案”,此时已经显示生成成功,显示如下:
1>FinalizeBuildStatus: 1> 正在删除文件“Debug\ARFirstApplication.unsuccessfulbuild”。 1> 正在对“Debug\ARFirstApplication.lastbuildstate”执行 Touch 任务。 1> 1>生成成功。 1> 1>已用时间 00:00:07.16 ========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========
运行成功后效果图如图3所示:
图3 simpleTest测试效果图
重要参考:
1)【学习ARToolkit小记之五】 解决“error LNK2019: 无法解析的外部符号 ___glutCreateWindowWithExit@8”错误:(http://blog.csdn.net/qingyang8513/article/details/45339445)
2)【学习ARToolkit小记之六】 开发第一个ARToolkit程序(Developing your First Application):(http://blog.csdn.net/qingyang8513/article/details/45346087)
3)artoolkit 在vs2008(win7 64位)编译。。。:(http://www.artoolkit.net/viewthread.php?tid=3777&extra=page%3D9)
解决方法:OpenGL安装与配置中忘记在配置VS2010时将lib文件添加到附加依赖项(项目——项目属性——配置属性——链接器——输入——附加依赖项)
解决方法:针对64位系统dll文件添加位置错误,应该添加到C:\Windows\SysWOW64目录,而非C:\Windows\system32。建议OpenGL和ARtoolkit的所有dll在64位系统的情况下两个目录都添加一份。
解决方案:记事本打开D:\Program Files\ARToolKit\bin\Data\WDM_camera_flipV.xml,修改friendly_name="Integrated Camera"(使用笔记本内置摄像头,否则请参考下面链接)
参考:【学习ARToolkit小记之二】 videoTest.exe/simpleTest.exe运行出错停止的解决方法(http://blog.csdn.net/qingyang8513/article/details/45195933)
解决方案:请参考【学习ARToolkit小记之五】 解决“error LNK2019: 无法解析的外部符号 ___glutCreateWindowWithExit@8”错误:(http://blog.csdn.net/qingyang8513/article/details/45339445)
1、【学习OpenGL小记之一】 OpenGL开发环境配置(http://blog.csdn.net/qingyang8513/article/details/45565431)
2、【学习ARToolkit小记之一】 ARToolkit配置设置,解决64位操作系统运行sln生成错误:(http://blog.csdn.net/qingyang8513/article/details/45192677)
3、【学习ARToolkit小记之二】 videoTest.exe/simpleTest.exe运行出错停止的解决方法(http://blog.csdn.net/qingyang8513/article/details/45195933)
4)【学习ARToolkit小记之五】 解决“error LNK2019: 无法解析的外部符号 ___glutCreateWindowWithExit@8”错误:(http://blog.csdn.net/qingyang8513/article/details/45339445)
5、【学习ARToolkit小记之六】 开发第一个ARToolkit程序(Developing your First Application):(http://blog.csdn.net/qingyang8513/article/details/45346087)
6、vs2010配置ARToolkit:(http://m.blog.csdn.net/blog/dragonly945707194/34932271)
7、官网Setting up ARToolKit:(http://www.hitl.washington.edu/artoolkit/documentation/usersetup.htm)
8、artoolkit 在vs2008(win7 64位)编译。。。:(http://www.artoolkit.net/viewthread.php?tid=3777&extra=page%3D9)
自己也是一个初学者,接触ARToolkit一个月时间,和长期从事这方面研究的大牛们,上面的总结可能毛毛雨而已,不足乐道,可是对于同样是初学者的来说可能会起到一个借鉴和快速入手的功能。
上面的总结可能还会有一些问题,希望资深的大牛给指正批评,遇到的问题可能每个人都不一样,希望同样遇到问题的你选择性参考,如有意见和建议或者更好的方法请在后面留言,共同学习。