diff --git a/configs/test_cam1_face_det_rtsp_server.json b/configs/test_cam1_face_det_rtsp_server.json index 2c9716f..d6e0d32 100644 --- a/configs/test_cam1_face_det_rtsp_server.json +++ b/configs/test_cam1_face_det_rtsp_server.json @@ -36,11 +36,12 @@ "role": "filter", "enable": true, "model_path": "./models/RetinaFace_mobile320.rknn", - "conf": 0.6, + "conf": 0.3, "nms": 0.4, "max_faces": 10, "output_landmarks": true, - "input_format": "rgb" + "input_format": "rgb", + "debug": { "stats": true, "stats_interval": 30, "log_outputs": true } }, { "id": "osd_cam1", @@ -51,7 +52,8 @@ "draw_text": true, "line_width": 2, "font_scale": 1, - "labels": [] + "labels": [], + "debug": { "draw_test_rect": true, "force_clone_on_dma": true } }, { "id": "post_cam1", diff --git a/plugins/ai_face_det/ai_face_det_node.cpp b/plugins/ai_face_det/ai_face_det_node.cpp index a67711a..684ce12 100644 --- a/plugins/ai_face_det/ai_face_det_node.cpp +++ b/plugins/ai_face_det/ai_face_det_node.cpp @@ -674,6 +674,9 @@ private: std::cerr << "[ai_face_det] frame=" << frame->frame_id << " faces=" << n << " best=" << best + << " max=" << last_max_score_ + << " cand=" << last_candidates_ + << " prior_mismatch=" << (last_prior_mismatch_ ? 1 : 0) << " conf_thr=" << conf_thresh_ << " nms=" << nms_thresh_ << "\n"; @@ -685,6 +688,10 @@ private: int orig_w, int orig_h, int in_w, int in_h, FaceDetResult& out) { + last_prior_mismatch_ = false; + last_candidates_ = 0; + last_max_score_ = 0.0f; + // Find loc/conf/landms tensors. std::vector locs; std::vector confs; // Nx2 @@ -753,6 +760,7 @@ private: if (!priors.empty() && static_cast(priors.size()) != n) { // Mismatch: can't reliably decode. std::cerr << "[ai_face_det] prior mismatch: priors=" << priors.size() << " n=" << n << "\n"; + last_prior_mismatch_ = true; return; } @@ -784,7 +792,9 @@ private: if (s >= 0.0f && s <= 1.0f) score = s; else score = Sigmoid(s); } + if (score > last_max_score_) last_max_score_ = score; if (score < conf_thresh_) continue; + ++last_candidates_; const Prior p = priors.empty() ? Prior{0, 0, 0, 0} : priors[static_cast(i)]; @@ -898,6 +908,11 @@ private: bool log_outputs_ = false; uint64_t processed_ = 0; int printed_outputs_ = 0; + + // Debug stats per last decoded frame + bool last_prior_mismatch_ = false; + int last_candidates_ = 0; + float last_max_score_ = 0.0f; }; REGISTER_NODE(AiFaceDetNode, "ai_face_det"); diff --git a/plugins/osd/osd_node.cpp b/plugins/osd/osd_node.cpp index 2a5d76e..c743d20 100644 --- a/plugins/osd/osd_node.cpp +++ b/plugins/osd/osd_node.cpp @@ -295,6 +295,10 @@ public: stats_log_ = dbg->ValueOr("stats", stats_log_); stats_interval_ = std::max( 1, static_cast(dbg->ValueOr("stats_interval", static_cast(stats_interval_)))); + + // Debug helpers + draw_test_rect_ = dbg->ValueOr("draw_test_rect", draw_test_rect_); + force_clone_on_dma_ = dbg->ValueOr("force_clone_on_dma", force_clone_on_dma_); } // Load custom labels from config @@ -333,6 +337,9 @@ public: FramePtr out = frame; if (out->data && (out->det || out->face_det || out->face_recog)) { + if (force_clone_on_dma_ && out->dma_fd >= 0) { + out = CloneFrameForWrite(out); + } if (out.use_count() > 1) { out = CloneFrameForWrite(out); } @@ -345,6 +352,26 @@ public: DrawDetections(out); DrawFaceDet(out); DrawFaceRecog(out); + + if (draw_test_rect_) { + int w = out->width; + int h = out->height; + uint8_t* data = out->planes[0].data ? out->planes[0].data : out->data; + PixelFormat fmt = out->format; + int stride; + if (fmt == PixelFormat::RGB || fmt == PixelFormat::BGR) { + stride = out->planes[0].stride > 0 ? out->planes[0].stride : (out->stride > 0 ? out->stride : w * 3); + } else if (fmt == PixelFormat::NV12 || fmt == PixelFormat::YUV420) { + stride = out->planes[0].stride > 0 ? out->planes[0].stride : (out->stride > 0 ? out->stride : w); + } else { + stride = 0; + } + if (data && stride > 0) { + const Color c{255, 0, 255}; + DrawRect(data, w, h, stride, fmt, 10, 10, 220, 120, std::max(2, line_width_), c); + DrawText(data, w, h, stride, fmt, 14, 14, "OSD", font_scale_, c); + } + } if (out->dma_fd >= 0 && out->data) { DmaSyncEndFd(out->dma_fd); } @@ -538,6 +565,9 @@ private: bool stats_log_ = false; uint64_t stats_interval_ = 100; + + bool draw_test_rect_ = false; + bool force_clone_on_dma_ = false; }; REGISTER_NODE(OsdNode, "osd");