diff --git a/configs/full_pipeline_1080p_test_alarm.json b/configs/full_pipeline_1080p_test_alarm.json index edcc991..f41013d 100644 --- a/configs/full_pipeline_1080p_test_alarm.json +++ b/configs/full_pipeline_1080p_test_alarm.json @@ -238,6 +238,7 @@ "max_shoe_roi_area_ratio": 0.25, "min_front_shoe_width_ratio": 0.18, "max_front_shoe_aspect_ratio": 1.5, + "max_side_height_width_ratio": 1.1, "max_shoe_aspect_ratio": 2.0 } }, diff --git a/plugins/logic_gate/logic_gate_node.cpp b/plugins/logic_gate/logic_gate_node.cpp index afec5d9..2d028cb 100644 --- a/plugins/logic_gate/logic_gate_node.cpp +++ b/plugins/logic_gate/logic_gate_node.cpp @@ -35,6 +35,7 @@ struct PersonShoeCheckConfig { float max_shoe_roi_area_ratio = 0.25f; float min_front_shoe_width_ratio = 0.18f; float max_front_shoe_aspect_ratio = 1.5f; + 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; @@ -156,6 +157,7 @@ private: float max_shoe_roi_area_ratio, float min_front_shoe_width_ratio, float max_front_shoe_aspect_ratio, + float max_side_height_width_ratio, float max_shoe_aspect_ratio) { ShoeGeomMetrics m; const float person_w = std::max(1.0f, person_bbox.w); @@ -181,6 +183,7 @@ private: PersonShoeShapeConfig{ min_front_shoe_width_ratio, max_front_shoe_aspect_ratio, + max_side_height_width_ratio, }); m.aspect_ratio = shape_metrics.aspect_ratio; m.is_front_view = shape_metrics.is_front_view; @@ -263,6 +266,8 @@ private: "min_front_shoe_width_ratio", config.person_shoe.min_front_shoe_width_ratio); config.person_shoe.max_front_shoe_aspect_ratio = ps->ValueOr( "max_front_shoe_aspect_ratio", config.person_shoe.max_front_shoe_aspect_ratio); + config.person_shoe.max_side_height_width_ratio = ps->ValueOr( + "max_side_height_width_ratio", config.person_shoe.max_side_height_width_ratio); 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()) { @@ -379,6 +384,7 @@ private: config_.person_shoe.max_shoe_roi_area_ratio, config_.person_shoe.min_front_shoe_width_ratio, config_.person_shoe.max_front_shoe_aspect_ratio, + config_.person_shoe.max_side_height_width_ratio, config_.person_shoe.max_shoe_aspect_ratio); const bool size_preferred = !config_.person_shoe.enable_size_preferred || (metrics.person_gate && metrics.roi_gate && metrics.shape_gate); diff --git a/plugins/logic_gate/person_shoe_shape.h b/plugins/logic_gate/person_shoe_shape.h index de0107c..db07543 100644 --- a/plugins/logic_gate/person_shoe_shape.h +++ b/plugins/logic_gate/person_shoe_shape.h @@ -7,7 +7,7 @@ namespace rk3588 { struct PersonShoeShapeConfig { float min_front_shoe_width_ratio = 0.18f; float max_front_aspect_ratio = 1.5f; - float max_side_height_width_ratio = 0.8f; + float max_side_height_width_ratio = 1.1f; }; struct PersonShoeShapeMetrics { diff --git a/tests/test_person_shoe_shape.cpp b/tests/test_person_shoe_shape.cpp index 6cc3d0c..138f2a5 100644 --- a/tests/test_person_shoe_shape.cpp +++ b/tests/test_person_shoe_shape.cpp @@ -1,75 +1,124 @@ #include +#include +#include +#include + #include "../plugins/logic_gate/person_shoe_shape.h" +#include "utils/simple_json.h" namespace rk3588 { namespace { -TEST(PersonShoeShapeTest, RejectsTallSideViewBoxes) { - PersonShoeShapeConfig config; - config.min_front_shoe_width_ratio = 0.18f; - config.max_front_aspect_ratio = 1.5f; - config.max_side_height_width_ratio = 0.8f; +PersonShoeShapeConfig LoadShapeConfig() { + std::ifstream file("configs/full_pipeline_1080p_test_alarm.json"); + if (!file.is_open()) { + throw std::runtime_error("failed to open configs/full_pipeline_1080p_test_alarm.json"); + } - const auto metrics = EvaluatePersonShoeShape(20.0f, 33.0f, 100.0f, config); + std::ostringstream buffer; + buffer << file.rdbuf(); + + SimpleJson root; + std::string err; + if (!ParseSimpleJson(buffer.str(), root, err)) { + throw std::runtime_error("failed to parse configs/full_pipeline_1080p_test_alarm.json: " + err); + } + + const auto& graphs = root.Find("graphs")->AsArray(); + const auto& nodes = graphs.at(0).Find("nodes")->AsArray(); + for (const auto& node : nodes) { + if (node.ValueOr("id", "") != "shoe_assoc") continue; + const SimpleJson* ps = node.Find("person_shoe_check"); + if (!ps || !ps->IsObject()) break; + + PersonShoeShapeConfig config; + config.min_front_shoe_width_ratio = + ps->ValueOr("min_front_shoe_width_ratio", config.min_front_shoe_width_ratio); + config.max_front_aspect_ratio = + ps->ValueOr("max_front_shoe_aspect_ratio", config.max_front_aspect_ratio); + config.max_side_height_width_ratio = + ps->ValueOr("max_side_height_width_ratio", config.max_side_height_width_ratio); + return config; + } + + throw std::runtime_error("failed to find shoe_assoc.person_shoe_check config"); +} + +TEST(PersonShoeShapeTest, RejectsSideViewBoxesBeyondConfiguredRatio) { + const auto config = LoadShapeConfig(); + const float shoe_w = 20.0f; + const float shoe_h = shoe_w * (config.max_side_height_width_ratio + 0.25f); + const float person_w = shoe_w / (config.min_front_shoe_width_ratio + 0.02f); + + const auto metrics = EvaluatePersonShoeShape(shoe_w, shoe_h, person_w, config); EXPECT_FALSE(metrics.is_front_view); EXPECT_FALSE(metrics.shape_gate); - EXPECT_FLOAT_EQ(metrics.person_width_ratio, 0.2f); - EXPECT_FLOAT_EQ(metrics.aspect_ratio, 1.65f); + EXPECT_GT(metrics.person_width_ratio, config.min_front_shoe_width_ratio); + EXPECT_GT(metrics.aspect_ratio, config.max_side_height_width_ratio); } -TEST(PersonShoeShapeTest, AllowsSlightlyTallFrontViewBoxes) { - PersonShoeShapeConfig config; - config.min_front_shoe_width_ratio = 0.18f; - config.max_front_aspect_ratio = 1.5f; - config.max_side_height_width_ratio = 0.8f; +TEST(PersonShoeShapeTest, AllowsFrontViewBoxesAtConfiguredAspectLimit) { + const auto config = LoadShapeConfig(); + const float shoe_w = 16.0f; + const float shoe_h = shoe_w * config.max_front_aspect_ratio; + const float person_w = shoe_w / (config.min_front_shoe_width_ratio - 0.02f); - const auto metrics = EvaluatePersonShoeShape(16.0f, 24.0f, 100.0f, config); + const auto metrics = EvaluatePersonShoeShape(shoe_w, shoe_h, person_w, config); EXPECT_TRUE(metrics.is_front_view); EXPECT_TRUE(metrics.shape_gate); - EXPECT_FLOAT_EQ(metrics.person_width_ratio, 0.16f); - EXPECT_FLOAT_EQ(metrics.aspect_ratio, 1.5f); + EXPECT_LT(metrics.person_width_ratio, config.min_front_shoe_width_ratio); + EXPECT_FLOAT_EQ(metrics.aspect_ratio, config.max_front_aspect_ratio); } -TEST(PersonShoeShapeTest, RejectsFrontViewBoxesBeyondAllowedAspect) { - PersonShoeShapeConfig config; - config.min_front_shoe_width_ratio = 0.18f; - config.max_front_aspect_ratio = 1.5f; - config.max_side_height_width_ratio = 0.8f; +TEST(PersonShoeShapeTest, RejectsFrontViewBoxesBeyondConfiguredAspect) { + const auto config = LoadShapeConfig(); + const float shoe_w = 16.0f; + const float shoe_h = shoe_w * (config.max_front_aspect_ratio + 0.1f); + const float person_w = shoe_w / (config.min_front_shoe_width_ratio - 0.02f); - const auto metrics = EvaluatePersonShoeShape(16.0f, 25.0f, 100.0f, config); + const auto metrics = EvaluatePersonShoeShape(shoe_w, shoe_h, person_w, config); EXPECT_TRUE(metrics.is_front_view); EXPECT_FALSE(metrics.shape_gate); - EXPECT_FLOAT_EQ(metrics.aspect_ratio, 1.5625f); + EXPECT_GT(metrics.aspect_ratio, config.max_front_aspect_ratio); } -TEST(PersonShoeShapeTest, AllowsWideSideViewBoxes) { - PersonShoeShapeConfig config; - config.min_front_shoe_width_ratio = 0.18f; - config.max_front_aspect_ratio = 1.5f; - config.max_side_height_width_ratio = 0.8f; +TEST(PersonShoeShapeTest, AllowsSideViewBoxesWithinConfiguredRatio) { + const auto config = LoadShapeConfig(); + const float shoe_w = 40.0f; + const float shoe_h = shoe_w * (config.max_side_height_width_ratio - 0.1f); + const float person_w = shoe_w / (config.min_front_shoe_width_ratio + 0.05f); - const auto metrics = EvaluatePersonShoeShape(40.0f, 24.0f, 100.0f, config); + const auto metrics = EvaluatePersonShoeShape(shoe_w, shoe_h, person_w, config); EXPECT_FALSE(metrics.is_front_view); EXPECT_TRUE(metrics.shape_gate); - EXPECT_FLOAT_EQ(metrics.aspect_ratio, 0.6f); + EXPECT_GT(metrics.person_width_ratio, config.min_front_shoe_width_ratio); + EXPECT_LT(metrics.aspect_ratio, config.max_side_height_width_ratio); } -TEST(PersonShoeShapeTest, RejectsNearSquareSideViewBoxes) { - PersonShoeShapeConfig config; - config.min_front_shoe_width_ratio = 0.18f; - config.max_front_aspect_ratio = 1.5f; - config.max_side_height_width_ratio = 0.8f; +TEST(PersonShoeShapeTest, AllowsNearSquareSideViewBoxesWhenConfigPermits) { + const auto config = LoadShapeConfig(); + const float shoe_w = 40.0f; + const float shoe_h = shoe_w * (config.max_side_height_width_ratio - 0.05f); + const float person_w = shoe_w / (config.min_front_shoe_width_ratio + 0.04f); - const auto metrics = EvaluatePersonShoeShape(40.0f, 33.0f, 100.0f, config); + const auto metrics = EvaluatePersonShoeShape(shoe_w, shoe_h, person_w, config); EXPECT_FALSE(metrics.is_front_view); - EXPECT_FALSE(metrics.shape_gate); - EXPECT_FLOAT_EQ(metrics.aspect_ratio, 0.825f); + EXPECT_TRUE(metrics.shape_gate); + EXPECT_LT(metrics.aspect_ratio, config.max_side_height_width_ratio); +} + +TEST(PersonShoeShapeTest, ReadsCurrentThresholdsFromRuntimeConfig) { + PersonShoeShapeConfig config; + ASSERT_NO_THROW(config = LoadShapeConfig()); + EXPECT_GT(config.min_front_shoe_width_ratio, 0.0f); + EXPECT_GT(config.max_front_aspect_ratio, 1.0f); + EXPECT_GT(config.max_side_height_width_ratio, 0.0f); } } // namespace