Use luminance bands for shoe color
This commit is contained in:
parent
f1f0922edf
commit
3f1cd92580
@ -84,6 +84,8 @@ ColorResult ColorAnalyzer::Analyze(const Frame& frame, const Rect& bbox) {
|
||||
LogInfo("[ColorAnalyzer] Brightness=" + std::to_string(result.brightness) +
|
||||
" is_dark=" + (result.is_dark ? "true" : "false") +
|
||||
" dark_ratio=" + std::to_string(result.dark_ratio) +
|
||||
" mid_ratio=" + std::to_string(result.mid_ratio) +
|
||||
" light_ratio=" + std::to_string(result.light_ratio) +
|
||||
" region=" + std::to_string(static_cast<int>(expanded.x)) + "," +
|
||||
std::to_string(static_cast<int>(expanded.y)) + "," +
|
||||
std::to_string(static_cast<int>(expanded.w)) + "x" +
|
||||
@ -108,10 +110,18 @@ void ColorAnalyzer::SaveDebugImage(const uint8_t* data, int w, int h, const std:
|
||||
}
|
||||
|
||||
bool ColorAnalyzer::IsSafetyBootsColor(const ColorResult& result) {
|
||||
// 判断标准:亮度低于阈值,且深色像素比例高
|
||||
bool brightness_ok = result.brightness < config_.dark_threshold;
|
||||
bool ratio_ok = result.dark_ratio > 0.6f; // 60%以上像素为深色
|
||||
|
||||
const bool dark_dominant = result.dark_ratio >= 0.45f &&
|
||||
result.dark_ratio > result.light_ratio &&
|
||||
result.dark_ratio >= result.mid_ratio;
|
||||
const bool light_dominant = result.light_ratio >= 0.45f &&
|
||||
result.light_ratio > result.dark_ratio &&
|
||||
result.light_ratio >= result.mid_ratio;
|
||||
|
||||
if (light_dominant) return false;
|
||||
if (dark_dominant) return true;
|
||||
|
||||
const bool brightness_ok = result.brightness < config_.dark_threshold;
|
||||
const bool ratio_ok = result.dark_ratio > 0.6f;
|
||||
return brightness_ok && ratio_ok;
|
||||
}
|
||||
|
||||
@ -187,6 +197,7 @@ ColorResult ColorAnalyzer::AnalyzeHSV(const uint8_t* data, int w, int h, int cha
|
||||
result.avg_s = total_s / static_cast<float>(total_pixels);
|
||||
result.brightness = result.avg_v; // V通道作为亮度
|
||||
result.dark_ratio = dark_pixels / static_cast<float>(total_pixels);
|
||||
result.mid_ratio = 0.0f;
|
||||
result.light_ratio = 1.0f - result.dark_ratio;
|
||||
result.confidence = result.dark_ratio;
|
||||
result.valid = true;
|
||||
@ -199,6 +210,8 @@ ColorResult ColorAnalyzer::AnalyzeRGB(const uint8_t* data, int w, int h, int cha
|
||||
|
||||
long long total_brightness = 0;
|
||||
int dark_pixels = 0;
|
||||
int mid_pixels = 0;
|
||||
int light_pixels = 0;
|
||||
int total_pixels = w * h;
|
||||
|
||||
for (int i = 0; i < total_pixels; ++i) {
|
||||
@ -210,15 +223,20 @@ ColorResult ColorAnalyzer::AnalyzeRGB(const uint8_t* data, int w, int h, int cha
|
||||
int brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
||||
total_brightness += brightness;
|
||||
|
||||
if (brightness < config_.dark_threshold) {
|
||||
if (brightness <= 80) {
|
||||
dark_pixels++;
|
||||
} else if (brightness >= 161) {
|
||||
light_pixels++;
|
||||
} else {
|
||||
mid_pixels++;
|
||||
}
|
||||
}
|
||||
|
||||
result.brightness = total_brightness / static_cast<float>(total_pixels);
|
||||
result.dark_ratio = dark_pixels / static_cast<float>(total_pixels);
|
||||
result.light_ratio = 1.0f - result.dark_ratio;
|
||||
result.confidence = result.dark_ratio;
|
||||
result.mid_ratio = mid_pixels / static_cast<float>(total_pixels);
|
||||
result.light_ratio = light_pixels / static_cast<float>(total_pixels);
|
||||
result.confidence = std::max({result.dark_ratio, result.mid_ratio, result.light_ratio});
|
||||
result.valid = true;
|
||||
|
||||
return result;
|
||||
|
||||
@ -34,6 +34,7 @@ struct ColorResult {
|
||||
|
||||
// 颜色分布
|
||||
float dark_ratio = 0.0f; // 深色像素比例
|
||||
float mid_ratio = 0.0f; // 中间亮度像素比例
|
||||
float light_ratio = 0.0f; // 浅色像素比例
|
||||
};
|
||||
|
||||
|
||||
@ -54,7 +54,27 @@ TEST(ColorAnalyzerTest, UsesMiddleLowerRegionForBrightness) {
|
||||
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);
|
||||
EXPECT_GT(result.dark_ratio, result.light_ratio);
|
||||
EXPECT_GT(result.dark_ratio, result.mid_ratio);
|
||||
}
|
||||
|
||||
TEST(ColorAnalyzerTest, ClassifiesLightDominatedSampleAsNonDark) {
|
||||
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(10, 10, 30, 210, 220);
|
||||
Rect bbox{0.0f, 0.0f, 10.0f, 10.0f};
|
||||
|
||||
const ColorResult result = analyzer.Analyze(frame, bbox);
|
||||
|
||||
ASSERT_TRUE(result.valid);
|
||||
EXPECT_FALSE(result.is_dark);
|
||||
EXPECT_GT(result.light_ratio, result.dark_ratio);
|
||||
EXPECT_GT(result.light_ratio, result.mid_ratio);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Loading…
Reference in New Issue
Block a user