From 4bb08188cc21ff66bed75dc0dd1b8c20054129f6 Mon Sep 17 00:00:00 2001 From: haotian <2421912570@qq.com> Date: Thu, 12 Mar 2026 21:04:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A3=80=E6=B5=8B=E6=A1=86?= =?UTF-8?q?=E7=9A=84=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configs/full_pipeline_1080p.json | 13 +++--- docs/design/detection_parameters_guide.md | 56 +++++++++++++++++++++-- plugins/osd/osd_node.cpp | 48 +++++++++++-------- 3 files changed, 88 insertions(+), 29 deletions(-) diff --git a/configs/full_pipeline_1080p.json b/configs/full_pipeline_1080p.json index b18b20b..b12f867 100644 --- a/configs/full_pipeline_1080p.json +++ b/configs/full_pipeline_1080p.json @@ -105,14 +105,14 @@ "model_w": 768, "model_h": 768, "num_classes": 11, - "conf": 0.25, + "conf": 0.1, "nms": 0.45, "debug": { "stats": true, "stats_interval": 30, - "detections": false + "detections": true }, - "class_filter": [3, 6, 10] + "class_filter": [3, 6] }, { "id": "tracker", @@ -141,7 +141,7 @@ "anchor_class": 6, "boots_class": 3, "color_check": { - "enable": true, + "enable": false, "method": "hsv", "dark_threshold": 80, "roi_expand": 1.0 @@ -168,9 +168,10 @@ "draw_bbox": true, "draw_text": true, "draw_face_det": true, + "draw_face_recog": false, "draw_face_bbox": true, - "line_width": 2, - "font_scale": 1, + "line_width": 1.0, + "font_scale": 0.5, "use_rga_bbox": false, "labels": ["helmet", "gloves", "vest", "boots", "goggles", "none", "Person", "no_helmet", "no_goggle", "no_gloves", "no_boots", "violation"] }, diff --git a/docs/design/detection_parameters_guide.md b/docs/design/detection_parameters_guide.md index 8332a78..982a74e 100644 --- a/docs/design/detection_parameters_guide.md +++ b/docs/design/detection_parameters_guide.md @@ -650,9 +650,57 @@ MobileFaceNet 模型通常使用: --- -## 六、综合配置建议 +## 六、OSD 显示参数 (`osd`) -### 6.1 场景配置速查表 +OSD 节点负责在视频上绘制检测结果(边界框、文字标签等)。 + +### 6.1 参数说明 + +| 参数名 | 类型 | 默认值 | 范围 | 说明 | +|--------|------|--------|------|------| +| `draw_bbox` | bool | true | true/false | 绘制普通检测框(YOLO等) | +| `draw_text` | bool | true | true/false | 绘制文字标签 | +| `draw_face_det` | bool | true | true/false | 绘制人脸检测框(青色) | +| `draw_face_recog` | bool | true | true/false | 绘制人脸识别框(红色=陌生人,绿色=已识别) | +| `draw_face_bbox` | bool | true | true/false | 绘制人脸边界框(总开关) | +| `line_width` | float | 2.0 | ≥1.0 | 框线宽度(像素),最小1像素 | +| `font_scale` | float | 1.0 | ≥0.5 | 字体缩放比例,基础5×7像素 | +| `use_rga_bbox` | bool | true | true/false | 使用RGA硬件绘制(RK3588) | + +### 6.2 配置示例 + +```json +{ + "id": "osd", + "type": "osd", + "role": "filter", + "enable": true, + "draw_bbox": true, + "draw_text": true, + "draw_face_det": true, + "draw_face_recog": false, + "draw_face_bbox": true, + "line_width": 1.0, + "font_scale": 1.0, + "use_rga_bbox": false, + "labels": ["person", "face"] +} +``` + +### 6.3 注意事项 + +1. **框线宽度**:由于 `line_width` 转整数后最小为 1,设置 0.5 和 1.0 效果相同 +2. **字体大小**:基础字体为 5×7 像素,`font_scale` 控制缩放和字间距 +3. **颜色说明**: + - 人脸检测框:`{0, 180, 180}`(深青色) + - 人脸识别人脸:红色(`{255, 0, 0}`)表示陌生人,绿色(`{0, 255, 0}`)表示已识别 +4. **重叠问题**:当 `draw_face_det` 和 `draw_face_recog` 同时开启时,两个框坐标相同会重叠,建议只开启一个 + +--- + +## 七、综合配置建议 + +### 7.1 场景配置速查表 | 场景 | 检测节点 | 关键参数 | 说明 | |------|----------|----------|------| @@ -661,7 +709,7 @@ MobileFaceNet 模型通常使用: | **会议室** | `ai_scrfd` | conf=0.4, max_faces=50 | 多人场景 | | **户外/街道** | `ai_scrfd_sliding` | 2-4窗口 | 远距离检测 | -### 6.2 分辨率配置对照表 +### 7.2 分辨率配置对照表 | 分辨率 | 检测节点 | 输入处理 | 建议 | |--------|----------|----------|------| @@ -672,7 +720,7 @@ MobileFaceNet 模型通常使用: --- -## 七、常见问题汇总 +## 八、常见问题汇总 ### Q1: 检测框抖动/闪烁 diff --git a/plugins/osd/osd_node.cpp b/plugins/osd/osd_node.cpp index 822058d..81e7be1 100644 --- a/plugins/osd/osd_node.cpp +++ b/plugins/osd/osd_node.cpp @@ -42,10 +42,10 @@ struct Color { }; const Color kClassColors[] = { - {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, - {0, 255, 255}, {128, 0, 0}, {0, 128, 0}, {0, 0, 128}, {128, 128, 0}, - {128, 0, 128}, {0, 128, 128}, {255, 128, 0}, {255, 0, 128}, {128, 255, 0}, - {0, 255, 128}, {128, 0, 255}, {0, 128, 255}, {255, 128, 128}, {128, 255, 128} + {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, // 0-4: 红,绿,蓝,黄,紫 + {0, 255, 255}, {0, 255, 0}, {0, 128, 0}, {0, 0, 128}, {128, 128, 0}, // 5-9: 青,绿(人),深绿,深蓝,橄榄 + {128, 0, 128}, {0, 128, 128}, {255, 128, 0}, {255, 0, 128}, {128, 255, 0}, // 10-14 + {0, 255, 128}, {128, 0, 255}, {0, 128, 255}, {255, 128, 128}, {128, 255, 128} // 15-19 }; inline Color GetClassColor(int cls_id) { @@ -200,11 +200,13 @@ void DrawVLine(uint8_t* data, int w, int h, int stride, PixelFormat fmt, } void DrawRect(uint8_t* data, int w, int h, int stride, PixelFormat fmt, - int x1, int y1, int x2, int y2, int thickness, const Color& color) { - DrawHLine(data, w, h, stride, fmt, x1, x2, y1, thickness, color); - DrawHLine(data, w, h, stride, fmt, x1, x2, y2 - thickness + 1, thickness, color); - DrawVLine(data, w, h, stride, fmt, x1, y1, y2, thickness, color); - DrawVLine(data, w, h, stride, fmt, x2 - thickness + 1, y1, y2, thickness, color); + int x1, int y1, int x2, int y2, float thickness, const Color& color) { + int t = static_cast(thickness); + if (t < 1) t = 1; + DrawHLine(data, w, h, stride, fmt, x1, x2, y1, t, color); + DrawHLine(data, w, h, stride, fmt, x1, x2, y2 - t + 1, t, color); + DrawVLine(data, w, h, stride, fmt, x1, y1, y2, t, color); + DrawVLine(data, w, h, stride, fmt, x2 - t + 1, y1, y2, t, color); } const uint8_t kFont5x7[96][7] = { @@ -343,11 +345,16 @@ void DrawChar(uint8_t* data, int w, int h, int stride, PixelFormat fmt, } void DrawText(uint8_t* data, int w, int h, int stride, PixelFormat fmt, - int x, int y, const char* text, int scale, const Color& color) { + int x, int y, const char* text, float scale, const Color& color) { int cx = x; + int int_scale = static_cast(scale); + if (int_scale < 1) int_scale = 1; + // Calculate char spacing based on scale + int char_spacing = static_cast(6 * scale); + if (char_spacing < 4) char_spacing = 4; // minimum spacing while (*text) { - DrawChar(data, w, h, stride, fmt, cx, y, *text, scale, color); - cx += 6 * scale; + DrawChar(data, w, h, stride, fmt, cx, y, *text, int_scale, color); + cx += char_spacing; ++text; } } @@ -364,9 +371,10 @@ public: draw_bbox_ = config.ValueOr("draw_bbox", true); draw_text_ = config.ValueOr("draw_text", true); draw_face_det_ = config.ValueOr("draw_face_det", draw_face_det_); + draw_face_recog_ = config.ValueOr("draw_face_recog", draw_face_recog_); draw_face_bbox_ = config.ValueOr("draw_face_bbox", draw_face_bbox_); - line_width_ = config.ValueOr("line_width", 2); - font_scale_ = config.ValueOr("font_scale", 1); + line_width_ = config.ValueOr("line_width", 2.0f); + font_scale_ = config.ValueOr("font_scale", 1.0f); use_rga_bbox_ = config.ValueOr("use_rga_bbox", use_rga_bbox_); if (const SimpleJson* dbg = config.Find("debug"); dbg && dbg->IsObject()) { @@ -401,6 +409,7 @@ public: LogInfo(std::string("[osd] start id=") + id_ + " draw_bbox=" + (draw_bbox_ ? "true" : "false") + " draw_text=" + (draw_text_ ? "true" : "false") + " draw_face_det=" + (draw_face_det_ ? "true" : "false") + + " draw_face_recog=" + (draw_face_recog_ ? "true" : "false") + " draw_face_bbox=" + (draw_face_bbox_ ? "true" : "false") + " use_rga_bbox=" + (use_rga_bbox_ ? "true" : "false")); #if !defined(RK3588_ENABLE_RGA) @@ -425,7 +434,7 @@ public: } DrawDetections(out); if (draw_face_det_) DrawFaceDet(out); - DrawFaceRecog(out); + if (draw_face_recog_) DrawFaceRecog(out); } PushToDownstream(out); @@ -820,7 +829,7 @@ private: LogRgaBboxErrorThrottled("imbeginJob failed"); } else { bool ok = true; - const Color color{0, 255, 255}; + const Color color{0, 180, 180}; // 深青色,不那么刺眼 for (const auto& it : frame->face_det->faces) { int x = Clamp(static_cast(it.bbox.x), 0, w - 1); int y = Clamp(static_cast(it.bbox.y), 0, h - 1); @@ -868,7 +877,7 @@ private: frame->SyncStart(); } - const Color color{0, 255, 255}; + const Color color{0, 180, 180}; // 深青色,不那么刺眼 for (const auto& it : frame->face_det->faces) { int x1 = static_cast(it.bbox.x); int y1 = static_cast(it.bbox.y); @@ -896,10 +905,11 @@ private: bool draw_bbox_ = true; bool draw_text_ = true; bool draw_face_det_ = true; + bool draw_face_recog_ = true; bool draw_face_bbox_ = true; bool use_rga_bbox_ = true; - int line_width_ = 2; - int font_scale_ = 1; + float line_width_ = 2.0f; + float font_scale_ = 1.0f; std::vector labels_; void LogRgaBboxErrorThrottled(const std::string& reason) {