How Human Movement Affects Wi-Fi CSI Signals: A Technical Analysis of the wifi-densepose Repository
When humans move through a Wi-Fi environment, they alter multipath propagation paths, causing measurable variations in Channel State Information (CSI) amplitude, phase, and frequency-domain characteristics that the wifi-densepose pipeline detects through statistical feature extraction and temporal analysis.
Human movement detection through walls and obstacles using commodity Wi-Fi hardware relies on capturing subtle changes in Channel State Information (CSI). The open-source wifi-densepose repository (ruvnet/wifi-densepose) implements a complete pipeline that demonstrates how human movement affects Wi-Fi CSI signals by processing raw IQ samples into motion confidence scores and spatial features.
The Physics of Movement in Wi-Fi Channels
Wi-Fi CSI captures the complex-valued channel response for every sub-carrier, antenna pair, and transmit-receive combination. When a person moves, their body blocks, reflects, and scatters radio frequency signals, dynamically altering the multipath propagation environment. These physical changes manifest as amplitude attenuation, phase shifts, and Doppler frequency shifts across the CSI stream, creating a unique signature that distinguishes human motion from static environmental noise.
CSI Processing Pipeline Architecture
The wifi-densepose codebase processes these signal variations through a modular pipeline defined in v1/src/core/csi_processor.py. Raw bytes from ESP32 or router hardware flow through phase sanitization, noise removal, and feature extraction stages to produce a human detection confidence score.
The pipeline executes these sequential operations:
- Raw extraction (
csi_extractor.py): Captures byte streams from Wi-Fi hardware. - Phase sanitization (
phase_sanitizer.py): Unwraps phase discontinuities viasanitize_phaseand removes outliers. - Pre-processing (
CSIProcessor._remove_noise,_apply_windowing,_normalize_amplitude): Conditions the signal for analysis. - Feature extraction (
_extract_amplitude_features,_extract_phase_features,_extract_correlation_features,_extract_doppler_features): Computes statistical descriptors. - Motion analysis (
_analyze_motion_patterns): Derives a composite motion score from variance and correlation deviation. - Confidence calculation (
_calculate_detection_confidence,_apply_temporal_smoothing): Produces the final detection result.
How Movement Manifests in CSI Features
Amplitude Variance Across Sub-Carriers
Human bodies block specific propagation paths, causing time-varying attenuation in certain sub-carriers. The _extract_amplitude_features method in v1/src/core/csi_processor.py quantifies this effect by computing amplitude_variance = np.var(csi_data.amplitude, axis=0), capturing the temporal instability introduced by moving scatterers.
Phase Differences Between Adjacent Sub-Carriers
As a person moves, changing path lengths introduce phase shifts that differ across the frequency spectrum. The pipeline calculates this via np.diff(csi_data.phase, axis=1) in _extract_phase_features, averaging the differential phase response to detect motion-induced path length variations.
Antenna Correlation Degradation
Static environments maintain stable spatial correlation between multiple antennas. Human movement disrupts this correlation by introducing independent scattering at different antenna elements. The _extract_correlation_features method computes np.corrcoef(csi_data.amplitude) to measure this spatial decorrelation.
Doppler Frequency Shifts
Relative motion between the human body and Wi-Fi transceivers creates Doppler-shifted reflections visible in the power spectral density. The _extract_doppler_features method computes these frequency-domain characteristics using FFT-based PSD analysis, providing a placeholder Doppler vector for motion frequency analysis.
Motion Pattern Analysis and Detection Confidence
The system synthesizes these indicators into a motion-score within _analyze_motion_patterns. This weighted combination of amplitude variance and correlation deviation feeds into _calculate_detection_confidence, which applies _apply_temporal_smoothing to reduce false positives. When the confidence exceeds the configurable human_detection_threshold (default 0.8), the pipeline returns a HumanDetectionResult with human_detected=True.
Implementing the Detection Pipeline
The following example demonstrates the complete workflow from raw hardware bytes to human presence detection:
from src.hardware.csi_extractor import CSIExtractor
from src.core.phase_sanitizer import PhaseSanitizer
from src.core.csi_processor import CSIProcessor
# 1️⃣ Extract raw CSI (mocked in tests)
extractor = CSIExtractor(
config={'hardware_type': 'esp32', 'sampling_rate': 100, 'buffer_size': 256,
'timeout': 1.0}, logger=None
)
raw_csi = extractor._read_raw_data() # → bytes from ESP32
# 2️⃣ Parse into structured CSIData
csi_data = extractor.parser.parse(raw_csi)
# 3️⃣ Sanitize phase
phase_sanitizer = PhaseSanitizer(
config={'unwrapping_method': 'numpy', 'outlier_threshold': 3.0,
'smoothing_window': 5}, logger=None
)
csi_data.phase = phase_sanitizer.sanitize_phase(csi_data.phase)
# 4️⃣ Process and detect human presence
processor = CSIProcessor(
config={'sampling_rate': 100, 'window_size': 256, 'overlap': 0.5,
'noise_threshold': -80, 'human_detection_threshold': 0.8},
logger=None
)
result = await processor.process_csi_data(csi_data)
print(f"Human detected: {result.human_detected} (confidence {result.confidence:.2f})")
After processing, inspect the specific features that indicate movement:
features = processor.extract_features(csi_data)
print("Amplitude variance per sub‑carrier:", features.amplitude_variance[:5])
print("Mean phase difference:", features.phase_difference)
print("Correlation matrix shape:", features.correlation_matrix.shape)
print("Doppler placeholder vector:", features.doppler_shift[:3])
Adjust detection sensitivity by modifying the processor configuration:
processor.human_detection_threshold = 0.6 # more sensitive
processor.smoothing_factor = 0.7 # smoother confidence curve
Critical Source Files
v1/src/hardware/csi_extractor.py: Low-level parser for ESP32 and router CSI byte streams.v1/src/core/phase_sanitizer.py: Implements phase unwrapping viaunwrap_phaseand outlier removal viaremove_outliersto handle phase wraps caused by rapid motion.v1/src/core/csi_processor.py: Contains the full processing pipeline including feature extraction methods and the motion pattern analysis logic.v1/src/models/modality_translation.py: Translates CSI amplitude and sanitized phase into spatial feature maps for DensePose networks.v1/references/wifi_densepose_pytorch.py: End-to-end PyTorch model consuming spatial features for pose estimation.
Summary
- Human movement alters Wi-Fi multipath propagation, creating detectable variations in CSI amplitude, phase, and correlation structures.
- The wifi-densepose pipeline processes these changes through
PhaseSanitizerfor signal conditioning andCSIProcessorfor statistical feature extraction. - Key detection features include amplitude variance, differential phase, antenna correlation matrices, and Doppler characteristics.
- The system calculates a composite motion-score combining variance and correlation deviation, applying temporal smoothing to generate a confidence score.
- Detection triggers when confidence exceeds the
human_detection_threshold(default 0.8), as implemented inv1/src/core/csi_processor.py.
Frequently Asked Questions
What specific CSI features indicate human movement?
Human movement primarily affects amplitude variance across sub-carriers, phase differences between adjacent frequencies, and spatial correlation between antenna streams. The wifi-densepose code extracts these via np.var() for amplitude instability, np.diff() for phase gradients, and np.corrcoef() for antenna decorrelation in v1/src/core/csi_processor.py.
How does the repository handle noisy phase data?
The PhaseSanitizer class in v1/src/core/phase_sanitizer.py applies phase unwrapping via unwrap_phase to resolve discontinuities, outlier removal via remove_outliers using a configurable threshold (default 3.0), and optional smoothing windows to eliminate high-frequency noise introduced by rapid motion.
What is the default detection threshold for human presence?
The CSIProcessor uses a default human_detection_threshold of 0.8, configurable during initialization or runtime. Values closer to 0.6 increase sensitivity for small movements but may introduce false positives, while higher values reduce false alarms at the cost of missing subtle motions.
Can this system distinguish between multiple moving people?
The current implementation in v1/src/core/csi_processor.py calculates a single composite motion score without spatial localization of multiple scatterers. While the correlation features and Doppler analysis theoretically contain information about multiple moving objects, the repository's _analyze_motion_patterns method aggregates these into a binary detection decision rather than individual tracking.
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 →