转载自:http://www.arjishu.com/forum.php?mod=viewthread&tid=5221
前提: 从今天起就要进入分析源码的世界,之所以选择SimpleLite.c, 是因为它是一个描述了ARToolKit的完整过程的控制台应用程序, 因此通过它, 我们能够初步窥探ARToolKit的大门
SimpleLite.c的框架
:
1 读取摄像头和模板参数,完成视频捕获前的初始化工作
2 读取视频
2.1 在每一帧中, 识别出标志物
2.2 计算标志物到摄像头的方位
2.3 渲染该方位下模型
2.4 配准模型到标志物上
3 关闭摄像头
框架下每一模块的源码分析
:
以上框架对应着main函数中的每一部分
具体分析如下
:
首先,在了解相关的头文件之前,先搞清楚什么是外部依赖项:
外部依赖项: 就是被你调用过 但没有被直接 添加到工程的资源
首先是头文件
:
#include <GL/glut.h> :GLUT是专为构建中小型OpenGL程序, 它是OpenGL的应用工具包
config.h: 该文件主要是 定义一些宏定义或版本
video.h: 提供了多平台的视频支持库(子程序), windows下 主要是Microsoft DirectShow (之前使用的VFM弃用了)。该库主要提供了两套处理方法:
1 只有一路视频流 arVideo 2 对于两路视频流 ar2Video
arVideo可以将当前视频流作为全局变量, 且可以内部调用ar2Video方法
param.h: 一个全局结构(参数)子程序, 它主要完成的是对加载、保存、修改摄像机参数。
ar.h(重要):它是ARToolKit的一个库, 提供了图像分析和标记物检测的程序。 包括:1 摄像机参数和标记模板的配置。2处理标记的信息结构。3 传递 摄像机相对于标记物的3D位置
gsub_lite.h : 主要是一些有用的OpenGl的程序的集合, 它是SimpleLite.c这个样本中的一个例子.
它的功能主要包含了:绘制摄像机视频, 优化纹理机。 设置OpenGl观看视角的画面, 以及一些位置参数
它不依赖与任何任何系统的窗体或消除处理机制
1
初始化部分
:
这一部分, 包含一些全局变量和main函数中的初始化工作
(
对于全局变量,在了解了整个程序的运行机制后,再详细研究
)
main函数中的初始化:
char glutGamemode[32]: [url=]//目前还不知道是什么意思[/url]
const char *cparam_name://摄像机参数, 是从标定的结果中得来的。
摄像机配置参数:
char *vconf: 这个是用xml文件定义的,目前对于xml文件不是很熟悉
const char *patt_name: 模板文件
2
方法函数
:
1
glutInit(&argc, argv)
;
这是lib文件中的一个函数, 是完成窗口创建的初始化工作
强调的一点是: 所有的openGL函数都有glut作为开头,且这些函数大多都需要初始化工作,
因此在使用它们之前需要调用该函数:
argc: 一个指针, 指向从main()函数传递过来的没更改的argc变量
argv: 一个指针, 指向从main()函数传递过来的没更改的argv变量
注: 由于ARToolKit是直接使用opengl的, 因此在这里就不着重去研究和分析该函数了
2 硬件搭建
1 setupCamera(cparam_name, vconf, &gARTCparam)
该函数是本控制台应用程序的一个子方法
功能:完成的是摄像机采集的一些初始化工作
其中包括
1 视频打开,arVideoOpen(char *config)
[url=]//videoWin32DirectShow.cpp中定义的[/url]
它又调用了
ar2VideoOpen
这个函数, 从这个函数可以看出, 它返回的是一个
AR2VideoParamT
类(它在一个工程中是一个全局变量, 一旦获取就会一直在), 该类有一个方法
BuildGraphFromXMLStrin
g能够将 xml转为相应
图形(窗体)
注: 这一步的功能主要是, 初始化采集的工作: 主要包括 摄像头打开,分配内存空间,
创建采集界面 因此,如果要更换的话, 自己写的函数主要应该包含这些功能(用Directshow开发是比较好的)
2 获取窗口大小,
arParamLoad(cparam_name, 1, &wparam)
主要是通过
ar2VideoInqSize(gVid, x, y)获取 视频帧的宽和高, 其中gVid的类型就是那个全局变量AR2VideoParamT。 所以这里的宽和高还是跟那个
xml文件有关。
3 加载摄像机参数, 重新分配窗口大小和初始化
arParamLoad(cparam_name, 1, &wparam)
: 主要是外部依赖项的
paramFile.c
中定义的
它主要完成的是 打开一个文件并读取的功能。 即从第一个参数中读取文件,并保存到第三个参数中
注: 第三个参数的类型为,
ARParam, 它主要是一个结构体文件, 摄像机参数是一个3*3矩阵(内参), 其中 (1,3)和(2,3)为摄像头的分辨率
4
arParamChangeSize 将摄像头分辨率调整到窗口的分辨率
5
arInitCparam(cparam); 主要是将摄像机参数的值传递给一个全局变量
6
arVideoCapStart() , 通过ar2VideoCapStart(AR2VideoParamT *vid)来实现, 而vid就是通过读xml文件获取的, 然后它里面有一个 graphManager类 中的run方法 来实现采集启动
小结: 通过以上分析可得: 1-6步实际上是完成从打开摄像头到采集的过程, 这个是基于windows的Direcshow来实现的。 这个例子能够选择的窗体大小都是固定的。
你会发现,窗体大小, 早在第1步变决定好了,即通过读配置文件得到的。 如果想自己定义窗口大小可以修改这一步,即修改
BuildGraphFromXMLStrin
g函数或xml文件。
由于1-6步都与
AR2VideoParamT
类即vid有密不可分的关系,所以如果想不用xml, 也可以自己用directshow写一个采集程序 或者 避免使用xml文件(具体研究AR2VideoParamT的实现)