aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/argaze/ArFeatures.py71
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: