aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThéo de la Hogue2024-09-03 09:51:42 +0200
committerThéo de la Hogue2024-09-03 09:51:42 +0200
commit4a02316c505f1ed3cbef39540264a7f96387bc2d (patch)
tree22d1f387fb7b5676fe52042855873923e9f5a586 /src
parent91a30dfadad1425c834f00e1022f7e42603af646 (diff)
parent84fd53edaa66cda11e4e47abce3fbe7cc7ace657 (diff)
downloadargaze-4a02316c505f1ed3cbef39540264a7f96387bc2d.zip
argaze-4a02316c505f1ed3cbef39540264a7f96387bc2d.tar.gz
argaze-4a02316c505f1ed3cbef39540264a7f96387bc2d.tar.bz2
argaze-4a02316c505f1ed3cbef39540264a7f96387bc2d.tar.xz
merging dev/G3andNeon branch and fixing conflicts about size.
Diffstat (limited to 'src')
-rw-r--r--src/argaze/utils/contexts/PupilLabsNeon.py140
-rw-r--r--src/argaze/utils/demo/aruco_markers_pipeline.json8
-rw-r--r--src/argaze/utils/demo/gaze_analysis_pipeline.json4
-rw-r--r--src/argaze/utils/demo/pupillabs_neon_live_stream_context.json6
4 files changed, 156 insertions, 2 deletions
diff --git a/src/argaze/utils/contexts/PupilLabsNeon.py b/src/argaze/utils/contexts/PupilLabsNeon.py
new file mode 100644
index 0000000..e7d1f47
--- /dev/null
+++ b/src/argaze/utils/contexts/PupilLabsNeon.py
@@ -0,0 +1,140 @@
+"""Handle network connection to Pupil Labs devices. Tested with Pupil Neon.
+ Based on Pupil Labs' Realtime Python API."""
+
+"""
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <https://www.gnu.org/licenses/>.
+"""
+
+__author__ = "Damien Mouratille"
+__credits__ = []
+__copyright__ = "Copyright 2024, Ecole Nationale de l'Aviation Civile (ENAC)"
+__license__ = "GPLv3"
+
+import sys
+import logging
+import time
+
+import threading
+from dataclasses import dataclass
+
+from argaze import ArFeatures, DataFeatures, GazeFeatures
+from argaze.utils import UtilsFeatures
+
+import numpy
+import cv2
+
+from pupil_labs.realtime_api.simple import discover_one_device
+
+
+class LiveStream(ArFeatures.DataCaptureContext):
+
+ @DataFeatures.PipelineStepInit
+ def __init__(self, **kwargs):
+
+ # Init DataCaptureContext class
+ super().__init__()
+
+ def __enter__(self):
+
+ logging.info('Pupil-Labs Neon connexion starts...')
+
+ # Init timestamp
+ self.__start_time = time.time()
+
+ # Look for devices. Returns as soon as it has found the first device.
+ self.__device = discover_one_device(max_search_duration_seconds=10)
+
+ if self.__device is None:
+ logging.info('No device found. Exit!')
+ raise SystemExit(-1)
+ else:
+ logging.info('Device found. Stream loading.')
+
+ # Open gaze stream
+ self.__gaze_thread = threading.Thread(target=self.__stream_gaze)
+
+ logging.debug('> starting gaze thread...')
+
+ self.__gaze_thread.start()
+
+ # Open video stream
+ self.__video_thread = threading.Thread(target=self.__stream_video)
+
+ logging.debug('> starting video thread...')
+
+ self.__video_thread.start()
+
+ return self
+
+ def __stream_gaze(self):
+ """Stream gaze."""
+
+ logging.debug('Stream gaze from Pupil Neon')
+
+ while self.is_running():
+
+ try:
+ while True:
+ gaze = self.__device.receive_gaze_datum()
+
+ gaze_timestamp = int((gaze.timestamp_unix_seconds - self.__start_time) * 1e3)
+
+ logging.debug('Gaze received at %i timestamp', gaze_timestamp)
+
+ # When gaze position is valid
+ if gaze.worn is True:
+
+ self._process_gaze_position(
+ timestamp=gaze_timestamp,
+ x=int(gaze.x),
+ y=int(gaze.y))
+ else:
+ # Process empty gaze position
+ logging.debug('Not worn at %i timestamp', gaze_timestamp)
+
+ self._process_gaze_position(timestamp=gaze_timestamp)
+
+ except KeyboardInterrupt:
+ pass
+
+ def __stream_video(self):
+ """Stream video."""
+
+ logging.debug('Stream video from Pupil Neon')
+
+ while self.is_running():
+
+ try:
+ while True:
+ scene_frame, frame_datetime = self.__device.receive_scene_video_frame()
+
+ scene_timestamp = int((frame_datetime - self.__start_time) * 1e3)
+
+ logging.debug('Video received at %i timestamp', scene_timestamp)
+
+ self._process_camera_image(
+ timestamp=scene_timestamp,
+ image=scene_frame)
+
+ except KeyboardInterrupt:
+ pass
+
+ @DataFeatures.PipelineStepExit
+ def __exit__(self, exception_type, exception_value, exception_traceback):
+
+ logging.debug('Pupil-Labs context stops...')
+
+ # Close data stream
+ self.stop()
+
+ # Stop streaming
+ threading.Thread.join(self.__gaze_thread)
+ threading.Thread.join(self.__video_thread)
diff --git a/src/argaze/utils/demo/aruco_markers_pipeline.json b/src/argaze/utils/demo/aruco_markers_pipeline.json
index 8221cec..e8d85eb 100644
--- a/src/argaze/utils/demo/aruco_markers_pipeline.json
+++ b/src/argaze/utils/demo/aruco_markers_pipeline.json
@@ -56,7 +56,11 @@
},
"frames": {
"GrayRectangle": {
+<<<<<<< HEAD
"size": [1088, 1080],
+=======
+ "size": [1600, 1200],
+>>>>>>> dev/G3andNeon
"background": "frame_background.jpg",
"gaze_movement_identifier": {
"argaze.GazeAnalysis.DispersionThresholdIdentification.GazeMovementIdentifier": {
@@ -71,7 +75,11 @@
"argaze.GazeAnalysis.Basic.ScanPathAnalyzer": {},
"argaze.GazeAnalysis.KCoefficient.ScanPathAnalyzer": {},
"argaze.GazeAnalysis.NearestNeighborIndex.ScanPathAnalyzer": {
+<<<<<<< HEAD
"size": [1088, 1080]
+=======
+ "size": [1600, 1200]
+>>>>>>> dev/G3andNeon
},
"argaze.GazeAnalysis.ExploreExploitRatio.ScanPathAnalyzer": {
"short_fixation_duration_threshold": 0
diff --git a/src/argaze/utils/demo/gaze_analysis_pipeline.json b/src/argaze/utils/demo/gaze_analysis_pipeline.json
index 6e23321..e0f99a8 100644
--- a/src/argaze/utils/demo/gaze_analysis_pipeline.json
+++ b/src/argaze/utils/demo/gaze_analysis_pipeline.json
@@ -126,8 +126,8 @@
},
"recorders.FrameImageRecorder": {
"path": "_export/records/video.mp4",
- "width": 1920,
- "height": 1080,
+ "width": 1600,
+ "height": 1200,
"fps": 15
}
}
diff --git a/src/argaze/utils/demo/pupillabs_neon_live_stream_context.json b/src/argaze/utils/demo/pupillabs_neon_live_stream_context.json
new file mode 100644
index 0000000..a87c30e
--- /dev/null
+++ b/src/argaze/utils/demo/pupillabs_neon_live_stream_context.json
@@ -0,0 +1,6 @@
+{
+ "argaze.utils.contexts.PupilLabsNeon.LiveStream" : {
+ "name": "PupilLabs Neon",
+ "pipeline": "aruco_markers_pipeline.json"
+ }
+} \ No newline at end of file