From 80d49c1c3240ad22d328180cd49d8125dcae1e0e Mon Sep 17 00:00:00 2001 From: Charles Otto Date: Tue, 24 Feb 2015 12:03:31 -0800 Subject: [PATCH] Add a simple binary .ut format, add matlab scripts to write to it --- openbr/plugins/gallery/binary.cpp | 31 ++++++++++++++++++++++++++++++- scripts/matlab/writeUT.m | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ scripts/matlab/writeUTFVectors.m | 21 +++++++++++++++++++++ 3 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 scripts/matlab/writeUT.m create mode 100644 scripts/matlab/writeUTFVectors.m diff --git a/openbr/plugins/gallery/binary.cpp b/openbr/plugins/gallery/binary.cpp index eca2cd7..1f7a94d 100644 --- a/openbr/plugins/gallery/binary.cpp +++ b/openbr/plugins/gallery/binary.cpp @@ -228,7 +228,36 @@ 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 { + } + else if (ut.algorithmID == 7) { + // binary data consisting of a single channel matrix, of a supported type. + // 3 element header: + // uint32 datatype (single channel opencv datatype code) + // uint32 matrix rows + // uint32 matrix cols + // Followed by serialized data, in row-major order. + // #### NOTE! matlab's default order is col-major, so some work should + // be done on the matlab side to make sure that the initial serialization is correct. + uint32_t dataType = *reinterpret_cast(dataStart); + dataStart += sizeof(uint32_t); + + uint32_t matrixRows = *reinterpret_cast(dataStart); + dataStart += sizeof(uint32_t); + + uint32_t matrixCols = *reinterpret_cast(dataStart); + dataStart += sizeof(uint32_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.append(cv::Mat(matrixRows, matrixCols, CV_MAKETYPE(dataType, 1), dataStart).clone() /* We don't want a shallow copy! */); + return t; + } + else { t.file.set("X", ut.x); t.file.set("Y", ut.y); t.file.set("Width", ut.width); diff --git a/scripts/matlab/writeUT.m b/scripts/matlab/writeUT.m new file mode 100644 index 0000000..70d0340 --- /dev/null +++ b/scripts/matlab/writeUT.m @@ -0,0 +1,149 @@ +function writeUT(handle, matrix, imageID, roi_x, roi_y, roi_width, roi_height, label, url) +% write a single matrix of supported datatype (i.e. not int32) to the file +% handle in UT format, algorithmID 7 +% inputs: file handle, single layer matrix, imageID (16 char md5 hash, can +% be empty, in which case we generated a null 16 byte string), roix, roiy, +% roiw, roih (bounding box of matrix roi), label (class label for training) +% and url (can be empty) +% +% computed values: fvSize, urlSize (url encoded as null-terminated 8-bit +% string, urlSize includes null terminator), a null terminator will be +% added to url by this function + +if (size(matrix,3) ~= 1) + disp('Cannot serialize matrix, only single channel matrices are supported'); + return; +end + + +% UT format; +% 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. +% The remaining _fvSize_ bytes represent the feature vector. */ +% }; + +% algorithm 7 binary data format: +% uint32 datatype code (copied from opencv, base datatype codes, single +% channel is assumed) +% uint32 matrix rows +% uint32 matrix cols +% row-major serialization of matrix + +% opencv data type definitions +% #define CV_8U 0 +% #define CV_8S 1 +% #define CV_16U 2 +% #define CV_16S 3 +% #define CV_32S 4 +% #define CV_32F 5 +% #define CV_64F 6 +% #define CV_USRTYPE1 7 + +if (numel(imageID) ~= 16) + imageID = uint8(zeros(16,1)); +end + +% fixed for this function +algorithmID = 7; + +% append null terminator +url = [url, '\0']; +% calculate complete string length +urlSize = uint32(length(url)); + +% figure out datatype code based on the input matrix's data type +matlab_type = class(matrix(1,1)); + +type_code = uint32(0); +% bytes per element +typeSize = 1; + +switch(matlab_type) + case 'uint8' + type_code = 0; + typeSize = 1; + case 'int8' + type_code = 1; + typeSize = 1; + case 'uint16' + type_code = 2; + typeSize = 2; + case 'int16' + type_code = 3; + typeSize = 2; + case 'uint32' + disp(' uint32 datatype not supported, please try again'); + return; + case 'int32' + type_code = 4; + typeSize = 4; + + case 'single' + type_code = 5; + typeSize = 4; + case 'double' + type_code = 6; + typeSize = 8; + otherwise + disp(['Unrecognized matlab datatype, ', matlab_type]); + return; +end + +% total size of feature vecotr in bytes, plus 12 byte header encoding +% [uint32 datatype, copied from opencv codes; uint32(matrix width); +% uint32(matrix height)] +fvSize = uint32(typeSize * numel(matrix) + 4*3); + +% imageID +fwrite(handle, imageID, 'uint8'); + +% algorithmID +fwrite(handle, algorithmID, 'int32'); + +% roi x +fwrite(handle, roi_x, 'uint32'); +% roi y +fwrite(handle, roi_y, 'uint32'); +% roi width +fwrite(handle, roi_width, 'uint32'); + +% roi height +fwrite(handle, roi_height, 'uint32'); + +% label +fwrite(handle, label, 'uint32'); + +% url size +fwrite(handle, urlSize, 'uint32'); + +% feature vector size +fwrite(handle, fvSize, 'uint32'); + +% url (just writing a single null byte) +fwrite(handle, url, 'uint8'); + +% binary data header -- datatype code, row count, col count +fwrite(handle, type_code,'uint32'); +fwrite(handle, uint32(size(matrix,1)), 'uint32'); +fwrite(handle, uint32(size(matrix,2)), 'uint32'); + +% write feature vector data, explicit row-major enumeration, matrix(:) is +% col-major +for i = 1:size(matrix,1) + fwrite(handle, matrix(i,:), matlab_type); +end + + + diff --git a/scripts/matlab/writeUTFVectors.m b/scripts/matlab/writeUTFVectors.m new file mode 100644 index 0000000..5b0d00c --- /dev/null +++ b/scripts/matlab/writeUTFVectors.m @@ -0,0 +1,21 @@ +function writeUTFVectors(handle, fvectors) +% write the rows of fvectors as separate ut format 7 templates. Dummy +% values will be used for roi settings/imageID/url/etc. +% handle will not be opened/closed by this function. +% +% see also writeUT + + +dummy_ID = []; +roi_x = uint32(0); +roi_y = uint32(0); +roi_width = uint32(0); +roi_height = uint32(0); +label = uint32(0); + +urlTotal = ''; +for i = 1:size(fvectors,1) + writeUT(handle, fvectors(i,:), dummy_ID, roi_x, roi_y, roi_width, roi_height, label, urlTotal); + +end + -- libgit2 0.21.4