utils.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
  3. * Full license terms provided in LICENSE.md file.
  4. */
  5. #ifndef TRT_IMAGE_CLASSIFICATION_UTILS_H
  6. #define TRT_IMAGE_CLASSIFICATION_UTILS_H
  7. #include <opencv2/opencv.hpp>
  8. #include <vector>
  9. #include <algorithm>
  10. #include <NvInfer.h>
  11. void cvImageToTensor(const cv::Mat & image, float *tensor, nvinfer1::Dims dimensions)
  12. {
  13. const size_t channels = dimensions.d[0];
  14. const size_t height = dimensions.d[1];
  15. const size_t width = dimensions.d[2];
  16. // TODO: validate dimensions match
  17. const size_t stridesCv[3] = { width * channels, channels, 1 };
  18. const size_t strides[3] = { height * width, width, 1 };
  19. for (int i = 0; i < height; i++)
  20. {
  21. for (int j = 0; j < width; j++)
  22. {
  23. for (int k = 0; k < channels; k++)
  24. {
  25. const size_t offsetCv = i * stridesCv[0] + j * stridesCv[1] + k * stridesCv[2];
  26. const size_t offset = k * strides[0] + i * strides[1] + j * strides[2];
  27. tensor[offset] = (float) image.data[offsetCv];
  28. }
  29. }
  30. }
  31. }
  32. void preprocessVgg(float *tensor, nvinfer1::Dims dimensions)
  33. {
  34. size_t channels = dimensions.d[0];
  35. size_t height = dimensions.d[1];
  36. size_t width = dimensions.d[2];
  37. const size_t strides[3] = { height * width, width, 1 };
  38. const float mean[3] = { 123.68, 116.78, 103.94 }; // values from TensorFlow slim models code
  39. for (int i = 0; i < height; i++)
  40. {
  41. for (int j = 0; j < width; j++)
  42. {
  43. for (int k = 0; k < channels; k++)
  44. {
  45. const size_t offset = k * strides[0] + i * strides[1] + j * strides[2];
  46. tensor[offset] -= mean[k];
  47. }
  48. }
  49. }
  50. }
  51. void preprocessInception(float *tensor, nvinfer1::Dims dimensions)
  52. {
  53. size_t channels = dimensions.d[0];
  54. size_t height = dimensions.d[1];
  55. size_t width = dimensions.d[2];
  56. const size_t numel = channels * height * width;
  57. for (int i = 0; i < numel; i++)
  58. tensor[i] = 2.0 * (tensor[i] / 255.0 - 0.5); // values from TensorFlow slim models code
  59. }
  60. int argmax(float *tensor, nvinfer1::Dims dimensions)
  61. {
  62. size_t channels = dimensions.d[0];
  63. size_t height = dimensions.d[1];
  64. size_t width = dimensions.d[2];
  65. size_t numel = channels * height * width;
  66. if (numel <= 0)
  67. return 0;
  68. size_t maxIndex = 0;
  69. float max = tensor[0];
  70. for (int i = 0; i < numel; i++)
  71. {
  72. if (tensor[i] > max)
  73. {
  74. maxIndex = i;
  75. max = tensor[i];
  76. }
  77. }
  78. return maxIndex;
  79. }
  80. size_t numTensorElements(nvinfer1::Dims dimensions)
  81. {
  82. if (dimensions.nbDims == 0)
  83. return 0;
  84. size_t size = 1;
  85. for (int i = 0; i < dimensions.nbDims; i++)
  86. size *= dimensions.d[i];
  87. return size;
  88. }
  89. std::vector<size_t> argsort(float *tensor, nvinfer1::Dims dimensions)
  90. {
  91. size_t numel = numTensorElements(dimensions);
  92. std::vector<size_t> indices(numel);
  93. for (int i = 0; i < numel; i++)
  94. indices[i] = i;
  95. std::sort(indices.begin(), indices.begin() + numel, [tensor](size_t idx1, size_t idx2) {
  96. return tensor[idx1] > tensor[idx2];
  97. });
  98. return indices;
  99. }
  100. #endif