Use bottom-third shoe color sampling
This commit is contained in:
parent
578d894425
commit
866ab2c27c
@ -33,25 +33,23 @@ ColorResult ColorAnalyzer::Analyze(const Frame& frame, const Rect& bbox) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const float center_w_scale = std::clamp(config_.center_w_scale, 0.1f, 1.0f);
|
||||
const float center_h_scale = std::clamp(config_.center_h_scale, 0.1f, 1.0f);
|
||||
const int inner_w = std::max(1, static_cast<int>(crop_w * center_w_scale));
|
||||
const int inner_h = std::max(1, static_cast<int>(crop_h * center_h_scale));
|
||||
const int inner_x = std::max(0, (crop_w - inner_w) / 2);
|
||||
const int inner_y = std::max(0, (crop_h - inner_h) / 2);
|
||||
const int sample_w = crop_w;
|
||||
const int sample_h = std::max(1, crop_h / 3);
|
||||
const int sample_x = 0;
|
||||
const int sample_y = std::max(0, crop_h - sample_h);
|
||||
|
||||
std::vector<uint8_t> center(inner_w * inner_h * 3);
|
||||
for (int row = 0; row < inner_h; ++row) {
|
||||
const uint8_t* src_row = cropped.data() + ((inner_y + row) * crop_w + inner_x) * 3;
|
||||
uint8_t* dst_row = center.data() + row * inner_w * 3;
|
||||
std::memcpy(dst_row, src_row, inner_w * 3);
|
||||
std::vector<uint8_t> sample(sample_w * sample_h * 3);
|
||||
for (int row = 0; row < sample_h; ++row) {
|
||||
const uint8_t* src_row = cropped.data() + ((sample_y + row) * crop_w + sample_x) * 3;
|
||||
uint8_t* dst_row = sample.data() + row * sample_w * 3;
|
||||
std::memcpy(dst_row, src_row, sample_w * 3);
|
||||
}
|
||||
|
||||
// 保存调试图像(用于检查裁剪区域)
|
||||
if (config_.debug_output) {
|
||||
static int save_count = 0;
|
||||
if (save_count++ % 30 == 0) { // 每30帧保存一次
|
||||
SaveDebugImage(center.data(), inner_w, inner_h, "/tmp/boot_debug_" + std::to_string(save_count) + ".ppm");
|
||||
SaveDebugImage(sample.data(), sample_w, sample_h, "/tmp/boot_debug_" + std::to_string(save_count) + ".ppm");
|
||||
LogInfo("[ColorAnalyzer] Saved debug image: /tmp/boot_debug_" + std::to_string(save_count) + ".ppm");
|
||||
}
|
||||
}
|
||||
@ -59,13 +57,13 @@ ColorResult ColorAnalyzer::Analyze(const Frame& frame, const Rect& bbox) {
|
||||
// 根据方法进行分析
|
||||
switch (config_.method) {
|
||||
case ColorMethod::HSV:
|
||||
result = AnalyzeHSV(center.data(), inner_w, inner_h, 3);
|
||||
result = AnalyzeHSV(sample.data(), sample_w, sample_h, 3);
|
||||
break;
|
||||
case ColorMethod::RGB:
|
||||
result = AnalyzeRGB(center.data(), inner_w, inner_h, 3);
|
||||
result = AnalyzeRGB(sample.data(), sample_w, sample_h, 3);
|
||||
break;
|
||||
case ColorMethod::BRIGHTNESS:
|
||||
result = AnalyzeBrightness(center.data(), inner_w, inner_h, 3);
|
||||
result = AnalyzeBrightness(sample.data(), sample_w, sample_h, 3);
|
||||
break;
|
||||
default:
|
||||
LogWarn("[ColorAnalyzer] Unsupported color method: " +
|
||||
@ -88,8 +86,8 @@ ColorResult ColorAnalyzer::Analyze(const Frame& frame, const Rect& bbox) {
|
||||
std::to_string(static_cast<int>(expanded.y)) + "," +
|
||||
std::to_string(static_cast<int>(expanded.w)) + "x" +
|
||||
std::to_string(static_cast<int>(expanded.h)) +
|
||||
" center=" + std::to_string(inner_x) + "," + std::to_string(inner_y) + "," +
|
||||
std::to_string(inner_w) + "x" + std::to_string(inner_h));
|
||||
" sample=" + std::to_string(sample_x) + "," + std::to_string(sample_y) + "," +
|
||||
std::to_string(sample_w) + "x" + std::to_string(sample_h));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -17,8 +17,6 @@ struct ColorConfig {
|
||||
ColorMethod method = ColorMethod::HSV;
|
||||
int dark_threshold = 80; // 深色阈值(亮度0-255)
|
||||
float roi_expand = 1.0f; // ROI扩大系数
|
||||
float center_w_scale = 0.6f; // 中心区域宽度比例
|
||||
float center_h_scale = 0.6f; // 中心区域高度比例
|
||||
bool debug_output = false; // 是否输出调试信息
|
||||
};
|
||||
|
||||
|
||||
@ -226,8 +226,6 @@ private:
|
||||
}
|
||||
config.color.dark_threshold = color->ValueOr<int>("dark_threshold", 80);
|
||||
config.color.roi_expand = color->ValueOr<float>("roi_expand", 1.0f);
|
||||
config.color.center_w_scale = color->ValueOr<float>("center_w_scale", 0.6f);
|
||||
config.color.center_h_scale = color->ValueOr<float>("center_h_scale", 0.6f);
|
||||
config.color.debug_output = config.debug;
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ endif()
|
||||
|
||||
# New Google Test based tests
|
||||
add_executable(rk3588_gtests
|
||||
test_color_analyzer.cpp
|
||||
test_result.cpp
|
||||
test_spsc_queue.cpp
|
||||
test_simple_json.cpp
|
||||
@ -57,6 +58,7 @@ add_executable(rk3588_gtests
|
||||
${CMAKE_SOURCE_DIR}/plugins/region_event/region_event_node.cpp
|
||||
${CMAKE_SOURCE_DIR}/plugins/action_recog/action_recog_node.cpp
|
||||
${CMAKE_SOURCE_DIR}/plugins/event_fusion/event_fusion_node.cpp
|
||||
${CMAKE_SOURCE_DIR}/plugins/logic_gate/color_analyzer.cpp
|
||||
${CMAKE_SOURCE_DIR}/plugins/alarm/rule_engine.cpp
|
||||
)
|
||||
|
||||
|
||||
56
tests/test_color_analyzer.cpp
Normal file
56
tests/test_color_analyzer.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "frame/frame.h"
|
||||
#include "../plugins/logic_gate/color_analyzer.h"
|
||||
|
||||
namespace rk3588 {
|
||||
namespace {
|
||||
|
||||
Frame MakeRgbFrame(int width, int height, uint8_t top_value, uint8_t bottom_value) {
|
||||
auto pixels = std::make_shared<std::vector<uint8_t>>(static_cast<size_t>(width * height * 3), 0);
|
||||
for (int y = 0; y < height; ++y) {
|
||||
const uint8_t value = (y < (height * 2 / 3)) ? top_value : bottom_value;
|
||||
for (int x = 0; x < width; ++x) {
|
||||
const size_t idx = static_cast<size_t>((y * width + x) * 3);
|
||||
(*pixels)[idx] = value;
|
||||
(*pixels)[idx + 1] = value;
|
||||
(*pixels)[idx + 2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
Frame frame;
|
||||
frame.width = width;
|
||||
frame.height = height;
|
||||
frame.format = PixelFormat::RGB;
|
||||
frame.stride = width * 3;
|
||||
frame.data = pixels->data();
|
||||
frame.data_size = pixels->size();
|
||||
frame.data_owner = pixels;
|
||||
return frame;
|
||||
}
|
||||
|
||||
TEST(ColorAnalyzerTest, UsesBottomThirdInsteadOfCenterRegionForBrightness) {
|
||||
ColorConfig config;
|
||||
config.method = ColorMethod::RGB;
|
||||
config.dark_threshold = 80;
|
||||
config.roi_expand = 1.0f;
|
||||
config.debug_output = false;
|
||||
|
||||
ColorAnalyzer analyzer(config);
|
||||
Frame frame = MakeRgbFrame(9, 9, 180, 20);
|
||||
Rect bbox{0.0f, 0.0f, 9.0f, 9.0f};
|
||||
|
||||
const ColorResult result = analyzer.Analyze(frame, bbox);
|
||||
|
||||
ASSERT_TRUE(result.valid);
|
||||
EXPECT_TRUE(result.is_dark);
|
||||
EXPECT_LT(result.brightness, static_cast<float>(config.dark_threshold));
|
||||
EXPECT_GT(result.dark_ratio, 0.6f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace rk3588
|
||||
Loading…
Reference in New Issue
Block a user