diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/argaze/ArFeatures.py | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index 456467f..def7675 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -80,6 +80,7 @@ class ArFrame(): aoi_2d_scene: AOI2DScene.AOI2DScene = field(default_factory=AOI2DScene.AOI2DScene) background: numpy.array = field(default_factory=numpy.array) gaze_movement_identifier: GazeFeatures.GazeMovementIdentifier = field(default_factory=GazeFeatures.GazeMovementIdentifier) + current_fixation_matching: bool = field(default=False) looked_aoi_covering_threshold: int = field(default=0) scan_path: GazeFeatures.ScanPath = field(default_factory=GazeFeatures.ScanPath) scan_path_analyzers: dict = field(default_factory=dict) @@ -166,11 +167,20 @@ class ArFrame(): gaze_movement_identifier_type, gaze_movement_identifier_parameters = gaze_movement_identifier_value.popitem() gaze_movement_identifier_module = importlib.import_module(f'argaze.GazeAnalysis.{gaze_movement_identifier_type}') - finished_gaze_movement_identifier = gaze_movement_identifier_module.GazeMovementIdentifier(**gaze_movement_identifier_parameters) + temp_gaze_movement_identifier = gaze_movement_identifier_module.GazeMovementIdentifier(**gaze_movement_identifier_parameters) except KeyError: - finished_gaze_movement_identifier = None + temp_gaze_movement_identifier = None + + # Current fixation matching + try: + + current_fixation_matching = frame_data.pop('current_fixation_matching') + + except KeyError: + + current_fixation_matching = False # Looked aoi validity threshold try: @@ -318,7 +328,8 @@ class ArFrame(): new_frame_size, \ new_aoi_2d_scene, \ new_frame_background, \ - finished_gaze_movement_identifier, \ + temp_gaze_movement_identifier, \ + current_fixation_matching, \ looked_aoi_covering_threshold, \ new_scan_path, \ new_scan_path_analyzers, \ @@ -435,13 +446,13 @@ class ArFrame(): # Update looked aoi covering mean self.__looked_aoi_covering_mean = int(100 * max_covering / (len(fixation.positions) - 2)) / 100 - def look(self, timestamp: int|float, inner_gaze_position: GazeFeatures.GazePosition = GazeFeatures.UnvalidGazePosition(), identified_gaze_movement: GazeFeatures.GazeMovement = GazeFeatures.UnvalidGazeMovement(), current_fixation_matching: bool = False) -> Tuple[GazeFeatures.GazeMovement, dict, dict, dict]: + def look(self, timestamp: int|float, inner_gaze_position: GazeFeatures.GazePosition = GazeFeatures.UnvalidGazePosition(), identified_gaze_movement: GazeFeatures.GazeMovement = GazeFeatures.UnvalidGazeMovement()) -> Tuple[GazeFeatures.GazeMovement, dict, dict, dict]: """ GazeFeatures.AOIScanStepError Returns: - finished_gaze_movement: identified gaze movement (if gaze_movement_identifier is instanciated) + temp_gaze_movement: identified gaze movement (if gaze_movement_identifier is instanciated) or current gaze movement (if current_fixation_matching is True) scan_step: new scan step (if scan_path is instanciated) aoi_scan_step: new scan step (if aoi_scan_path is instanciated) exception: error catched during gaze position processing @@ -454,7 +465,7 @@ class ArFrame(): self.__gaze_position = inner_gaze_position # No gaze movement identified by default - finished_gaze_movement = GazeFeatures.UnvalidGazeMovement() + temp_gaze_movement = GazeFeatures.UnvalidGazeMovement() # Init scan path analysis report scan_step_analysis = {} @@ -481,7 +492,7 @@ class ArFrame(): identification_start = time.time() # Identify finished gaze movement - finished_gaze_movement = self.gaze_movement_identifier.identify(timestamp, self.__gaze_position) + temp_gaze_movement = self.gaze_movement_identifier.identify(timestamp, self.__gaze_position) # Assess movement identification time in ms times['gaze_movement_identifier'] = (time.time() - identification_start) * 1e3 @@ -489,18 +500,18 @@ class ArFrame(): # Use given identified gaze movement else: - finished_gaze_movement = identified_gaze_movement + temp_gaze_movement = identified_gaze_movement # Valid and finished gaze movement has been identified - if finished_gaze_movement.valid: + if temp_gaze_movement.valid and temp_gaze_movement.finished: - if GazeFeatures.is_fixation(finished_gaze_movement): + if GazeFeatures.is_fixation(temp_gaze_movement): # Store aoi matching start date matching_start = time.time() # Does the finished fixation match an aoi? - self.__update_looked_aoi_data(finished_gaze_movement) + self.__update_looked_aoi_data(temp_gaze_movement) # Assess aoi matching time in ms times['aoi_matcher'] = (time.time() - matching_start) * 1e3 @@ -508,12 +519,12 @@ class ArFrame(): # Append fixation to scan path if self.scan_path != None: - self.scan_path.append_fixation(timestamp, finished_gaze_movement) + self.scan_path.append_fixation(timestamp, temp_gaze_movement) # Append fixation to aoi scan path if self.aoi_scan_path != None and self.looked_aoi != None and self.looked_aoi_covering_mean > self.looked_aoi_covering_threshold: - aoi_scan_step = self.aoi_scan_path.append_fixation(timestamp, finished_gaze_movement, self.looked_aoi) + aoi_scan_step = self.aoi_scan_path.append_fixation(timestamp, temp_gaze_movement, self.looked_aoi) # Is there a new step? if aoi_scan_step and len(self.aoi_scan_path) > 1: @@ -532,7 +543,7 @@ class ArFrame(): # Store analysis aoi_scan_step_analysis[aoi_scan_path_analyzer_type] = aoi_scan_path_analyzer.analysis - elif GazeFeatures.is_saccade(finished_gaze_movement): + elif GazeFeatures.is_saccade(temp_gaze_movement): # Reset looked aoi self.__init_looked_aoi_data() @@ -540,7 +551,7 @@ class ArFrame(): # Append saccade to scan path if self.scan_path != None: - scan_step = self.scan_path.append_saccade(timestamp, finished_gaze_movement) + scan_step = self.scan_path.append_saccade(timestamp, temp_gaze_movement) # Is there a new step? if scan_step and len(self.scan_path) > 1: @@ -562,15 +573,17 @@ class ArFrame(): # Append saccade to aoi scan path if self.aoi_scan_path != None: - self.aoi_scan_path.append_saccade(timestamp, finished_gaze_movement) + self.aoi_scan_path.append_saccade(timestamp, temp_gaze_movement) # No valid finished gaze movement: optionnaly check current fixation matching - elif self.gaze_movement_identifier and current_fixation_matching: + elif self.gaze_movement_identifier and self.current_fixation_matching: current_fixation = self.gaze_movement_identifier.current_fixation if current_fixation.valid: + temp_gaze_movement = current_fixation + # Store aoi matching start date matching_start = time.time() @@ -625,7 +638,7 @@ class ArFrame(): times['total'] = total_time # Return look data - return finished_gaze_movement, scan_step_analysis, aoi_scan_step_analysis, times, exception + return temp_gaze_movement, scan_step_analysis, aoi_scan_step_analysis, times, exception def draw(self, image:numpy.array, aoi_color=(0, 0, 0)) -> Exception: """ @@ -649,27 +662,25 @@ class ArFrame(): # Draw current gaze position self.__gaze_position.draw(image, color=(255, 255, 255)) - # Draw current gaze movements - if self.gaze_movement_identifier: + # Draw current gaze movement + current_gaze_movement = self.gaze_movement_identifier.current_gaze_movement - current_fixation = self.gaze_movement_identifier.current_fixation + if current_gaze_movement.valid: - if current_fixation.valid: + if GazeFeatures.is_fixation(current_gaze_movement): - current_fixation.draw(image, color=(0, 255, 255)) - current_fixation.draw_positions(image) + current_gaze_movement.draw(image, color=(0, 255, 255)) + current_gaze_movement.draw_positions(image) # Draw looked aoi if self.looked_aoi_covering_mean > self.looked_aoi_covering_threshold: - self.aoi_2d_scene.draw_circlecast(image, current_fixation.focus, current_fixation.deviation_max, matching_aoi = [self.__looked_aoi], base_color=(0, 0, 0), matching_color=(255, 255, 255)) - - current_saccade = self.gaze_movement_identifier.current_saccade + self.aoi_2d_scene.draw_circlecast(image, current_gaze_movement.focus, current_gaze_movement.deviation_max, matching_aoi = [self.__looked_aoi], base_color=(0, 0, 0), matching_color=(255, 255, 255)) - if current_saccade.valid: + elif GazeFeatures.is_saccade(current_gaze_movement): - current_saccade.draw(image, color=(0, 255, 255)) - current_saccade.draw_positions(image) + current_gaze_movement.draw(image, color=(0, 255, 255)) + current_gaze_movement.draw_positions(image) except Exception as e: |