stride_pad.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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/common/processors/stride_pad.h"
  15. namespace ultra_infer {
  16. namespace vision {
  17. bool StridePad::ImplByOpenCV(Mat *mat) {
  18. if (mat->layout != Layout::HWC) {
  19. FDERROR << "StridePad: The input data must be Layout::HWC format!"
  20. << std::endl;
  21. return false;
  22. }
  23. if (mat->Channels() > 4) {
  24. FDERROR << "StridePad: Only support channels <= 4." << std::endl;
  25. return false;
  26. }
  27. if (mat->Channels() != value_.size()) {
  28. FDERROR
  29. << "StridePad: Require input channels equals to size of padding value, "
  30. "but now channels = "
  31. << mat->Channels() << ", the size of padding values = " << value_.size()
  32. << "." << std::endl;
  33. return false;
  34. }
  35. int origin_w = mat->Width();
  36. int origin_h = mat->Height();
  37. int pad_h = (mat->Height() / stride_) * stride_ +
  38. (mat->Height() % stride_ != 0) * stride_ - mat->Height();
  39. int pad_w = (mat->Width() / stride_) * stride_ +
  40. (mat->Width() % stride_ != 0) * stride_ - mat->Width();
  41. if (pad_h == 0 && pad_w == 0) {
  42. return true;
  43. }
  44. cv::Mat *im = mat->GetOpenCVMat();
  45. cv::Scalar value;
  46. if (value_.size() == 1) {
  47. value = cv::Scalar(value_[0]);
  48. } else if (value_.size() == 2) {
  49. value = cv::Scalar(value_[0], value_[1]);
  50. } else if (value_.size() == 3) {
  51. value = cv::Scalar(value_[0], value_[1], value_[2]);
  52. } else {
  53. value = cv::Scalar(value_[0], value_[1], value_[2], value_[3]);
  54. }
  55. // top, bottom, left, right
  56. cv::copyMakeBorder(*im, *im, 0, pad_h, 0, pad_w, cv::BORDER_CONSTANT, value);
  57. mat->SetHeight(origin_h + pad_h);
  58. mat->SetWidth(origin_w + pad_w);
  59. return true;
  60. }
  61. #ifdef ENABLE_FLYCV
  62. bool StridePad::ImplByFlyCV(Mat *mat) {
  63. if (mat->layout != Layout::HWC) {
  64. FDERROR << "StridePad: The input data must be Layout::HWC format!"
  65. << std::endl;
  66. return false;
  67. }
  68. if (mat->Channels() > 4) {
  69. FDERROR << "StridePad: Only support channels <= 4." << std::endl;
  70. return false;
  71. }
  72. if (mat->Channels() != value_.size()) {
  73. FDERROR
  74. << "StridePad: Require input channels equals to size of padding value, "
  75. "but now channels = "
  76. << mat->Channels() << ", the size of padding values = " << value_.size()
  77. << "." << std::endl;
  78. return false;
  79. }
  80. int origin_w = mat->Width();
  81. int origin_h = mat->Height();
  82. int pad_h = (mat->Height() / stride_) * stride_ +
  83. (mat->Height() % stride_ != 0) * stride_ - mat->Height();
  84. int pad_w = (mat->Width() / stride_) * stride_ +
  85. (mat->Width() % stride_ != 0) * stride_ - mat->Width();
  86. if (pad_h == 0 && pad_w == 0) {
  87. return true;
  88. }
  89. fcv::Mat *im = mat->GetFlyCVMat();
  90. fcv::Scalar value;
  91. if (value_.size() == 1) {
  92. value = fcv::Scalar(value_[0]);
  93. } else if (value_.size() == 2) {
  94. value = fcv::Scalar(value_[0], value_[1]);
  95. } else if (value_.size() == 3) {
  96. value = fcv::Scalar(value_[0], value_[1], value_[2]);
  97. } else {
  98. value = fcv::Scalar(value_[0], value_[1], value_[2], value_[3]);
  99. }
  100. fcv::Mat new_im;
  101. // top, bottom, left, right
  102. fcv::copy_make_border(*im, new_im, 0, pad_h, 0, pad_w,
  103. fcv::BorderType::BORDER_CONSTANT, value);
  104. mat->SetMat(new_im);
  105. mat->SetHeight(new_im.height());
  106. mat->SetWidth(new_im.width());
  107. return true;
  108. }
  109. #endif
  110. #ifdef ENABLE_CVCUDA
  111. bool StridePad::ImplByCvCuda(FDMat *mat) {
  112. if (mat->layout != Layout::HWC) {
  113. FDERROR << "StridePad: The input data must be Layout::HWC format!"
  114. << std::endl;
  115. return false;
  116. }
  117. if (mat->Channels() > 4) {
  118. FDERROR << "StridePad: Only support channels <= 4." << std::endl;
  119. return false;
  120. }
  121. if (mat->Channels() != value_.size()) {
  122. FDERROR
  123. << "StridePad: Require input channels equals to size of padding value, "
  124. "but now channels = "
  125. << mat->Channels() << ", the size of padding values = " << value_.size()
  126. << "." << std::endl;
  127. return false;
  128. }
  129. int origin_w = mat->Width();
  130. int origin_h = mat->Height();
  131. int pad_h = (mat->Height() / stride_) * stride_ +
  132. (mat->Height() % stride_ != 0) * stride_ - mat->Height();
  133. int pad_w = (mat->Width() / stride_) * stride_ +
  134. (mat->Width() % stride_ != 0) * stride_ - mat->Width();
  135. if (pad_h == 0 && pad_w == 0) {
  136. return true;
  137. }
  138. float4 value;
  139. if (value_.size() == 1) {
  140. value = make_float4(value_[0], 0.0f, 0.0f, 0.0f);
  141. } else if (value_.size() == 2) {
  142. value = make_float4(value_[0], value_[1], 0.0f, 0.0f);
  143. } else if (value_.size() == 3) {
  144. value = make_float4(value_[0], value_[1], value_[2], 0.0f);
  145. } else {
  146. value = make_float4(value_[0], value_[1], value_[2], value_[3]);
  147. }
  148. // Prepare input tensor
  149. FDTensor *src = CreateCachedGpuInputTensor(mat);
  150. auto src_tensor = CreateCvCudaTensorWrapData(*src);
  151. int height = mat->Height() + pad_h;
  152. int width = mat->Width() + pad_w;
  153. // Prepare output tensor
  154. mat->output_cache->Resize({height, width, mat->Channels()}, mat->Type(),
  155. "output_cache", Device::GPU);
  156. auto dst_tensor = CreateCvCudaTensorWrapData(*(mat->output_cache));
  157. cvcuda_pad_op_(mat->Stream(), *src_tensor, *dst_tensor, 0, 0,
  158. NVCV_BORDER_CONSTANT, value);
  159. mat->SetTensor(mat->output_cache);
  160. mat->mat_type = ProcLib::CVCUDA;
  161. return true;
  162. }
  163. #endif
  164. bool StridePad::Run(Mat *mat, int stride, const std::vector<float> &value,
  165. ProcLib lib) {
  166. auto p = StridePad(stride, value);
  167. return p(mat, lib);
  168. }
  169. } // namespace vision
  170. } // namespace ultra_infer