diff --git a/configs/full_pipeline_1080p_test_alarm.json b/configs/full_pipeline_1080p_test_alarm.json index 5dcf400..40308d8 100644 --- a/configs/full_pipeline_1080p_test_alarm.json +++ b/configs/full_pipeline_1080p_test_alarm.json @@ -196,10 +196,9 @@ "max_rois": 3, "min_person_height": 60, "max_box_area_ratio": 0.6, - "x_offset": -0.24, - "y_offset": 0.64, - "width_scale": 1.48, - "height_scale": 0.58 + "y_offset": 0.8, + "width_scale": 1.6, + "height_scale": 0.3 } }, { @@ -222,10 +221,9 @@ "attach_person_track_to_shoe": true, "emit_missing_violation": false, "foot_region": { - "x_offset": -0.24, - "y_offset": 0.64, - "width_scale": 1.48, - "height_scale": 0.58 + "y_offset": 0.8, + "width_scale": 1.6, + "height_scale": 0.3 }, "enable_size_preferred": true, "min_shoe_height_ratio": 0.08, diff --git a/include/utils/person_shoe_roi.h b/include/utils/person_shoe_roi.h new file mode 100644 index 0000000..6898d1f --- /dev/null +++ b/include/utils/person_shoe_roi.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "frame/rect.h" + +namespace rk3588 { + +inline float ComputeCenteredXOffset(float width_scale) { + return (1.0f - width_scale) * 0.5f; +} + +inline Rect ClipPersonShoeRoi(const Rect& roi, int img_w, int img_h) { + Rect out = roi; + out.x = std::max(0.0f, out.x); + out.y = std::max(0.0f, out.y); + if (img_w > 0) out.w = std::min(out.w, static_cast(img_w) - out.x); + if (img_h > 0) out.h = std::min(out.h, static_cast(img_h) - out.y); + out.w = std::max(0.0f, out.w); + out.h = std::max(0.0f, out.h); + return out; +} + +inline Rect BuildPersonFootRegion(const Rect& person_bbox, + int img_w, + int img_h, + float y_offset, + float width_scale, + float height_scale) { + Rect roi; + roi.x = person_bbox.x + person_bbox.w * ComputeCenteredXOffset(width_scale); + roi.y = person_bbox.y + person_bbox.h * y_offset; + roi.w = person_bbox.w * width_scale; + roi.h = person_bbox.h * height_scale; + return ClipPersonShoeRoi(roi, img_w, img_h); +} + +} // namespace rk3588 diff --git a/plugins/ai_shoe_det/ai_shoe_det_node.cpp b/plugins/ai_shoe_det/ai_shoe_det_node.cpp index 6d65462..78e7a7d 100644 --- a/plugins/ai_shoe_det/ai_shoe_det_node.cpp +++ b/plugins/ai_shoe_det/ai_shoe_det_node.cpp @@ -19,6 +19,7 @@ #include "hw/i_infer_backend.h" #include "node.h" #include "utils/logger.h" +#include "utils/person_shoe_roi.h" #if defined(RK3588_ENABLE_RKNN) #include "rknn_api.h" @@ -44,7 +45,6 @@ struct DynamicRoiConfig { int max_rois = 8; int min_person_height = 0; float max_box_area_ratio = 0.0f; - float x_offset = -0.15f; float y_offset = 0.72f; float width_scale = 1.30f; float height_scale = 0.38f; @@ -337,7 +337,6 @@ public: std::max(0, dyn->ValueOr("min_person_height", dynamic_roi_.min_person_height)); dynamic_roi_.max_box_area_ratio = std::max(0.0f, dyn->ValueOr("max_box_area_ratio", dynamic_roi_.max_box_area_ratio)); - dynamic_roi_.x_offset = dyn->ValueOr("x_offset", dynamic_roi_.x_offset); dynamic_roi_.y_offset = dyn->ValueOr("y_offset", dynamic_roi_.y_offset); dynamic_roi_.width_scale = dyn->ValueOr("width_scale", dynamic_roi_.width_scale); dynamic_roi_.height_scale = dyn->ValueOr("height_scale", dynamic_roi_.height_scale); @@ -511,15 +510,17 @@ private: for (size_t i = 0; i < max_rois; ++i) { const Detection& person = persons[(start_index + i) % persons.size()]; const Rect& bbox = person.bbox; - const float roi_x = bbox.x + bbox.w * dynamic_roi_.x_offset; - const float roi_y = bbox.y + bbox.h * dynamic_roi_.y_offset; - const float roi_w = bbox.w * dynamic_roi_.width_scale; - const float roi_h = bbox.h * dynamic_roi_.height_scale; + const Rect roi = BuildPersonFootRegion(bbox, + src_w, + src_h, + dynamic_roi_.y_offset, + dynamic_roi_.width_scale, + dynamic_roi_.height_scale); - const int x0 = std::max(0, static_cast(roi_x)); - const int y0 = std::max(0, static_cast(roi_y)); - const int x1 = std::min(src_w, static_cast(roi_x + roi_w)); - const int y1 = std::min(src_h, static_cast(roi_y + roi_h)); + const int x0 = std::max(0, static_cast(roi.x)); + const int y0 = std::max(0, static_cast(roi.y)); + const int x1 = std::min(src_w, static_cast(roi.x + roi.w)); + const int y1 = std::min(src_h, static_cast(roi.y + roi.h)); if (x1 <= x0 || y1 <= y0) continue; rois.push_back({x0, y0, x1 - x0, y1 - y0}); diff --git a/plugins/logic_gate/logic_gate_node.cpp b/plugins/logic_gate/logic_gate_node.cpp index 521f78a..383bcdc 100644 --- a/plugins/logic_gate/logic_gate_node.cpp +++ b/plugins/logic_gate/logic_gate_node.cpp @@ -11,6 +11,7 @@ #include "frame/frame.h" #include "node.h" #include "utils/logger.h" +#include "utils/person_shoe_roi.h" #include "utils/simple_json.h" namespace rk3588 { @@ -39,7 +40,6 @@ struct PersonShoeCheckConfig { float max_side_height_width_ratio = 1.1f; float max_shoe_aspect_ratio = 2.0f; float match_iou = 0.02f; - float x_offset = -0.20f; float y_offset = 0.64f; float width_scale = 1.48f; float height_scale = 0.58f; @@ -272,7 +272,6 @@ private: config.person_shoe.max_shoe_aspect_ratio = ps->ValueOr( "max_shoe_aspect_ratio", config.person_shoe.max_shoe_aspect_ratio); if (const SimpleJson* fr = ps->Find("foot_region"); fr && fr->IsObject()) { - config.person_shoe.x_offset = fr->ValueOr("x_offset", config.person_shoe.x_offset); config.person_shoe.y_offset = fr->ValueOr("y_offset", config.person_shoe.y_offset); config.person_shoe.width_scale = fr->ValueOr("width_scale", config.person_shoe.width_scale); config.person_shoe.height_scale = fr->ValueOr("height_scale", config.person_shoe.height_scale); @@ -304,12 +303,12 @@ private: } Rect BuildFootRegion(const Rect& person_bbox, int img_w, int img_h) const { - Rect roi; - roi.x = person_bbox.x + person_bbox.w * config_.person_shoe.x_offset; - roi.y = person_bbox.y + person_bbox.h * config_.person_shoe.y_offset; - roi.w = person_bbox.w * config_.person_shoe.width_scale; - roi.h = person_bbox.h * config_.person_shoe.height_scale; - return ClipRect(roi, img_w, img_h); + return BuildPersonFootRegion(person_bbox, + img_w, + img_h, + config_.person_shoe.y_offset, + config_.person_shoe.width_scale, + config_.person_shoe.height_scale); } void ProcessPersonShoeCheck(const FramePtr& frame) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6ba9bc3..feb007d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable(rk3588_gtests test_behavior_event_model.cpp test_person_shoe_shape.cpp test_person_shoe_filter.cpp + test_person_shoe_roi.cpp test_region_event.cpp test_action_recog.cpp test_event_fusion.cpp diff --git a/tests/test_person_shoe_roi.cpp b/tests/test_person_shoe_roi.cpp new file mode 100644 index 0000000..a539d6d --- /dev/null +++ b/tests/test_person_shoe_roi.cpp @@ -0,0 +1,25 @@ +#include + +#include "utils/person_shoe_roi.h" + +namespace rk3588 { +namespace { + +TEST(PersonShoeRoiTest, ComputesCenteredHorizontalOffsetFromWidthScale) { + EXPECT_FLOAT_EQ(ComputeCenteredXOffset(1.0f), 0.0f); + EXPECT_FLOAT_EQ(ComputeCenteredXOffset(1.6f), -0.3f); + EXPECT_FLOAT_EQ(ComputeCenteredXOffset(1.48f), -0.24f); +} + +TEST(PersonShoeRoiTest, BuildsCenteredFootRegionHorizontally) { + const Rect person{100.0f, 200.0f, 200.0f, 400.0f}; + const Rect roi = BuildPersonFootRegion(person, 1920, 1080, 0.8f, 1.6f, 0.3f); + + EXPECT_FLOAT_EQ(roi.x, 40.0f); + EXPECT_FLOAT_EQ(roi.y, 520.0f); + EXPECT_FLOAT_EQ(roi.w, 320.0f); + EXPECT_FLOAT_EQ(roi.h, 120.0f); +} + +} // namespace +} // namespace rk3588