aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThéo de la Hogue2022-09-07 11:37:13 +0200
committerThéo de la Hogue2022-09-07 11:37:13 +0200
commitd0c462824c7e3251df4f8aedc3493b7d48bbd3c7 (patch)
tree493625cb8b803ffa1be9154a1bdc7eac28e3c3d3
parent2323ff9aec813d087ea589be63e0f360d754b265 (diff)
downloadargaze-d0c462824c7e3251df4f8aedc3493b7d48bbd3c7.zip
argaze-d0c462824c7e3251df4f8aedc3493b7d48bbd3c7.tar.gz
argaze-d0c462824c7e3251df4f8aedc3493b7d48bbd3c7.tar.bz2
argaze-d0c462824c7e3251df4f8aedc3493b7d48bbd3c7.tar.xz
Exporting files into a folder named according time range setting. Processing gaze accuracy for further movements analysis.
-rw-r--r--src/argaze/utils/export_tobii_segment_movements.py49
1 files changed, 43 insertions, 6 deletions
diff --git a/src/argaze/utils/export_tobii_segment_movements.py b/src/argaze/utils/export_tobii_segment_movements.py
index ee41a60..ece8cff 100644
--- a/src/argaze/utils/export_tobii_segment_movements.py
+++ b/src/argaze/utils/export_tobii_segment_movements.py
@@ -8,6 +8,7 @@ from argaze.TobiiGlassesPro2 import TobiiEntities, TobiiVideo
from argaze.utils import MiscFeatures
import cv2 as cv
+import numpy
def main():
"""
@@ -41,6 +42,16 @@ def main():
destination_path = args.segment_path
+ # Export into a dedicated time range folder
+ timerange_path = f'[{int(args.time_range[0])}s - {int(args.time_range[1])}s]'
+
+ destination_path = f'{destination_path}/{timerange_path}'
+
+ if not os.path.exists(destination_path):
+
+ os.makedirs(destination_path)
+ print(f'{destination_path} folder created')
+
fixations_filepath = f'{destination_path}/movements_fixations.csv'
saccades_filepath = f'{destination_path}/movements_saccades.csv'
@@ -68,8 +79,30 @@ def main():
ts_gaze_positions = GazeFeatures.TimeStampedGazePositions()
for ts, tobii_gaze_position in tobii_ts_gaze_positions.items():
- video_gaze_pixel = (int(tobii_gaze_position.value[0] * tobii_segment_video.get_width()), int(tobii_gaze_position.value[1] * tobii_segment_video.get_height()))
- ts_gaze_positions[ts/1000] = video_gaze_pixel
+ gaze_position_pixel = (int(tobii_gaze_position.value[0] * tobii_segment_video.get_width()), int(tobii_gaze_position.value[1] * tobii_segment_video.get_height()))
+ ts_gaze_positions[ts/1000] = gaze_position_pixel
+
+ # Access to timestamped gaze 3D positions data buffer
+ tobii_ts_gaze_positions_3d = tobii_segment_data['GazePosition3D']
+
+ # Format gaze accuracies in pixel and store them using millisecond unit timestamp
+ ts_gaze_accuracies = GazeFeatures.TimeStampedGazeAccuracies()
+
+ # !!! the parameters below are specific to the TobiiGlassesPro2 !!!
+ # Reference : https://www.biorxiv.org/content/10.1101/299925v1
+ tobii_accuracy = 1.42 # degree
+ tobii_precision = 0.34 # degree
+ tobii_camera_hfov = 82 # degree
+
+ for ts, tobii_ts_gaze_position_3d in tobii_ts_gaze_positions_3d.items():
+
+ if tobii_ts_gaze_position_3d.value[2] > 0:
+
+ gaze_accuracy_mm = numpy.sin(numpy.deg2rad(tobii_accuracy)) * tobii_ts_gaze_position_3d.value[2]
+ tobii_camera_hfov_mm = numpy.sin(numpy.deg2rad(tobii_camera_hfov)) * tobii_ts_gaze_position_3d.value[2]
+ gaze_accuracy_pixel = round(tobii_segment_video.get_width() * float(gaze_accuracy_mm) / float(tobii_camera_hfov_mm))
+
+ ts_gaze_accuracies[ts/1000] = gaze_accuracy_pixel
print(f'Dispersion threshold: {args.dispersion_threshold}')
print(f'Duration threshold: {args.duration_threshold}')
@@ -175,15 +208,19 @@ def main():
current_fixation_time_counter += 1
- cv.circle(video_frame.matrix, current_fixation.centroid, current_fixation.dispersion + current_fixation_time_counter, (0, 255, 255), 1)
+ cv.circle(video_frame.matrix, current_fixation.centroid, current_fixation.dispersion + current_fixation_time_counter, (0, 255, 0), 1)
try:
# Get closest gaze position before video timestamp and remove all gaze positions before
- closest_gaze_ts, closest_gaze_position = ts_gaze_positions.pop_first_until(video_ts_ms)
+ _, nearest_gaze_position = ts_gaze_positions.pop_first_until(video_ts_ms)
+
+ # Get closest gaze accuracy before video timestamp and remove all gaze accuracies before
+ _, nearest_gaze_accuracy = ts_gaze_accuracies.pop_first_until(video_ts_ms)
- # Draw gaze position
- cv.circle(video_frame.matrix, closest_gaze_position, 10, (0, 255, 255), 2)
+ # Draw gaze position and precision
+ cv.circle(video_frame.matrix, nearest_gaze_position, 2, (0, 255, 255), -1)
+ cv.circle(video_frame.matrix, nearest_gaze_position, nearest_gaze_accuracy, (0, 255, 255), 1)
# Wait for gaze position
except ValueError: