drawNode.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "common/utils.hpp"
  2. #include "nodes/base/base.hpp"
  3. #include "nodes/draw/drawNode.hpp"
  4. #include "nodes/draw/position.hpp"
  5. #include <opencv2/opencv.hpp>
  6. #include <chrono>
  7. #include <tuple>
  8. namespace GNode
  9. {
  10. static std::tuple<int, int, int> getFontSize(const std::string& text)
  11. {
  12. int baseline = 0;
  13. cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 2, &baseline);
  14. // std::cout << textSize << std::endl;
  15. return std::make_tuple(textSize.width, textSize.height, baseline);
  16. }
  17. static std::tuple<uint8_t, uint8_t, uint8_t> hsv2bgr(float h, float s, float v)
  18. {
  19. const int h_i = static_cast<int>(h * 6);
  20. const float f = h * 6 - h_i;
  21. const float p = v * (1 - s);
  22. const float q = v * (1 - f * s);
  23. const float t = v * (1 - (1 - f) * s);
  24. float r, g, b;
  25. switch (h_i) {
  26. case 0:
  27. r = v, g = t, b = p;
  28. break;
  29. case 1:
  30. r = q, g = v, b = p;
  31. break;
  32. case 2:
  33. r = p, g = v, b = t;
  34. break;
  35. case 3:
  36. r = p, g = q, b = v;
  37. break;
  38. case 4:
  39. r = t, g = p, b = v;
  40. break;
  41. case 5:
  42. r = v, g = p, b = q;
  43. break;
  44. default:
  45. r = 1, g = 1, b = 1;
  46. break;
  47. }
  48. return std::make_tuple(static_cast<uint8_t>(b * 255), static_cast<uint8_t>(g * 255),
  49. static_cast<uint8_t>(r * 255));
  50. }
  51. static std::tuple<uint8_t, uint8_t, uint8_t> random_color(int id)
  52. {
  53. float h_plane = ((((unsigned int)id << 2) ^ 0x937151) % 100) / 100.0f;
  54. float s_plane = ((((unsigned int)id << 3) ^ 0x315793) % 100) / 100.0f;
  55. return hsv2bgr(h_plane, s_plane, 1);
  56. }
  57. void DrawNode::work()
  58. {
  59. printf("DrawNode %s\n", name_.c_str());
  60. while (running_)
  61. {
  62. bool has_data = false;
  63. for (auto& input_buffer : input_buffers_)
  64. {
  65. printf("DrawNode %s queue size : %d\n", name_.c_str(), input_buffer.second->size());
  66. std::shared_ptr<meta::MetaData> metaData;
  67. if (!input_buffer.second->try_pop(metaData))
  68. {
  69. continue;
  70. }
  71. has_data = true;
  72. // printf("Node %s get data from %s\n", name_.c_str(), input_buffer.first.c_str());
  73. cv::Mat image = metaData->image.clone();
  74. int image_width = image.cols;
  75. int image_height = image.rows;
  76. PositionManager<float> pm(getFontSize);
  77. for (auto& box : metaData->track_boxes)
  78. {
  79. uint8_t b, g, r;
  80. std::tie(b, g, r) = random_color(box.class_id);
  81. cv::rectangle(image, cv::Point(box.left, box.top), cv::Point(box.right, box.bottom), cv::Scalar(b, g, r), 2);
  82. std::tuple<int, int, int, int> pbox = std::make_tuple(box.left, box.top, box.right, box.bottom);
  83. int x, y;
  84. std::string text;
  85. if (box.class_id != -1)
  86. {
  87. text = str_format("%s %.2f id=%d", box.label.c_str(), box.score, box.class_id);
  88. }
  89. else
  90. {
  91. text = str_format("%s %.2f", box.label.c_str(), box.score);
  92. }
  93. std::tie(x, y) = pm.selectOptimalPosition(pbox, image_width, image_height, text);
  94. cv::putText(image, text, cv::Point(x, y), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(b, g, r), 2);
  95. }
  96. metaData->draw_image = image;
  97. for (auto& output_buffer : output_buffers_)
  98. {
  99. // printf("Node %s push data to %s\n", name_.c_str(), output_buffer.first.c_str());
  100. output_buffer.second->push(metaData);
  101. }
  102. }
  103. if (!has_data) {
  104. // printf("draw wait data\n");
  105. std::unique_lock<std::mutex> lock(mutex_);
  106. cond_var_->wait_for(lock, std::chrono::milliseconds(100), [this] {
  107. return !running_; // 等待时检查退出条件
  108. });
  109. }
  110. }
  111. }
  112. }