[Artoolkit] Marker of nftSimple

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

 

1.

int main(int argc, char** argv)
{
    char glutGamemode[32];
    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(-1);
    }
    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(-1);
    }    

 

 

newMarkers 到底是如何工作的呢?


# Number of markers
1

# 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

 

 

  1 void newMarkers(const char *markersConfigDataFilePathC, ARMarkerNFT **markersNFT_out, int *markersNFTCount_out)
  2 {
  3     FILE          *fp;
  4     char           buf[MAXPATHLEN], buf1[MAXPATHLEN];
  5     int            tempI;
  6     ARMarkerNFT   *markersNFT;
  7     int            markersNFTCount;
  8     ARdouble       tempF;
  9     int            i;
 10     char           markersConfigDataDirC[MAXPATHLEN];
 11     size_t         markersConfigDataDirCLen;
 12 
 13     if (!markersConfigDataFilePathC || markersConfigDataFilePathC[0] == '\0' || !markersNFT_out || !markersNFTCount_out) return;
 14         
 15     // Load the marker data file.
 16     ARLOGd("Opening marker config. data file from path '%s'.\n", markersConfigDataFilePathC);
 17     arUtilGetDirectoryNameFromPath(markersConfigDataDirC, markersConfigDataFilePathC, MAXPATHLEN, 1); // 1 = add '/' at end.
 18     markersConfigDataDirCLen = strlen(markersConfigDataDirC);
 19     if ((fp = fopen(markersConfigDataFilePathC, "r")) == NULL) {
 20         ARLOGe("Error: unable to locate marker config data file '%s'.\n", markersConfigDataFilePathC);
 21         return;
 22     }
 23     
 24     // First line is number of markers to read.
 25     get_buff(buf, MAXPATHLEN, fp, 1);
 26     if (sscanf(buf, "%d", &tempI) != 1 ) {
 27         ARLOGe("Error in marker configuration data file; expected marker count.\n");
 28         fclose(fp);
 29         return;
 30     }
 31     
 32     arMallocClear(markersNFT, ARMarkerNFT, tempI);
 33     markersNFTCount = tempI;
 34     
 35     ARLOGd("Reading %d marker configuration(s).\n", markersNFTCount);
 36 
 37     for (i = 0; i < markersNFTCount; i++) {
 38         
 39         // Read marker file name.
 40         if (!get_buff(buf, MAXPATHLEN, fp, 1)) {
 41             ARLOGe("Error in marker configuration data file; expected marker name.\n");
 42             break;
 43         }
 44         
 45         // Read marker type.
 46         if (!get_buff(buf1, MAXPATHLEN, fp, 1)) {
 47             ARLOGe("Error in marker configuration data file; expected marker type.\n");
 48             break;
 49         }
 50         
 51         // Interpret marker type, and read more data.
 52         if (strcmp(buf1, "SINGLE") == 0) {
 53             ARLOGe("Error in marker configuration data file; SINGLE markers not supported in this build.\n");
 54         } else if (strcmp(buf1, "MULTI") == 0) {
 55             ARLOGe("Error in marker configuration data file; MULTI markers not supported in this build.\n");
 56         } else if (strcmp(buf1, "NFT") == 0) {
 57             markersNFT[i].valid = markersNFT[i].validPrev = FALSE;
 58             arMalloc(markersNFT[i].datasetPathname, char, markersConfigDataDirCLen + strlen(buf) + 1);
 59             strcpy(markersNFT[i].datasetPathname, markersConfigDataDirC);
 60             strcpy(markersNFT[i].datasetPathname + markersConfigDataDirCLen, buf);
 61             markersNFT[i].pageNo = -1;
 62         } else {
 63             ARLOGe("Error in marker configuration data file; unsupported marker type %s.\n", buf1);
 64         }
 65         
 66         // Look for optional tokens. A blank line marks end of options.
 67         while (get_buff(buf, MAXPATHLEN, fp, 0) && (buf[0] != '\0')) {
 68             if (strncmp(buf, "FILTER", 6) == 0) {
 69                 markersNFT[i].filterCutoffFrequency  = AR_FILTER_TRANS_MAT_CUTOFF_FREQ_DEFAULT;
 70                 markersNFT[i].filterSampleRate      = AR_FILTER_TRANS_MAT_SAMPLE_RATE_DEFAULT;
 71                 if (strlen(buf) != 6) {
 72                     if (sscanf(&buf[6],
 73 #ifdef ARDOUBLE_IS_FLOAT
 74                                "%f"
 75 #else
 76                                "%lf"
 77 #endif
 78                                , &tempF) == 1) markersNFT[i].filterCutoffFrequency = tempF;
 79                 }
 80                 markersNFT[i].ftmi = arFilterTransMatInit(markersNFT[i].filterSampleRate, markersNFT[i].filterCutoffFrequency);
 81             }
 82             // Unknown tokens are ignored.
 83         }
 84     }
 85     fclose(fp);
 86     
 87     // If not all markers were read, an error occurred.
 88     if (i < markersNFTCount) {
 89     
 90         // Clean up.
 91         for (; i >= 0; i--) {
 92             if (markersNFT[i].datasetPathname)  free(markersNFT[i].datasetPathname);
 93             if (markersNFT[i].ftmi) arFilterTransMatFinal(markersNFT[i].ftmi);
 94         }
 95         free(markersNFT);
 96                 
 97         *markersNFTCount_out = 0;
 98         *markersNFT_out = NULL;
 99         return;
100     }
101     
102     *markersNFTCount_out = markersNFTCount;
103     *markersNFT_out      = markersNFT;
104 }

 

typedef struct _ARMarkerNFT {
    // ARMarker protected 
    bool       valid;
    bool       validPrev;
    ARdouble   trans[3][4];
    ARPose     pose;
    ARdouble   marker_width;
    ARdouble   marker_height;
    // ARMarker private
    ARFilterTransMatInfo *ftmi;  // 变换矩阵,为何使用链表的形式?
    ARdouble   filterCutoffFrequency;
    ARdouble   filterSampleRate;
    // ARMarkerNFT
    int        pageNo;
    char      *datasetPathname;
} ARMarkerNFT;

 

loadNFTData 开始分析。


 

 1 // References globals: markersNFTCount
 2 // Modifies globals: threadHandle, surfaceSet[], surfaceSetCount, markersNFT[]
 3 static int loadNFTData(void)
 4 {
 5     int i;
 6     KpmRefDataSet *refDataSet;
 7     
 8     // If data was already loaded, stop KPM tracking thread and unload previously loaded data.
 9     if (threadHandle) {
10         ARLOGi("Reloading NFT data.\n");
11         unloadNFTData();
12     } else {
13         ARLOGi("Loading NFT data.\n");
14     }
15     
16     refDataSet = NULL;
17     
18     for (i = 0; i < markersNFTCount; i++) {  // 重点在这里!
19         // (1) Load KPM data.
20         KpmRefDataSet  *refDataSet2;
21         ARLOGi("Reading %s.fset3\n", markersNFT[i].datasetPathname);
22         if (kpmLoadRefDataSet(markersNFT[i].datasetPathname, "fset3", &refDataSet2) < 0 ) {
23             ARLOGe("Error reading KPM data from %s.fset3\n", markersNFT[i].datasetPathname);
24             markersNFT[i].pageNo = -1;
25             continue;
26         }
27         markersNFT[i].pageNo = surfaceSetCount;
28         ARLOGi("  Assigned page no. %d.\n", surfaceSetCount);
29         if (kpmChangePageNoOfRefDataSet(refDataSet2, KpmChangePageNoAllPages, surfaceSetCount) < 0) {
30             ARLOGe("Error: kpmChangePageNoOfRefDataSet\n");
31             exit(-1);
32         }
33         if (kpmMergeRefDataSet(&refDataSet, &refDataSet2) < 0) {
34             ARLOGe("Error: kpmMergeRefDataSet\n");
35             exit(-1);
36         }
37         ARLOGi("  Done.\n");
38         
39         // (2) Load AR2 data.
40         ARLOGi("Reading %s.fset\n", markersNFT[i].datasetPathname);
41         
42         if ((surfaceSet[surfaceSetCount] = ar2ReadSurfaceSet(markersNFT[i].datasetPathname, "fset", NULL)) == NULL ) {
43             ARLOGe("Error reading data from %s.fset\n", markersNFT[i].datasetPathname);
44         }
45         ARLOGi("  Done.\n");
46         
47         surfaceSetCount++;
48         if (surfaceSetCount == PAGES_MAX) break;
49     }
50     if (kpmSetRefDataSet(kpmHandle, refDataSet) < 0) {
51         ARLOGe("Error: kpmSetRefDataSet\n");
52         exit(-1);
53     }
54     kpmDeleteRefDataSet(&refDataSet);
55     
56     // Start the KPM tracking thread.
57     threadHandle = trackingInitInit(kpmHandle);
58     if (!threadHandle) exit(-1);
59 
60     ARLOGi("Loading of NFT data complete.\n");
61     return (TRUE);
62 }

 

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

posted @ 2017-02-25 10:37  郝壹贰叁  阅读(1059)  评论(0编辑  收藏  举报