affine.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #ifndef AFFINE_HPP__
  2. #define AFFINE_HPP__
  3. #include <memory>
  4. #include <cuda_runtime.h>
  5. namespace affine
  6. {
  7. enum class NormType : int { None = 0, MeanStd = 1, AlphaBeta = 2 };
  8. enum class ChannelType : int { None = 0, SwapRB = 1 };
  9. struct Norm
  10. {
  11. float mean[3];
  12. float std[3];
  13. float alpha, beta;
  14. NormType type = NormType::None;
  15. ChannelType channel_type = ChannelType::None;
  16. // out = (x * alpha - mean) / std
  17. static Norm mean_std(const float mean[3], const float std[3], float alpha = 1 / 255.0f,
  18. ChannelType channel_type = ChannelType::None);
  19. // out = x * alpha + beta
  20. static Norm alpha_beta(float alpha, float beta = 0, ChannelType channel_type = ChannelType::None);
  21. // None
  22. static Norm None();
  23. };
  24. struct ResizeMatrix
  25. {
  26. float i2d[6]; // image to dst(network), 2x3 matrix
  27. float d2i[6]; // dst to image, 2x3 matrix
  28. void compute(const std::tuple<int, int> &from, const std::tuple<int, int> &to)
  29. {
  30. float scale_x = std::get<0>(to) / (float)std::get<0>(from);
  31. float scale_y = std::get<1>(to) / (float)std::get<1>(from);
  32. float scale = std::min(scale_x, scale_y);
  33. // resize
  34. i2d[0] = scale_x;
  35. i2d[1] = 0;
  36. i2d[2] = 0;
  37. i2d[3] = 0;
  38. i2d[4] = scale_y;
  39. i2d[5] = 0;
  40. double D = i2d[0] * i2d[4] - i2d[1] * i2d[3];
  41. D = D != 0. ? double(1.) / D : double(0.);
  42. double A11 = i2d[4] * D, A22 = i2d[0] * D, A12 = -i2d[1] * D, A21 = -i2d[3] * D;
  43. double b1 = -A11 * i2d[2] - A12 * i2d[5];
  44. double b2 = -A21 * i2d[2] - A22 * i2d[5];
  45. d2i[0] = A11;
  46. d2i[1] = A12;
  47. d2i[2] = b1;
  48. d2i[3] = A21;
  49. d2i[4] = A22;
  50. d2i[5] = b2;
  51. }
  52. };
  53. struct LetterBoxMatrix
  54. {
  55. float i2d[6]; // image to dst(network), 2x3 matrix
  56. float d2i[6]; // dst to image, 2x3 matrix
  57. void compute(const std::tuple<int, int> &from, const std::tuple<int, int> &to)
  58. {
  59. float scale_x = std::get<0>(to) / (float)std::get<0>(from);
  60. float scale_y = std::get<1>(to) / (float)std::get<1>(from);
  61. float scale = std::min(scale_x, scale_y);
  62. // letter box
  63. i2d[0] = scale;
  64. i2d[1] = 0;
  65. i2d[2] = -scale * std::get<0>(from) * 0.5 + std::get<0>(to) * 0.5 + scale * 0.5 - 0.5;
  66. i2d[3] = 0;
  67. i2d[4] = scale;
  68. i2d[5] = -scale * std::get<1>(from) * 0.5 + std::get<1>(to) * 0.5 + scale * 0.5 - 0.5;
  69. double D = i2d[0] * i2d[4] - i2d[1] * i2d[3];
  70. D = D != 0. ? double(1.) / D : double(0.);
  71. double A11 = i2d[4] * D, A22 = i2d[0] * D, A12 = -i2d[1] * D, A21 = -i2d[3] * D;
  72. double b1 = -A11 * i2d[2] - A12 * i2d[5];
  73. double b2 = -A21 * i2d[2] - A22 * i2d[5];
  74. d2i[0] = A11;
  75. d2i[1] = A12;
  76. d2i[2] = b1;
  77. d2i[3] = A21;
  78. d2i[4] = A22;
  79. d2i[5] = b2;
  80. }
  81. };
  82. void warp_affine_bilinear_and_normalize_plane(uint8_t *src, int src_line_size, int src_width,
  83. int src_height, float *dst, int dst_width,
  84. int dst_height, float *matrix_2_3,
  85. uint8_t const_value, const Norm &norm,
  86. cudaStream_t stream);
  87. void warp_affine_bilinear_single_channel_plane(float *src, int src_line_size, int src_width,
  88. int src_height, float *dst, int dst_width,
  89. int dst_height, float *matrix_2_3,
  90. float const_value, cudaStream_t stream);
  91. }
  92. #endif // AFFINE_HPP__