ARToolKit 框架
ARToolKit 是基於opengl和DSVL的增強現實軟件包。它遵循opengl的運行模式,基於幀循環實現3D渲染。
主要流程:
1. 初始化視頻捕獲arVideoCapStart()、讀取文件的標記模式、相機參數 arVideoOpen(vconf)
2. 獲取一幀輸入視頻
3. 在輸入視頻圖像中 檢測標識和註冊的模板
4. 計算相機相對於檢測到模板的位置
5. 繪製虛擬模型到檢測的模板上
6. 關閉視頻捕獲arVideoCapStop()、arVideoClose(),回收資源argCleanup()
SimpleTest.c源碼
// simpleTest.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/param.h>
#include <AR/ar.h>
//攝像機默認參數
char *vconf = "Data\\WDM_camera_flipV.xml";
//攝像機特徵參數
char *cparam_name = "Data/camera_para.dat";
//標識信息
char *patt_name = "Data/patt.hiro";
int xsize, ysize;
int thresh = 100;
int count = 0;
ARParam cparam;
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)
{
//opengl初始化
glutInit(&argc, argv);
//初始化想次參數 和顯示窗口
init();
//啓動相機
arVideoCapStart();
//進入幀循環、並設定響應事件(參數均爲函數指針)
//argMainLoop()函數 有三個參數 分別是 mouseEvent keyEvent mainLoop
argMainLoop(NULL, keyEvent, mainLoop);
return (0);
}
static void keyEvent(unsigned char key, int x, int y)
{
if (key == 0x1b) {
printf("*** %f (frame/sec)\n", (double)count / arUtilTimer());
cleanup();
exit(0);
}
}
/* main loop */
static void mainLoop(void)
{
ARUint8 *dataPtr;
ARMarkerInfo *marker_info; //標誌信息struct
int marker_num;
int j, k;
//獲取一幀圖像
if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL) {
//調用延遲
arUtilSleep(2);
return;
}
if (count == 0) arUtilTimerReset();
count++;
//爲了渲染2d 更新當前相機參數
argDrawMode2D();
argDispImage(dataPtr, 0, 0);
//檢測標識
/*
arDetectMarker()的參數分別是
dataPtr 幀數據
thresh 二值化閾值
marker_info 標識特徵信息
marker_num 標識數量
*/
if (arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0) {
cleanup();
exit(0);
}
//每一幀都要調用,支持諸多功能的完成
arVideoCapNext();
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;
//打開相機參數文件
arVideoOpen(vconf);
//獲取視頻窗口大小
arVideoInqSize(&xsize, &ysize);
//設置相機特徵參數
arParamLoad(cparam_name, 1, &wparam);
arParamChangeSize(&wparam, xsize, ysize, &cparam);
//初始化相機
arInitCparam(&cparam);
arParamDisp(&cparam);
//讀取多個標識 的定義文件
patt_id = arLoadPatt(patt_name);
//打開圖像窗口
argInit(&cparam, 1.0, 0, 0, 0, 0);
}
//cleanup
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 };
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);
glTranslatef(0.0, 0.0, 25.0);
glutSolidCube(50.0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
}