#include "common/utils.hpp" #include "nodes/base/base.hpp" #include "nodes/draw/drawNode.hpp" #include "nodes/draw/position.hpp" #include #include #include namespace GNode { static std::tuple getFontSize(const std::string& text) { int baseline = 0; cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 2, &baseline); // std::cout << textSize << std::endl; return std::make_tuple(textSize.width, textSize.height, baseline); } static std::tuple hsv2bgr(float h, float s, float v) { const int h_i = static_cast(h * 6); const float f = h * 6 - h_i; const float p = v * (1 - s); const float q = v * (1 - f * s); const float t = v * (1 - (1 - f) * s); float r, g, b; switch (h_i) { case 0: r = v, g = t, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = t; break; case 3: r = p, g = q, b = v; break; case 4: r = t, g = p, b = v; break; case 5: r = v, g = p, b = q; break; default: r = 1, g = 1, b = 1; break; } return std::make_tuple(static_cast(b * 255), static_cast(g * 255), static_cast(r * 255)); } static std::tuple random_color(int id) { float h_plane = ((((unsigned int)id << 2) ^ 0x937151) % 100) / 100.0f; float s_plane = ((((unsigned int)id << 3) ^ 0x315793) % 100) / 100.0f; return hsv2bgr(h_plane, s_plane, 1); } void DrawNode::work() { printf("DrawNode %s\n", name_.c_str()); while (running_) { bool has_data = false; for (auto& input_buffer : input_buffers_) { printf("DrawNode %s queue size : %d\n", name_.c_str(), input_buffer.second->size()); std::shared_ptr metaData; if (!input_buffer.second->try_pop(metaData)) { continue; } has_data = true; // printf("Node %s get data from %s\n", name_.c_str(), input_buffer.first.c_str()); cv::Mat image = metaData->image.clone(); int image_width = image.cols; int image_height = image.rows; PositionManager pm(getFontSize); for (auto& box : metaData->track_boxes) { uint8_t b, g, r; std::tie(b, g, r) = random_color(box.class_id); cv::rectangle(image, cv::Point(box.left, box.top), cv::Point(box.right, box.bottom), cv::Scalar(b, g, r), 2); std::tuple pbox = std::make_tuple(box.left, box.top, box.right, box.bottom); int x, y; std::string text; if (box.class_id != -1) { text = str_format("%s %.2f id=%d", box.label.c_str(), box.score, box.class_id); } else { text = str_format("%s %.2f", box.label.c_str(), box.score); } std::tie(x, y) = pm.selectOptimalPosition(pbox, image_width, image_height, text); cv::putText(image, text, cv::Point(x, y), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(b, g, r), 2); } metaData->draw_image = image; for (auto& output_buffer : output_buffers_) { // printf("Node %s push data to %s\n", name_.c_str(), output_buffer.first.c_str()); output_buffer.second->push(metaData); } } if (!has_data) { // printf("draw wait data\n"); std::unique_lock lock(mutex_); cond_var_->wait_for(lock, std::chrono::milliseconds(100), [this] { return !running_; // 等待时检查退出条件 }); } } } }