cv_process and helpers (frame_diff, extract_blob, find_centroids) now read diff_thresh, min_blob_px, max_move, max_missed, and line_offset from state.tuning instead of file-scope static const constants. The four thresholds are promoted to file-local constexpr defaults in cv.cpp (CV_DEFAULT_*) and are no longer part of the public cv.h API — external code can't depend on them. cv_process signature drops the line_pct parameter; callers use state.tuning.line_offset instead. This eliminates the drift hazard of having two sources of truth (DeviceConfig.line_offset vs CVTuning.line_offset); the former is deleted. main.cpp now calls config_load_tuning(g_cv.tuning) after cv_init on boot so previously persisted tuning survives reboot; logs whether tuning came from NVS or defaults. The legacy NVS key "line_offset" is intentionally left alone — harmless and flash_device.py may still write it during provisioning. Migration is out of scope. Tests: 12/12 passing (11 existing + 1 new test_cv_process_respects_runtime_min_blob proving the runtime-read path). Flash: 1,414,069 bytes (89.9%). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
46 lines
1.1 KiB
C++
46 lines
1.1 KiB
C++
// firmware/lib/cv/cv.h
|
|
#pragma once
|
|
#include <stdint.h>
|
|
#include <vector>
|
|
|
|
static const int CV_W = 96;
|
|
static const int CV_H = 96;
|
|
static const int CV_PIXELS = CV_W * CV_H;
|
|
|
|
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<CVTrack> 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);
|
|
void cv_reset_counts(CVState& state);
|