JeVoisBase  1.22
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
Loading...
Searching...
No Matches
ARMarkerSquare.c
Go to the documentation of this file.
1/*
2 * ARMarkerSquare.c
3 * ARToolKit5
4 *
5 * Demonstration of ARToolKit NFT with models rendered in OSG,
6 * and marker pose estimates filtered to reduce jitter.
7 *
8 * Press '?' while running for help on available key commands.
9 *
10 * Disclaimer: IMPORTANT: This Daqri software is supplied to you by Daqri
11 * LLC ("Daqri") in consideration of your agreement to the following
12 * terms, and your use, installation, modification or redistribution of
13 * this Daqri software constitutes acceptance of these terms. If you do
14 * not agree with these terms, please do not use, install, modify or
15 * redistribute this Daqri software.
16 *
17 * In consideration of your agreement to abide by the following terms, and
18 * subject to these terms, Daqri grants you a personal, non-exclusive
19 * license, under Daqri's copyrights in this original Daqri software (the
20 * "Daqri Software"), to use, reproduce, modify and redistribute the Daqri
21 * Software, with or without modifications, in source and/or binary forms;
22 * provided that if you redistribute the Daqri Software in its entirety and
23 * without modifications, you must retain this notice and the following
24 * text and disclaimers in all such redistributions of the Daqri Software.
25 * Neither the name, trademarks, service marks or logos of Daqri LLC may
26 * be used to endorse or promote products derived from the Daqri Software
27 * without specific prior written permission from Daqri. Except as
28 * expressly stated in this notice, no other rights or licenses, express or
29 * implied, are granted by Daqri herein, including but not limited to any
30 * patent rights that may be infringed by your derivative works or by other
31 * works in which the Daqri Software may be incorporated.
32 *
33 * The Daqri Software is provided by Daqri on an "AS IS" basis. DAQRI
34 * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
35 * THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
36 * FOR A PARTICULAR PURPOSE, REGARDING THE DAQRI SOFTWARE OR ITS USE AND
37 * OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
38 *
39 * IN NO EVENT SHALL DAQRI BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
40 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
43 * MODIFICATION AND/OR DISTRIBUTION OF THE DAQRI SOFTWARE, HOWEVER CAUSED
44 * AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
45 * STRICT LIABILITY OR OTHERWISE, EVEN IF DAQRI HAS BEEN ADVISED OF THE
46 * POSSIBILITY OF SUCH DAMAGE.
47 *
48 * Copyright 2015 Daqri LLC. All Rights Reserved.
49 * Copyright 2011-2015 ARToolworks, Inc. All Rights Reserved.
50 *
51 * Author(s): Philip Lamb.
52 *
53 */
54
56
57#ifdef _WIN32
58# include <windows.h>
59# define MAXPATHLEN MAX_PATH
60#else
61# include <sys/param.h> // MAXPATHLEN
62#endif
63#include <stdlib.h> // calloc()
64#include <string.h>
65
66const ARPose ARPoseUnity = {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}};
67
68static char *get_buff(char *buf, int n, FILE *fp, int skipblanks)
69{
70 char *ret;
71 size_t l;
72
73 do {
74 ret = fgets(buf, n, fp);
75 if (ret == NULL) return (NULL); // EOF or error.
76
77 // Remove NLs and CRs from end of string.
78 l = strlen(buf);
79 while (l > 0) {
80 if (buf[l - 1] != '\n' && buf[l - 1] != '\r') break;
81 l--;
82 buf[l] = '\0';
83 }
84 } while (buf[0] == '#' || (skipblanks && buf[0] == '\0')); // Reject comments and blank lines.
85
86 return (ret);
87}
88
89void newMarkers(const char *markersConfigDataFilePathC, ARPattHandle *arPattHandle, ARMarkerSquare **markersSquare_out, int *markersSquareCount_out, int *patternDetectionMode_out)
90{
91 FILE *fp;
92 char buf[MAXPATHLEN], buf1[MAXPATHLEN];
93 int tempI;
94 ARMarkerSquare *markersSquare;
95 int markersSquareCount;
96 ARdouble tempF;
97 int i;
98 char markersConfigDataDirC[MAXPATHLEN];
99 size_t markersConfigDataDirCLen;
100 int patt_type = 0;
101
102 if (!markersConfigDataFilePathC || markersConfigDataFilePathC[0] == '\0' || !markersSquareCount_out || !markersSquare_out) return;
103
104 // Load the marker data file.
105 ARLOGd("Opening marker config. data file from path '%s'.\n", markersConfigDataFilePathC);
106 arUtilGetDirectoryNameFromPath(markersConfigDataDirC, markersConfigDataFilePathC, MAXPATHLEN, 1); // 1 = add '/' at end.
107 markersConfigDataDirCLen = strlen(markersConfigDataDirC);
108 if ((fp = fopen(markersConfigDataFilePathC, "r")) == NULL) {
109 ARLOGe("Error: unable to locate marker config data file '%s'.\n", markersConfigDataFilePathC);
110 return;
111 }
112
113 // First line is number of markers to read.
114 get_buff(buf, MAXPATHLEN, fp, 1);
115 if (sscanf(buf, "%d", &tempI) != 1 ) {
116 ARLOGe("Error in marker configuration data file; expected marker count.\n");
117 fclose(fp);
118 return;
119 }
120
121 arMallocClear(markersSquare, ARMarkerSquare, tempI);
122 markersSquareCount = tempI;
123
124 ARLOGd("Reading %d marker configuration(s).\n", markersSquareCount);
125
126 for (i = 0; i < markersSquareCount; i++) {
127
128 // Read marker name.
129 if (!get_buff(buf, MAXPATHLEN, fp, 1)) {
130 ARLOGe("Error in marker configuration data file; expected marker name.\n");
131 break;
132 }
133
134 // Read marker type.
135 if (!get_buff(buf1, MAXPATHLEN, fp, 1)) {
136 ARLOGe("Error in marker configuration data file; expected marker type.\n");
137 break;
138 }
139
140 // Interpret marker type, and read more data.
141 if (strcmp(buf1, "SINGLE") == 0) {
142 markersSquare[i].valid = markersSquare[i].validPrev = FALSE;
143
144 // Read marker width.
145 if (!get_buff(buf1, MAXPATHLEN, fp, 1) || sscanf(buf1,
146#ifdef ARDOUBLE_IS_FLOAT
147 "%f"
148#else
149 "%lf"
150#endif
151 , &tempF) != 1) {
152 ARLOGe("Error in marker configuration data file; expected marker width.\n");
153 break;
154 }
155
156 // Interpret marker name (still in buf), test if it's a pattern number, load as pattern file if not.
157 if (sscanf(buf, "%d", &tempI) != 1) {
158 if (!arPattHandle) {
159 ARLOGe("Error: Marker pattern file '%s' specified but only barcodes allowed.\n", markersSquare[i].patternPathname);
160 break;
161 }
162 arMalloc(markersSquare[i].patternPathname, char, markersConfigDataDirCLen + strlen(buf) + 1);
163 strcpy(markersSquare[i].patternPathname, markersConfigDataDirC);
164 strcpy(markersSquare[i].patternPathname + markersConfigDataDirCLen, buf);
165
166 // Now load pattern file.
167 if ((markersSquare[i].patt_id = arPattLoad(arPattHandle, markersSquare[i].patternPathname)) < 0 ) {
168 ARLOGe("Error: Unable to load marker pattern from file'%s'.\n", markersSquare[i].patternPathname);
169 break;
170 }
171 markersSquare[i].marker_width = markersSquare[i].marker_height = tempF;
172 markersSquare[i].patt_type = AR_PATTERN_TYPE_TEMPLATE;
173 patt_type |= 0x01;
174 } else {
175 markersSquare[i].patternPathname = NULL;
176 markersSquare[i].patt_id = tempI;
177 //ARLOGi("markersSquare[%d].patt_id = %d\n",i,markersSquare[i].patt_id);
178 //ARLOGi("tempI = %d\n",tempI);
179 markersSquare[i].marker_width = markersSquare[i].marker_height = tempF;
180 markersSquare[i].patt_type = AR_PATTERN_TYPE_MATRIX;
181 patt_type |= 0x02;
182 }
183
184 } else if (strcmp(buf1, "MULTI") == 0) {
185 ARLOGe("Error in marker configuration data file; MULTI markers not supported in this build.\n");
186 } else if (strcmp(buf1, "NFT") == 0) {
187 ARLOGe("Error in marker configuration data file; NFT markers not supported in this build.\n");
188 } else {
189 ARLOGe("Error in marker configuration data file; unsupported marker type %s.\n", buf1);
190 }
191
192 // Look for optional tokens. A blank line marks end of options.
193 while (get_buff(buf, MAXPATHLEN, fp, 0) && (buf[0] != '\0')) {
194 if (strncmp(buf, "FILTER", 6) == 0) {
195 markersSquare[i].filterCutoffFrequency = AR_FILTER_TRANS_MAT_CUTOFF_FREQ_DEFAULT;
196 markersSquare[i].filterSampleRate = AR_FILTER_TRANS_MAT_SAMPLE_RATE_DEFAULT;
197 if (strlen(buf) != 6) {
198 if (sscanf(&buf[6],
199#ifdef ARDOUBLE_IS_FLOAT
200 "%f"
201#else
202 "%lf"
203#endif
204 , &tempF) == 1) markersSquare[i].filterCutoffFrequency = tempF;
205 }
206 markersSquare[i].ftmi = arFilterTransMatInit(markersSquare[i].filterSampleRate, markersSquare[i].filterCutoffFrequency);
207 }
208 // Unknown tokens are ignored.
209 }
210 }
211 fclose(fp);
212
213 // If not all markers were read, an error occurred.
214 if (i < markersSquareCount) {
215
216 // Clean up.
217 for (; i >= 0; i--) {
218 if (markersSquare[i].patt_type == AR_PATTERN_TYPE_TEMPLATE && markersSquare[i].patt_id && arPattHandle) arPattFree(arPattHandle, markersSquare[i].patt_id);
219 if (markersSquare[i].patternPathname) free(markersSquare[i].patternPathname);
220 if (markersSquare[i].ftmi) arFilterTransMatFinal(markersSquare[i].ftmi);
221 }
222 free(markersSquare);
223
224 *markersSquareCount_out = 0;
225 *markersSquare_out = NULL;
226 if (patternDetectionMode_out) *patternDetectionMode_out = -1;
227 return;
228 }
229
230 *markersSquareCount_out = markersSquareCount;
231 *markersSquare_out = markersSquare;
232 //ARLOGi("patternDetectionMode_out = %d\n", patternDetectionMode_out);
233 if (patternDetectionMode_out) {
234 // Work out square marker detection mode.
235 //ARLOGi("patternDetectionMode_out = %d\n", patternDetectionMode_out);
236 if ((patt_type & 0x03) == 0x03) {*patternDetectionMode_out = AR_TEMPLATE_MATCHING_COLOR_AND_MATRIX; }
237 else if (patt_type & 0x02) {*patternDetectionMode_out = AR_MATRIX_CODE_DETECTION;}
238 else {*patternDetectionMode_out = AR_TEMPLATE_MATCHING_COLOR;}
239 }
240}
241
242void deleteMarkers(ARMarkerSquare **markersSquare_p, int *markersSquareCount_p, ARPattHandle *arPattHandle)
243{
244 int i;
245
246 if (!markersSquare_p || !*markersSquare_p || !*markersSquareCount_p || *markersSquareCount_p < 1) return;
247
248 for (i = 0; i < *markersSquareCount_p; i++) {
249 if ((*markersSquare_p)[i].patt_type == AR_PATTERN_TYPE_TEMPLATE && (*markersSquare_p)[i].patt_id && arPattHandle) arPattFree(arPattHandle, (*markersSquare_p)[i].patt_id);
250 if ((*markersSquare_p)[i].patternPathname) {
251 free((*markersSquare_p)[i].patternPathname);
252 (*markersSquare_p)[i].patternPathname = NULL;
253 }
254 if ((*markersSquare_p)[i].ftmi) {
255 arFilterTransMatFinal((*markersSquare_p)[i].ftmi);
256 (*markersSquare_p)[i].ftmi = NULL;
257 }
258 }
259 free(*markersSquare_p);
260 *markersSquare_p = NULL;
261 *markersSquareCount_p = 0;
262}
const ARPose ARPoseUnity
void deleteMarkers(ARMarkerSquare **markersSquare_p, int *markersSquareCount_p, ARPattHandle *arPattHandle)
void newMarkers(const char *markersConfigDataFilePathC, ARPattHandle *arPattHandle, ARMarkerSquare **markersSquare_out, int *markersSquareCount_out, int *patternDetectionMode_out)
#define AR_PATTERN_TYPE_MATRIX
#define AR_PATTERN_TYPE_TEMPLATE
ARdouble filterCutoffFrequency
ARFilterTransMatInfo * ftmi
ARdouble marker_height
ARdouble marker_width
ARdouble filterSampleRate