重点看:markers.dat 的解析原理

1.

int main(int argc, char** argv)
{
char glutGamemode[];
const char *cparam_name = "Data2/camera_para.dat";
char vconf[] = "";
const char markerConfigDataFilename[] = "Data2/markers.dat";

2.

    // Load marker(s).
newMarkers(markerConfigDataFilename, &markersNFT, &markersNFTCount);
if (!markersNFTCount) {
ARLOGe("Error loading markers from config. file '%s'.\n", markerConfigDataFilename);
cleanup();
exit(-);
}
ARLOGi("Marker count = %d\n", markersNFTCount);  //等于1

3.

    // Marker data has been loaded, so now load NFT data.
if (!loadNFTData()) {
ARLOGe("Error loading NFT data.\n");
cleanup();
exit(-);
}

newMarkers 到底是如何工作的呢?


# Number of markers

# Entries for each marker. Format is:
#
# Name of pattern file (relative to this file)
# Marker type (SINGLE)
# Marker width in millimetres (floating point number)
# Optional tokens:
# FILTER [x] Enable pose estimate filtering for the preceding marker
# x (optional) specifies the cutoff frequency. Default
# value is AR_FILTER_TRANS_MAT_CUTOFF_FREQ_DEFAULT, which
# at time of writing, equals 5.0.
# A blank line ../DataNFT/pinball
NFT
FILTER 15.0
 void newMarkers(const char *markersConfigDataFilePathC, ARMarkerNFT **markersNFT_out, int *markersNFTCount_out)
{
FILE *fp;
char buf[MAXPATHLEN], buf1[MAXPATHLEN];
int tempI;
ARMarkerNFT *markersNFT;
int markersNFTCount;
ARdouble tempF;
int i;
char markersConfigDataDirC[MAXPATHLEN];
size_t markersConfigDataDirCLen; if (!markersConfigDataFilePathC || markersConfigDataFilePathC[] == '\0' || !markersNFT_out || !markersNFTCount_out) return; // Load the marker data file.
ARLOGd("Opening marker config. data file from path '%s'.\n", markersConfigDataFilePathC);
arUtilGetDirectoryNameFromPath(markersConfigDataDirC, markersConfigDataFilePathC, MAXPATHLEN, ); // 1 = add '/' at end.
markersConfigDataDirCLen = strlen(markersConfigDataDirC);
if ((fp = fopen(markersConfigDataFilePathC, "r")) == NULL) {
ARLOGe("Error: unable to locate marker config data file '%s'.\n", markersConfigDataFilePathC);
return;
} // First line is number of markers to read.
get_buff(buf, MAXPATHLEN, fp, );
if (sscanf(buf, "%d", &tempI) != ) {
ARLOGe("Error in marker configuration data file; expected marker count.\n");
fclose(fp);
return;
} arMallocClear(markersNFT, ARMarkerNFT, tempI);
markersNFTCount = tempI; ARLOGd("Reading %d marker configuration(s).\n", markersNFTCount); 37 for (i = ; i < markersNFTCount; i++) { // Read marker file name.
if (!get_buff(buf, MAXPATHLEN, fp, )) {
ARLOGe("Error in marker configuration data file; expected marker name.\n");
break;
} // Read marker type.
if (!get_buff(buf1, MAXPATHLEN, fp, )) {
ARLOGe("Error in marker configuration data file; expected marker type.\n");
break;
} // Interpret marker type, and read more data.
if (strcmp(buf1, "SINGLE") == ) {
ARLOGe("Error in marker configuration data file; SINGLE markers not supported in this build.\n");
} else if (strcmp(buf1, "MULTI") == ) {
ARLOGe("Error in marker configuration data file; MULTI markers not supported in this build.\n");
} else if (strcmp(buf1, "NFT") == ) {
markersNFT[i].valid = markersNFT[i].validPrev = FALSE;
arMalloc(markersNFT[i].datasetPathname, char, markersConfigDataDirCLen + strlen(buf) + );
strcpy(markersNFT[i].datasetPathname, markersConfigDataDirC);
strcpy(markersNFT[i].datasetPathname + markersConfigDataDirCLen, buf);
markersNFT[i].pageNo = -;
} else {
ARLOGe("Error in marker configuration data file; unsupported marker type %s.\n", buf1);
} // Look for optional tokens. A blank line marks end of options.
while (get_buff(buf, MAXPATHLEN, fp, ) && (buf[] != '\0')) {
if (strncmp(buf, "FILTER", ) == ) {
markersNFT[i].filterCutoffFrequency  = AR_FILTER_TRANS_MAT_CUTOFF_FREQ_DEFAULT;
markersNFT[i].filterSampleRate     = AR_FILTER_TRANS_MAT_SAMPLE_RATE_DEFAULT;
if (strlen(buf) != ) {
if (sscanf(&buf[],
#ifdef ARDOUBLE_IS_FLOAT
"%f"
#else
"%lf"
#endif
, &tempF) == ) markersNFT[i].filterCutoffFrequency = tempF;
}
markersNFT[i].ftmi = arFilterTransMatInit(markersNFT[i].filterSampleRate, markersNFT[i].filterCutoffFrequency);
}
// Unknown tokens are ignored.
}
84 }
fclose(fp); // If not all markers were read, an error occurred.
if (i < markersNFTCount) { // Clean up.
for (; i >= ; i--) {
if (markersNFT[i].datasetPathname) free(markersNFT[i].datasetPathname);
if (markersNFT[i].ftmi) arFilterTransMatFinal(markersNFT[i].ftmi);
}
free(markersNFT); *markersNFTCount_out = ;
*markersNFT_out = NULL;
return;
} *markersNFTCount_out = markersNFTCount;
*markersNFT_out = markersNFT;
}
typedef struct _ARMarkerNFT {
// ARMarker protected
bool valid;
bool validPrev;
ARdouble trans[][];
ARPose pose;
ARdouble marker_width;
ARdouble marker_height;
// ARMarker private
ARFilterTransMatInfo *ftmi;  // 变换矩阵,为何使用链表的形式?
ARdouble filterCutoffFrequency;
ARdouble filterSampleRate;
// ARMarkerNFT
int pageNo;
char *datasetPathname;
} ARMarkerNFT;

loadNFTData 开始分析。


 // References globals: markersNFTCount
// Modifies globals: threadHandle, surfaceSet[], surfaceSetCount, markersNFT[]
static int loadNFTData(void)
{
int i;
KpmRefDataSet *refDataSet; // If data was already loaded, stop KPM tracking thread and unload previously loaded data.
if (threadHandle) {
ARLOGi("Reloading NFT data.\n");
unloadNFTData();
} else {
ARLOGi("Loading NFT data.\n");
} refDataSet = NULL; 18 for (i = ; i < markersNFTCount; i++) {  // 重点在这里!
// (1) Load KPM data.
KpmRefDataSet *refDataSet2;
ARLOGi("Reading %s.fset3\n", markersNFT[i].datasetPathname);
if (kpmLoadRefDataSet(markersNFT[i].datasetPathname, "fset3", &refDataSet2) < ) {
ARLOGe("Error reading KPM data from %s.fset3\n", markersNFT[i].datasetPathname);
markersNFT[i].pageNo = -;
continue;
}
markersNFT[i].pageNo = surfaceSetCount;
ARLOGi(" Assigned page no. %d.\n", surfaceSetCount);
if (kpmChangePageNoOfRefDataSet(refDataSet2, KpmChangePageNoAllPages, surfaceSetCount) < ) {
ARLOGe("Error: kpmChangePageNoOfRefDataSet\n");
exit(-);
}
if (kpmMergeRefDataSet(&refDataSet, &refDataSet2) < ) {
ARLOGe("Error: kpmMergeRefDataSet\n");
exit(-);
}
ARLOGi(" Done.\n"); // (2) Load AR2 data.
ARLOGi("Reading %s.fset\n", markersNFT[i].datasetPathname); if ((surfaceSet[surfaceSetCount] = ar2ReadSurfaceSet(markersNFT[i].datasetPathname, "fset", NULL)) == NULL ) {
ARLOGe("Error reading data from %s.fset\n", markersNFT[i].datasetPathname);
}
ARLOGi(" Done.\n"); surfaceSetCount++;
if (surfaceSetCount == PAGES_MAX) break;
49 }
if (kpmSetRefDataSet(kpmHandle, refDataSet) < ) {
ARLOGe("Error: kpmSetRefDataSet\n");
exit(-);
}
kpmDeleteRefDataSet(&refDataSet); // Start the KPM tracking thread.
threadHandle = trackingInitInit(kpmHandle);
if (!threadHandle) exit(-); ARLOGi("Loading of NFT data complete.\n");
return (TRUE);
}

需要找个multi marker的例子再继续分析。

[Artoolkit] Marker of nftSimple的更多相关文章

  1. [Artoolkit] Marker Training

    Link: Documentation About the Traditional Template Square Marker Limitations (重要) Traditional Templa ...

  2. 本人AI知识体系导航 - AI menu

    Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯   徐亦达老板 Dirichlet Process 学习 ...

  3. [Artoolkit] Framework Analysis of nftSimple

    What is nftSimple? Loads NFT dataset names from a configuration file. The example uses the “Pinball. ...

  4. [Artoolkit] Android Sample of nftSimple

    结合:[Artoolkit] ARToolKit's SDK Structure on Android 重难点:aRBaseLib/, nftSimple/, libcpufeatures.a aRB ...

  5. 【AR实验室】ARToolKit之制作自己的Marker/NFT

    0x00 - 前言 看过example后,就会想自己动动手,这里改改那里修修.我们先试着添加自己喜欢的marker/nft进行识别. 比如我做了一个法拉利的marker: 还有网上找了一个法拉利log ...

  6. [Artoolkit] kpmMatching & Tracking of nftSimple

    1. kpmMatching thread main() --> loadNFTData() --> trackingInitInit() --> In static void *t ...

  7. [Artoolkit] ARToolKit's SDK Structure on Android

    Most applications on Android are developed in Java, and Android provides a rich framework of classes ...

  8. 【AR实验室】ARToolKit之Example篇

    0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...

  9. 【AR实验室】ARToolKit之概述篇

    0x00 - 前言 我从去年就开始对AR(Augmented Reality)技术比较关注,但是去年AR行业一直处于偶尔发声的状态,丝毫没有其"异姓同名"的兄弟VR(Virtual ...

随机推荐

  1. CoordTools

    APPLICATION_VERSION="JTNDYXBwbGljYXRpb24lMjBuYW1lJTIwJTNEJTIwJTIyQ29vcmRUb29sc1BybyUyMiUyMHZlcn ...

  2. CSS属性级Hack

     CSS属性级Hack    color:red; /* 所有浏览器可识别*/   _color:red; /* 仅IE6 识别 */   *color:red; /* IE6.IE7 识别 */   ...

  3. 关于SS的一点笔记

    过年的时候抽了点时间了解了下ss的协议.整理了一点笔记,一直没有时间发.今天发一下,免得忘了. SS的结构本身比较简单,他的基本结构如下: ss通常分为client和server两部分 client是 ...

  4. Markdown 语法手册 - 完整版(上)

    https://blog.csdn.net/witnessai1/article/details/52551362 1. 斜体和粗体 代码: *斜体*或_斜体_ **粗体** ***加粗斜体*** ~ ...

  5. MUI DtPicker 显示自定义日期

    MUI地址:http://dev.dcloud.net.cn/mui/ 首先引入相关JS CSS脚本. HTML代码: <input class="dt flat" styl ...

  6. 技术分享:几种常见的JavaScript混淆和反混淆工具分析实战【转】

    信息安全常被描述成一场军备竞赛,白帽与黑帽,渗透测试者与黑客,善与恶,本文将聚焦这场永无止境决斗中的一个小点. HTML5 & JS 应用中充满着对输入进行验证/注入的问题,需要开发人员始终保 ...

  7. WPF如何为程序添加splashScreen(初始屏幕)

    一.考虑到大部分的splashscreen其实都只是一个图片,所以最简单的做法是,先导入一张图片,然后设置它的生成操作为“splash screen” 二.通过程序设置SplashScreen pub ...

  8. Recover database using backup controlfile until cancel

    http://searchoracle.techtarget.com/answer/Recover-database-using-backup-controlfile-until-cancel Wha ...

  9. LEAPMOTION开发UI专题(1)

    非常 抱歉的是,之前说的LEAP/UI框架设计可能仅仅有两篇 由于个人时间实在是不同意 这个问题假设展开去写的话 那么说写本书都是不为过的 且由于内容改动非常是杂乱 所以我第一篇文章用来介绍LEAP预 ...

  10. V-rep学习笔记:转动关节2

    Torque or force mode: in this mode, the joint is simulated by the dynamics module, if and only if it ...