Motion protocol

What actually breaks it?

Two earlier recordings disagreed about whether movement breaks the measurement, because nobody had measured how much movement there was. So the test was rebuilt: five conditions, each recorded as still, then the condition, then still again, so every one carries its own baseline — and the movement was measured, not described.

PHASE-Net · at rest
8.0BPM off

Error while sitting perfectly still - nothing is moving.

POS · at rest
6.8BPM off

Error while sitting perfectly still - nothing is moving.

Worst condition
15.5BPM off

PHASE-Net during slow turns. About twice the resting error, and nothing gets worse than this.

Slow turns → fast turns
2.8×more movement

Triple the movement, and the error changes by 0.1 BPM.

Movement doubles the error, then stops mattering

Each dot is one condition. Movement is how much the picture inside the face crop changes between frames, above what it changes while still.

The curve lifts off the resting floor to roughly double it, then flattens. Going from slow to fast head turns triples the measured movement and changes nothing, so how much someone moves is not what sets the ceiling.

Which conditions differ from doing nothing?

The same numbers as bars. Each dashed line is that method's error while still, so a bar level with its own line added nothing measurable.

Talking sits on the line. Only turning the head lifts either method clearly above its own floor — and both rise together, so neither is the robust one.

Every condition, side by side

Resting rate comes from the still half of the same recording. Drift is how far the reading strayed from that baseline.

still → condition → still
ConditionMovementFace movedof facePHASE-Net restduringdriftPOS restduringdrift
still
nothing at all - the control
0.008 px6 %8077
8.0
8075
6.8
talking
speak, head kept still
0.299 px7 %8282
7.8
6667
5.9
mixed
turn, nod and lean at once
0.5528 px22 %7981
10.5
7863
13.7
slow turns
turn left and right, one cycle per 4 s
1.0448 px38 %8096
15.5
7765
12.9
fast turns
the same turn, one cycle per 1.5 s
2.8837 px29 %8172
15.4
7164
14.1

The face never travels far: the largest excursion anywhere is 38 % of a face width, so it stays inside the crop throughout. And even in the control, single readings from PHASE-Net span 68108 BPM while nothing at all is happening.

Three explanations, all rejected

each was turned into a test that could kill it

The face leaves the fixed crop under motion

One recording processed twice - fixed box versus re-detecting the face every second - so the crop strategy is the only variable.

rejected
Crop fixed on the first frame
10.5BPM off
Face re-detected every second
24.6BPM off
2.3× worse — following the face made it worse, not better. A box that is re-detected every second jitters, and that jitter is movement of its own.
Furthest the face ever moved
21 % of a face width
Does error track the face moving?
0.07 out of 1.00 - no link

Tracking made it worse: a re-detected box jitters between frames and injects motion of its own. A slightly misaligned but stable crop beats a well-centred jittery one.

Facial appearance change (speech, expression) breaks it

A 'talk' condition - the face changes continuously but barely moves.

rejected
Talking, head still
7.8BPM off
Doing nothing
8.0BPM off
Face moved while talking
8.8 px

Talking is indistinguishable from doing nothing.

One method is inherently more motion-robust

Dose-response across five measured motion levels.

rejected
PHASE-Net, slow then fast turns
15.5 → 15.4BPM off
POS, slow then fast turns
12.9 → 14.1BPM off

Both degrade by a similar factor and the effect saturates - tripling the motion from slow to fast changes nothing.

What survived: the twenty-fold gap

The same model is about 0.39 BPM off on controlled recordings and about 8 BPM off on this webcam before anyone moves — roughly 21× worse. Movement adds a further doubling on top of that, and then stops.

So the bottleneck is the camera, the lighting, the distance and how much of the frame the face fills — not movement, and not the model. A better capture setup is worth more than a more motion-tolerant architecture. The controlled-data figure →

Five recordings, one person, one webcam. 10-second windows; smartwatch cross-check 83 BPM.·13_record_full.py · 14_static_vs_dynamic.py · 15_motion_protocol.py