Tighten person-shoe shape filtering

This commit is contained in:
tian 2026-04-14 13:09:01 +08:00
parent a08dbdf62a
commit ddc99dc2a8
6 changed files with 149 additions and 2 deletions

View File

@ -22,6 +22,12 @@ This repository is a plugin-based C++ video analytics system for RK3588. Develop
- Do not distort production code to satisfy the local machine environment. - Do not distort production code to satisfy the local machine environment.
- Do not remove or weaken RK3588-specific paths just because they are not runnable on the current workstation. - Do not remove or weaken RK3588-specific paths just because they are not runnable on the current workstation.
## Shell Environment Rules
- For agent-run shell commands on this workstation, use PowerShell 7.6 instead of Windows PowerShell 5.1.
- Prefer explicit invocation via `C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.0.0_x64__8wekyb3d8bbwe\pwsh.exe` when running commands.
- Do not rely on the system-default `powershell.exe` resolving to the desired version.
## Plugin and Architecture Rules ## Plugin and Architecture Rules
- New analytics capabilities should be implemented as plugins when they represent pipeline nodes. - New analytics capabilities should be implemented as plugins when they represent pipeline nodes.

View File

@ -236,6 +236,8 @@
"max_shoe_roi_width_ratio": 0.65, "max_shoe_roi_width_ratio": 0.65,
"max_shoe_roi_height_ratio": 0.6, "max_shoe_roi_height_ratio": 0.6,
"max_shoe_roi_area_ratio": 0.25, "max_shoe_roi_area_ratio": 0.25,
"min_front_shoe_width_ratio": 0.18,
"max_front_shoe_aspect_ratio": 1.5,
"max_shoe_aspect_ratio": 2.0 "max_shoe_aspect_ratio": 2.0
} }
}, },

View File

@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "color_analyzer.h" #include "color_analyzer.h"
#include "person_shoe_shape.h"
#include "frame/frame.h" #include "frame/frame.h"
#include "node.h" #include "node.h"
#include "utils/logger.h" #include "utils/logger.h"
@ -32,6 +33,8 @@ struct PersonShoeCheckConfig {
float max_shoe_roi_width_ratio = 0.65f; float max_shoe_roi_width_ratio = 0.65f;
float max_shoe_roi_height_ratio = 0.60f; float max_shoe_roi_height_ratio = 0.60f;
float max_shoe_roi_area_ratio = 0.25f; 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_shoe_aspect_ratio = 2.0f; float max_shoe_aspect_ratio = 2.0f;
float match_iou = 0.02f; float match_iou = 0.02f;
float x_offset = -0.20f; float x_offset = -0.20f;
@ -61,6 +64,7 @@ struct ShoeGeomMetrics {
float roi_height_ratio = 0.0f; float roi_height_ratio = 0.0f;
float roi_area_ratio = 0.0f; float roi_area_ratio = 0.0f;
float aspect_ratio = 0.0f; float aspect_ratio = 0.0f;
bool is_front_view = false;
bool person_gate = false; bool person_gate = false;
bool roi_gate = false; bool roi_gate = false;
bool shape_gate = false; bool shape_gate = false;
@ -150,6 +154,8 @@ private:
float max_shoe_roi_width_ratio, float max_shoe_roi_width_ratio,
float max_shoe_roi_height_ratio, float max_shoe_roi_height_ratio,
float max_shoe_roi_area_ratio, float max_shoe_roi_area_ratio,
float min_front_shoe_width_ratio,
float max_front_shoe_aspect_ratio,
float max_shoe_aspect_ratio) { float max_shoe_aspect_ratio) {
ShoeGeomMetrics m; ShoeGeomMetrics m;
const float person_w = std::max(1.0f, person_bbox.w); const float person_w = std::max(1.0f, person_bbox.w);
@ -168,7 +174,16 @@ private:
m.roi_width_ratio = shoe_w / roi_w; m.roi_width_ratio = shoe_w / roi_w;
m.roi_height_ratio = shoe_h / roi_h; m.roi_height_ratio = shoe_h / roi_h;
m.roi_area_ratio = shoe_area / roi_area; m.roi_area_ratio = shoe_area / roi_area;
m.aspect_ratio = shoe_h / shoe_w; const PersonShoeShapeMetrics shape_metrics = EvaluatePersonShoeShape(
shoe_w,
shoe_h,
person_w,
PersonShoeShapeConfig{
min_front_shoe_width_ratio,
max_front_shoe_aspect_ratio,
});
m.aspect_ratio = shape_metrics.aspect_ratio;
m.is_front_view = shape_metrics.is_front_view;
m.person_gate = m.person_gate =
m.person_height_ratio >= min_shoe_height_ratio && m.person_height_ratio >= min_shoe_height_ratio &&
@ -180,7 +195,7 @@ private:
m.roi_width_ratio <= max_shoe_roi_width_ratio && m.roi_width_ratio <= max_shoe_roi_width_ratio &&
m.roi_height_ratio <= max_shoe_roi_height_ratio && m.roi_height_ratio <= max_shoe_roi_height_ratio &&
m.roi_area_ratio <= max_shoe_roi_area_ratio; m.roi_area_ratio <= max_shoe_roi_area_ratio;
m.shape_gate = m.aspect_ratio <= max_shoe_aspect_ratio; m.shape_gate = shape_metrics.shape_gate && m.aspect_ratio <= max_shoe_aspect_ratio;
return m; return m;
} }
@ -244,6 +259,10 @@ private:
"max_shoe_roi_height_ratio", config.person_shoe.max_shoe_roi_height_ratio); "max_shoe_roi_height_ratio", config.person_shoe.max_shoe_roi_height_ratio);
config.person_shoe.max_shoe_roi_area_ratio = ps->ValueOr<float>( config.person_shoe.max_shoe_roi_area_ratio = ps->ValueOr<float>(
"max_shoe_roi_area_ratio", config.person_shoe.max_shoe_roi_area_ratio); "max_shoe_roi_area_ratio", config.person_shoe.max_shoe_roi_area_ratio);
config.person_shoe.min_front_shoe_width_ratio = ps->ValueOr<float>(
"min_front_shoe_width_ratio", config.person_shoe.min_front_shoe_width_ratio);
config.person_shoe.max_front_shoe_aspect_ratio = ps->ValueOr<float>(
"max_front_shoe_aspect_ratio", config.person_shoe.max_front_shoe_aspect_ratio);
config.person_shoe.max_shoe_aspect_ratio = ps->ValueOr<float>( config.person_shoe.max_shoe_aspect_ratio = ps->ValueOr<float>(
"max_shoe_aspect_ratio", config.person_shoe.max_shoe_aspect_ratio); "max_shoe_aspect_ratio", config.person_shoe.max_shoe_aspect_ratio);
if (const SimpleJson* fr = ps->Find("foot_region"); fr && fr->IsObject()) { if (const SimpleJson* fr = ps->Find("foot_region"); fr && fr->IsObject()) {
@ -358,6 +377,8 @@ private:
config_.person_shoe.max_shoe_roi_width_ratio, config_.person_shoe.max_shoe_roi_width_ratio,
config_.person_shoe.max_shoe_roi_height_ratio, config_.person_shoe.max_shoe_roi_height_ratio,
config_.person_shoe.max_shoe_roi_area_ratio, 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_shoe_aspect_ratio); config_.person_shoe.max_shoe_aspect_ratio);
const bool size_preferred = !config_.person_shoe.enable_size_preferred || const bool size_preferred = !config_.person_shoe.enable_size_preferred ||
(metrics.person_gate && metrics.roi_gate && metrics.shape_gate); (metrics.person_gate && metrics.roi_gate && metrics.shape_gate);
@ -383,6 +404,7 @@ private:
",h:" + std::to_string(metrics.roi_height_ratio) + ",h:" + std::to_string(metrics.roi_height_ratio) +
",a:" + std::to_string(metrics.roi_area_ratio) + ")" + ",a:" + std::to_string(metrics.roi_area_ratio) + ")" +
" aspect=" + std::to_string(metrics.aspect_ratio) + " aspect=" + std::to_string(metrics.aspect_ratio) +
" front_view=" + std::string(metrics.is_front_view ? "true" : "false") +
" gates=(person:" + std::string(metrics.person_gate ? "true" : "false") + " gates=(person:" + std::string(metrics.person_gate ? "true" : "false") +
",roi:" + std::string(metrics.roi_gate ? "true" : "false") + ",roi:" + std::string(metrics.roi_gate ? "true" : "false") +
",shape:" + std::string(metrics.shape_gate ? "true" : "false") + ")" + ",shape:" + std::string(metrics.shape_gate ? "true" : "false") + ")" +

View File

@ -0,0 +1,40 @@
#pragma once
#include <algorithm>
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;
};
struct PersonShoeShapeMetrics {
float person_width_ratio = 0.0f;
float aspect_ratio = 0.0f;
bool is_front_view = false;
bool shape_gate = false;
};
inline PersonShoeShapeMetrics EvaluatePersonShoeShape(float shoe_w,
float shoe_h,
float person_w,
const PersonShoeShapeConfig& config) {
PersonShoeShapeMetrics m;
const float safe_person_w = std::max(1.0f, person_w);
const float safe_shoe_w = std::max(1.0f, shoe_w);
const float safe_shoe_h = std::max(1.0f, shoe_h);
m.person_width_ratio = safe_shoe_w / safe_person_w;
m.aspect_ratio = safe_shoe_h / safe_shoe_w;
m.is_front_view = m.person_width_ratio < config.min_front_shoe_width_ratio;
if (m.is_front_view) {
m.shape_gate = m.aspect_ratio <= config.max_front_aspect_ratio;
} else {
m.shape_gate = safe_shoe_h <= (safe_shoe_w * config.max_side_height_width_ratio);
}
return m;
}
} // namespace rk3588

View File

@ -38,6 +38,7 @@ add_executable(rk3588_gtests
test_hw_factory.cpp test_hw_factory.cpp
test_frame_buffer.cpp test_frame_buffer.cpp
test_behavior_event_model.cpp test_behavior_event_model.cpp
test_person_shoe_shape.cpp
test_region_event.cpp test_region_event.cpp
test_action_recog.cpp test_action_recog.cpp
test_event_fusion.cpp test_event_fusion.cpp

View File

@ -0,0 +1,76 @@
#include <gtest/gtest.h>
#include "../plugins/logic_gate/person_shoe_shape.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;
const auto metrics = EvaluatePersonShoeShape(20.0f, 33.0f, 100.0f, 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);
}
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;
const auto metrics = EvaluatePersonShoeShape(16.0f, 24.0f, 100.0f, 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);
}
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;
const auto metrics = EvaluatePersonShoeShape(16.0f, 25.0f, 100.0f, config);
EXPECT_TRUE(metrics.is_front_view);
EXPECT_FALSE(metrics.shape_gate);
EXPECT_FLOAT_EQ(metrics.aspect_ratio, 1.5625f);
}
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;
const auto metrics = EvaluatePersonShoeShape(40.0f, 24.0f, 100.0f, config);
EXPECT_FALSE(metrics.is_front_view);
EXPECT_TRUE(metrics.shape_gate);
EXPECT_FLOAT_EQ(metrics.aspect_ratio, 0.6f);
}
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;
const auto metrics = EvaluatePersonShoeShape(40.0f, 33.0f, 100.0f, config);
EXPECT_FALSE(metrics.is_front_view);
EXPECT_FALSE(metrics.shape_gate);
EXPECT_FLOAT_EQ(metrics.aspect_ratio, 0.825f);
}
} // namespace
} // namespace rk3588