aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/argaze/ArFeatures.py111
-rw-r--r--src/argaze/utils/demo_ar_features_run.py7
-rw-r--r--src/argaze/utils/demo_gaze_features_run.py2
3 files changed, 78 insertions, 42 deletions
diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py
index 3e2bc12..43496ef 100644
--- a/src/argaze/ArFeatures.py
+++ b/src/argaze/ArFeatures.py
@@ -294,9 +294,10 @@ class ArFrame():
GazeFeatures.AOIScanStepError
Returns:
- gaze_movement: identified gaze movement (if gaze_movement_identifier is intanciated)
- scan_step: new scan step (if scan_path is intanciated)
- aoi_scan_step: new scan step (if aoi_scan_path is intanciated)
+ fixation: identified fixation (if gaze_movement_identifier is instanciated)
+ look at: when identified fixation looks at
+ scan_step: new scan step (if scan_path is instanciated)
+ aoi_scan_step: new scan step (if aoi_scan_path is instanciated)
"""
# Lock frame exploitation
@@ -305,6 +306,9 @@ class ArFrame():
# Update current gaze position
self.__gaze_position = inner_gaze_position
+ # No fixation is identified by default
+ fixation = GazeFeatures.UnvalidGazeMovement()
+
# No aoi is looked by default
look_at = None
@@ -318,63 +322,92 @@ class ArFrame():
# Identify finished gaze movement
finished_gaze_movement = self.gaze_movement_identifier.identify(timestamp, self.__gaze_position)
- if GazeFeatures.is_fixation(finished_gaze_movement):
+ # Valid and finished gaze movement has been identified
+ if finished_gaze_movement.valid:
- # Does the fixation match an aoi?
- for name, aoi in self.aoi_2d_scene.items():
+ if GazeFeatures.is_fixation(finished_gaze_movement):
- _, _, circle_ratio = aoi.circle_intersection(finished_gaze_movement.focus, finished_gaze_movement.deviation_max)
+ # Update current fixation
+ fixation = finished_gaze_movement
- if circle_ratio > 0.25:
+ # Does the fixation match an aoi?
+ for name, aoi in self.aoi_2d_scene.items():
- if name != self.name:
+ _, _, circle_ratio = aoi.circle_intersection(finished_gaze_movement.focus, finished_gaze_movement.deviation_max)
- # Update current look at
- look_at = name
- break
+ if circle_ratio > 0.25:
- # Append fixation to scan path
- if self.scan_path != None:
+ if name != self.name:
- self.scan_path.append_fixation(timestamp, finished_gaze_movement)
+ # Update current look at
+ look_at = name
+ break
- # Append fixation to aoi scan path
- if self.aoi_scan_path != None and look_at != None:
+ # Append fixation to scan path
+ if self.scan_path != None:
- aoi_scan_step = self.aoi_scan_path.append_fixation(timestamp, finished_gaze_movement, look_at)
+ self.scan_path.append_fixation(timestamp, finished_gaze_movement)
- # Analyze aoi scan path
- if aoi_scan_step and len(self.aoi_scan_path) > 1:
+ # Append fixation to aoi scan path
+ if self.aoi_scan_path != None and look_at != None:
- for aoi_scan_path_analyzer_type, aoi_scan_path_analyzer in self.aoi_scan_path_analyzers.items():
+ aoi_scan_step = self.aoi_scan_path.append_fixation(timestamp, finished_gaze_movement, look_at)
- aoi_scan_path_analyzer.analyze(self.aoi_scan_path)
+ # Analyze aoi scan path
+ if aoi_scan_step and len(self.aoi_scan_path) > 1:
- aoi_scan_step_analysis[aoi_scan_path_analyzer_type] = aoi_scan_path_analyzer.analysis
+ for aoi_scan_path_analyzer_type, aoi_scan_path_analyzer in self.aoi_scan_path_analyzers.items():
- elif GazeFeatures.is_saccade(finished_gaze_movement):
+ aoi_scan_path_analyzer.analyze(self.aoi_scan_path)
- # Update current look at
- look_at = None
+ aoi_scan_step_analysis[aoi_scan_path_analyzer_type] = aoi_scan_path_analyzer.analysis
- # Append saccade to scan path
- if self.scan_path != None:
-
- scan_step = self.scan_path.append_saccade(timestamp, finished_gaze_movement)
+ elif GazeFeatures.is_saccade(finished_gaze_movement):
+
+ # Update current look at
+ look_at = None
+
+ # Append saccade to scan path
+ if self.scan_path != None:
+
+ scan_step = self.scan_path.append_saccade(timestamp, finished_gaze_movement)
+
+ # Analyze aoi scan path
+ if scan_step and len(self.scan_path) > 1:
+
+ for scan_path_analyzer_type, scan_path_analyzer in self.scan_path_analyzers.items():
+
+ 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:
+
+ self.aoi_scan_path.append_saccade(timestamp, finished_gaze_movement)
+
+ # No valid finished gaze movement: check current fixation
+ else:
+
+ current_fixation = self.gaze_movement_identifier.current_fixation
+
+ if current_fixation.valid:
- # Analyze aoi scan path
- if scan_step and len(self.scan_path) > 1:
+ # Update current fixation
+ fixation = current_fixation
- for scan_path_analyzer_type, scan_path_analyzer in self.scan_path_analyzers.items():
+ # Does the fixation match an aoi?
+ for name, aoi in self.aoi_2d_scene.items():
- scan_path_analyzer.analyze(self.scan_path)
+ _, _, circle_ratio = aoi.circle_intersection(current_fixation.focus, current_fixation.deviation_max)
- scan_step_analysis[scan_path_analyzer_type] = scan_path_analyzer.analysis
+ if circle_ratio > 0.25:
- # Append saccade to aoi scan path
- if self.aoi_scan_path != None:
+ if name != self.name:
- self.aoi_scan_path.append_saccade(timestamp, finished_gaze_movement)
+ # Update current look at
+ look_at = name
+ break
# Update heatmap
if self.heatmap:
@@ -385,7 +418,7 @@ class ArFrame():
self.__look_lock.release()
# Return look data
- return finished_gaze_movement, look_at, scan_step_analysis, aoi_scan_step_analysis
+ return fixation, look_at, scan_step_analysis, aoi_scan_step_analysis
def draw(self, image:numpy.array):
"""
diff --git a/src/argaze/utils/demo_ar_features_run.py b/src/argaze/utils/demo_ar_features_run.py
index 6151188..f8158d6 100644
--- a/src/argaze/utils/demo_ar_features_run.py
+++ b/src/argaze/utils/demo_ar_features_run.py
@@ -47,8 +47,11 @@ def main():
# Project gaze position into environment
for frame, look_data in ar_environment.look(timestamp, GazeFeatures.GazePosition((x, y))):
- # Do nothing with look data
- pass
+ # Unpack look data
+ fixation, look_at, scan_step_analysis, aoi_scan_step_analysis = look_data
+
+ # Do something with look data
+ # ...
# Attach mouse callback to window
cv2.setMouseCallback(ar_environment.name, on_mouse_event)
diff --git a/src/argaze/utils/demo_gaze_features_run.py b/src/argaze/utils/demo_gaze_features_run.py
index 2e6070f..8719e84 100644
--- a/src/argaze/utils/demo_gaze_features_run.py
+++ b/src/argaze/utils/demo_gaze_features_run.py
@@ -56,7 +56,7 @@ def main():
timestamp = int((time.time() - start_time) * 1e3)
# Project gaze position into frame
- ended_gaze_movement, look_at, scan_step_analysis, aoi_scan_step_analysis = ar_frame.look(timestamp, GazeFeatures.GazePosition((x, y)))
+ fixation, look_at, scan_step_analysis, aoi_scan_step_analysis = ar_frame.look(timestamp, GazeFeatures.GazePosition((x, y)))
# Do something with look data
# ...