aboutsummaryrefslogtreecommitdiff
path: root/src/argaze/GazeFeatures.py
diff options
context:
space:
mode:
authorThéo de la Hogue2022-04-25 16:07:11 +0200
committerThéo de la Hogue2022-04-25 16:07:11 +0200
commit0cc4c65d28c236d8bba1c7eeb6be83c905630245 (patch)
treedc0a708b7f5f1f54771e103baaa44f487ff724b0 /src/argaze/GazeFeatures.py
parent6e46a56ea44390580068850e6b26d8ba6cbf44da (diff)
downloadargaze-0cc4c65d28c236d8bba1c7eeb6be83c905630245.zip
argaze-0cc4c65d28c236d8bba1c7eeb6be83c905630245.tar.gz
argaze-0cc4c65d28c236d8bba1c7eeb6be83c905630245.tar.bz2
argaze-0cc4c65d28c236d8bba1c7eeb6be83c905630245.tar.xz
Processing gaze position relatively to area corners.
Diffstat (limited to 'src/argaze/GazeFeatures.py')
-rw-r--r--src/argaze/GazeFeatures.py55
1 files changed, 32 insertions, 23 deletions
diff --git a/src/argaze/GazeFeatures.py b/src/argaze/GazeFeatures.py
index e0c3e73..73dace9 100644
--- a/src/argaze/GazeFeatures.py
+++ b/src/argaze/GazeFeatures.py
@@ -17,6 +17,9 @@ class GazePosition():
x: float
y: float
+ def as_tuple(self):
+ return (self.x, self.y)
+
class TimeStampedGazePositions(DataStructures.TimeStampedBuffer):
"""Define timestamped buffer to store gaze positions."""
@@ -206,11 +209,11 @@ class DispersionBasedFixationIdentifier(FixationIdentifier):
@dataclass
class VisualScanStep():
- """Define a visual scan step as a duration, the name of the area of interest and all its frames during the step."""
+ """Define a visual scan step as a duration, the name of the area of interest and where gaze looked at in each frame during the step."""
duration: float
area: str
- frames: DataStructures.TimeStampedBuffer
+ look_at: DataStructures.TimeStampedBuffer
class TimeStampedVisualScanSteps(DataStructures.TimeStampedBuffer):
"""Define timestamped buffer to store visual scan steps."""
@@ -247,14 +250,15 @@ class VisualScanGenerator():
return visual_scan_steps
class PointerBasedVisualScan(VisualScanGenerator):
- """Build visual scan on the basis of AOI's pointer information."""
+ """Build visual scan on the basis of which AOI are looked."""
- def __init__(self, ts_aoi_scenes: AOIFeatures.TimeStampedAOIScenes): # TODO : add tolerance_to_lacking ?
+ def __init__(self, ts_aoi_scenes: AOIFeatures.TimeStampedAOIScenes, ts_gaze_positions: TimeStampedGazePositions):
super().__init__(ts_aoi_scenes)
# process identification on a copy
self.__ts_aoi_scenes = ts_aoi_scenes.copy()
+ self.__ts_gaze_positions = ts_gaze_positions.copy()
# a dictionary to store when an aoi starts to be looked
self.__step_dict = {}
@@ -267,35 +271,40 @@ class PointerBasedVisualScan(VisualScanGenerator):
(ts_current, aoi_scene_current) = self.__ts_aoi_scenes.pop_first()
- #if not aoi_scene_current.looked:
- # raise ValueError('TimeStampedAOIScenes must be looked using look_at method.')
+ try:
+
+ gaze_position = self.__ts_gaze_positions[ts_current]
+
+ for name, aoi in aoi_scene_current.areas.items():
- for name, aoi in aoi_scene_current.areas.items():
+ looked = aoi.looked(gaze_position)
- aoi_looked = aoi.pointer != None
+ if looked:
- if aoi_looked:
+ if not name in self.__step_dict.keys():
- if not name in self.__step_dict.keys():
+ # aoi starts to be looked
+ self.__step_dict[name] = {
+ 'start': ts_current,
+ 'look_at': DataStructures.TimeStampedBuffer()
+ }
- # aoi starts to be looked
- self.__step_dict[name] = {
- 'start': ts_current,
- 'frames': DataStructures.TimeStampedBuffer()
- }
+ # store where the aoi is looked
+ self.__step_dict[name]['look_at'][ts_current] = aoi.look_at(gaze_position).tolist()
- # store current aoi
- self.__step_dict[name]['frames'][ts_current] = aoi
+ elif name in self.__step_dict.keys():
- elif name in self.__step_dict.keys():
+ ts_start = self.__step_dict[name]['start']
- ts_start = self.__step_dict[name]['start']
+ # aoi stops to be looked
+ yield ts_start, VisualScanStep(ts_current - ts_start, name, self.__step_dict[name]['look_at'])
- # aoi stops to be looked
- yield ts_start, VisualScanStep(ts_current - ts_start, name, self.__step_dict[name]['frames'])
+ # forget the aoi
+ del self.__step_dict[name]
- # forget the aoi
- del self.__step_dict[name]
+ # ignore missing gaze position
+ except KeyError:
+ pass
class FixationBasedVisualScan(VisualScanGenerator):
"""Build visual scan on the basis of timestamped fixations."""