preprocessor.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "ultra_infer/vision/detection/contrib/rknpu2/preprocessor.h"
  15. #include "ultra_infer/function/concat.h"
  16. namespace ultra_infer {
  17. namespace vision {
  18. namespace detection {
  19. RKYOLOPreprocessor::RKYOLOPreprocessor() {
  20. size_ = {640, 640};
  21. padding_value_ = {114.0, 114.0, 114.0};
  22. is_mini_pad_ = false;
  23. is_no_pad_ = false;
  24. is_scale_up_ = true;
  25. stride_ = 32;
  26. max_wh_ = 7680.0;
  27. }
  28. void RKYOLOPreprocessor::LetterBox(FDMat *mat) {
  29. float scale =
  30. std::min(size_[1] * 1.0 / mat->Height(), size_[0] * 1.0 / mat->Width());
  31. if (!is_scale_up_) {
  32. scale = std::min(scale, 1.0f);
  33. }
  34. scale_.push_back(scale);
  35. int resize_h = int(round(mat->Height() * scale));
  36. int resize_w = int(round(mat->Width() * scale));
  37. int pad_w = size_[0] - resize_w;
  38. int pad_h = size_[1] - resize_h;
  39. if (is_mini_pad_) {
  40. pad_h = pad_h % stride_;
  41. pad_w = pad_w % stride_;
  42. } else if (is_no_pad_) {
  43. pad_h = 0;
  44. pad_w = 0;
  45. resize_h = size_[1];
  46. resize_w = size_[0];
  47. }
  48. pad_hw_values_.push_back({pad_h, pad_w});
  49. if (std::fabs(scale - 1.0f) > 1e-06) {
  50. Resize::Run(mat, resize_w, resize_h);
  51. }
  52. if (pad_h > 0 || pad_w > 0) {
  53. float half_h = pad_h * 1.0 / 2;
  54. int top = int(round(half_h - 0.1));
  55. int bottom = int(round(half_h + 0.1));
  56. float half_w = pad_w * 1.0 / 2;
  57. int left = int(round(half_w - 0.1));
  58. int right = int(round(half_w + 0.1));
  59. Pad::Run(mat, top, bottom, left, right, padding_value_);
  60. }
  61. }
  62. bool RKYOLOPreprocessor::Preprocess(FDMat *mat, FDTensor *output) {
  63. // RKYOLO's preprocess steps
  64. // 1. letterbox
  65. // 2. convert_and_permute(swap_rb=true)
  66. LetterBox(mat);
  67. BGR2RGB::Run(mat);
  68. mat->ShareWithTensor(output);
  69. output->ExpandDim(0); // reshape to n, h, w, c
  70. return true;
  71. }
  72. bool RKYOLOPreprocessor::Run(std::vector<FDMat> *images,
  73. std::vector<FDTensor> *outputs) {
  74. if (images->size() == 0) {
  75. FDERROR << "The size of input images should be greater than 0."
  76. << std::endl;
  77. return false;
  78. }
  79. outputs->resize(1);
  80. // Concat all the preprocessed data to a batch tensor
  81. std::vector<FDTensor> tensors(images->size());
  82. for (size_t i = 0; i < images->size(); ++i) {
  83. if (!Preprocess(&(*images)[i], &tensors[i])) {
  84. FDERROR << "Failed to preprocess input image." << std::endl;
  85. return false;
  86. }
  87. }
  88. if (tensors.size() == 1) {
  89. (*outputs)[0] = std::move(tensors[0]);
  90. } else {
  91. function::Concat(tensors, &((*outputs)[0]), 0);
  92. }
  93. return true;
  94. }
  95. } // namespace detection
  96. } // namespace vision
  97. } // namespace ultra_infer