diff --git a/plugins/logic_gate/color_analyzer.cpp b/plugins/logic_gate/color_analyzer.cpp index 2551e4f..7320ee9 100644 --- a/plugins/logic_gate/color_analyzer.cpp +++ b/plugins/logic_gate/color_analyzer.cpp @@ -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(expanded.x)) + "," + std::to_string(static_cast(expanded.y)) + "," + std::to_string(static_cast(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(total_pixels); result.brightness = result.avg_v; // V通道作为亮度 result.dark_ratio = dark_pixels / static_cast(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(total_pixels); result.dark_ratio = dark_pixels / static_cast(total_pixels); - result.light_ratio = 1.0f - result.dark_ratio; - result.confidence = result.dark_ratio; + result.mid_ratio = mid_pixels / static_cast(total_pixels); + result.light_ratio = light_pixels / static_cast(total_pixels); + result.confidence = std::max({result.dark_ratio, result.mid_ratio, result.light_ratio}); result.valid = true; return result; diff --git a/plugins/logic_gate/color_analyzer.h b/plugins/logic_gate/color_analyzer.h index b963d26..303fbaf 100644 --- a/plugins/logic_gate/color_analyzer.h +++ b/plugins/logic_gate/color_analyzer.h @@ -34,6 +34,7 @@ struct ColorResult { // 颜色分布 float dark_ratio = 0.0f; // 深色像素比例 + float mid_ratio = 0.0f; // 中间亮度像素比例 float light_ratio = 0.0f; // 浅色像素比例 }; diff --git a/tests/test_color_analyzer.cpp b/tests/test_color_analyzer.cpp index 7f0677b..886f3c2 100644 --- a/tests/test_color_analyzer.cpp +++ b/tests/test_color_analyzer.cpp @@ -54,7 +54,27 @@ TEST(ColorAnalyzerTest, UsesMiddleLowerRegionForBrightness) { ASSERT_TRUE(result.valid); EXPECT_TRUE(result.is_dark); EXPECT_LT(result.brightness, static_cast(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