Tighten person-shoe shape filtering
This commit is contained in:
parent
a08dbdf62a
commit
ddc99dc2a8
@ -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 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
|
||||
|
||||
- New analytics capabilities should be implemented as plugins when they represent pipeline nodes.
|
||||
|
||||
@ -236,6 +236,8 @@
|
||||
"max_shoe_roi_width_ratio": 0.65,
|
||||
"max_shoe_roi_height_ratio": 0.6,
|
||||
"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
|
||||
}
|
||||
},
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "color_analyzer.h"
|
||||
#include "person_shoe_shape.h"
|
||||
#include "frame/frame.h"
|
||||
#include "node.h"
|
||||
#include "utils/logger.h"
|
||||
@ -32,6 +33,8 @@ struct PersonShoeCheckConfig {
|
||||
float max_shoe_roi_width_ratio = 0.65f;
|
||||
float max_shoe_roi_height_ratio = 0.60f;
|
||||
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 match_iou = 0.02f;
|
||||
float x_offset = -0.20f;
|
||||
@ -61,6 +64,7 @@ struct ShoeGeomMetrics {
|
||||
float roi_height_ratio = 0.0f;
|
||||
float roi_area_ratio = 0.0f;
|
||||
float aspect_ratio = 0.0f;
|
||||
bool is_front_view = false;
|
||||
bool person_gate = false;
|
||||
bool roi_gate = false;
|
||||
bool shape_gate = false;
|
||||
@ -150,6 +154,8 @@ private:
|
||||
float max_shoe_roi_width_ratio,
|
||||
float max_shoe_roi_height_ratio,
|
||||
float max_shoe_roi_area_ratio,
|
||||
float min_front_shoe_width_ratio,
|
||||
float max_front_shoe_aspect_ratio,
|
||||
float max_shoe_aspect_ratio) {
|
||||
ShoeGeomMetrics m;
|
||||
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_height_ratio = shoe_h / roi_h;
|
||||
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_height_ratio >= min_shoe_height_ratio &&
|
||||
@ -180,7 +195,7 @@ private:
|
||||
m.roi_width_ratio <= max_shoe_roi_width_ratio &&
|
||||
m.roi_height_ratio <= max_shoe_roi_height_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;
|
||||
}
|
||||
|
||||
@ -244,6 +259,10 @@ private:
|
||||
"max_shoe_roi_height_ratio", config.person_shoe.max_shoe_roi_height_ratio);
|
||||
config.person_shoe.max_shoe_roi_area_ratio = ps->ValueOr<float>(
|
||||
"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>(
|
||||
"max_shoe_aspect_ratio", config.person_shoe.max_shoe_aspect_ratio);
|
||||
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_height_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);
|
||||
const bool size_preferred = !config_.person_shoe.enable_size_preferred ||
|
||||
(metrics.person_gate && metrics.roi_gate && metrics.shape_gate);
|
||||
@ -383,6 +404,7 @@ private:
|
||||
",h:" + std::to_string(metrics.roi_height_ratio) +
|
||||
",a:" + std::to_string(metrics.roi_area_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") +
|
||||
",roi:" + std::string(metrics.roi_gate ? "true" : "false") +
|
||||
",shape:" + std::string(metrics.shape_gate ? "true" : "false") + ")" +
|
||||
|
||||
40
plugins/logic_gate/person_shoe_shape.h
Normal file
40
plugins/logic_gate/person_shoe_shape.h
Normal 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
|
||||
@ -38,6 +38,7 @@ add_executable(rk3588_gtests
|
||||
test_hw_factory.cpp
|
||||
test_frame_buffer.cpp
|
||||
test_behavior_event_model.cpp
|
||||
test_person_shoe_shape.cpp
|
||||
test_region_event.cpp
|
||||
test_action_recog.cpp
|
||||
test_event_fusion.cpp
|
||||
|
||||
76
tests/test_person_shoe_shape.cpp
Normal file
76
tests/test_person_shoe_shape.cpp
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user