JeVois  1.16
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Utils.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2020 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 #include <jevois/DNN/Utils.H>
19 #include <jevois/Util/Utils.H>
20 #include <jevois/Debug/Log.H>
21 #include <fstream>
22 #include <regex>
23 
24 // ##############################################################################################################
25 std::map<int, std::string> jevois::dnn::readLabelsFile(std::string const & fname)
26 {
27  std::ifstream ifs(fname);
28  if (ifs.is_open() == false) LFATAL("Failed to open file " << fname);
29 
30  size_t linenum = 1; std::map<int, std::string> ret; int id = 0;
31  for (std::string line; std::getline(ifs, line); ++linenum)
32  {
33  size_t idx1 = line.find_first_not_of(" \t"); if (idx1 == line.npos) continue;
34  size_t idx2 = line.find_last_not_of(" \t\r\n"); if (idx2 == line.npos) continue;
35  if (line[idx1] == '#') continue;
36 
37  try { id = std::stoi(line, &idx1); idx1 = line.find_first_not_of("0123456789 \t,:", idx1); } catch (...) { }
38 
39  std::string classname;
40  if (idx1 >= idx2)
41  {
42  LERROR(fname << ':' << linenum << ": empty class name -- REPLACING BY 'unspecified'");
43  classname = "unspecified";
44  }
45  else classname = line.substr(idx1, idx2 + 1 - idx1);
46 
47  // Possibly replace two double quotes by one:
48  classname = std::regex_replace(classname, std::regex("\"\""), "\"");
49 
50  // Possibly remove enclosing double quotes:
51  size_t len = classname.length();
52  if (len > 1 && classname[0] == '"' && classname[len-1] == '"') classname = classname.substr(1, len-2);
53 
54  ret[id] = classname;
55 
56  // Increment id in case no ID number is given in the file:
57  ++id;
58  }
59 
60  ifs.close();
61 
62  LINFO("Loaded " << ret.size() << " class names from " << fname);
63 
64  return ret;
65 }
66 
67 // ##############################################################################################################
68 std::string jevois::dnn::getLabel(std::map<int, std::string> const & labels, int id)
69 {
70  auto itr = labels.find(id);
71  if (itr == labels.end()) return std::to_string(id);
72  return itr->second;
73 }
74 
75 // ##############################################################################################################
76 int jevois::dnn::stringToRGBA(std::string const & label, unsigned char alpha)
77 {
78  int col = 0x80808080;
79  for (char const c : label) col = c + ((col << 5) - col);
80  col = (col & 0xffffff) | (alpha << 24);
81  return col;
82 }
83 
84 // ##############################################################################################################
85 void jevois::dnn::topK(float const * pfProb, float * pfMaxProb, uint32_t * pMaxClass, uint32_t outputCount,
86  uint32_t topNum)
87 {
88  memset(pfMaxProb, 0xfe, sizeof(float) * topNum);
89  memset(pMaxClass, 0xff, sizeof(float) * topNum);
90 
91  for (uint32_t j = 0; j < topNum; ++j)
92  {
93  for (uint32_t i = 0; i < outputCount; ++i)
94  {
95  uint32_t k;
96  for (k = 0; k < topNum; ++k) if (i == pMaxClass[k]) break;
97  if (k != topNum) continue;
98 
99  if (pfProb[i] > pfMaxProb[j]) { pfMaxProb[j] = pfProb[i]; pMaxClass[j] = i; }
100  }
101  }
102 }
103 
104 // ##############################################################################################################
105 std::string jevois::dnn::shapestr(cv::Mat const & m)
106 {
107  cv::MatSize const & ms = m.size; int const nd = ms.dims();
108  std::string ret = std::to_string(nd) + "D ";
109  for (int i = 0; i < nd; ++i) ret += std::to_string(ms[i]) + (i < nd-1 ? "x" : "");
110  ret += ' ' + jevois::cvtypestr(m.type());
111  return ret;
112 }
113 
114 // ##############################################################################################################
115 std::string jevois::dnn::shapestr(TfLiteTensor const * t)
116 {
117 
118  TfLiteIntArray const & dims = *t->dims;
119  std::string ret = std::to_string(dims.size) + "D ";
120  for (int i = 0; i < dims.size; ++i) ret += std::to_string(dims.data[i]) + (i < dims.size-1 ? "x" : "");
121 
122  // Do not use TfLiteTypeGetName() as it returns different names...
123  switch (t->type)
124  {
125  case kTfLiteNoType: ret += " NoType"; break;
126  case kTfLiteFloat32: ret += " 32F"; break;
127  case kTfLiteInt32: ret += " 32S"; break;
128  case kTfLiteUInt8: ret += " 8U"; break;
129  case kTfLiteInt64: ret += " 64S"; break;
130  case kTfLiteString: ret += " String"; break;
131  case kTfLiteBool: ret += " 8B"; break;
132  case kTfLiteInt16: ret += " 16S"; break;
133  case kTfLiteComplex64: ret += " 64C"; break;
134  case kTfLiteInt8: ret += " 8I"; break;
135  case kTfLiteFloat16: ret += " 16F"; break;
136  case kTfLiteFloat64: ret += " 64F"; break;
137  case kTfLiteComplex128: ret += " 128C"; break;
138  default: ret += " UnknownType"; break;
139  }
140  return ret;
141 }
142 
143 // ##############################################################################################################
144 std::string jevois::dnn::shapestr(vsi_nn_tensor_attr_t const & attr)
145 {
146  std::string ret = std::to_string(attr.dim_num) + "D ";
147  for (uint32_t i = 0; i < attr.dim_num; ++i)
148  ret += std::to_string(attr.size[attr.dim_num-1-i]) + (i < attr.dim_num-1 ? "x" : "");
149 
150  // Value type:
151  switch (attr.dtype.vx_type)
152  {
153  case VSI_NN_TYPE_UINT8: ret += " 8U"; break;
154  case VSI_NN_TYPE_INT8: ret += " 8S"; break;
155  case VSI_NN_TYPE_BOOL8: ret += " 8B"; break;
156  case VSI_NN_TYPE_UINT16: ret += " 16U"; break;
157  case VSI_NN_TYPE_INT16: ret += " 16S"; break;
158  case VSI_NN_TYPE_FLOAT16: ret += " 16F"; break;
159  case VSI_NN_TYPE_BFLOAT16: ret += " 16B"; break;
160  case VSI_NN_TYPE_UINT32: ret += " 32U"; break;
161  case VSI_NN_TYPE_INT32: ret += " 32S"; break;
162  case VSI_NN_TYPE_FLOAT32: ret += " 32F"; break;
163  case VSI_NN_TYPE_UINT64: ret += " 64U"; break;
164  case VSI_NN_TYPE_INT64: ret += " 64S"; break;
165  case VSI_NN_TYPE_FLOAT64: ret += " 64F"; break;
166  default: throw std::range_error("shapestr: Unsupported tensor type " + std::to_string(attr.dtype.vx_type));
167  }
168 
169  return ret;
170 }
171 
172 // ##############################################################################################################
173 std::vector<size_t> jevois::dnn::strshape(std::string const & str)
174 {
175  std::vector<size_t> ret;
176  auto tok = jevois::split(str, "x");
177  for (std::string const & t : tok) ret.emplace_back(std::stoi(t));
178  return ret;
179 }
180 
181 // ##############################################################################################################
182 int jevois::dnn::tf2cv(TfLiteType t)
183 {
184  switch (t)
185  {
186  case kTfLiteFloat32: return CV_32F;
187  case kTfLiteInt32: return CV_32S;
188  case kTfLiteUInt8: return CV_8U;
189  case kTfLiteInt16: return CV_16S;
190  case kTfLiteInt8: return CV_8S;
191  case kTfLiteFloat16: return CV_16S;
192  case kTfLiteFloat64: return CV_64F;
193  //case kTfLiteComplex128:
194  //case kTfLiteComplex64:
195  //case kTfLiteBool:
196  //case kTfLiteString:
197  //case kTfLiteInt64:
198  //case kTfLiteNoType:
199  default:
200  LFATAL("Unsupported type " << TfLiteTypeGetName(t));
201  }
202 }
203 
204 // ##############################################################################################################
205 int jevois::dnn::vsi2cv(vsi_nn_type_e t)
206 {
207  switch (t)
208  {
209  case VSI_NN_TYPE_UINT8: return CV_8U;
210  case VSI_NN_TYPE_INT8: return CV_8S;
211  case VSI_NN_TYPE_BOOL8: return CV_8U;
212  case VSI_NN_TYPE_UINT16: return CV_16U;
213  case VSI_NN_TYPE_INT16: return CV_16S;
214  case VSI_NN_TYPE_FLOAT16: return CV_16F;
215  case VSI_NN_TYPE_BFLOAT16: return CV_16F; // check
216  //case VSI_NN_TYPE_UINT32: return CV_32U; // unsupported by opencv
217  case VSI_NN_TYPE_INT32: return CV_32S;
218  case VSI_NN_TYPE_FLOAT32: return CV_32F;
219  //case VSI_NN_TYPE_UINT64: return CV_64U; // unsupported by opencv
220  //case VSI_NN_TYPE_INT64: return CV_64S; // unsupported by opencv
221  case VSI_NN_TYPE_FLOAT64: return CV_64F;
222  default: throw std::range_error("vsi2cv: Unsupported tensor type " + std::to_string(t));
223  }
224 }
225 
226 // ##############################################################################################################
227 vsi_nn_type_e jevois::dnn::tf2vsi(TfLiteType t)
228 {
229  switch (t)
230  {
231  case kTfLiteFloat32: return VSI_NN_TYPE_FLOAT32;
232  case kTfLiteInt32: return VSI_NN_TYPE_INT32;
233  case kTfLiteUInt8: return VSI_NN_TYPE_UINT8;
234  case kTfLiteInt16: return VSI_NN_TYPE_INT16;
235  case kTfLiteInt8: return VSI_NN_TYPE_INT8;
236  case kTfLiteFloat16: return VSI_NN_TYPE_FLOAT16;
237  case kTfLiteFloat64: return VSI_NN_TYPE_FLOAT64;
238  case kTfLiteInt64: return VSI_NN_TYPE_INT64;
239  case kTfLiteBool: return VSI_NN_TYPE_BOOL8; // fixme: need to check
240  case kTfLiteNoType: return VSI_NN_TYPE_NONE;
241  //case kTfLiteComplex128:
242  //case kTfLiteComplex64:
243  //case kTfLiteString:
244  default:
245  LFATAL("Unsupported type " << TfLiteTypeGetName(t));
246  }
247 }
248 
249 // ##############################################################################################################
250 void jevois::dnn::clamp(cv::Rect & r, int width, int height)
251 {
252  int tx = std::min(width - 1, std::max(0, r.x));
253  int ty = std::min(height - 1, std::max(0, r.y));
254  int bx = std::min(width - 1, std::max(0, r.x + r.width));
255  int by = std::min(height - 1, std::max(0, r.y + r.height));
256  r.x = tx; r.y = ty; r.width = bx - tx; r.height = by - ty;
257 }
258 
259 // ##############################################################################################################
260 std::vector<vsi_nn_tensor_attr_t> jevois::dnn::parseTensorSpecs(std::string const & specs)
261 {
262  char const * const specdef = "[NCHW:|NHWC:|NA:|AUTO:]Type:[NxCxHxW|NxHxWxC|...][:QNT[:fl|:scale:zero]]";
263  std::vector<std::string> spectok = jevois::split(specs, ",\\s*");
264  std::vector<vsi_nn_tensor_attr_t> ret;
265 
266  for (std::string const & spec : spectok)
267  {
268  vsi_nn_tensor_attr_t attr; memset(&attr, 0, sizeof(attr));
269 
270  // NCHW:Type:NxCxHxW:QNT:scale:mean
271  std::vector<std::string> tok = jevois::split(spec, ":");
272  if (tok.size() < 2) throw std::runtime_error("parseTensorSpecs: Malformed tensor spec ["+spec+"] not "+specdef);
273 
274  // Decode optional shape:
275  size_t n = 0; // next tok to parse
276  if (tok[0] == "NCHW") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_NCHW; } // planar RGB
277  else if (tok[0] == "NHWC") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_NHWC; } // packed RGB
278  else if (tok[0] == "NA") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_NA; }
279  else if (tok[0] == "AUTO") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO; }
280  else attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO; // use AUTO if it was not given
281 
282  // We need at least type and dims:
283  if (tok.size() < n+2) throw std::runtime_error("parseTensorSpecs: Malformed tensor spec ["+spec+"] not "+specdef);
284 
285  // Decode type and convert to vsi:
286  if (tok[n] == "8U") attr.dtype.vx_type = VSI_NN_TYPE_UINT8;
287  else if (tok[n] == "8S") attr.dtype.vx_type = VSI_NN_TYPE_INT8;
288  else if (tok[n] == "8B") attr.dtype.vx_type = VSI_NN_TYPE_BOOL8;
289  else if (tok[n] == "16U") attr.dtype.vx_type = VSI_NN_TYPE_UINT16;
290  else if (tok[n] == "16S") attr.dtype.vx_type = VSI_NN_TYPE_INT16;
291  else if (tok[n] == "16F") attr.dtype.vx_type = VSI_NN_TYPE_FLOAT16;
292  else if (tok[n] == "16B") attr.dtype.vx_type = VSI_NN_TYPE_BFLOAT16;
293  else if (tok[n] == "32U") attr.dtype.vx_type = VSI_NN_TYPE_UINT32;
294  else if (tok[n] == "32S") attr.dtype.vx_type = VSI_NN_TYPE_INT32;
295  else if (tok[n] == "32F") attr.dtype.vx_type = VSI_NN_TYPE_FLOAT32;
296  else if (tok[n] == "64U") attr.dtype.vx_type = VSI_NN_TYPE_UINT64;
297  else if (tok[n] == "64S") attr.dtype.vx_type = VSI_NN_TYPE_INT64;
298  else if (tok[n] == "64F") attr.dtype.vx_type = VSI_NN_TYPE_FLOAT64;
299  else throw std::range_error("parseTensorSpecs: Invalid tensor type [" + tok[n] + "] in " + spec);
300  ++n; // next token
301 
302  // Decode the dims:
303  std::vector<size_t> dims = jevois::dnn::strshape(tok[n]);
304  attr.dim_num = dims.size();
305  for (size_t i = 0; i < attr.dim_num; ++i) attr.size[attr.dim_num - 1 - i] = dims[i];
306  ++n; // next token
307 
308  // Decode optional quantization type and its possible extra parameters:
309  if (n == tok.size() || tok[n] == "NONE")
310  {
311  attr.dtype.qnt_type = VSI_NN_QNT_TYPE_NONE;
312  }
313  else if (tok[n] == "DFP")
314  {
315  attr.dtype.qnt_type = VSI_NN_QNT_TYPE_DFP;
316  if (tok.size() != n+2)
317  throw std::range_error("parseTensorSpecs: In "+spec+", DFP quantization needs :fl param (" + specdef + ')');
318  attr.dtype.fl = std::stoi(tok[n+1]);
319  }
320 
321  else if (tok[n] == "AA")
322  {
323  attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
324  if (tok.size() != n+3)
325  throw std::range_error("parseTensorSpecs: In "+spec+", AA quantization needs :scale:zero params ("+specdef+')');
326  attr.dtype.scale = std::stof(tok[n+1]);
327  attr.dtype.zero_point = std::stoi(tok[n+2]);
328  }
329  else if (tok[n] == "APS")
330  {
331  attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_PERCHANNEL_SYMMETRIC;
332  throw std::range_error("parseTensorSpecs: In " + spec + ", AFFINE_PERCHANNEL_SYMMETRIC quant not yet supported");
333  }
334  else throw std::range_error("parseTensorSpecs: Invalid quantization type in " + spec);
335 
336  // Done with this tensor:
337  ret.emplace_back(attr);
338  }
339 
340  return ret;
341 }
342 
343 // ##############################################################################################################
344 cv::Size jevois::dnn::attrsize(vsi_nn_tensor_attr_t const & attr)
345 {
346  switch (attr.dtype.fmt)
347  {
348  case VSI_NN_DIM_FMT_NHWC:
349  if (attr.dim_num < 3) throw std::range_error("attrsize: need at least 3D, got " + jevois::dnn::attrstr(attr));
350  return cv::Size(attr.size[1], attr.size[2]);
351 
352  case VSI_NN_DIM_FMT_NCHW:
353  default:
354  if (attr.dim_num < 2) throw std::range_error("attrsize: need at least 2D, got " + jevois::dnn::attrstr(attr));
355  return cv::Size(attr.size[0], attr.size[1]);
356  }
357 }
358 
359 // ##############################################################################################################
360 std::string jevois::dnn::attrstr(vsi_nn_tensor_attr_t const & attr)
361 {
362  std::string ret;
363 
364  // Dimension ordering:
365  switch (attr.dtype.fmt)
366  {
367  case VSI_NN_DIM_FMT_NCHW: ret += "NCHW:"; break;
368  case VSI_NN_DIM_FMT_NHWC: ret += "NHWC:"; break;
369  default: break;
370  }
371 
372  // Value type:
373  switch (attr.dtype.vx_type)
374  {
375  case VSI_NN_TYPE_UINT8: ret += "8U:"; break;
376  case VSI_NN_TYPE_INT8: ret += "8S:"; break;
377  case VSI_NN_TYPE_BOOL8: ret += "8B:"; break;
378  case VSI_NN_TYPE_UINT16: ret += "16U:"; break;
379  case VSI_NN_TYPE_INT16: ret += "16S:"; break;
380  case VSI_NN_TYPE_FLOAT16: ret += "16F:"; break;
381  case VSI_NN_TYPE_BFLOAT16: ret += "16B:"; break;
382  case VSI_NN_TYPE_UINT32: ret += "32U:"; break;
383  case VSI_NN_TYPE_INT32: ret += "32S:"; break;
384  case VSI_NN_TYPE_FLOAT32: ret += "32F:"; break;
385  case VSI_NN_TYPE_UINT64: ret += "64U:"; break;
386  case VSI_NN_TYPE_INT64: ret += "64S:"; break;
387  case VSI_NN_TYPE_FLOAT64: ret += "64F:"; break;
388  default: std::range_error("attrstr: Unsupported tensor type " + std::to_string(attr.dtype.vx_type));
389  }
390 
391  // Dims:
392  for (uint32_t i = 0; i < attr.dim_num; ++i)
393  ret += std::to_string(attr.size[attr.dim_num - 1 - i]) + ((i<attr.dim_num-1) ? 'x' : ':');
394 
395  // Quantization:
396  switch (attr.dtype.qnt_type)
397  {
398  case VSI_NN_QNT_TYPE_NONE: ret += ":NONE"; break;
399  case VSI_NN_QNT_TYPE_DFP: ret += ":DFP:" + std::to_string(attr.dtype.fl); break;
400  case VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC: ret += ":AA:" + std::to_string(attr.dtype.scale) + ':' +
401  std::to_string(attr.dtype.zero_point); break;
402  case VSI_NN_QNT_TYPE_AFFINE_PERCHANNEL_SYMMETRIC: ret += ":APS:unsupported"; break;
403  default: std::range_error("attrstr: Unsupported tensor quantization " + std::to_string(attr.dtype.qnt_type));
404  }
405 
406  return ret;
407 }
408 
409 // ##############################################################################################################
410 vsi_nn_tensor_attr_t jevois::dnn::tensorattr(TfLiteTensor const * t)
411 {
412  vsi_nn_tensor_attr_t attr; memset(&attr, 0, sizeof(attr));
413  attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO;
414  attr.dtype.vx_type = jevois::dnn::tf2vsi(t->type);
415 
416  switch (t->quantization.type)
417  {
418  case kTfLiteNoQuantization:
419  attr.dtype.qnt_type = VSI_NN_QNT_TYPE_NONE;
420  break;
421 
422  case kTfLiteAffineQuantization:
423  {
424  attr.dtype.qnt_type = VSI_NN_QNT_TYPE_DFP;
425  //TfLiteAffineQuantization const * q = reinterpret_cast<TfLiteAffineQuantization const *>(t->quantization.params);
426  //attr.dtype.scale = q->scale[0];//fixme
427  //attr.dtype.zero_point = q->zero_point[0]; //fixme
428  // FIXME q->quantized_dimension
429  }
430  break;
431 
432  default: LFATAL("unsupported quantization " << t->quantization.type);
433  }
434 
435  TfLiteIntArray const & dims = *t->dims;
436  attr.dim_num = dims.size;
437  for (int i = 0; i < dims.size; ++i) attr.size[dims.size - 1 - i] = dims.data[i];
438 
439  return attr;
440 }
441 
442 // ##############################################################################################################
443 void jevois::dnn::softmax(float const * input, size_t n, float fac, float * output)
444 {
445  float sum = 0.0F;
446  float largest = -FLT_MAX;
447  for (size_t i = 0; i < n; ++i) if (input[i] > largest) largest = input[i];
448  for (size_t i = 0; i < n; ++i)
449  {
450  float e = exp(input[i]/fac - largest/fac);
451  sum += e;
452  output[i] = e;
453  }
454  if (sum) for (size_t i = 0; i < n; ++i) output[i] /= sum;
455 }
jevois::dnn::clamp
void clamp(cv::Rect &r, int width, int height)
Clamp a rectangle to within given image width and height.
Definition: Utils.C:250
jevois::dnn::tf2cv
int tf2cv(TfLiteType t)
Convert from TensorFlow data type to OpenCV.
Definition: Utils.C:182
jevois::split
std::vector< std::string > split(std::string const &input, std::string const &regex="\\s+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
Definition: Utils.C:257
jevois::cvtypestr
std::string cvtypestr(unsigned int cvtype)
Convert cv::Mat::type() code to to a string (e.g., CV_8UC1, CV_32SC3, etc)
Definition: Utils.C:57
Utils.H
jevois::dnn::vsi2cv
int vsi2cv(vsi_nn_type_e t)
Convert from NPU data type to OpenCV.
Definition: Utils.C:205
jevois::dnn::tensorattr
vsi_nn_tensor_attr_t tensorattr(TfLiteTensor const *t)
Get tensor shape and type attributes for a TensorFlow Lite tensor.
Definition: Utils.C:410
jevois::dnn::stringToRGBA
int stringToRGBA(std::string const &label, unsigned char alpha=128)
Compute a color from a label name.
Definition: Utils.C:76
jevois::dnn::readLabelsFile
std::map< int, std::string > readLabelsFile(std::string const &fname)
Read a label file.
Definition: Utils.C:25
LERROR
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
Definition: Log.H:198
jevois::dnn::parseTensorSpecs
std::vector< vsi_nn_tensor_attr_t > parseTensorSpecs(std::string const &specs)
Parse tensor specification.
Definition: Utils.C:260
jevois::dnn::shapestr
std::string shapestr(cv::Mat const &m)
Get a string of the form: "nD AxBxC... TYPE" from an n-dimensional cv::Mat with data type TYPE.
Definition: Utils.C:105
jevois::dnn::getLabel
std::string getLabel(std::map< int, std::string > const &labels, int id)
Get a label from an id.
Definition: Utils.C:68
Log.H
LFATAL
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
Definition: Log.H:217
jevois::dnn::strshape
std::vector< size_t > strshape(std::string const &str)
Get a vector of size_t from a string containing AxBxC...
Definition: Utils.C:173
jevois::to_string
std::string to_string(T const &val)
Convert from type to string.
jevois::dnn::attrsize
cv::Size attrsize(vsi_nn_tensor_attr_t const &attr)
Get a tensor's size in cv::Size format.
Definition: Utils.C:344
jevois::dnn::softmax
void softmax(float const *input, size_t n, float fac, float *output)
Apply softmax to a float vector.
Definition: Utils.C:443
jevois::dnn::attrstr
std::string attrstr(vsi_nn_tensor_attr_t const &attr)
Get a string describing the specs of a tensor.
Definition: Utils.C:360
Utils.H
jevois::dnn::tf2vsi
vsi_nn_type_e tf2vsi(TfLiteType t)
Convert from TensorFlow data type to vsi_nn.
Definition: Utils.C:227
LINFO
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
Definition: Log.H:181
jevois::dnn::topK
void topK(float const *pfProb, float *pfMaxProb, uint32_t *pMaxClass, uint32_t outputCount, uint32_t topNum)
Get top-k entries and their indices.
Definition: Utils.C:85