Center person shoe ROI horizontally

This commit is contained in:
tian 2026-04-14 15:46:50 +08:00
parent d9cbaad65d
commit 3a9a3bccc1
6 changed files with 88 additions and 26 deletions

View File

@ -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,

View File

@ -0,0 +1,38 @@
#pragma once
#include <algorithm>
#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<float>(img_w) - out.x);
if (img_h > 0) out.h = std::min(out.h, static_cast<float>(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

View File

@ -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<int>("min_person_height", dynamic_roi_.min_person_height));
dynamic_roi_.max_box_area_ratio =
std::max(0.0f, dyn->ValueOr<float>("max_box_area_ratio", dynamic_roi_.max_box_area_ratio));
dynamic_roi_.x_offset = dyn->ValueOr<float>("x_offset", dynamic_roi_.x_offset);
dynamic_roi_.y_offset = dyn->ValueOr<float>("y_offset", dynamic_roi_.y_offset);
dynamic_roi_.width_scale = dyn->ValueOr<float>("width_scale", dynamic_roi_.width_scale);
dynamic_roi_.height_scale = dyn->ValueOr<float>("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<int>(roi_x));
const int y0 = std::max(0, static_cast<int>(roi_y));
const int x1 = std::min(src_w, static_cast<int>(roi_x + roi_w));
const int y1 = std::min(src_h, static_cast<int>(roi_y + roi_h));
const int x0 = std::max(0, static_cast<int>(roi.x));
const int y0 = std::max(0, static_cast<int>(roi.y));
const int x1 = std::min(src_w, static_cast<int>(roi.x + roi.w));
const int y1 = std::min(src_h, static_cast<int>(roi.y + roi.h));
if (x1 <= x0 || y1 <= y0) continue;
rois.push_back({x0, y0, x1 - x0, y1 - y0});

View File

@ -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<float>(
"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<float>("x_offset", config.person_shoe.x_offset);
config.person_shoe.y_offset = fr->ValueOr<float>("y_offset", config.person_shoe.y_offset);
config.person_shoe.width_scale = fr->ValueOr<float>("width_scale", config.person_shoe.width_scale);
config.person_shoe.height_scale = fr->ValueOr<float>("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) {

View File

@ -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

View File

@ -0,0 +1,25 @@
#include <gtest/gtest.h>
#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