perception.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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 <algorithm>
  15. #include "opencv2/calib3d/calib3d.hpp"
  16. #include "opencv2/imgproc/imgproc.hpp"
  17. #include "ultra_infer/vision/visualize/visualize.h"
  18. #include "yaml-cpp/yaml.h"
  19. namespace ultra_infer {
  20. namespace vision {
  21. using matrix = std::vector<std::vector<float>>;
  22. matrix Multiple(const matrix a, const matrix b) {
  23. const int m = a.size(); // a rows
  24. if (m == 0) {
  25. matrix c;
  26. return c;
  27. }
  28. if (a[0].size() != b.size()) {
  29. FDERROR << "A[m,n] * B[p,q], n must equal to p." << std::endl;
  30. matrix c;
  31. return c;
  32. }
  33. const int n = a[0].size(); // a cols
  34. const int p = b[0].size(); // b cols
  35. matrix c(m, std::vector<float>(p, 0));
  36. for (auto i = 0; i < m; i++) {
  37. for (auto j = 0; j < p; j++) {
  38. for (auto k = 0; k < n; k++)
  39. c[i][j] += a[i][k] * b[k][j];
  40. }
  41. }
  42. return c;
  43. }
  44. cv::Mat VisPerception(const cv::Mat &im, const PerceptionResult &result,
  45. const std::string &config_file, float score_threshold,
  46. int line_size, float font_size) {
  47. if (result.scores.empty()) {
  48. return im;
  49. }
  50. YAML::Node cfg;
  51. try {
  52. cfg = YAML::LoadFile(config_file);
  53. } catch (YAML::BadFile &e) {
  54. FDERROR << "Failed to load yaml file " << config_file
  55. << ", maybe you should check this file." << std::endl;
  56. return im;
  57. }
  58. std::vector<int> target_size;
  59. for (const auto &op : cfg["Preprocess"]) {
  60. std::string op_name = op["type"].as<std::string>();
  61. if (op_name == "Resize") {
  62. target_size = op["target_size"].as<std::vector<int>>();
  63. }
  64. }
  65. std::vector<float> vec_k_data = cfg["k_data"].as<std::vector<float>>();
  66. if (vec_k_data.size() != 9) {
  67. FDERROR
  68. << "The K data load from the yaml file: " << config_file
  69. << " is unexpected, the expected size is 9, but the loaded size is: "
  70. << vec_k_data.size() << " ,maybe you should check this file."
  71. << std::endl;
  72. return im;
  73. }
  74. matrix k_data(3, std::vector<float>());
  75. for (auto j = 0; j < 3; j++) {
  76. k_data[j].insert(k_data[j].begin(), vec_k_data.begin() + j * 3,
  77. vec_k_data.begin() + j * 3 + 3);
  78. }
  79. std::vector<double> rvec = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
  80. std::vector<double> tvec = {0, 0, 0};
  81. matrix connect_line_id = {{1, 0}, {2, 7}, {3, 6}, {4, 5}, {1, 2}, {2, 3},
  82. {3, 4}, {4, 1}, {0, 7}, {7, 6}, {6, 5}, {5, 0}};
  83. int max_label_id =
  84. *std::max_element(result.label_ids.begin(), result.label_ids.end());
  85. std::vector<int> color_map = GenerateColorMap(max_label_id);
  86. int h = im.rows;
  87. int w = im.cols;
  88. cv::Mat vis_im = im.clone();
  89. cv::resize(im, vis_im, cv::Size(target_size[1], target_size[0]), 0, 0, 0);
  90. for (size_t i = 0; i < result.scores.size(); ++i) {
  91. if (result.scores[i] < 0.5) {
  92. continue;
  93. }
  94. float h = result.boxes[i][4];
  95. float w = result.boxes[i][5];
  96. float l = result.boxes[i][6];
  97. float x = result.center[i][0];
  98. float y = result.center[i][1];
  99. float z = result.center[i][2];
  100. std::vector<float> x_corners = {0, l, l, l, l, 0, 0, 0};
  101. std::vector<float> y_corners = {0, 0, h, h, 0, 0, h, h};
  102. std::vector<float> z_corners = {0, 0, 0, w, w, w, w, 0};
  103. for (auto j = 0; j < x_corners.size(); j++) {
  104. x_corners[j] = x_corners[j] - l / 2;
  105. y_corners[j] = y_corners[j] - h;
  106. z_corners[j] = z_corners[j] - w / 2;
  107. }
  108. matrix corners_3d = {x_corners, y_corners, z_corners};
  109. float ry = result.yaw_angle[i];
  110. matrix rot_mat = {
  111. {cosf(ry), 0, sinf(ry)}, {0, 1, 0}, {sinf(ry), 0, cosf(ry)}};
  112. matrix rot_corners_3d = Multiple(rot_mat, corners_3d);
  113. for (auto j = 0; j < rot_corners_3d[0].size(); j++) {
  114. rot_corners_3d[0][j] += x;
  115. rot_corners_3d[1][j] += y;
  116. rot_corners_3d[2][j] += z;
  117. }
  118. auto corners_2d = Multiple(k_data, rot_corners_3d);
  119. for (auto j = 0; j < corners_2d[0].size(); j++) {
  120. corners_2d[0][j] /= corners_2d[2][j];
  121. corners_2d[1][j] /= corners_2d[2][j];
  122. }
  123. std::vector<float> box2d = {
  124. *std::min_element(corners_2d[0].begin(), corners_2d[0].end()),
  125. *std::min_element(corners_2d[1].begin(), corners_2d[1].end()),
  126. *std::max_element(corners_2d[0].begin(), corners_2d[0].end()),
  127. *std::max_element(corners_2d[1].begin(), corners_2d[1].end())};
  128. if (box2d[0] == 0 && box2d[1] == 0 && box2d[2] == 0 && box2d[3] == 0) {
  129. continue;
  130. }
  131. std::vector<cv::Point3f> points3d;
  132. for (auto j = 0; j < rot_corners_3d[0].size(); j++) {
  133. points3d.push_back(cv::Point3f(rot_corners_3d[0][j], rot_corners_3d[1][j],
  134. rot_corners_3d[2][j]));
  135. }
  136. cv::Mat rVec(3, 3, cv::DataType<double>::type, rvec.data());
  137. cv::Mat tVec(3, 1, cv::DataType<double>::type, tvec.data());
  138. std::vector<float> vec_k;
  139. for (auto &&v : k_data) {
  140. vec_k.insert(vec_k.end(), v.begin(), v.end());
  141. }
  142. cv::Mat intrinsicMat(3, 3, cv::DataType<float>::type, vec_k.data());
  143. cv::Mat distCoeffs(5, 1, cv::DataType<double>::type);
  144. std::vector<cv::Point2f> projectedPoints;
  145. cv::projectPoints(points3d, rVec, tVec, intrinsicMat, distCoeffs,
  146. projectedPoints);
  147. int c0 = color_map[3 * result.label_ids[i] + 0];
  148. int c1 = color_map[3 * result.label_ids[i] + 1];
  149. int c2 = color_map[3 * result.label_ids[i] + 2];
  150. cv::Scalar color = cv::Scalar(c0, c1, c2);
  151. for (auto id = 0; id < connect_line_id.size(); id++) {
  152. int p1 = connect_line_id[id][0];
  153. int p2 = connect_line_id[id][1];
  154. cv::line(vis_im, projectedPoints[p1], projectedPoints[p2], color, 1);
  155. }
  156. int font = cv::FONT_HERSHEY_SIMPLEX;
  157. std::string score = std::to_string(result.scores[i]);
  158. if (score.size() > 4) {
  159. score = score.substr(0, 4);
  160. }
  161. std::string text = std::to_string(result.label_ids[i]) + ", " + score;
  162. cv::Point2f original;
  163. original.x = box2d[0];
  164. original.y = box2d[1];
  165. cv::putText(vis_im, text, original, font, font_size,
  166. cv::Scalar(255, 255, 255), 1);
  167. }
  168. return vis_im;
  169. }
  170. } // namespace vision
  171. } // namespace ultra_infer