#include #include #include #include "frame/frame.h" #include "node.h" #include "utils/simple_json.h" #include "../plugins/region_event/region_event_node.h" namespace rk3588 { namespace { SimpleJson ParseConfigText(const std::string& text) { SimpleJson config; std::string err; EXPECT_TRUE(ParseSimpleJson(text, config, err)) << err; return config; } TEST(RegionEventTest, EmitsIntrusionWhenTrackedPersonStaysInsideRegion) { RegionEventNode node; const std::string config_text = R"({ "id": "region_evt", "events": [ { "type": "intrusion", "region_id": "zone_a", "roi": {"x": 0.10, "y": 0.10, "w": 0.50, "h": 0.50}, "min_duration_ms": 0 } ] })"; SimpleJson config = ParseConfigText(config_text); NodeContext ctx; auto out = std::make_shared>(4, QueueDropStrategy::DropOldest); ctx.output_queues.push_back(out); ASSERT_TRUE(node.Init(config, ctx)); ASSERT_TRUE(node.Start()); auto frame = std::make_shared(); frame->width = 1920; frame->height = 1080; frame->pts = 1000; frame->det = std::make_shared(); frame->det->img_w = 1920; frame->det->img_h = 1080; frame->det->items.push_back(Detection{0, 0.95f, Rect{300.0f, 220.0f, 180.0f, 420.0f}, 42}); EXPECT_EQ(static_cast(node.Process(frame)), static_cast(NodeStatus::OK)); ASSERT_NE(frame->behavior_events, nullptr); ASSERT_EQ(frame->behavior_events->items.size(), 1u); EXPECT_EQ(frame->behavior_events->items[0].type, BehaviorEventType::Intrusion); ASSERT_EQ(frame->behavior_events->items[0].track_ids.size(), 1u); EXPECT_EQ(frame->behavior_events->items[0].track_ids[0], 42); } TEST(RegionEventTest, EmitsClimbWhenTrackCrossesBoundaryOverTime) { RegionEventNode node; const std::string config_text = R"({ "id": "region_evt", "events": [ { "type": "climb", "region_id": "fence_1", "line": {"x1": 0.20, "y1": 0.40, "x2": 0.80, "y2": 0.40}, "min_duration_ms": 0, "min_vertical_motion": 40 } ] })"; SimpleJson config = ParseConfigText(config_text); NodeContext ctx; auto out = std::make_shared>(4, QueueDropStrategy::DropOldest); ctx.output_queues.push_back(out); ASSERT_TRUE(node.Init(config, ctx)); ASSERT_TRUE(node.Start()); auto frame1 = std::make_shared(); frame1->width = 1920; frame1->height = 1080; frame1->pts = 1000; frame1->det = std::make_shared(); frame1->det->img_w = 1920; frame1->det->img_h = 1080; frame1->det->items.push_back(Detection{0, 0.90f, Rect{700.0f, 520.0f, 120.0f, 260.0f}, 7}); auto frame2 = std::make_shared(); frame2->width = 1920; frame2->height = 1080; frame2->pts = 1100; frame2->det = std::make_shared(); frame2->det->img_w = 1920; frame2->det->img_h = 1080; frame2->det->items.push_back(Detection{0, 0.92f, Rect{700.0f, 320.0f, 120.0f, 260.0f}, 7}); EXPECT_EQ(static_cast(node.Process(frame1)), static_cast(NodeStatus::OK)); EXPECT_EQ(static_cast(node.Process(frame2)), static_cast(NodeStatus::OK)); ASSERT_NE(frame2->behavior_events, nullptr); ASSERT_EQ(frame2->behavior_events->items.size(), 1u); EXPECT_EQ(frame2->behavior_events->items[0].type, BehaviorEventType::Climb); ASSERT_EQ(frame2->behavior_events->items[0].track_ids.size(), 1u); EXPECT_EQ(frame2->behavior_events->items[0].track_ids[0], 7); } } // namespace } // namespace rk3588