// firmware/lib/cv/cv.h #pragma once #include #include static const int CV_W = 96; static const int CV_H = 96; static const int CV_PIXELS = CV_W * CV_H; static const uint8_t CV_DIFF_THRESH = 30; static const int CV_MIN_BLOB_PX = 64; static const float CV_MAX_MOVE = 15.0f; static const int CV_MAX_MISSED = 10; struct CVTrack { int id; float x, y; bool above_line; int missed; }; struct CVTuning { uint8_t diff_thresh; // per-pixel motion threshold int min_blob_px; // min foreground pixels for a blob float max_move; // max inter-frame track jump (px) int max_missed; // frames before drop uint8_t line_offset; // 0-100, percent of frame height for virtual line uint32_t cfg_version; // monotonic; server increments on push }; struct CVState { uint8_t background[CV_PIXELS]; bool bg_valid; uint32_t last_motion_frame; uint32_t frame_index; int next_id; std::vector tracks; int entries; int exits; CVTuning tuning; }; struct CVResult { int entries_delta; int exits_delta; }; void cv_init(CVState& state); CVResult cv_process(CVState& state, const uint8_t* frame, uint8_t line_pct); void cv_reset_counts(CVState& state);