How to Integrate Motion Detection with WiFi DensePose: A Complete Implementation Guide
Motion detection in WiFi DensePose analyzes Channel State Information (CSI) amplitude variance and antenna correlation to generate a motion score that gates DensePose inference, filtering static frames before they reach the pose estimation pipeline.
WiFi DensePose combines Wi-Fi Channel State Information (CSI) processing with deep-learning pose estimation to track human body positions using only wireless signals. The motion detection subsystem operates on the CSI stream before the pose pipeline executes, enabling the system to conserve computational resources and reduce false positives. This guide explains how to integrate and configure motion detection according to the ruvnet/wifi-densepose source code architecture.
How Motion Detection Works in WiFi DensePose
The motion detection system processes raw CSI data to distinguish between static environments and human movement. In src/core/csi_processor.py, the _analyze_motion_patterns method combines amplitude variance across subcarriers with antenna correlation metrics to produce a motion_score ranging from 0 to 1.
This score undergoes temporal smoothing via _apply_temporal_smoothing using an exponential moving average (EMA), then feeds into _calculate_detection_confidence to produce the final confidence value. The Pose Service compares this confidence against configurable thresholds to determine whether to invoke the DensePose model or drop the frame.
Core Architecture and Data Flow
Understanding the component interaction is essential for proper integration. The pipeline flows from hardware abstraction through CSI processing to pose estimation.
CSI Processor (src/core/csi_processor.py)
The CSIProcessor class serves as the primary motion analysis engine. Its process_csi_data method executes a multi-stage pipeline:
- Pre-processing: Noise removal, windowing, and amplitude normalization using
csi_noise_threshold - Feature extraction: Computes amplitude mean/variance, phase differences, correlation matrices, Doppler shifts, and power spectral density
- Motion analysis:
_analyze_motion_patternsreturns the rawmotion_score - Human detection: Aggregates features into a smoothed confidence score wrapped in a
HumanDetectionResultobject
Pose Service (src/services/pose_service.py)
The PoseService orchestrates the full inference pipeline. Its process_csi_data method receives the HumanDetectionResult containing both motion_score and final confidence values. The service compares the confidence against settings.pose_confidence_threshold:
- Above threshold: CSI features pass to the modality translator → DensePose model → pose objects
- Below threshold: Frame is dropped or logged without inference
Hardware Service (src/services/hardware_service.py)
The HardwareService manages router interfaces and feeds raw CSI into the pipeline. It periodically calls router_interface.get_csi_data() to obtain np.ndarray CSI frames, then forwards them to PoseService.process_csi_data along with metadata including timestamps, zone IDs, and SNR values.
Complete Data Flow
- Router →
src/hardware/csi_extractor.pyproducesCSIDataobjects with raw amplitude/phase arrays - Hardware Service converts
CSIDatainto NumPy arrays with metadata - Pose Service invokes
CSIProcessor.process_csi_data() - Confidence check against
pose_confidence_thresholddetermines DensePose execution - Output: Pose objects or null result based on motion detection results
Configuration Parameters for Motion Sensitivity
Fine-tuning motion detection requires adjusting these configuration values in src/config/settings.py and CSIProcessor initialization:
| Parameter | Location | Default | Effect |
|---|---|---|---|
csi_noise_threshold |
src/config/settings.py |
20.0 dB | Controls noise filtering aggressiveness; higher values zero out more data |
human_detection_threshold |
CSIProcessor.__init__ |
0.8 | Minimum smoothed confidence required to classify a human as present |
pose_confidence_threshold |
src/config/settings.py |
0.7 | Minimum confidence required to trigger DensePose inference |
csi_smoothing_factor |
CSIProcessor.__init__ |
0.9 | EMA smoothing factor for confidence values; higher values reduce jitter |
Lowering pose_confidence_threshold when motion scores are high captures more poses during active movement, while raising it during static periods prevents false detections.
Implementation Examples
Basic Pipeline Integration
Initialize the full pipeline and process CSI frames with motion detection:
import asyncio
import numpy as np
from src.services.pose_service import PoseService
from src.config.settings import Settings
from src.config.domains import DomainConfig
async def main():
# Configure motion detection parameters
settings = Settings(
mock_pose_data=False,
pose_confidence_threshold=0.7,
mock_hardware=True,
csi_noise_threshold=20.0,
csi_smoothing_factor=0.85,
)
domain_cfg = DomainConfig()
# Initialize services
pose_srv = PoseService(settings, domain_cfg)
await pose_srv.start()
# Simulate CSI frame: (subcarriers, antennas, samples)
mock_csi = np.random.randn(64, 56, 3)
metadata = {
"timestamp": asyncio.get_event_loop().time(),
"zone_ids": ["zone_1"],
"frequency": 5.0,
"bandwidth": 20.0,
}
# Process with motion detection
result = await pose_srv.process_csi_data(mock_csi, metadata)
if result["poses"]:
print(f"Motion score: {result['confidence_scores'][0]:.2f}")
print(f"Pose confidence: {result['poses'][0]['confidence']:.2f}")
else:
print("No motion detected - frame filtered")
await pose_srv.stop()
asyncio.run(main())
WebSocket Motion Events
Stream motion-aware pose updates to connected clients:
import asyncio
from src.services.pose_service import PoseService
from src.config.settings import Settings
from src.config.domains import DomainConfig
async def stream_motion_events():
settings = Settings(mock_hardware=True, mock_pose_data=True)
pose_srv = PoseService(settings, DomainConfig())
await pose_srv.start()
async for zone_data in pose_srv.get_current_pose_data():
for zone_id, payload in zone_data.items():
# Filter by motion-aware confidence
if payload["confidence"] > 0.5:
print(f"[{zone_id}] Motion detected: {payload['pose']['count']} person(s)")
# Broadcast to WebSocket clients here
await asyncio.sleep(0.1)
asyncio.run(stream_motion_events())
Dynamic Confidence Thresholding
Adjust sensitivity based on real-time motion scores:
async def adaptive_motion_processing(pose_srv: PoseService):
while True:
csi_frame = await acquire_csi() # Your hardware interface
metadata = {"zone_ids": ["zone_2"]}
detection = await pose_srv.process_csi_data(csi_frame, metadata)
motion_score = detection.get("motion_score", 0.0)
# Adapt threshold based on motion intensity
if motion_score > 0.8:
pose_srv.settings.pose_confidence_threshold = 0.6
else:
pose_srv.settings.pose_confidence_threshold = 0.8
await asyncio.sleep(pose_srv.settings.hardware_polling_interval)
Extending Motion Detection Capabilities
The modular architecture supports several customization patterns:
- Custom motion classifiers: Replace
_analyze_motion_patternsinsrc/core/csi_processor.pywith Doppler-tracking algorithms or machine-learning classifiers trained on specific movement patterns - Multi-zone aggregation: Leverage
zone_idmetadata fromhardware_service.pyto compute independent motion scores per spatial zone before aggregation - Event hooks: Implement async callbacks in
HardwareServiceor extendpose_service.get_current_pose_data()to broadcast WebSocket events when motion transitions from 0 to 1
Summary
- Motion detection operates on CSI amplitude variance and antenna correlation in
src/core/csi_processor.pybefore DensePose inference occurs - The
_analyze_motion_patternsmethod generates a 0-1motion_scorethat feeds into confidence calculations via_apply_temporal_smoothing - Pose Service gates DensePose execution using
pose_confidence_threshold, dropping static frames to conserve resources - Configuration through
src/config/settings.pyenables tuning of noise thresholds, smoothing factors, and confidence levels for specific environments - Real-time adaptation allows dynamic threshold adjustment based on motion intensity scores
Frequently Asked Questions
How is the motion score calculated in WiFi DensePose?
The motion score is calculated in src/core/csi_processor.py by the _analyze_motion_patterns method, which combines amplitude variance across CSI subcarriers with antenna correlation metrics. This raw score is temporally smoothed using an exponential moving average (EMA) with the csi_smoothing_factor (default 0.9) to reduce jitter, then normalized to a 0-1 range representing the probability of human movement.
What configuration settings control motion detection sensitivity?
Four primary settings control sensitivity: csi_noise_threshold filters environmental noise in decibels; human_detection_threshold (default 0.8) sets the minimum confidence to classify a detection as human; pose_confidence_threshold gates DensePose inference; and csi_smoothing_factor (default 0.9) determines how aggressively the system smooths confidence values over time. Adjust these in src/config/settings.py or during CSIProcessor initialization.
Can motion detection be customized for specific environments?
Yes, developers can extend the motion detection system by overriding _analyze_motion_patterns with custom logic such as Doppler-based tracking or trained classifiers for specific movement types. The architecture also supports multi-zone awareness by processing zone_id metadata from src/services/hardware_service.py to compute zone-specific motion scores before aggregation.
How does motion detection affect DensePose inference performance?
Motion detection significantly improves performance by filtering static frames before they reach the DensePose model. When HumanDetectionResult.confidence falls below pose_confidence_threshold, the system skips the computationally expensive pose estimation step entirely. This reduces GPU/CPU utilization and latency for scenes with intermittent human presence, as implemented in src/services/pose_service.py.
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 →