picodet_openvino.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. // reference from https://github.com/RangiLyu/nanodet/tree/main/demo_openvino
  15. #include "picodet_openvino.h"
  16. inline float fast_exp(float x) {
  17. union {
  18. uint32_t i;
  19. float f;
  20. } v{};
  21. v.i = (1 << 23) * (1.4426950409 * x + 126.93490512f);
  22. return v.f;
  23. }
  24. inline float sigmoid(float x) { return 1.0f / (1.0f + fast_exp(-x)); }
  25. template <typename _Tp>
  26. int activation_function_softmax(const _Tp* src, _Tp* dst, int length) {
  27. const _Tp alpha = *std::max_element(src, src + length);
  28. _Tp denominator{0};
  29. for (int i = 0; i < length; ++i) {
  30. dst[i] = fast_exp(src[i] - alpha);
  31. denominator += dst[i];
  32. }
  33. for (int i = 0; i < length; ++i) {
  34. dst[i] /= denominator;
  35. }
  36. return 0;
  37. }
  38. PicoDet::PicoDet(const char* model_path) {
  39. InferenceEngine::Core ie;
  40. InferenceEngine::CNNNetwork model = ie.ReadNetwork(model_path);
  41. // prepare input settings
  42. InferenceEngine::InputsDataMap inputs_map(model.getInputsInfo());
  43. input_name_ = inputs_map.begin()->first;
  44. InferenceEngine::InputInfo::Ptr input_info = inputs_map.begin()->second;
  45. // prepare output settings
  46. InferenceEngine::OutputsDataMap outputs_map(model.getOutputsInfo());
  47. for (auto& output_info : outputs_map) {
  48. output_info.second->setPrecision(InferenceEngine::Precision::FP32);
  49. }
  50. // get network
  51. network_ = ie.LoadNetwork(model, "CPU");
  52. infer_request_ = network_.CreateInferRequest();
  53. }
  54. PicoDet::~PicoDet() {}
  55. void PicoDet::preprocess(cv::Mat& image, InferenceEngine::Blob::Ptr& blob) {
  56. int img_w = image.cols;
  57. int img_h = image.rows;
  58. int channels = 3;
  59. InferenceEngine::MemoryBlob::Ptr mblob =
  60. InferenceEngine::as<InferenceEngine::MemoryBlob>(blob);
  61. if (!mblob) {
  62. THROW_IE_EXCEPTION
  63. << "We expect blob to be inherited from MemoryBlob in matU8ToBlob, "
  64. << "but by fact we were not able to cast inputBlob to MemoryBlob";
  65. }
  66. auto mblobHolder = mblob->wmap();
  67. float* blob_data = mblobHolder.as<float*>();
  68. for (size_t c = 0; c < channels; c++) {
  69. for (size_t h = 0; h < img_h; h++) {
  70. for (size_t w = 0; w < img_w; w++) {
  71. blob_data[c * img_w * img_h + h * img_w + w] =
  72. (float)image.at<cv::Vec3b>(h, w)[c];
  73. }
  74. }
  75. }
  76. }
  77. std::vector<BoxInfo> PicoDet::detect(cv::Mat image,
  78. float score_threshold,
  79. float nms_threshold) {
  80. InferenceEngine::Blob::Ptr input_blob = infer_request_.GetBlob(input_name_);
  81. preprocess(image, input_blob);
  82. // do inference
  83. infer_request_.Infer();
  84. // get output
  85. std::vector<std::vector<BoxInfo>> results;
  86. results.resize(this->num_class_);
  87. for (const auto& head_info : this->heads_info_) {
  88. const InferenceEngine::Blob::Ptr dis_pred_blob =
  89. infer_request_.GetBlob(head_info.dis_layer);
  90. const InferenceEngine::Blob::Ptr cls_pred_blob =
  91. infer_request_.GetBlob(head_info.cls_layer);
  92. auto mdis_pred =
  93. InferenceEngine::as<InferenceEngine::MemoryBlob>(dis_pred_blob);
  94. auto mdis_pred_holder = mdis_pred->rmap();
  95. const float* dis_pred = mdis_pred_holder.as<const float*>();
  96. auto mcls_pred =
  97. InferenceEngine::as<InferenceEngine::MemoryBlob>(cls_pred_blob);
  98. auto mcls_pred_holder = mcls_pred->rmap();
  99. const float* cls_pred = mcls_pred_holder.as<const float*>();
  100. this->decode_infer(
  101. cls_pred, dis_pred, head_info.stride, score_threshold, results);
  102. }
  103. std::vector<BoxInfo> dets;
  104. for (int i = 0; i < (int)results.size(); i++) {
  105. this->nms(results[i], nms_threshold);
  106. for (auto& box : results[i]) {
  107. dets.push_back(box);
  108. }
  109. }
  110. return dets;
  111. }
  112. void PicoDet::decode_infer(const float*& cls_pred,
  113. const float*& dis_pred,
  114. int stride,
  115. float threshold,
  116. std::vector<std::vector<BoxInfo>>& results) {
  117. int feature_h = input_size_ / stride;
  118. int feature_w = input_size_ / stride;
  119. for (int idx = 0; idx < feature_h * feature_w; idx++) {
  120. int row = idx / feature_w;
  121. int col = idx % feature_w;
  122. float score = 0;
  123. int cur_label = 0;
  124. for (int label = 0; label < num_class_; label++) {
  125. if (cls_pred[idx * num_class_ + label] > score) {
  126. score = cls_pred[idx * num_class_ + label];
  127. cur_label = label;
  128. }
  129. }
  130. if (score > threshold) {
  131. const float* bbox_pred = dis_pred + idx * (reg_max_ + 1) * 4;
  132. results[cur_label].push_back(
  133. this->disPred2Bbox(bbox_pred, cur_label, score, col, row, stride));
  134. }
  135. }
  136. }
  137. BoxInfo PicoDet::disPred2Bbox(
  138. const float*& dfl_det, int label, float score, int x, int y, int stride) {
  139. float ct_x = (x + 0.5) * stride;
  140. float ct_y = (y + 0.5) * stride;
  141. std::vector<float> dis_pred;
  142. dis_pred.resize(4);
  143. for (int i = 0; i < 4; i++) {
  144. float dis = 0;
  145. float* dis_after_sm = new float[reg_max_ + 1];
  146. activation_function_softmax(
  147. dfl_det + i * (reg_max_ + 1), dis_after_sm, reg_max_ + 1);
  148. for (int j = 0; j < reg_max_ + 1; j++) {
  149. dis += j * dis_after_sm[j];
  150. }
  151. dis *= stride;
  152. dis_pred[i] = dis;
  153. delete[] dis_after_sm;
  154. }
  155. float xmin = (std::max)(ct_x - dis_pred[0], .0f);
  156. float ymin = (std::max)(ct_y - dis_pred[1], .0f);
  157. float xmax = (std::min)(ct_x + dis_pred[2], (float)this->input_size_);
  158. float ymax = (std::min)(ct_y + dis_pred[3], (float)this->input_size_);
  159. return BoxInfo{xmin, ymin, xmax, ymax, score, label};
  160. }
  161. void PicoDet::nms(std::vector<BoxInfo>& input_boxes, float NMS_THRESH) {
  162. std::sort(input_boxes.begin(), input_boxes.end(), [](BoxInfo a, BoxInfo b) {
  163. return a.score > b.score;
  164. });
  165. std::vector<float> vArea(input_boxes.size());
  166. for (int i = 0; i < int(input_boxes.size()); ++i) {
  167. vArea[i] = (input_boxes.at(i).x2 - input_boxes.at(i).x1 + 1) *
  168. (input_boxes.at(i).y2 - input_boxes.at(i).y1 + 1);
  169. }
  170. for (int i = 0; i < int(input_boxes.size()); ++i) {
  171. for (int j = i + 1; j < int(input_boxes.size());) {
  172. float xx1 = (std::max)(input_boxes[i].x1, input_boxes[j].x1);
  173. float yy1 = (std::max)(input_boxes[i].y1, input_boxes[j].y1);
  174. float xx2 = (std::min)(input_boxes[i].x2, input_boxes[j].x2);
  175. float yy2 = (std::min)(input_boxes[i].y2, input_boxes[j].y2);
  176. float w = (std::max)(float(0), xx2 - xx1 + 1);
  177. float h = (std::max)(float(0), yy2 - yy1 + 1);
  178. float inter = w * h;
  179. float ovr = inter / (vArea[i] + vArea[j] - inter);
  180. if (ovr >= NMS_THRESH) {
  181. input_boxes.erase(input_boxes.begin() + j);
  182. vArea.erase(vArea.begin() + j);
  183. } else {
  184. j++;
  185. }
  186. }
  187. }
  188. }