aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThéo de la Hogue2022-04-28 09:14:26 +0200
committerThéo de la Hogue2022-04-28 09:14:26 +0200
commitb560ddb3a7a687c3b2191fa32aadf4301b1ae7b4 (patch)
treeba8cb606e60ee956f74239e8774cda88df64cb55
parentcb090f1202e21e2851a494c87c5a48d0dea3133f (diff)
downloadargaze-b560ddb3a7a687c3b2191fa32aadf4301b1ae7b4.zip
argaze-b560ddb3a7a687c3b2191fa32aadf4301b1ae7b4.tar.gz
argaze-b560ddb3a7a687c3b2191fa32aadf4301b1ae7b4.tar.bz2
argaze-b560ddb3a7a687c3b2191fa32aadf4301b1ae7b4.tar.xz
Renaming script.
-rw-r--r--src/argaze/utils/export_tobii_segment_movements.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/argaze/utils/export_tobii_segment_movements.py b/src/argaze/utils/export_tobii_segment_movements.py
new file mode 100644
index 0000000..624d758
--- /dev/null
+++ b/src/argaze/utils/export_tobii_segment_movements.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+import argparse
+import bisect
+import os
+
+from argaze import GazeFeatures
+from argaze.TobiiGlassesPro2 import TobiiEntities
+from argaze.utils import MiscFeatures
+
+def main():
+ """
+ Analyse Tobii segment fixations
+ """
+
+ # Manage arguments
+ parser = argparse.ArgumentParser(description=main.__doc__.split('-')[0])
+ parser.add_argument('-s', '--segment_path', metavar='SEGMENT_PATH', type=str, default=None, help='path to a tobii segment folder')
+ parser.add_argument('-r', '--time_range', metavar=('START_TIME', 'END_TIME'), nargs=2, type=float, default=(0., None), help='start and end time (in second)')
+ parser.add_argument('-d', '--dispersion_threshold', metavar='DISPERSION_THRESHOLD', type=int, default=10, help='dispersion threshold in pixel')
+ parser.add_argument('-t', '--duration_threshold', metavar='DURATION_THRESHOLD', type=int, default=100, help='duration threshold in millisecond')
+ parser.add_argument('-o', '--output', metavar='OUT', type=str, default=None, help='destination folder path (segment folder by default)')
+ args = parser.parse_args()
+
+ if args.segment_path != None:
+
+ # Manage destination path
+ if args.output != None:
+
+ if not os.path.exists(os.path.dirname(args.output)):
+
+ os.makedirs(os.path.dirname(args.output))
+ print(f'{os.path.dirname(args.output)} folder created')
+
+ fixations_filepath = f'{args.output}/fixations.csv'
+ saccades_filepath = f'{args.output}/saccades.csv'
+
+ else:
+
+ fixations_filepath = f'{args.segment_path}/fixations.csv'
+ saccades_filepath = f'{args.segment_path}/saccades.csv'
+
+ # Load a tobii segment
+ tobii_segment = TobiiEntities.TobiiSegment(args.segment_path, int(args.time_range[0] * 1000000), int(args.time_range[1] * 1000000) if args.time_range[1] != None else None)
+
+ # Load a tobii segment video
+ tobii_segment_video = tobii_segment.load_video()
+ print(f'Video duration: {tobii_segment_video.get_duration()/1000000}, width: {tobii_segment_video.get_width()}, height: {tobii_segment_video.get_height()}')
+
+ # Load a tobii segment data
+ tobii_segment_data = tobii_segment.load_data()
+ print(f'Data keys: {tobii_segment_data.keys()}')
+
+ # Access to timestamped gaze position data buffer
+ tobii_ts_gaze_positions = tobii_segment_data.gidx_l_gp
+ print(f'{len(tobii_ts_gaze_positions)} gaze positions loaded')
+
+ # Format tobii gaze data into generic gaze data and store them using millisecond 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_positions[ts/1000] = generic_data
+
+ print(f'Dispersion threshold: {args.dispersion_threshold}')
+ print(f'Duration threshold: {args.duration_threshold}')
+
+ # Start movement identification
+ movement_identifier = GazeFeatures.DispersionBasedMovementIdentifier(generic_ts_gaze_positions, args.dispersion_threshold, args.duration_threshold)
+ fixations = GazeFeatures.TimeStampedFixations()
+ saccades = GazeFeatures.TimeStampedSaccades()
+
+ # Initialise progress bar
+ MiscFeatures.printProgressBar(0, int(tobii_segment_video.get_duration()/1000), prefix = 'Progress:', suffix = 'Complete', length = 100)
+
+ for ts, item in movement_identifier:
+
+ if isinstance(item, GazeFeatures.Fixation):
+ fixations[ts] = item
+
+ elif isinstance(item, GazeFeatures.Saccade):
+ saccades[ts] = item
+
+ else:
+ continue
+
+ # Update Progress Bar
+ progress = ts - int(args.time_range[0] * 1000)
+ MiscFeatures.printProgressBar(progress, int(tobii_segment_video.get_duration()/1000), prefix = 'Progress:', suffix = 'Complete', length = 100)
+
+ print(f'\n{len(fixations)} fixations and {len(saccades)} saccades found')
+
+ # Export fixations analysis
+ fixations.export_as_csv(fixations_filepath)
+ print(f'Fixations saved into {fixations_filepath}')
+
+ # Export saccades analysis
+ saccades.export_as_csv(saccades_filepath)
+ print(f'Saccades saved into {saccades_filepath}')
+
+if __name__ == '__main__':
+
+ main() \ No newline at end of file