feat: add low-light brightness gate

This commit is contained in:
zmv
2026-10-09 16:02:15 +08:00
parent 4eff3825be
commit 69d565fda5
18 changed files with 319 additions and 26 deletions
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include <opencv2/core.hpp>
#include <string>
namespace cms {
struct BrightnessGateConfig {
bool enabled{true};
double roi_x1{0.02}, roi_y1{0.05}, roi_x2{0.88}, roi_y2{0.98};
double dark_pixel_luma{40.0};
double enter_median_luma{18.0}, enter_dark_ratio{0.85}, enter_dark_tile_ratio{0.75};
double exit_median_luma{24.0}, exit_dark_ratio{0.80}, exit_dark_tile_ratio{0.70};
int startup_frames{5}, enter_frames{15}, exit_frames{15};
};
struct BrightnessDecision {
std::string state{"INITIALIZING"}, reason{"initializing"}, transition;
bool allow_downstream{};
double median_luma{}, p75_luma{}, mean_luma{}, dark_pixel_luma{40.0}, dark_ratio{}, dark_tile_ratio{};
int dark_streak{}, bright_streak{};
int enter_frames{}, exit_frames{};
};
class BrightnessGate {
public:
explicit BrightnessGate(BrightnessGateConfig config = {});
BrightnessDecision update(cv::Mat const& bgr);
private:
BrightnessGateConfig config_;
std::string state_{"INITIALIZING"};
int startup_count_{}, startup_dark_votes_{}, dark_streak_{}, bright_streak_{};
};
}
+2
View File
@@ -1,5 +1,6 @@
#pragma once
#include "camera.hpp"
#include "brightness_gate.hpp"
#include "frame_result.hpp"
#include "output_writer.hpp"
#include <filesystem>
@@ -16,6 +17,7 @@ struct PipelineConfig {
double detector_confidence{0.30};
int max_people{3};
double warning_relative{0.30},release_relative{0.45};
BrightnessGateConfig brightness_gate;
std::size_t queue_capacity{2};
bool door_mask_calibration_verified{false};
};
+2
View File
@@ -2,6 +2,7 @@
// Public downstream contract. Owns its data; no GPU, JSON or network handles.
#include "image.hpp"
#include "can_types.hpp"
#include "brightness_gate.hpp"
#include <array>
#include <cstdint>
#include <memory>
@@ -77,6 +78,7 @@ struct FrameResult {
std::shared_ptr<const BgrImage> image;
std::shared_ptr<const BinaryMask> door_mask_pixels;
bool door_mask_calibration_verified{};
BrightnessDecision brightness;
};
using FrameResultPtr = std::shared_ptr<const FrameResult>;
}
+3 -2
View File
@@ -5,8 +5,9 @@
namespace cms {
class CameraPipeline;
// Pure drawing from the immutable result. Never re-runs inference.
cv::Mat renderResult(FrameResult const& result,CanSnapshot const* liveCan=nullptr);
cv::Mat renderResult(FrameResult const& result,CanSnapshot const* liveCan=nullptr,bool drawText=true);
cv::Mat renderVisualization(FrameResult const& result,CanSnapshot const& liveCan);
void renderCanOverlay(cv::Mat& image,CanSnapshot const& can);
// Optional observer: closing the window returns without stopping the pipeline.
void runLocalVisualization(CameraPipeline const& pipeline);
void runLocalVisualization(CameraPipeline const& pipeline, bool keepFinalFrame = false);
}