[Artoolkit] Marker of nftSimple
重点看: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的更多相关文章
- [Artoolkit] Marker Training
Link: Documentation About the Traditional Template Square Marker Limitations (重要) Traditional Templa ...
- 本人AI知识体系导航 - AI menu
Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯 徐亦达老板 Dirichlet Process 学习 ...
- [Artoolkit] Framework Analysis of nftSimple
What is nftSimple? Loads NFT dataset names from a configuration file. The example uses the “Pinball. ...
- [Artoolkit] Android Sample of nftSimple
结合:[Artoolkit] ARToolKit's SDK Structure on Android 重难点:aRBaseLib/, nftSimple/, libcpufeatures.a aRB ...
- 【AR实验室】ARToolKit之制作自己的Marker/NFT
0x00 - 前言 看过example后,就会想自己动动手,这里改改那里修修.我们先试着添加自己喜欢的marker/nft进行识别. 比如我做了一个法拉利的marker: 还有网上找了一个法拉利log ...
- [Artoolkit] kpmMatching & Tracking of nftSimple
1. kpmMatching thread main() --> loadNFTData() --> trackingInitInit() --> In static void *t ...
- [Artoolkit] ARToolKit's SDK Structure on Android
Most applications on Android are developed in Java, and Android provides a rich framework of classes ...
- 【AR实验室】ARToolKit之Example篇
0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...
- 【AR实验室】ARToolKit之概述篇
0x00 - 前言 我从去年就开始对AR(Augmented Reality)技术比较关注,但是去年AR行业一直处于偶尔发声的状态,丝毫没有其"异姓同名"的兄弟VR(Virtual ...
随机推荐
- spring boot + embed tomcat + standalone jar的内存泄露问题
前一阵遇到了一个很坑的内存泄露问题,记录于此: 有个项目采用spring cloud重构后,部署到线上(其中有一个接口,大概每天调用量在1千万次左右),发现zabbix监控里,linux的可用内存一直 ...
- 在windows下安装git中文版客户端并连接gitlab
下载git Windows客户端 git客户端下载地址:https://git-scm.com/downloads 我这里下载的是Git-2.14.0-64-bit.exe版本 下载TortoiseG ...
- CentOS 6.8 安装 Erlang 及 RabbitMQ Server
安装 Erlang 19.3 # 安装依赖包 yum install -y gcc gcc-c++ unixODBC-devel openssl-devel ncurses-devel # 下载 er ...
- [YARN] 2.2 GB of 2.1 GB virtual memory used. Killing container.
Spark程序在yarn的集群运行,出现 Current usage: 105.9 MB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual ...
- keybd_event 被 SendInput 替代
keybd_event 函数功能:该函数合成一次击键事件.系统可使用这种合成的击键事件来产生WM_KEYUP或WM_KEYDOWN消息,键盘驱动程序的中断处理程序调用keybd_event函数.在 ...
- 给你的 CentOS 7 安装中文支持
今天给大家分享个给 CentOS 7 安装中文支持的方法,所谓“中文支持”目前明月观测到的是指命令行提示支持中文提示显示,还有就是 Vim 启动后看到的也是有中文提是的界面包括 Vim 内各种提示也会 ...
- softmax,softmax loss和cross entropy的区别
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014380165/article/details/77284921 我们知道卷积神经网络(CNN ...
- Andorid之官方导航栏Toobar
在前面学习使用ActionBar的时候,我们就发现ActionBar中有些方法被标记为过时了,原来在android5.0之后,google推出了一个新的导航工具栏,官方将其定义为:A standard ...
- Visual Studio 打开程序提示仅我的代码怎么办
工具-->选项--->调试---->常规-->禁用"启动仅我的代码"
- git的使用笔记
1.git下载:https://git-scm.com/downloads 安装git 2.在github.com网站上注册账号 网址:https://github.com/ 3.使用gi ...