keypoint_detector.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 <sstream>
  15. // for setprecision
  16. #include <chrono>
  17. #include <iomanip>
  18. #include "keypoint_detector.h"
  19. namespace PaddleDetection {
  20. // Visualiztion MaskDetector results
  21. cv::Mat VisualizeKptsResult(const cv::Mat& img,
  22. const std::vector<KeyPointResult>& results,
  23. const std::vector<int>& colormap,
  24. float threshold) {
  25. const int edge[][2] = {{0, 1},
  26. {0, 2},
  27. {1, 3},
  28. {2, 4},
  29. {3, 5},
  30. {4, 6},
  31. {5, 7},
  32. {6, 8},
  33. {7, 9},
  34. {8, 10},
  35. {5, 11},
  36. {6, 12},
  37. {11, 13},
  38. {12, 14},
  39. {13, 15},
  40. {14, 16},
  41. {11, 12}};
  42. cv::Mat vis_img = img.clone();
  43. for (int batchid = 0; batchid < results.size(); batchid++) {
  44. for (int i = 0; i < results[batchid].num_joints; i++) {
  45. if (results[batchid].keypoints[i * 3] > threshold) {
  46. int x_coord = int(results[batchid].keypoints[i * 3 + 1]);
  47. int y_coord = int(results[batchid].keypoints[i * 3 + 2]);
  48. cv::circle(vis_img,
  49. cv::Point2d(x_coord, y_coord),
  50. 1,
  51. cv::Scalar(0, 0, 255),
  52. 2);
  53. }
  54. }
  55. for (int i = 0; i < results[batchid].num_joints; i++) {
  56. if (results[batchid].keypoints[edge[i][0] * 3] > threshold &&
  57. results[batchid].keypoints[edge[i][1] * 3] > threshold) {
  58. int x_start = int(results[batchid].keypoints[edge[i][0] * 3 + 1]);
  59. int y_start = int(results[batchid].keypoints[edge[i][0] * 3 + 2]);
  60. int x_end = int(results[batchid].keypoints[edge[i][1] * 3 + 1]);
  61. int y_end = int(results[batchid].keypoints[edge[i][1] * 3 + 2]);
  62. cv::line(vis_img,
  63. cv::Point2d(x_start, y_start),
  64. cv::Point2d(x_end, y_end),
  65. colormap[i],
  66. 1);
  67. }
  68. }
  69. }
  70. return vis_img;
  71. }
  72. void KeyPointDetector::Postprocess(std::vector<float>& output,
  73. std::vector<uint64_t>& output_shape,
  74. std::vector<float>& idxout,
  75. std::vector<uint64_t>& idx_shape,
  76. std::vector<KeyPointResult>* result,
  77. std::vector<std::vector<float>>& center_bs,
  78. std::vector<std::vector<float>>& scale_bs) {
  79. std::vector<float> preds(output_shape[1] * 3, 0);
  80. for (int batchid = 0; batchid < output_shape[0]; batchid++) {
  81. get_final_preds(output,
  82. output_shape,
  83. idxout,
  84. idx_shape,
  85. center_bs[batchid],
  86. scale_bs[batchid],
  87. preds,
  88. batchid,
  89. this->use_dark());
  90. KeyPointResult result_item;
  91. result_item.num_joints = output_shape[1];
  92. result_item.keypoints.clear();
  93. for (int i = 0; i < output_shape[1]; i++) {
  94. result_item.keypoints.emplace_back(preds[i * 3]);
  95. result_item.keypoints.emplace_back(preds[i * 3 + 1]);
  96. result_item.keypoints.emplace_back(preds[i * 3 + 2]);
  97. }
  98. result->push_back(result_item);
  99. }
  100. }
  101. void KeyPointDetector::Predict(const std::vector<cv::Mat> imgs,
  102. std::vector<std::vector<float>>& center_bs,
  103. std::vector<std::vector<float>>& scale_bs,
  104. std::vector<KeyPointResult>* result) {
  105. int batch_size = imgs.size();
  106. auto insize = 3 * in_h * in_w;
  107. InferenceEngine::Blob::Ptr input_blob = infer_request_.GetBlob(input_name_);
  108. // Preprocess image
  109. InferenceEngine::MemoryBlob::Ptr mblob =
  110. InferenceEngine::as<InferenceEngine::MemoryBlob>(input_blob);
  111. if (!mblob) {
  112. THROW_IE_EXCEPTION
  113. << "We expect blob to be inherited from MemoryBlob in matU8ToBlob, "
  114. << "but by fact we were not able to cast inputBlob to MemoryBlob";
  115. }
  116. auto mblobHolder = mblob->wmap();
  117. float* blob_data = mblobHolder.as<float*>();
  118. cv::Mat resized_im;
  119. for (int bs_idx = 0; bs_idx < batch_size; bs_idx++) {
  120. cv::Mat im = imgs.at(bs_idx);
  121. cv::resize(im, resized_im, cv::Size(in_w, in_h));
  122. for (size_t c = 0; c < 3; c++) {
  123. for (size_t h = 0; h < in_h; h++) {
  124. for (size_t w = 0; w < in_w; w++) {
  125. blob_data[c * in_w * in_h + h * in_w + w] =
  126. (float)resized_im.at<cv::Vec3b>(h, w)[c];
  127. }
  128. }
  129. }
  130. }
  131. // Run predictor
  132. auto inference_start = std::chrono::steady_clock::now();
  133. // do inference
  134. infer_request_.Infer();
  135. InferenceEngine::Blob::Ptr output_blob =
  136. infer_request_.GetBlob("conv2d_441.tmp_1");
  137. auto output_shape = output_blob->getTensorDesc().getDims();
  138. InferenceEngine::MemoryBlob::Ptr moutput =
  139. InferenceEngine::as<InferenceEngine::MemoryBlob>(output_blob);
  140. if (moutput) {
  141. // locked memory holder should be alive all time while access to its
  142. // buffer happens
  143. auto minputHolder = moutput->rmap();
  144. auto data = minputHolder.as<const InferenceEngine::PrecisionTrait<
  145. InferenceEngine::Precision::FP32>::value_type*>();
  146. // Calculate output length
  147. int output_size = 1;
  148. for (int j = 0; j < output_shape.size(); ++j) {
  149. output_size *= output_shape[j];
  150. }
  151. output_data_.resize(output_size);
  152. std::copy_n(data, output_size, output_data_.data());
  153. }
  154. InferenceEngine::Blob::Ptr output_blob2 =
  155. infer_request_.GetBlob("argmax_0.tmp_0");
  156. auto idx_shape = output_blob2->getTensorDesc().getDims();
  157. InferenceEngine::MemoryBlob::Ptr moutput2 =
  158. InferenceEngine::as<InferenceEngine::MemoryBlob>(output_blob2);
  159. if (moutput2) {
  160. // locked memory holder should be alive all time while access to its
  161. // buffer happens
  162. auto minputHolder = moutput2->rmap();
  163. // Original I64 precision was converted to I32
  164. auto data = minputHolder.as<const InferenceEngine::PrecisionTrait<
  165. InferenceEngine::Precision::FP32>::value_type*>();
  166. // Calculate output length
  167. int output_size = 1;
  168. for (int j = 0; j < idx_shape.size(); ++j) {
  169. output_size *= idx_shape[j];
  170. }
  171. idx_data_.resize(output_size);
  172. std::copy_n(data, output_size, idx_data_.data());
  173. }
  174. auto inference_end = std::chrono::steady_clock::now();
  175. std::chrono::duration<double> elapsed = inference_end - inference_start;
  176. printf("keypoint inference time: %f s\n", elapsed.count());
  177. // Postprocessing result
  178. Postprocess(output_data_,
  179. output_shape,
  180. idx_data_,
  181. idx_shape,
  182. result,
  183. center_bs,
  184. scale_bs);
  185. }
  186. } // namespace PaddleDetection