Interaction of segmentation_threshold and threshold_mode in Micro-ESPectre
In Micro-ESPectre, the SEG_THRESHOLD configuration variable controls whether the motion detector uses a fixed numeric threshold or an adaptive threshold computed from baseline noise, with the auto mode applying a 95th percentile × 1.1 multiplier and min mode using the maximum value (100th percentile) for maximum sensitivity.
The interaction between segmentation_threshold and threshold_mode determines how the Micro-ESPectre motion detection pipeline balances sensitivity against false positives. This relationship is governed by the SEG_THRESHOLD setting in micro-espectre/src/config.py, which instructs the system to either use a static value or dynamically calculate an adaptive threshold based on calibration statistics. Understanding this interaction is essential for tuning the ESP32-based Wi-Fi sensing implementation in the francescopace/espectre repository.
How SEG_THRESHOLD Defines the Threshold Mode
Located in micro-espectre/src/config.py (lines 58-63), the SEG_THRESHOLD variable accepts three distinct value types that control the threshold behavior:
# config.py
# SEG_THRESHOLD can be:
# - "auto" (default): adaptive threshold based on baseline noise
# - "min": maximum sensitivity (may have false positives)
# - a number (0.0-10.0): fixed manual threshold
SEG_THRESHOLD = "auto"
When set to a string value ("auto" or "min"), the system enters adaptive mode and computes the threshold from calibration data. When set to a numeric value, the system bypasses adaptive calculation and uses the fixed value directly.
Mapping Threshold Modes to Statistical Parameters
The micro-espectre/src/threshold.py module translates the threshold mode into specific statistical parameters used during calibration. Two functions determine the behavior:
get_threshold_percentile(threshold_mode)– selects the percentile of baseline noise to useget_threshold_factor(threshold_mode)– applies a safety multiplier to the calculated value
| Mode | Percentile | Factor |
|---|---|---|
"auto" |
95 | 1.1 |
"min" |
100 | 1.0 |
The "auto" mode uses the 95th percentile of baseline measurements multiplied by 1.1 to provide margin above typical noise. The "min" mode uses the 100th percentile (maximum observed value) with no multiplier, maximizing sensitivity at the risk of false positives.
Computing the Adaptive Threshold
During calibration (typically via 3_analyze_moving_variance_segmentation.py), the calculate_adaptive_threshold function in threshold.py (lines 60-78) computes the final value:
percentile = get_threshold_percentile(threshold_mode) # 95 or 100
factor = get_threshold_factor(threshold_mode) # 1.1 or 1.0
adaptive_threshold = calculate_percentile(cal_values, percentile) * factor
This calculation ensures that the segmentation threshold scales with the actual RF environment noise characteristics captured during the calibration run.
Applying Thresholds in the Detection Pipeline
The runtime detector uses the SegmentationContext class in micro-espectre/src/segmentation.py to maintain state. The threshold is injected via set_adaptive_threshold:
def set_adaptive_threshold(self, threshold):
# clamp to a sane range (1µ to 10)
self.threshold = max(1e-6, min(10.0, threshold))
The update_state() method compares self.current_moving_variance against self.threshold to determine motion start/stop events. If SEG_THRESHOLD was set to a numeric value, the system skips adaptive calculation and initializes SegmentationContext with the fixed constant directly.
Configuration Examples
Using Auto Mode for Balanced Detection
# config.py
SEG_THRESHOLD = "auto"
from micro_espectre.src.threshold import calculate_adaptive_threshold
from micro_espectre.src.segmentation import SegmentationContext
# Run calibration on quiet environment
adaptive_thr, perc = calculate_adaptive_threshold(calibration_values, "auto")
print(f"Threshold set to P{perc}×1.1 = {adaptive_thr:.3f}")
ctx = SegmentationContext(window_size=100, threshold=adaptive_thr)
Using Min Mode for Maximum Sensitivity
# config.py
SEG_THRESHOLD = "min"
adaptive_thr, perc = calculate_adaptive_threshold(calibration_values, "min")
# Uses maximum observed value with no multiplier
ctx = SegmentationContext(window_size=100, threshold=adaptive_thr)
Using Fixed Manual Threshold
# config.py
SEG_THRESHOLD = 1.5 # Fixed value 0.0-10.0
# No calibration calculation needed
ctx = SegmentationContext(window_size=100, threshold=1.5)
Runtime Recalibration
# Update threshold without restarting
new_thr, _ = calculate_adaptive_threshold(new_cal_values, "auto")
ctx.set_adaptive_threshold(new_thr) # Automatically clamps to [1e-6, 10.0]
Summary
- SEG_THRESHOLD in
config.pycontrols whether Micro-ESPectre uses fixed or adaptive thresholds via the threshold mode (auto,min, or numeric). - Adaptive calculation occurs in
threshold.py, whereautomode applies a 95th percentile × 1.1 multiplier andminmode uses the 100th percentile × 1.0. - Runtime application happens through
SegmentationContext.set_adaptive_threshold(), which clamps values to the range 1×10⁻⁶ to 10.0 before use in the motion state machine. - Fixed thresholds bypass calibration entirely, using the numeric value directly in the detector initialization.
Frequently Asked Questions
What is the difference between "auto" and "min" threshold modes?
The auto mode calculates the threshold using the 95th percentile of baseline noise multiplied by 1.1, providing robustness against minor fluctuations while maintaining sensitivity. The min mode uses the 100th percentile (maximum observed value) with no multiplier, offering maximum sensitivity but increasing the risk of false positives from noise spikes.
Can I change the threshold without recalibrating?
Yes, you can update the threshold at runtime using the set_adaptive_threshold() method on the SegmentationContext instance. This method automatically clamps the value to the valid range between 1×10⁻⁶ and 10.0, allowing dynamic adjustment without restarting the detector or recalibrating the system.
Why does the threshold get clamped to 1e-6 and 10.0?
The clamping in SegmentationContext.set_adaptive_threshold() prevents invalid threshold values that could break the motion detection logic. Values below 1×10⁻⁶ would be numerically unstable, while values above 10.0 exceed the maximum expected moving variance range for Wi-Fi sensing signals, ensuring the detector operates within physically meaningful bounds.
Where is the threshold actually used in the detection logic?
The threshold is compared against self.current_moving_variance in the update_state() method of SegmentationContext (located in micro-espectre/src/segmentation.py). When the moving variance exceeds the threshold, the state machine transitions to the motion-detected state; when it falls below, the system returns to the idle state.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →