diff --git a/openbr/plugins/gallery/binary.cpp b/openbr/plugins/gallery/binary.cpp index c70a1d3..89bb3e3 100644 --- a/openbr/plugins/gallery/binary.cpp +++ b/openbr/plugins/gallery/binary.cpp @@ -213,23 +213,22 @@ class utGallery : public BinaryGallery Template t; br_universal_template ut; if (gallery.read((char*)&ut, sizeof(br_universal_template)) == sizeof(br_universal_template)) { - QByteArray data(ut.urlSize + ut.fvSize, Qt::Uninitialized); + QByteArray data(ut.mdSize + ut.fvSize, Qt::Uninitialized); char *dst = data.data(); - qint64 bytesNeeded = ut.urlSize + ut.fvSize; + qint64 bytesNeeded = ut.mdSize + ut.fvSize; while (bytesNeeded > 0) { qint64 bytesRead = gallery.read(dst, bytesNeeded); if (bytesRead <= 0) { qDebug() << gallery.errorString(); - qFatal("Unexepected EOF while reading universal template data, needed: %d more of: %d bytes.", int(bytesNeeded), int(ut.urlSize + ut.fvSize)); + qFatal("Unexepected EOF while reading universal template data, needed: %d more of: %d bytes.", int(bytesNeeded), int(ut.mdSize + ut.fvSize)); } bytesNeeded -= bytesRead; dst += bytesRead; } - t.file.set("ImageID", QVariant(QByteArray((const char*)ut.imageID, 16).toHex())); t.file.set("AlgorithmID", ut.algorithmID); - t.file.set("URL", QString(data.data())); - char *dataStart = data.data() + ut.urlSize; + t.file.set("Metadata", QString(data.data())); + char *dataStart = data.data() + ut.mdSize; uint32_t dataSize = ut.fvSize; if ((ut.algorithmID <= -1) && (ut.algorithmID >= -3)) { t.file.set("FrontalFace", QRectF(ut.x, ut.y, ut.width, ut.height)); @@ -244,8 +243,7 @@ class utGallery : public BinaryGallery dataSize -= sizeof(uint32_t)*4; t.file.set("First_Eye", QPointF(*rightEyeX, *rightEyeY)); t.file.set("Second_Eye", QPointF(*leftEyeX, *leftEyeY)); - } - else if (ut.algorithmID == 7) { + } else if (ut.algorithmID == 7) { // binary data consisting of a single channel matrix, of a supported type. // 4 element header: // uint16 datatype (single channel opencv datatype code) @@ -269,22 +267,21 @@ class utGallery : public BinaryGallery dataStart += sizeof(uint16_t); // Set metadata - t.file.set("Label", ut.label); t.file.set("X", ut.x); t.file.set("Y", ut.y); t.file.set("Width", ut.width); t.file.set("Height", ut.height); + t.file.set("Confidence", ut.confidence); t.append(cv::Mat(matrixRows, matrixCols, CV_MAKETYPE(dataType, matrixDepth), dataStart).clone() /* We don't want a shallow copy! */); return t; - } - else { + } else { t.file.set("X", ut.x); t.file.set("Y", ut.y); t.file.set("Width", ut.width); t.file.set("Height", ut.height); + t.file.set("Confidence", ut.confidence); } - t.file.set("Label", ut.label); t.append(cv::Mat(1, dataSize, CV_8UC1, dataStart).clone() /* We don't want a shallow copy! */); } else { if (!gallery.atEnd()) @@ -296,18 +293,15 @@ class utGallery : public BinaryGallery void writeTemplate(const Template &t) { - const QByteArray imageID = QByteArray::fromHex(t.file.get("ImageID", QByteArray(32, '0'))); - if (imageID.size() != 16) - qFatal("Expected 16-byte ImageID, got: %d bytes.", imageID.size()); - const int32_t algorithmID = (t.isEmpty() || t.file.fte) ? 0 : t.file.get("AlgorithmID"); // QUrl::fromUserInput provides some nice functionality in terms of completing URLs // e.g. C:/test.jpg -> file://C:/test.jpg and google.com/image.jpg -> http://google.com/image.jpg - const QByteArray url = QUrl::fromUserInput(t.file.get("URL", t.file.name)).toEncoded(); + const QByteArray metadata = QUrl::fromUserInput(t.file.get("URL", t.file.name)).toEncoded(); int32_t x = 0, y = 0; uint32_t width = 0, height = 0; + float confidence = 0; QByteArray header; if ((algorithmID <= -1) && (algorithmID >= -3)) { const QRectF frontalFace = t.file.get("FrontalFace"); @@ -332,25 +326,24 @@ class utGallery : public BinaryGallery y = t.file.get("Y", 0); width = t.file.get("Width", 0); height = t.file.get("Height", 0); + confidence = t.file.get("Confidence", 0); } - const uint32_t label = t.file.get("Label", 0); - gallery.write(imageID); gallery.write((const char*) &algorithmID, sizeof(int32_t)); gallery.write((const char*) &x , sizeof(int32_t)); gallery.write((const char*) &y , sizeof(int32_t)); gallery.write((const char*) &width , sizeof(uint32_t)); gallery.write((const char*) &height , sizeof(uint32_t)); - gallery.write((const char*) &label , sizeof(uint32_t)); + gallery.write((const char*) &confidence , sizeof(float)); - const uint32_t urlSize = url.size() + 1; - gallery.write((const char*) &urlSize, sizeof(uint32_t)); + const uint32_t mdSize = metadata.size() + 1; + gallery.write((const char*) &mdSize, sizeof(uint32_t)); const uint32_t signatureSize = (algorithmID == 0) ? 0 : t.m().rows * t.m().cols * t.m().elemSize(); const uint32_t fvSize = header.size() + signatureSize; gallery.write((const char*) &fvSize, sizeof(uint32_t)); - gallery.write((const char*) url.data(), urlSize); + gallery.write((const char*) metadata.data(), mdSize); if (algorithmID != 0) { gallery.write(header); gallery.write((const char*) t.m().data, signatureSize); diff --git a/openbr/universal_template.cpp b/openbr/universal_template.cpp index 1681615..4db21ae 100644 --- a/openbr/universal_template.cpp +++ b/openbr/universal_template.cpp @@ -8,21 +8,20 @@ #include "universal_template.h" -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) +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) { - const uint32_t urlSize = strlen(url) + 1; - br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + urlSize + fvSize); - memcpy(utemplate->imageID, imageID, 16); + const uint32_t mdSize = strlen(metadata) + 1; + br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + mdSize + fvSize); utemplate->algorithmID = algorithmID; utemplate->x = x; utemplate->y = y; utemplate->width = width; utemplate->height = height; - utemplate->label = label; - utemplate->urlSize = urlSize; + utemplate->confidence = confidence; + utemplate->mdSize = mdSize; utemplate->fvSize = fvSize; - memcpy(reinterpret_cast(utemplate+1) + 0, url , urlSize); - memcpy(reinterpret_cast(utemplate+1) + urlSize, fv, fvSize); + memcpy(reinterpret_cast(utemplate+1) + 0, metadata , mdSize); + memcpy(reinterpret_cast(utemplate+1) + mdSize, featureVector, fvSize); return utemplate; } @@ -33,14 +32,14 @@ void br_free_utemplate(br_const_utemplate utemplate) void br_append_utemplate(FILE *file, br_const_utemplate utemplate) { - fwrite(utemplate, sizeof(br_universal_template) + utemplate->urlSize + utemplate->fvSize, 1, file); + fwrite(utemplate, sizeof(br_universal_template) + utemplate->mdSize + utemplate->fvSize, 1, file); } void br_iterate_utemplates(br_const_utemplate begin, br_const_utemplate end, br_utemplate_callback callback, br_callback_context context) { while (begin != end) { callback(begin, context); - begin = reinterpret_cast(reinterpret_cast(begin) + sizeof(br_universal_template) + begin->urlSize + begin->fvSize); + begin = reinterpret_cast(reinterpret_cast(begin) + sizeof(br_universal_template) + begin->mdSize + begin->fvSize); if (begin > end) qFatal("Overshot end of buffer"); } @@ -88,8 +87,8 @@ int br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_ca break; } - t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->urlSize + t->fvSize); - if (!read_buffer(file, (char*) &t->data, t->urlSize + t->fvSize)) { + t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->mdSize + t->fvSize); + if (!read_buffer(file, (char*) &t->data, t->mdSize + t->fvSize)) { free(t); // Try to rewind header read diff --git a/openbr/universal_template.h b/openbr/universal_template.h index edb90d4..3cdaa56 100644 --- a/openbr/universal_template.h +++ b/openbr/universal_template.h @@ -35,18 +35,17 @@ extern "C" { */ struct br_universal_template { - unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */ - int32_t algorithmID; /*!< interpretation of _data_ after _urlSize_. */ - int32_t x; /*!< region of interest horizontal offset (pixels). */ - int32_t y; /*!< region of interest vertical offset (pixels). */ - uint32_t width; /*!< region of interest horizontal size (pixels). */ - uint32_t height; /*!< region of interest vertical size (pixels). */ - uint32_t label; /*!< supervised training class or manually annotated ground truth. */ - uint32_t urlSize; /*!< length of null-terminated URL at the beginning of _data_, - including the null-terminator character. */ - uint32_t fvSize; /*!< length of the feature vector after the URL in _data_. */ - unsigned char data[]; /*!< (_urlSize_ + _fvSize_)-byte buffer. - The first _urlSize_ bytes represent the URL. + int32_t algorithmID; /*!< Interpretation of _data_ after _mdSize_. */ + int32_t x; /*!< Region of interest horizontal offset (pixels). */ + int32_t y; /*!< Region of interest vertical offset (pixels). */ + uint32_t width; /*!< Region of interest horizontal size (pixels). */ + uint32_t height; /*!< Region of interest vertical size (pixels). */ + float confidence; /*!< Region of interest confidence. */ + uint32_t mdSize; /*!< Length of a null-terminated metadata string at the beginning of _data_, + including the null-terminator character itself. */ + uint32_t fvSize; /*!< Length of the feature vector after the metadata in _data_. */ + unsigned char data[]; /*!< (_mdSize_ + _fvSize_)-byte buffer. + The first _mdSize_ bytes represent the metadata. The remaining _fvSize_ bytes represent the feature vector. */ }; @@ -57,7 +56,7 @@ typedef const struct br_universal_template *br_const_utemplate; * \brief br_universal_template constructor. * \see br_free_utemplate */ -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); +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); /*! * \brief br_universal_template destructor.