From 11fdcdf12b84b41ca32d053cd7ad8c9bd4f6f3e0 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Thu, 21 Mar 2024 08:46:24 +0100 Subject: Adding provider property to ArFrame class. --- src/argaze/ArFeatures.py | 143 ++++++++++++++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index 65b2c69..ed152bf 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -28,6 +28,7 @@ import time from argaze import DataFeatures, GazeFeatures from argaze.AreaOfInterest import * from argaze.GazeAnalysis import * +from argaze.utils import Providers import numpy import cv2 @@ -75,31 +76,31 @@ class LoadingFailed(Exception): # Define default ArLayer draw parameters DEFAULT_ARLAYER_DRAW_PARAMETERS = { - "draw_aoi_scene": { - "draw_aoi": { - "color": (255, 255, 255), - "border_size": 1 - } - }, - "draw_aoi_matching": { - "draw_matched_fixation": { - "deviation_circle_color": (255, 255, 255) - }, - "draw_matched_fixation_positions": { - "position_color": (0, 255, 255), - "line_color": (0, 0, 0) - }, - "draw_matched_region": { - "color": (0, 255, 0), - "border_size": 4 - }, - "draw_looked_aoi": { - "color": (0, 255, 0), - "border_size": 2 - }, - "looked_aoi_name_color": (255, 255, 255), - "looked_aoi_name_offset": (0, -10) - } + "draw_aoi_scene": { + "draw_aoi": { + "color": (255, 255, 255), + "border_size": 1 + } + }, + "draw_aoi_matching": { + "draw_matched_fixation": { + "deviation_circle_color": (255, 255, 255) + }, + "draw_matched_fixation_positions": { + "position_color": (0, 255, 255), + "line_color": (0, 0, 0) + }, + "draw_matched_region": { + "color": (0, 255, 0), + "border_size": 4 + }, + "draw_looked_aoi": { + "color": (0, 255, 0), + "border_size": 2 + }, + "looked_aoi_name_color": (255, 255, 255), + "looked_aoi_name_offset": (0, -10) + } } class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): @@ -478,23 +479,23 @@ class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): # Define default ArFrame image parameters DEFAULT_ARFRAME_IMAGE_PARAMETERS = { - "background_weight": 1., - "heatmap_weight": 0.5, - "draw_scan_path": { - "draw_fixations": { - "deviation_circle_color": (255, 255, 255), - "duration_border_color": (127, 127, 127), - "duration_factor": 1e-2 - }, - "draw_saccades": { - "line_color": (255, 255, 255) - }, - "deepness": 0 - }, - "draw_gaze_positions": { - "color": (0, 255, 255), - "size": 2 - } + "background_weight": 1., + "heatmap_weight": 0.5, + "draw_scan_path": { + "draw_fixations": { + "deviation_circle_color": (255, 255, 255), + "duration_border_color": (127, 127, 127), + "duration_factor": 1e-2 + }, + "draw_saccades": { + "line_color": (255, 255, 255) + }, + "deepness": 0 + }, + "draw_gaze_positions": { + "color": (0, 255, 255), + "size": 2 + } } class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): @@ -505,11 +506,12 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): Inherits from DataFeatures.SharedObject class to be shared by multiple threads """ - def __init__(self, size: tuple[int] = (1, 1), gaze_position_calibrator: GazeFeatures.GazePositionCalibrator = None, gaze_movement_identifier: GazeFeatures.GazeMovementIdentifier = None, filter_in_progress_identification: bool = True, scan_path: GazeFeatures.ScanPath = None, scan_path_analyzers: dict = None, background: numpy.array = numpy.array([]), heatmap: AOIFeatures.Heatmap = None, layers: dict = None, image_parameters: dict = DEFAULT_ARFRAME_IMAGE_PARAMETERS, **kwargs): + def __init__(self, size: tuple[int] = (1, 1), provider: DataFeatures.PipelineInputProvider = None, gaze_position_calibrator: GazeFeatures.GazePositionCalibrator = None, gaze_movement_identifier: GazeFeatures.GazeMovementIdentifier = None, filter_in_progress_identification: bool = True, scan_path: GazeFeatures.ScanPath = None, scan_path_analyzers: dict = None, background: numpy.array = numpy.array([]), heatmap: AOIFeatures.Heatmap = None, layers: dict = None, image_parameters: dict = DEFAULT_ARFRAME_IMAGE_PARAMETERS, **kwargs): """ Initialize ArFrame Parameters: size: defines the dimension of the rectangular area where gaze positions are projected + provider: provider object related to this frame gaze_position_calibrator: gaze position calibration algoritm gaze_movement_identifier: gaze movement identification algorithm filter_in_progress_identification: ignore in progress gaze movement identification @@ -527,6 +529,7 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): # Init private attributes self.__size = size + self.__provider = provider self.__gaze_position_calibrator = gaze_position_calibrator self.__gaze_movement_identifier = gaze_movement_identifier self.__filter_in_progress_identification = filter_in_progress_identification @@ -542,6 +545,10 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): self.__scan_path_analyzed = False # Edit pipeline step objects parent + if self.__provider is not None: + + self.__provider.parent = self + if self.__gaze_position_calibrator is not None: self.__gaze_position_calibrator.parent = self @@ -570,6 +577,11 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): def size(self) -> tuple[int]: """Get frame's size.""" return self.__size + + @property + def provider(self) -> DataFeatures.PipelineInputProvider: + """Get frame's provider.""" + return self.__provider @property def gaze_position_calibrator(self) -> GazeFeatures.GazePositionCalibrator: @@ -649,11 +661,12 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): """Export ArFrame attributes as dictionary. Returns: - frame_data: dictionary with frame attributes values. + frame_data: dictionary with frame attributes values. """ d = { **DataFeatures.PipelineStepObject.as_dict(self), "size": self.__size, + "provider": self.__provider, "gaze_position_calibrator": self.__gaze_position_calibrator, "gaze_movement_identifier": self.__gaze_movement_identifier, "filter_in_progress_identification": self.__filter_in_progress_identification, @@ -690,6 +703,38 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): new_frame_size = (0, 0) + # Load provider + try: + + provider_value = frame_data.pop('provider') + + # str: relative path to file + if type(provider_value) == str: + + filepath = os.path.join(working_directory, provider_value) + file_format = filepath.split('.')[-1] + + # JSON file format + if file_format == 'json': + + with open(filepath) as file: + + provider_value = json.load(file) + + # Create gaze position calibrator + provider_module_path, provider_parameters = provider_value.popitem() + + # Prepend argaze.utils.Providers path when a single name is provided + if len(provider_module_path.split('.')) == 1: + provider_module_path = f'argaze.utils.Providers.{provider_module_path}' + + provider_module = importlib.import_module(provider_module_path) + new_provider = provider_module.Provider(**provider_parameters) + + except KeyError: + + new_provider = None + # Load gaze position calibrator try: @@ -708,17 +753,12 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): gaze_movement_calibrator_value = json.load(file) - # dict: - else: - - gaze_movement_calibrator_value = frame_data.pop('gaze_movement_identifier') - # Create gaze position calibrator gaze_position_calibrator_module_path, gaze_position_calibrator_parameters = gaze_movement_calibrator_value.popitem() # Prepend argaze.GazeAnalysis path when a single name is provided if len(gaze_position_calibrator_module_path.split('.')) == 1: - gaze_position_calibrator_module_path = f'argaze.GazeAnalysis.{gaze_position_calibrator_module_path}' + gaze_position_calibrator_module_path = f'argaze.GazeAnalysis.{gaze_position_calibrator_module_path}' gaze_position_calibrator_module = importlib.import_module(gaze_position_calibrator_module_path) new_gaze_position_calibrator = gaze_position_calibrator_module.GazePositionCalibrator(**gaze_position_calibrator_parameters) @@ -877,6 +917,7 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): # Create frame return ArFrame( \ new_frame_size, \ + new_provider, \ new_gaze_position_calibrator, \ new_gaze_movement_identifier, \ filter_in_progress_identification, \ @@ -1444,7 +1485,7 @@ class ArCamera(ArFrame): Parameters: image: image where to extract AR features - """ + """ raise NotImplementedError('watch() method not implemented') -- cgit v1.1