Pupil Core camera synchronisationΒΆ
We used this protocol to investigate how well Pupil Capture synchronises the clocks of the Eye and World cameras on a Pupil Core headset. See here for a detailed explanation and analysis showing how this is dependant on operating system and camera settings.
[2]:
from time import sleep
from pyplr.stlab import SpectraTuneLab, pulse_protocol
from pyplr.pupil import PupilCore
# Set up pupil
p = PupilCore()
# Annotations / notifications can crash Capture if they are sent too
# close together so we will wait and send them at the end of the script
p.annotation_capture_plugin(should='stop')
sleep(.02)
# Setup stlab and make spectrum with near-IR
d = SpectraTuneLab(password='****************')
spec = [0, 0, 0, 0, 0, 0, 0, 4095, 0, 0]
pulse_protocol(spec, 1000, '1s_near_IR_pulse')
d.load_video_file('1s_near_IR_pulse.dsf')
# light_stamper params
threshold = 10
timeout = 6.
# Make annotations for each camera
world_annotation = p.new_annotation('LIGHT_ON_WORLD')
eye_0_annotation = p.new_annotation('LIGHT_ON_EYE_0')
eye_1_annotation = p.new_annotation('LIGHT_ON_EYE_1')
# Dict for the light_stamper timestamps
results = {'world': [],
'eye_0': [],
'eye_1': []}
# Start recording and wait a while
p.command('R pupil_core_camera_sync_tests')
sleep(5.)
# Begin testing protocol
for i in range(3):
# Start light_stampers
lst_world = p.light_stamper(
world_annotation,
threshold,
timeout,
topic='frame.world')
lst_eye_0 = p.light_stamper(
eye_0_annotation,
threshold,
timeout,
topic='frame.eye.0')
lst_eye_1 = p.light_stamper(
eye_1_annotation,
threshold,
timeout,
topic='frame.eye.1')
# Wait 100 ms then flash light
sleep(1.)
d.play_video_file()
sleep(timeout)
# Add timestamps to results dictionary
results['world'].append(lst_world.result())
results['eye_0'].append(lst_eye_0.result())
results['eye_1'].append(lst_eye_1.result())
# Start Annotation Capture plugin
p.annotation_capture_plugin(should='start')
sleep(.02)
# Send the annotations with 20 ms spacing
for k in results.keys():
for ts in [val[1] for val in results[k]]:
annotation = p.new_annotation('light_on_{}'.format(k))
annotation['timestamp'] = ts
p.send_annotation(annotation)
sleep(0.02)
# Wait for 5 s and stop recording
sleep(5.)
p.command('r')
STLAB device setup complete...
"1s_near_IR_pulse.dsf" saved in the current working directory.
video file loaded...
> Waiting for a light to stamp...
> Waiting for a light to stamp...
> Waiting for a light to stamp...
playing video file...
> Light stamped on frame.eye.0 at 346194.799512
> Light stamped on frame.world at 346194.774064
> Light stamped on frame.eye.1 at 346194.805085
> Waiting for a light to stamp...
> Waiting for a light to stamp...
> Waiting for a light to stamp...
playing video file...
> Light stamped on frame.eye.0 at 346201.864576
> Light stamped on frame.eye.1 at 346201.870149
> Light stamped on frame.world at 346201.846864
> Waiting for a light to stamp...
> Waiting for a light to stamp...
> Waiting for a light to stamp...
playing video file...
> Light stamped on frame.world at 346208.919664
> Light stamped on frame.eye.0 at 346208.945881
> Light stamped on frame.eye.1 at 346208.951454
[2]:
'OK'