preprocess_op.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright (c) 2021 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. #pragma once
  15. #include <iostream>
  16. #include <memory>
  17. #include <string>
  18. #include <unordered_map>
  19. #include <utility>
  20. #include <vector>
  21. #include <opencv2/core/core.hpp>
  22. #include <opencv2/highgui/highgui.hpp>
  23. #include <opencv2/imgproc/imgproc.hpp>
  24. #include "json/json.h"
  25. namespace PaddleDetection {
  26. // Object for storing all preprocessed data
  27. class ImageBlob {
  28. public:
  29. // image width and height
  30. std::vector<float> im_shape_;
  31. // Buffer for image data after preprocessing
  32. std::vector<float> im_data_;
  33. // in net data shape(after pad)
  34. std::vector<float> in_net_shape_;
  35. // Evaluation image width and height
  36. // std::vector<float> eval_im_size_f_;
  37. // Scale factor for image size to origin image size
  38. std::vector<float> scale_factor_;
  39. };
  40. // Abstraction of preprocessing opration class
  41. class PreprocessOp {
  42. public:
  43. virtual void Init(const Json::Value& item) = 0;
  44. virtual void Run(cv::Mat* im, ImageBlob* data) = 0;
  45. };
  46. class InitInfo : public PreprocessOp {
  47. public:
  48. virtual void Init(const Json::Value& item) {}
  49. virtual void Run(cv::Mat* im, ImageBlob* data);
  50. };
  51. class NormalizeImage : public PreprocessOp {
  52. public:
  53. virtual void Init(const Json::Value& item) {
  54. mean_.clear();
  55. scale_.clear();
  56. for (auto tmp : item["mean"]) {
  57. mean_.emplace_back(tmp.as<float>());
  58. }
  59. for (auto tmp : item["std"]) {
  60. scale_.emplace_back(tmp.as<float>());
  61. }
  62. is_scale_ = item["is_scale"].as<bool>();
  63. }
  64. virtual void Run(cv::Mat* im, ImageBlob* data);
  65. private:
  66. // CHW or HWC
  67. std::vector<float> mean_;
  68. std::vector<float> scale_;
  69. bool is_scale_;
  70. };
  71. class Permute : public PreprocessOp {
  72. public:
  73. virtual void Init(const Json::Value& item) {}
  74. virtual void Run(cv::Mat* im, ImageBlob* data);
  75. };
  76. class Resize : public PreprocessOp {
  77. public:
  78. virtual void Init(const Json::Value& item) {
  79. interp_ = item["interp"].as<int>();
  80. // max_size_ = item["target_size"].as<int>();
  81. keep_ratio_ = item["keep_ratio"].as<bool>();
  82. target_size_.clear();
  83. for (auto tmp : item["target_size"]) {
  84. target_size_.emplace_back(tmp.as<int>());
  85. }
  86. }
  87. // Compute best resize scale for x-dimension, y-dimension
  88. std::pair<float, float> GenerateScale(const cv::Mat& im);
  89. virtual void Run(cv::Mat* im, ImageBlob* data);
  90. private:
  91. int interp_;
  92. bool keep_ratio_;
  93. std::vector<int> target_size_;
  94. std::vector<int> in_net_shape_;
  95. };
  96. // Models with FPN need input shape % stride == 0
  97. class PadStride : public PreprocessOp {
  98. public:
  99. virtual void Init(const Json::Value& item) {
  100. stride_ = item["stride"].as<int>();
  101. }
  102. virtual void Run(cv::Mat* im, ImageBlob* data);
  103. private:
  104. int stride_;
  105. };
  106. class TopDownEvalAffine : public PreprocessOp {
  107. public:
  108. virtual void Init(const Json::Value& item) {
  109. trainsize_.clear();
  110. for (auto tmp : item["trainsize"]) {
  111. trainsize_.emplace_back(tmp.as<int>());
  112. }
  113. }
  114. virtual void Run(cv::Mat* im, ImageBlob* data);
  115. private:
  116. int interp_ = 1;
  117. std::vector<int> trainsize_;
  118. };
  119. void CropImg(cv::Mat& img,
  120. cv::Mat& crop_img,
  121. std::vector<int>& area,
  122. std::vector<float>& center,
  123. std::vector<float>& scale,
  124. float expandratio = 0.15);
  125. class Preprocessor {
  126. public:
  127. void Init(const Json::Value& config_node) {
  128. // initialize image info at first
  129. ops_["InitInfo"] = std::make_shared<InitInfo>();
  130. for (const auto& item : config_node) {
  131. auto op_name = item["type"].as<std::string>();
  132. ops_[op_name] = CreateOp(op_name);
  133. ops_[op_name]->Init(item);
  134. }
  135. }
  136. std::shared_ptr<PreprocessOp> CreateOp(const std::string& name) {
  137. if (name == "Resize") {
  138. return std::make_shared<Resize>();
  139. } else if (name == "Permute") {
  140. return std::make_shared<Permute>();
  141. } else if (name == "NormalizeImage") {
  142. return std::make_shared<NormalizeImage>();
  143. } else if (name == "PadStride") {
  144. // use PadStride instead of PadBatch
  145. return std::make_shared<PadStride>();
  146. } else if (name == "TopDownEvalAffine") {
  147. return std::make_shared<TopDownEvalAffine>();
  148. }
  149. std::cerr << "can not find function of OP: " << name
  150. << " and return: nullptr" << std::endl;
  151. return nullptr;
  152. }
  153. void Run(cv::Mat* im, ImageBlob* data);
  154. public:
  155. static const std::vector<std::string> RUN_ORDER;
  156. private:
  157. std::unordered_map<std::string, std::shared_ptr<PreprocessOp>> ops_;
  158. };
  159. } // namespace PaddleDetection