Commit 5b27d6643798189814323b8eb5a3e79067a19a32

Authored by Josh Klontz
2 parents 5bae8c7a 1f940027

Merge pull request #379 from biometrics/ut_revision

Refactored br_universal_template format
openbr/plugins/gallery/binary.cpp
@@ -213,23 +213,22 @@ class utGallery : public BinaryGallery @@ -213,23 +213,22 @@ class utGallery : public BinaryGallery
213 Template t; 213 Template t;
214 br_universal_template ut; 214 br_universal_template ut;
215 if (gallery.read((char*)&ut, sizeof(br_universal_template)) == sizeof(br_universal_template)) { 215 if (gallery.read((char*)&ut, sizeof(br_universal_template)) == sizeof(br_universal_template)) {
216 - QByteArray data(ut.urlSize + ut.fvSize, Qt::Uninitialized); 216 + QByteArray data(ut.mdSize + ut.fvSize, Qt::Uninitialized);
217 char *dst = data.data(); 217 char *dst = data.data();
218 - qint64 bytesNeeded = ut.urlSize + ut.fvSize; 218 + qint64 bytesNeeded = ut.mdSize + ut.fvSize;
219 while (bytesNeeded > 0) { 219 while (bytesNeeded > 0) {
220 qint64 bytesRead = gallery.read(dst, bytesNeeded); 220 qint64 bytesRead = gallery.read(dst, bytesNeeded);
221 if (bytesRead <= 0) { 221 if (bytesRead <= 0) {
222 qDebug() << gallery.errorString(); 222 qDebug() << gallery.errorString();
223 - qFatal("Unexepected EOF while reading universal template data, needed: %d more of: %d bytes.", int(bytesNeeded), int(ut.urlSize + ut.fvSize)); 223 + qFatal("Unexepected EOF while reading universal template data, needed: %d more of: %d bytes.", int(bytesNeeded), int(ut.mdSize + ut.fvSize));
224 } 224 }
225 bytesNeeded -= bytesRead; 225 bytesNeeded -= bytesRead;
226 dst += bytesRead; 226 dst += bytesRead;
227 } 227 }
228 228
229 - t.file.set("ImageID", QVariant(QByteArray((const char*)ut.imageID, 16).toHex()));  
230 t.file.set("AlgorithmID", ut.algorithmID); 229 t.file.set("AlgorithmID", ut.algorithmID);
231 - t.file.set("URL", QString(data.data()));  
232 - char *dataStart = data.data() + ut.urlSize; 230 + t.file.set("Metadata", QString(data.data()));
  231 + char *dataStart = data.data() + ut.mdSize;
233 uint32_t dataSize = ut.fvSize; 232 uint32_t dataSize = ut.fvSize;
234 if ((ut.algorithmID <= -1) && (ut.algorithmID >= -3)) { 233 if ((ut.algorithmID <= -1) && (ut.algorithmID >= -3)) {
235 t.file.set("FrontalFace", QRectF(ut.x, ut.y, ut.width, ut.height)); 234 t.file.set("FrontalFace", QRectF(ut.x, ut.y, ut.width, ut.height));
@@ -244,8 +243,7 @@ class utGallery : public BinaryGallery @@ -244,8 +243,7 @@ class utGallery : public BinaryGallery
244 dataSize -= sizeof(uint32_t)*4; 243 dataSize -= sizeof(uint32_t)*4;
245 t.file.set("First_Eye", QPointF(*rightEyeX, *rightEyeY)); 244 t.file.set("First_Eye", QPointF(*rightEyeX, *rightEyeY));
246 t.file.set("Second_Eye", QPointF(*leftEyeX, *leftEyeY)); 245 t.file.set("Second_Eye", QPointF(*leftEyeX, *leftEyeY));
247 - }  
248 - else if (ut.algorithmID == 7) { 246 + } else if (ut.algorithmID == 7) {
249 // binary data consisting of a single channel matrix, of a supported type. 247 // binary data consisting of a single channel matrix, of a supported type.
250 // 4 element header: 248 // 4 element header:
251 // uint16 datatype (single channel opencv datatype code) 249 // uint16 datatype (single channel opencv datatype code)
@@ -269,22 +267,21 @@ class utGallery : public BinaryGallery @@ -269,22 +267,21 @@ class utGallery : public BinaryGallery
269 dataStart += sizeof(uint16_t); 267 dataStart += sizeof(uint16_t);
270 268
271 // Set metadata 269 // Set metadata
272 - t.file.set("Label", ut.label);  
273 t.file.set("X", ut.x); 270 t.file.set("X", ut.x);
274 t.file.set("Y", ut.y); 271 t.file.set("Y", ut.y);
275 t.file.set("Width", ut.width); 272 t.file.set("Width", ut.width);
276 t.file.set("Height", ut.height); 273 t.file.set("Height", ut.height);
  274 + t.file.set("Confidence", ut.confidence);
277 275
278 t.append(cv::Mat(matrixRows, matrixCols, CV_MAKETYPE(dataType, matrixDepth), dataStart).clone() /* We don't want a shallow copy! */); 276 t.append(cv::Mat(matrixRows, matrixCols, CV_MAKETYPE(dataType, matrixDepth), dataStart).clone() /* We don't want a shallow copy! */);
279 return t; 277 return t;
280 - }  
281 - else { 278 + } else {
282 t.file.set("X", ut.x); 279 t.file.set("X", ut.x);
283 t.file.set("Y", ut.y); 280 t.file.set("Y", ut.y);
284 t.file.set("Width", ut.width); 281 t.file.set("Width", ut.width);
285 t.file.set("Height", ut.height); 282 t.file.set("Height", ut.height);
  283 + t.file.set("Confidence", ut.confidence);
286 } 284 }
287 - t.file.set("Label", ut.label);  
288 t.append(cv::Mat(1, dataSize, CV_8UC1, dataStart).clone() /* We don't want a shallow copy! */); 285 t.append(cv::Mat(1, dataSize, CV_8UC1, dataStart).clone() /* We don't want a shallow copy! */);
289 } else { 286 } else {
290 if (!gallery.atEnd()) 287 if (!gallery.atEnd())
@@ -296,18 +293,15 @@ class utGallery : public BinaryGallery @@ -296,18 +293,15 @@ class utGallery : public BinaryGallery
296 293
297 void writeTemplate(const Template &t) 294 void writeTemplate(const Template &t)
298 { 295 {
299 - const QByteArray imageID = QByteArray::fromHex(t.file.get<QByteArray>("ImageID", QByteArray(32, '0')));  
300 - if (imageID.size() != 16)  
301 - qFatal("Expected 16-byte ImageID, got: %d bytes.", imageID.size());  
302 -  
303 const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get<int32_t>("AlgorithmID"); 296 const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get<int32_t>("AlgorithmID");
304 297
305 // QUrl::fromUserInput provides some nice functionality in terms of completing URLs 298 // QUrl::fromUserInput provides some nice functionality in terms of completing URLs
306 // e.g. C:/test.jpg -> file://C:/test.jpg and google.com/image.jpg -> http://google.com/image.jpg 299 // e.g. C:/test.jpg -> file://C:/test.jpg and google.com/image.jpg -> http://google.com/image.jpg
307 - const QByteArray url = QUrl::fromUserInput(t.file.get<QString>("URL", t.file.name)).toEncoded(); 300 + const QByteArray metadata = QUrl::fromUserInput(t.file.get<QString>("URL", t.file.name)).toEncoded();
308 301
309 int32_t x = 0, y = 0; 302 int32_t x = 0, y = 0;
310 uint32_t width = 0, height = 0; 303 uint32_t width = 0, height = 0;
  304 + float confidence = 0;
311 QByteArray header; 305 QByteArray header;
312 if ((algorithmID <= -1) && (algorithmID >= -3)) { 306 if ((algorithmID <= -1) && (algorithmID >= -3)) {
313 const QRectF frontalFace = t.file.get<QRectF>("FrontalFace"); 307 const QRectF frontalFace = t.file.get<QRectF>("FrontalFace");
@@ -332,25 +326,24 @@ class utGallery : public BinaryGallery @@ -332,25 +326,24 @@ class utGallery : public BinaryGallery
332 y = t.file.get<int32_t>("Y", 0); 326 y = t.file.get<int32_t>("Y", 0);
333 width = t.file.get<uint32_t>("Width", 0); 327 width = t.file.get<uint32_t>("Width", 0);
334 height = t.file.get<uint32_t>("Height", 0); 328 height = t.file.get<uint32_t>("Height", 0);
  329 + confidence = t.file.get<uint32_t>("Confidence", 0);
335 } 330 }
336 - const uint32_t label = t.file.get<uint32_t>("Label", 0);  
337 331
338 - gallery.write(imageID);  
339 gallery.write((const char*) &algorithmID, sizeof(int32_t)); 332 gallery.write((const char*) &algorithmID, sizeof(int32_t));
340 gallery.write((const char*) &x , sizeof(int32_t)); 333 gallery.write((const char*) &x , sizeof(int32_t));
341 gallery.write((const char*) &y , sizeof(int32_t)); 334 gallery.write((const char*) &y , sizeof(int32_t));
342 gallery.write((const char*) &width , sizeof(uint32_t)); 335 gallery.write((const char*) &width , sizeof(uint32_t));
343 gallery.write((const char*) &height , sizeof(uint32_t)); 336 gallery.write((const char*) &height , sizeof(uint32_t));
344 - gallery.write((const char*) &label , sizeof(uint32_t)); 337 + gallery.write((const char*) &confidence , sizeof(float));
345 338
346 - const uint32_t urlSize = url.size() + 1;  
347 - gallery.write((const char*) &urlSize, sizeof(uint32_t)); 339 + const uint32_t mdSize = metadata.size() + 1;
  340 + gallery.write((const char*) &mdSize, sizeof(uint32_t));
348 341
349 const uint32_t signatureSize = (algorithmID == 0) ? 0 : t.m().rows * t.m().cols * t.m().elemSize(); 342 const uint32_t signatureSize = (algorithmID == 0) ? 0 : t.m().rows * t.m().cols * t.m().elemSize();
350 const uint32_t fvSize = header.size() + signatureSize; 343 const uint32_t fvSize = header.size() + signatureSize;
351 gallery.write((const char*) &fvSize, sizeof(uint32_t)); 344 gallery.write((const char*) &fvSize, sizeof(uint32_t));
352 345
353 - gallery.write((const char*) url.data(), urlSize); 346 + gallery.write((const char*) metadata.data(), mdSize);
354 if (algorithmID != 0) { 347 if (algorithmID != 0) {
355 gallery.write(header); 348 gallery.write(header);
356 gallery.write((const char*) t.m().data, signatureSize); 349 gallery.write((const char*) t.m().data, signatureSize);
openbr/universal_template.cpp
@@ -8,21 +8,20 @@ @@ -8,21 +8,20 @@
8 8
9 #include "universal_template.h" 9 #include "universal_template.h"
10 10
11 -br_utemplate br_new_utemplate(const char *imageID, int32_t algorithmID, int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t label, const char *url, const char *fv, uint32_t fvSize) 11 +br_utemplate br_new_utemplate(int32_t algorithmID, int32_t x, int32_t y, uint32_t width, uint32_t height, float confidence, const char *metadata, const char *featureVector, uint32_t fvSize)
12 { 12 {
13 - const uint32_t urlSize = strlen(url) + 1;  
14 - br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + urlSize + fvSize);  
15 - memcpy(utemplate->imageID, imageID, 16); 13 + const uint32_t mdSize = strlen(metadata) + 1;
  14 + br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + mdSize + fvSize);
16 utemplate->algorithmID = algorithmID; 15 utemplate->algorithmID = algorithmID;
17 utemplate->x = x; 16 utemplate->x = x;
18 utemplate->y = y; 17 utemplate->y = y;
19 utemplate->width = width; 18 utemplate->width = width;
20 utemplate->height = height; 19 utemplate->height = height;
21 - utemplate->label = label;  
22 - utemplate->urlSize = urlSize; 20 + utemplate->confidence = confidence;
  21 + utemplate->mdSize = mdSize;
23 utemplate->fvSize = fvSize; 22 utemplate->fvSize = fvSize;
24 - memcpy(reinterpret_cast<char*>(utemplate+1) + 0, url , urlSize);  
25 - memcpy(reinterpret_cast<char*>(utemplate+1) + urlSize, fv, fvSize); 23 + memcpy(reinterpret_cast<char*>(utemplate+1) + 0, metadata , mdSize);
  24 + memcpy(reinterpret_cast<char*>(utemplate+1) + mdSize, featureVector, fvSize);
26 return utemplate; 25 return utemplate;
27 } 26 }
28 27
@@ -33,14 +32,14 @@ void br_free_utemplate(br_const_utemplate utemplate) @@ -33,14 +32,14 @@ void br_free_utemplate(br_const_utemplate utemplate)
33 32
34 void br_append_utemplate(FILE *file, br_const_utemplate utemplate) 33 void br_append_utemplate(FILE *file, br_const_utemplate utemplate)
35 { 34 {
36 - fwrite(utemplate, sizeof(br_universal_template) + utemplate->urlSize + utemplate->fvSize, 1, file); 35 + fwrite(utemplate, sizeof(br_universal_template) + utemplate->mdSize + utemplate->fvSize, 1, file);
37 } 36 }
38 37
39 void br_iterate_utemplates(br_const_utemplate begin, br_const_utemplate end, br_utemplate_callback callback, br_callback_context context) 38 void br_iterate_utemplates(br_const_utemplate begin, br_const_utemplate end, br_utemplate_callback callback, br_callback_context context)
40 { 39 {
41 while (begin != end) { 40 while (begin != end) {
42 callback(begin, context); 41 callback(begin, context);
43 - begin = reinterpret_cast<br_const_utemplate>(reinterpret_cast<const char*>(begin) + sizeof(br_universal_template) + begin->urlSize + begin->fvSize); 42 + begin = reinterpret_cast<br_const_utemplate>(reinterpret_cast<const char*>(begin) + sizeof(br_universal_template) + begin->mdSize + begin->fvSize);
44 if (begin > end) 43 if (begin > end)
45 qFatal("Overshot end of buffer"); 44 qFatal("Overshot end of buffer");
46 } 45 }
@@ -88,8 +87,8 @@ int br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_ca @@ -88,8 +87,8 @@ int br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_ca
88 break; 87 break;
89 } 88 }
90 89
91 - t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->urlSize + t->fvSize);  
92 - if (!read_buffer(file, (char*) &t->data, t->urlSize + t->fvSize)) { 90 + t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->mdSize + t->fvSize);
  91 + if (!read_buffer(file, (char*) &t->data, t->mdSize + t->fvSize)) {
93 free(t); 92 free(t);
94 93
95 // Try to rewind header read 94 // Try to rewind header read
openbr/universal_template.h
@@ -35,18 +35,17 @@ extern &quot;C&quot; { @@ -35,18 +35,17 @@ extern &quot;C&quot; {
35 */ 35 */
36 struct br_universal_template 36 struct br_universal_template
37 { 37 {
38 - unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */  
39 - int32_t algorithmID; /*!< interpretation of _data_ after _urlSize_. */  
40 - int32_t x; /*!< region of interest horizontal offset (pixels). */  
41 - int32_t y; /*!< region of interest vertical offset (pixels). */  
42 - uint32_t width; /*!< region of interest horizontal size (pixels). */  
43 - uint32_t height; /*!< region of interest vertical size (pixels). */  
44 - uint32_t label; /*!< supervised training class or manually annotated ground truth. */  
45 - uint32_t urlSize; /*!< length of null-terminated URL at the beginning of _data_,  
46 - including the null-terminator character. */  
47 - uint32_t fvSize; /*!< length of the feature vector after the URL in _data_. */  
48 - unsigned char data[]; /*!< (_urlSize_ + _fvSize_)-byte buffer.  
49 - The first _urlSize_ bytes represent the URL. 38 + int32_t algorithmID; /*!< Interpretation of _data_ after _mdSize_. */
  39 + int32_t x; /*!< Region of interest horizontal offset (pixels). */
  40 + int32_t y; /*!< Region of interest vertical offset (pixels). */
  41 + uint32_t width; /*!< Region of interest horizontal size (pixels). */
  42 + uint32_t height; /*!< Region of interest vertical size (pixels). */
  43 + float confidence; /*!< Region of interest confidence. */
  44 + uint32_t mdSize; /*!< Length of a null-terminated metadata string at the beginning of _data_,
  45 + including the null-terminator character itself. */
  46 + uint32_t fvSize; /*!< Length of the feature vector after the metadata in _data_. */
  47 + unsigned char data[]; /*!< (_mdSize_ + _fvSize_)-byte buffer.
  48 + The first _mdSize_ bytes represent the metadata.
50 The remaining _fvSize_ bytes represent the feature vector. */ 49 The remaining _fvSize_ bytes represent the feature vector. */
51 }; 50 };
52 51
@@ -57,7 +56,7 @@ typedef const struct br_universal_template *br_const_utemplate; @@ -57,7 +56,7 @@ typedef const struct br_universal_template *br_const_utemplate;
57 * \brief br_universal_template constructor. 56 * \brief br_universal_template constructor.
58 * \see br_free_utemplate 57 * \see br_free_utemplate
59 */ 58 */
60 -BR_EXPORT br_utemplate br_new_utemplate(const char *imageID, int32_t algorithmID, int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t label, const char *url, const char *fv, uint32_t fvSize); 59 +BR_EXPORT br_utemplate br_new_utemplate(int32_t algorithmID, int32_t x, int32_t y, uint32_t width, uint32_t height, float confidence, const char *metadata, const char *featureVector, uint32_t fvSize);
61 60
62 /*! 61 /*!
63 * \brief br_universal_template destructor. 62 * \brief br_universal_template destructor.