From d50374920452c537129f1e7786a945a732b4b509 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Mon, 3 Jul 2023 14:34:37 +0200 Subject: Returning AOI/ScanPath analysis results in ArScreen look method. Allowing to genrate looking data in ArEnvironment look method. --- src/argaze/ArFeatures.py | 69 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index b4d7c11..6e651f1 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -354,7 +354,7 @@ class ArEnvironment(): # Unlock scene projections exploitation self.__aoi_2d_scenes_lock.release() - def look(self, timestamp: int|float, gaze_position: GazeFeatures.GazePosition): + def look(self, timestamp: int|float, gaze_position: GazeFeatures.GazePosition, data_generator: bool = False): """Project timestamped gaze position into current scene projections.""" # Can't use scene projection when it is locked @@ -385,10 +385,12 @@ class ArEnvironment(): # QUESTION: How to project gaze precision? inner_gaze_position = GazeFeatures.GazePosition((inner_x, inner_y)) - gaze_movement, look_at, scan_step, aoi_scan_step = screen.look(timestamp, inner_gaze_position * screen.size) + gaze_movement, look_at, scan_step_analysis, aoi_scan_step_analysis = screen.look(timestamp, inner_gaze_position * screen.size) - # NOT COMPATIBLE without for loop - #yield scene_name, screen_name, screen, gaze_movement, look_at, scan_step, aoi_scan_step + # Generate looking data + if data_generator: + + yield scene_name, screen_name, screen, gaze_movement, look_at, scan_step_analysis, aoi_scan_step_analysis # Ignore missing aoi scene projection except KeyError: @@ -750,7 +752,47 @@ class ArScreen(): return GazeFeatures.UnvalidGazeMovement() - def look(self, timestamp: int|float, inner_gaze_position: GazeFeatures.GazePosition): + @property + def current_scan_path_analysis(self) -> dict: + """Get current scan path analysis.""" + + # Edit dictionary with all analysis + scan_path_analysis = {} + + if scan_path != None: + + # Wait for screen to be unlocked + while self.__looking_lock.locked(): + pass + + # For each scan path analyzer + for scan_path_analyzer_type, scan_path_analyzer in self.scan_path_analyzers.items(): + + scan_path_analysis[scan_path_analyzer_type] = scan_path_analyzer.analysis + + return scan_path_analysis + + @property + def current_aoi_scan_path_analysis(self) -> dict: + """Get current aoi scan path analysis.""" + + # Edit dictionary with all analysis + aoi_scan_path_analysis = {} + + if aoi_scan_path != None: + + # Wait for screen to be unlocked + while self.__looking_lock.locked(): + pass + + # For each aoi scan path analyzer + for aoi_scan_path_analyzer_type, aoi_scan_path_analyzer in self.aoi_scan_path_analyzers.items(): + + aoi_scan_path_analysis[aoi_scan_path_analyzer_type] = aoi_scan_path_analyzer.analysis + + return aoi_scan_path_analysis + + def look(self, timestamp: int|float, inner_gaze_position: GazeFeatures.GazePosition) -> Tuple[GazeFeatures.GazeMovement, str, dict, dict]: """ GazeFeatures.AOIScanStepError @@ -764,13 +806,14 @@ class ArScreen(): # Lock screen exploitation self.__looking_lock.acquire() + # Update internal gaze position self.__gaze_position = inner_gaze_position - # Prepare return - gaze_movement = None + # Prepare looking data + gaze_movement = GazeFeatures.UnvalidGazeMovement() look_at = self.name - scan_step = None - aoi_scan_step = None + scan_step_analysis = {} + aoi_scan_step_analysis = {} # Identify gaze movement if self.gaze_movement_identifier: @@ -809,6 +852,8 @@ class ArScreen(): aoi_scan_path_analyzer.analyze(self.aoi_scan_path) + aoi_scan_step_analysis[aoi_scan_path_analyzer_type] = aoi_scan_path_analyzer.analysis + elif GazeFeatures.is_saccade(gaze_movement): # Append saccade to scan path @@ -823,6 +868,8 @@ class ArScreen(): scan_path_analyzer.analyze(self.scan_path) + scan_step_analysis[scan_path_analyzer_type] = scan_path_analyzer.analysis + # Append saccade to aoi scan path if self.aoi_scan_path != None: @@ -836,5 +883,5 @@ class ArScreen(): # Unlock screen exploitation self.__looking_lock.release() - # Return - return gaze_movement, look_at, scan_step, aoi_scan_step + # Return looking data + return gaze_movement, look_at, scan_step_analysis, aoi_scan_step_analysis -- cgit v1.1