writeUT.m
4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
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
%
% For performance reasons, handle should be opened in 'W', i.e. buffered
% mode.
% 512 -- max supported channels in cv::Mat
if (size(matrix,3) > 512)
disp('Cannot serialize matrix, 512 is the max depth 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:
% uint16 datatype code (copied from opencv, base datatype codes, single
% channel is assumed)
% uint32 matrix rows
% uint32 matrix cols
% uint16 channel count (max valid is 512)
% channels->rows->columns
% 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, channel count
% (max 512). Datatype and channel count are uint16, dimensions are uint32
fwrite(handle, type_code,'uint16');
fwrite(handle, uint32(size(matrix,1)), 'uint32');
fwrite(handle, uint32(size(matrix,2)), 'uint32');
fwrite(handle, uint16(size(matrix,3)), 'uint16');
% write data, explicit row-major enumeration, matrix(:) is col-major,
% followed by depth. By permuting the dimensions, we can put the bytes in
% an appropriate order:
permuted = permute(matrix,[3,2,1]);
fwrite(handle, permuted(:), matlab_type);