From 1290c162df2f5d6772becfbfe57b5f0737f8205a Mon Sep 17 00:00:00 2001 From: sladro Date: Fri, 26 Dec 2025 15:02:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20OSD=20=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=A0=87=E7=AD=BE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configs/sample_ai_pipeline.json | 3 +- configs/sample_custom_yolov8.json | 78 +++++++++++++++++++++++++++++++ plugins/osd/osd_node.cpp | 21 ++++++++- 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 configs/sample_custom_yolov8.json diff --git a/configs/sample_ai_pipeline.json b/configs/sample_ai_pipeline.json index df3dfa6..b7a65b5 100644 --- a/configs/sample_ai_pipeline.json +++ b/configs/sample_ai_pipeline.json @@ -48,7 +48,8 @@ "draw_bbox": true, "draw_text": true, "line_width": 2, - "font_scale": 1 + "font_scale": 1, + "labels": [] }, { "id": "pub_cam1", diff --git a/configs/sample_custom_yolov8.json b/configs/sample_custom_yolov8.json new file mode 100644 index 0000000..c36c0db --- /dev/null +++ b/configs/sample_custom_yolov8.json @@ -0,0 +1,78 @@ +{ + "queue": { "size": 8, "strategy": "drop_oldest" }, + "graphs": [ + { + "name": "cam1_custom_yolov8", + "nodes": [ + { + "id": "in_cam1", + "type": "input_rtsp", + "role": "source", + "enable": true, + "url": "rtsp://192.168.1.100:554/stream", + "fps": 25, + "width": 1920, + "height": 1080, + "use_mpp": false, + "use_ffmpeg": true, + "force_tcp": true + }, + { + "id": "pre_cam1", + "type": "preprocess", + "role": "filter", + "enable": true, + "dst_w": 640, + "dst_h": 640, + "dst_format": "rgb", + "keep_ratio": false, + "use_rga": true + }, + { + "id": "ai_cam1", + "type": "ai_yolo", + "role": "filter", + "enable": true, + "model_path": "/models/your_custom_yolov8.rknn", + "model_version": "v8", + "num_classes": 5, + "conf": 0.5, + "nms": 0.45, + "class_filter": [] + }, + { + "id": "osd_cam1", + "type": "osd", + "role": "filter", + "enable": true, + "draw_bbox": true, + "draw_text": true, + "line_width": 3, + "font_scale": 2, + "labels": ["cat", "dog", "bird", "car", "person"] + }, + { + "id": "pub_cam1", + "type": "publish", + "role": "sink", + "enable": true, + "codec": "h264", + "fps": 25, + "gop": 50, + "bitrate_kbps": 2000, + "use_mpp": true, + "use_ffmpeg_mux": true, + "outputs": [ + { "proto": "rtsp_server", "port": 8554, "path": "/live/cam1" } + ] + } + ], + "edges": [ + ["in_cam1", "pre_cam1"], + ["pre_cam1", "ai_cam1"], + ["ai_cam1", "osd_cam1"], + ["osd_cam1", "pub_cam1"] + ] + } + ] +} diff --git a/plugins/osd/osd_node.cpp b/plugins/osd/osd_node.cpp index 2da95e8..c0f9767 100644 --- a/plugins/osd/osd_node.cpp +++ b/plugins/osd/osd_node.cpp @@ -286,6 +286,14 @@ public: line_width_ = config.ValueOr("line_width", 2); font_scale_ = config.ValueOr("font_scale", 1); + // Load custom labels from config + if (const SimpleJson* labels = config.Find("labels")) { + for (const auto& item : labels->AsArray()) { + labels_.push_back(item.AsString("")); + } + std::cout << "[osd] loaded " << labels_.size() << " custom labels\n"; + } + input_queue_ = ctx.input_queue; if (!input_queue_) { std::cerr << "[osd] no input queue for node " << id_ << "\n"; @@ -343,6 +351,16 @@ private: } } + const char* GetLabel(int cls_id) const { + if (!labels_.empty()) { + if (cls_id >= 0 && cls_id < static_cast(labels_.size())) { + return labels_[cls_id].c_str(); + } + return "unknown"; + } + return GetClassName(cls_id); + } + void DrawDetections(FramePtr frame) { if (!frame->det || frame->det->items.empty()) return; @@ -371,7 +389,7 @@ private: if (draw_text_) { char label[64]; - snprintf(label, sizeof(label), "%s %.0f%%", GetClassName(det.cls_id), det.score * 100); + snprintf(label, sizeof(label), "%s %.0f%%", GetLabel(det.cls_id), det.score * 100); int text_y = y1 - 8 * font_scale_; if (text_y < 0) text_y = y1 + 2; DrawText(data, w, h, stride, fmt, x1, text_y, label, font_scale_, color); @@ -384,6 +402,7 @@ private: bool draw_text_ = true; int line_width_ = 2; int font_scale_ = 1; + std::vector labels_; std::atomic running_{false}; std::shared_ptr> input_queue_;