pad.cc 5.0 KB

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