Commit 5b27d6643798189814323b8eb5a3e79067a19a32
Merge pull request #379 from biometrics/ut_revision
Refactored br_universal_template format
Showing
3 changed files
with
39 additions
and
48 deletions
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 "C" { | @@ -35,18 +35,17 @@ extern "C" { | ||
| 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. |