From d9072f1bcc69b21869f10dd18946666b8b1c4323 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Mon, 28 Mar 2022 13:52:44 +0200 Subject: Load tobii timestamps in raw format. Adding frames() member to access iterator --- src/argaze/DataStructures.py | 6 ++--- src/argaze/TobiiGlassesPro2/TobiiEntities.py | 8 +++++-- .../utils/analyse_tobii_segment_fixations.py | 28 ++++++++++++++-------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/argaze/DataStructures.py b/src/argaze/DataStructures.py index 9c0414c..2fd691b 100644 --- a/src/argaze/DataStructures.py +++ b/src/argaze/DataStructures.py @@ -40,9 +40,9 @@ class TimeStampedBuffer(collections.OrderedDict): pass def __setitem__(self, key: float, value): - """Force key to be a float""" - if type(key) != float: - raise KeyError('key must be a float') + """Force key to be a number""" + if type(key) != int and type(key) != float: + raise KeyError('key must be a number') super().__setitem__(key, value) diff --git a/src/argaze/TobiiGlassesPro2/TobiiEntities.py b/src/argaze/TobiiGlassesPro2/TobiiEntities.py index 96fd0af..30a966e 100644 --- a/src/argaze/TobiiGlassesPro2/TobiiEntities.py +++ b/src/argaze/TobiiGlassesPro2/TobiiEntities.py @@ -43,8 +43,8 @@ class TobiiSegmentData(DataStructures.DictObject): # accept only valid data (e.g. with status value equal to 0) if json_item.pop('s', -1) == 0: - # convert timestamp into ms - ts = json_item.pop('ts') / 1000.0 + # convert timestamp + ts = json_item.pop('ts') # keep first timestamp to offset all timestamps if self.__ts_start == 0: @@ -117,10 +117,14 @@ class TobiiSegmentVideo(): def get_height(self): return self.__height + def frames(self): + return self.__iter__() + def __iter__(self): # start decoding self.__container.decode(self.__stream) + return self def __next__(self): diff --git a/src/argaze/utils/analyse_tobii_segment_fixations.py b/src/argaze/utils/analyse_tobii_segment_fixations.py index 26f0838..3ab080f 100644 --- a/src/argaze/utils/analyse_tobii_segment_fixations.py +++ b/src/argaze/utils/analyse_tobii_segment_fixations.py @@ -32,28 +32,36 @@ def main(): print(f'Data keys: {tobii_segment_data.keys()}') # Access to timestamped gaze position data buffer - tobii_ts_gaze_position_buffer = tobii_segment_data['gidx-l-gp'] + tobii_ts_gaze_positions = tobii_segment_data['gidx-l-gp'] - print(f'{len(tobii_ts_gaze_position_buffer)} gaze positions loaded') + print(f'{len(tobii_ts_gaze_positions)} gaze positions loaded') - # format tobii gaze data into generic gaze data - generic_ts_gaze_position_buffer = GazeFeatures.TimeStampedGazePositions() + # Access to video timestamp index + tobii_vts = tobii_segment_data['vts'] - for ts, tobii_data in tobii_ts_gaze_position_buffer.items(): + print(f'{len(tobii_vts)} video timestamps loaded') + for ts, vts in tobii_vts.items(): + + print(f'ts: {ts/1000000}, vts: {vts.vts/1000000}') + + # Format tobii gaze data into generic gaze data and store them using second unit timestamp + generic_ts_gaze_positions = GazeFeatures.TimeStampedGazePositions() + + for ts, tobii_data in tobii_ts_gaze_positions.items(): generic_data = GazeFeatures.GazePosition(tobii_data.gp[0] * tobii_segment_video.get_width(), tobii_data.gp[1] * tobii_segment_video.get_height()) - generic_ts_gaze_position_buffer[ts] = generic_data + generic_ts_gaze_positions[ts/1000000] = generic_data - print(f'dispersion_threshold = {args.dispersion_threshold}') - print(f'duration_threshold = {args.duration_threshold}') + print(f'Dispersion threshold: {args.dispersion_threshold}') + print(f'Duration threshold: {args.duration_threshold}') - fixation_analyser = GazeFeatures.DispersionBasedFixationIdentifier(generic_ts_gaze_position_buffer, args.dispersion_threshold, args.duration_threshold) + fixation_analyser = GazeFeatures.DispersionBasedFixationIdentifier(generic_ts_gaze_positions, args.dispersion_threshold, args.duration_threshold) print(f'{len(fixation_analyser.fixations)} fixations found') for ts, f in fixation_analyser.fixations.items(): print(f'start time = {ts}, duration = {f.duration}, dispertion = {f.dispersion}, centroid = {f.centroid}') - # TODO : synchronise video and gaze + # TODO : Synchronise video and gaze #for ts, frame in tobii_segment_video: #print(ts) -- cgit v1.1