Commit 80d49c1c3240ad22d328180cd49d8125dcae1e0e

Authored by Charles Otto
1 parent ac515819

Add a simple binary .ut format, add matlab scripts to write to it

openbr/plugins/gallery/binary.cpp
@@ -228,7 +228,36 @@ class utGallery : public BinaryGallery @@ -228,7 +228,36 @@ class utGallery : public BinaryGallery
228 dataSize -= sizeof(uint32_t)*4; 228 dataSize -= sizeof(uint32_t)*4;
229 t.file.set("First_Eye", QPointF(*rightEyeX, *rightEyeY)); 229 t.file.set("First_Eye", QPointF(*rightEyeX, *rightEyeY));
230 t.file.set("Second_Eye", QPointF(*leftEyeX, *leftEyeY)); 230 t.file.set("Second_Eye", QPointF(*leftEyeX, *leftEyeY));
231 - } else { 231 + }
  232 + else if (ut.algorithmID == 7) {
  233 + // binary data consisting of a single channel matrix, of a supported type.
  234 + // 3 element header:
  235 + // uint32 datatype (single channel opencv datatype code)
  236 + // uint32 matrix rows
  237 + // uint32 matrix cols
  238 + // Followed by serialized data, in row-major order.
  239 + // #### NOTE! matlab's default order is col-major, so some work should
  240 + // be done on the matlab side to make sure that the initial serialization is correct.
  241 + uint32_t dataType = *reinterpret_cast<uint32_t*>(dataStart);
  242 + dataStart += sizeof(uint32_t);
  243 +
  244 + uint32_t matrixRows = *reinterpret_cast<uint32_t*>(dataStart);
  245 + dataStart += sizeof(uint32_t);
  246 +
  247 + uint32_t matrixCols = *reinterpret_cast<uint32_t*>(dataStart);
  248 + dataStart += sizeof(uint32_t);
  249 +
  250 + // Set metadata
  251 + t.file.set("Label", ut.label);
  252 + t.file.set("X", ut.x);
  253 + t.file.set("Y", ut.y);
  254 + t.file.set("Width", ut.width);
  255 + t.file.set("Height", ut.height);
  256 +
  257 + t.append(cv::Mat(matrixRows, matrixCols, CV_MAKETYPE(dataType, 1), dataStart).clone() /* We don't want a shallow copy! */);
  258 + return t;
  259 + }
  260 + else {
232 t.file.set("X", ut.x); 261 t.file.set("X", ut.x);
233 t.file.set("Y", ut.y); 262 t.file.set("Y", ut.y);
234 t.file.set("Width", ut.width); 263 t.file.set("Width", ut.width);
scripts/matlab/writeUT.m 0 → 100644
  1 +function writeUT(handle, matrix, imageID, roi_x, roi_y, roi_width, roi_height, label, url)
  2 +% write a single matrix of supported datatype (i.e. not int32) to the file
  3 +% handle in UT format, algorithmID 7
  4 +% inputs: file handle, single layer matrix, imageID (16 char md5 hash, can
  5 +% be empty, in which case we generated a null 16 byte string), roix, roiy,
  6 +% roiw, roih (bounding box of matrix roi), label (class label for training)
  7 +% and url (can be empty)
  8 +%
  9 +% computed values: fvSize, urlSize (url encoded as null-terminated 8-bit
  10 +% string, urlSize includes null terminator), a null terminator will be
  11 +% added to url by this function
  12 +
  13 +if (size(matrix,3) ~= 1)
  14 + disp('Cannot serialize matrix, only single channel matrices are supported');
  15 + return;
  16 +end
  17 +
  18 +
  19 +% UT format;
  20 +% struct br_universal_template
  21 +% {
  22 +% unsigned char imageID[16]; /*!< MD5 hash of the undecoded origin file. */
  23 +% int32_t algorithmID; /*!< interpretation of _data_ after _urlSize_. */
  24 +% int32_t x; /*!< region of interest horizontal offset (pixels). */
  25 +% int32_t y; /*!< region of interest vertical offset (pixels). */
  26 +% uint32_t width; /*!< region of interest horizontal size (pixels). */
  27 +% uint32_t height; /*!< region of interest vertical size (pixels). */
  28 +% uint32_t label; /*!< supervised training class or manually annotated ground truth. */
  29 +% uint32_t urlSize; /*!< length of null-terminated URL at the beginning of _data_,
  30 +% including the null-terminator character. */
  31 +% uint32_t fvSize; /*!< length of the feature vector after the URL in _data_. */
  32 +% unsigned char data[]; /*!< (_urlSize_ + _fvSize_)-byte buffer.
  33 +% The first _urlSize_ bytes represent the URL.
  34 +% The remaining _fvSize_ bytes represent the feature vector. */
  35 +% };
  36 +
  37 +% algorithm 7 binary data format:
  38 +% uint32 datatype code (copied from opencv, base datatype codes, single
  39 +% channel is assumed)
  40 +% uint32 matrix rows
  41 +% uint32 matrix cols
  42 +% row-major serialization of matrix
  43 +
  44 +% opencv data type definitions
  45 +% #define CV_8U 0
  46 +% #define CV_8S 1
  47 +% #define CV_16U 2
  48 +% #define CV_16S 3
  49 +% #define CV_32S 4
  50 +% #define CV_32F 5
  51 +% #define CV_64F 6
  52 +% #define CV_USRTYPE1 7
  53 +
  54 +if (numel(imageID) ~= 16)
  55 + imageID = uint8(zeros(16,1));
  56 +end
  57 +
  58 +% fixed for this function
  59 +algorithmID = 7;
  60 +
  61 +% append null terminator
  62 +url = [url, '\0'];
  63 +% calculate complete string length
  64 +urlSize = uint32(length(url));
  65 +
  66 +% figure out datatype code based on the input matrix's data type
  67 +matlab_type = class(matrix(1,1));
  68 +
  69 +type_code = uint32(0);
  70 +% bytes per element
  71 +typeSize = 1;
  72 +
  73 +switch(matlab_type)
  74 + case 'uint8'
  75 + type_code = 0;
  76 + typeSize = 1;
  77 + case 'int8'
  78 + type_code = 1;
  79 + typeSize = 1;
  80 + case 'uint16'
  81 + type_code = 2;
  82 + typeSize = 2;
  83 + case 'int16'
  84 + type_code = 3;
  85 + typeSize = 2;
  86 + case 'uint32'
  87 + disp(' uint32 datatype not supported, please try again');
  88 + return;
  89 + case 'int32'
  90 + type_code = 4;
  91 + typeSize = 4;
  92 +
  93 + case 'single'
  94 + type_code = 5;
  95 + typeSize = 4;
  96 + case 'double'
  97 + type_code = 6;
  98 + typeSize = 8;
  99 + otherwise
  100 + disp(['Unrecognized matlab datatype, ', matlab_type]);
  101 + return;
  102 +end
  103 +
  104 +% total size of feature vecotr in bytes, plus 12 byte header encoding
  105 +% [uint32 datatype, copied from opencv codes; uint32(matrix width);
  106 +% uint32(matrix height)]
  107 +fvSize = uint32(typeSize * numel(matrix) + 4*3);
  108 +
  109 +% imageID
  110 +fwrite(handle, imageID, 'uint8');
  111 +
  112 +% algorithmID
  113 +fwrite(handle, algorithmID, 'int32');
  114 +
  115 +% roi x
  116 +fwrite(handle, roi_x, 'uint32');
  117 +% roi y
  118 +fwrite(handle, roi_y, 'uint32');
  119 +% roi width
  120 +fwrite(handle, roi_width, 'uint32');
  121 +
  122 +% roi height
  123 +fwrite(handle, roi_height, 'uint32');
  124 +
  125 +% label
  126 +fwrite(handle, label, 'uint32');
  127 +
  128 +% url size
  129 +fwrite(handle, urlSize, 'uint32');
  130 +
  131 +% feature vector size
  132 +fwrite(handle, fvSize, 'uint32');
  133 +
  134 +% url (just writing a single null byte)
  135 +fwrite(handle, url, 'uint8');
  136 +
  137 +% binary data header -- datatype code, row count, col count
  138 +fwrite(handle, type_code,'uint32');
  139 +fwrite(handle, uint32(size(matrix,1)), 'uint32');
  140 +fwrite(handle, uint32(size(matrix,2)), 'uint32');
  141 +
  142 +% write feature vector data, explicit row-major enumeration, matrix(:) is
  143 +% col-major
  144 +for i = 1:size(matrix,1)
  145 + fwrite(handle, matrix(i,:), matlab_type);
  146 +end
  147 +
  148 +
  149 +
scripts/matlab/writeUTFVectors.m 0 → 100644
  1 +function writeUTFVectors(handle, fvectors)
  2 +% write the rows of fvectors as separate ut format 7 templates. Dummy
  3 +% values will be used for roi settings/imageID/url/etc.
  4 +% handle will not be opened/closed by this function.
  5 +%
  6 +% see also writeUT
  7 +
  8 +
  9 +dummy_ID = [];
  10 +roi_x = uint32(0);
  11 +roi_y = uint32(0);
  12 +roi_width = uint32(0);
  13 +roi_height = uint32(0);
  14 +label = uint32(0);
  15 +
  16 +urlTotal = '';
  17 +for i = 1:size(fvectors,1)
  18 + writeUT(handle, fvectors(i,:), dummy_ID, roi_x, roi_y, roi_width, roi_height, label, urlTotal);
  19 +
  20 +end
  21 +