From e302f47406c4730a71799c2b0df17bae1f1973f3 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Fri, 26 Jan 2024 12:14:03 +0100 Subject: Fixing demo script. --- src/argaze/ArFeatures.py | 30 ++++++++++++--------- src/argaze/ArUcoMarkers/ArUcoCamera.py | 13 ++++++++- src/argaze/ArUcoMarkers/ArUcoScene.py | 6 +++++ src/argaze/AreaOfInterest/AOIFeatures.py | 24 ++++++++++++++++- src/argaze/DataFeatures.py | 12 +++++++++ src/argaze/utils/demo_aruco_markers_run.py | 5 ++++ .../utils/demo_data/demo_aruco_markers_setup.json | 31 +++++++++++++++++++--- src/argaze/utils/demo_data/demo_layer_logger.py | 2 -- src/argaze/utils/demo_data/frame_logger.py | 4 --- 9 files changed, 104 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index 1c2de8e..758e702 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -136,14 +136,16 @@ class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): self.__aoi_scene = AOI3DScene.AOI3DScene(self.__aoi_scene) - # Edit expected AOI list by removing AOI with name equals to layer name - expected_aoi = list(self.__aoi_scene.keys()) + # Edit aoi_scan_path's expected aoi list by removing aoi with name equals to layer name + if self.__aoi_scan_path is not None: + + expected_aoi = list(self.__aoi_scene.keys()) - if self.name in expected_aoi: + if self.name in expected_aoi: - expected_aoi.remove(self.name) + expected_aoi.remove(self.name) - self.__aoi_scan_path.expected_aoi = expected_aoi + self.__aoi_scan_path.expected_aoi = expected_aoi # Edit pipeline step objects parent if self.__aoi_scene is not None: @@ -220,7 +222,7 @@ class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): """Export ArLayer attributes as dictionary.""" return { - **DataFeatures.PipelineStepObject.as_dict(), + **DataFeatures.PipelineStepObject.as_dict(self), "aoi_scene": self.__aoi_scene, "aoi_matcher": self.__aoi_matcher, "aoi_scan_path": self.__aoi_scan_path, @@ -665,7 +667,7 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): frame_data: dictionary with frame attributes values. """ d = { - **DataFeatures.PipelineStepObject.as_dict(), + **DataFeatures.PipelineStepObject.as_dict(self), "size": self.__size, "gaze_position_calibrator": self.__gaze_position_calibrator, "gaze_movement_identifier": self.__gaze_movement_identifier, @@ -678,8 +680,6 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): "image_parameters": self.__image_parameters } - print('ArFrame.as_dict', DataFeatures.PipelineStepObject.as_dict()) - return d @classmethod @@ -1097,6 +1097,9 @@ class ArScene(DataFeatures.PipelineStepObject): distance_tolerance: Optional distance error tolerance to validate marker pose in centimeter used into [estimate_pose][argaze.ArFeatures.ArScene.estimate_pose] function. """ + # DEBUG + print('ArScene.__init__', kwargs) + # Init parent classes super().__init__(**kwargs) @@ -1149,7 +1152,7 @@ class ArScene(DataFeatures.PipelineStepObject): """Export ArScene attributes as dictionary.""" return { - **DataFeatures.PipelineStepObject.as_dict(), + **DataFeatures.PipelineStepObject.as_dict(self), "layers": self.__layers, "frames": self.__frames, "angle_tolerance": self.__angle_tolerance, @@ -1325,7 +1328,7 @@ class ArScene(DataFeatures.PipelineStepObject): aoi_scene_copy = layer.aoi_scene.copy() # Project layer aoi scene - yield name, aoi_scene_copy.project(tvec, rvec, self.__parent.aruco_detector.optic_parameters.K) + yield name, aoi_scene_copy.project(tvec, rvec, self.parent.aruco_detector.optic_parameters.K) def draw(self, image: numpy.array, **kwargs: dict): """ @@ -1351,6 +1354,9 @@ class ArCamera(ArFrame): visual_vfov: Optional angle in degree to clip scenes projection according visual vertical field of view (VFOV). """ + # DEBUG + print('ArCamera.__init__', kwargs) + # Init parent class super().__init__(**kwargs) @@ -1443,7 +1449,7 @@ class ArCamera(ArFrame): """Export ArCamera attributes as dictionary.""" return { - **ArFrame.as_dict(), + **ArFrame.as_dict(self), "scenes": self.__scenes, "visual_hfov": self.__visual_hfov, "visual_vfov": self.__visual_vfov diff --git a/src/argaze/ArUcoMarkers/ArUcoCamera.py b/src/argaze/ArUcoMarkers/ArUcoCamera.py index f1ad6f2..7ba0c0e 100644 --- a/src/argaze/ArUcoMarkers/ArUcoCamera.py +++ b/src/argaze/ArUcoMarkers/ArUcoCamera.py @@ -44,6 +44,9 @@ class ArUcoCamera(ArFeatures.ArCamera): aruco_detector: ArUco marker detector """ + # DEBUG + print('ArUcoCamera.__init__', kwargs) + # Init parent class super().__init__(**kwargs) @@ -65,6 +68,11 @@ class ArUcoCamera(ArFeatures.ArCamera): # Note: The choice of 1000 for default focal length should be discussed... self.__aruco_detector.optic_parameters = ArUcoOpticCalibrator.OpticParameters(rms=-1, dimensions=self.size, K=ArUcoOpticCalibrator.K0(focal_length=(1000., 1000.), width=self.size[0], height=self.size[1])) + # Edit pipeline step objects parent + if self.__aruco_detector is not None: + + self.__aruco_detector.parent = self + @property def aruco_detector(self) -> ArUcoDetector.ArUcoDetector: """Get ArUco detector object.""" @@ -119,6 +127,9 @@ class ArUcoCamera(ArFeatures.ArCamera): # Load temporary frame from aruco_camera_data then export it as dict temp_frame_data = ArFeatures.ArFrame.from_dict(aruco_camera_data, working_directory).as_dict() + # DEBUG + print('ArUcoCamera.from_dict', temp_frame_data) + # Create new aruco camera using temporary ar frame values return ArUcoCamera( \ aruco_detector = new_aruco_detector, \ @@ -162,7 +173,7 @@ class ArUcoCamera(ArFeatures.ArCamera): # Clear former layers projection into camera frame for layer_name, layer in self.layers.items(): - layer.aoi_scene = AOI2DScene.AOI2DScene() + layer.aoi_scene.clear() # Project each aoi 3d scene into camera frame for scene_name, scene in self.scenes.items(): diff --git a/src/argaze/ArUcoMarkers/ArUcoScene.py b/src/argaze/ArUcoMarkers/ArUcoScene.py index b8817b3..e206fc7 100644 --- a/src/argaze/ArUcoMarkers/ArUcoScene.py +++ b/src/argaze/ArUcoMarkers/ArUcoScene.py @@ -33,6 +33,9 @@ class ArUcoScene(ArFeatures.ArScene): aruco_markers_group: ArUco markers 3D scene description used to estimate scene pose from detected markers: see [estimate_pose][argaze.ArFeatures.ArScene.estimate_pose] function below. """ + # DEBUG + print('ArUcoScene.__init__', kwargs) + # Init parent classes super().__init__(**kwargs) @@ -88,6 +91,9 @@ class ArUcoScene(ArFeatures.ArScene): # Load temporary scene from aruco_scene_data then export it as dict temp_scene_data = ArFeatures.ArScene.from_dict(aruco_scene_data, working_directory).as_dict() + # DEBUG + print('ArUcoScene.from_dict', temp_scene_data) + # Create new aruco scene using temporary ar scene values return ArUcoScene( \ aruco_markers_group = new_aruco_markers_group, \ diff --git a/src/argaze/AreaOfInterest/AOIFeatures.py b/src/argaze/AreaOfInterest/AOIFeatures.py index ff33a29..d97cda6 100644 --- a/src/argaze/AreaOfInterest/AOIFeatures.py +++ b/src/argaze/AreaOfInterest/AOIFeatures.py @@ -20,6 +20,7 @@ import matplotlib.path as mpath import numpy from shapely.geometry import Polygon from shapely.geometry.point import Point +from colorama import Style, Fore AreaOfInterestType = TypeVar('AreaOfInterest', bound="AreaOfInterest") # Type definition for type annotation convenience @@ -268,7 +269,7 @@ class AreaOfInterest(numpy.ndarray): AOISceneType = TypeVar('AOIScene', bound="AOIScene") # Type definition for type annotation convenience -class AOIScene(DataFeatures.PipelineStepObject): +class AOIScene(): """Define AOI scene as a dictionary of AOI.""" def __init__(self, dimension: int, areas: dict = None): @@ -531,6 +532,27 @@ class AOIScene(DataFeatures.PipelineStepObject): return scene_copy + def clear(self): + """Clear scene.""" + + self.__areas.clear() + + def __str__(self) -> str: + """ + String representation of pipeline step object. + + Returns: + String representation + """ + + output = '' + + for name, area in self.__areas.items(): + + output += f'{Fore.BLUE}{Style.BRIGHT}{name}{Style.RESET_ALL} ' + + return output + class TimeStampedAOIScenes(DataFeatures.TimeStampedBuffer): """Define timestamped buffer to store AOI scenes in time.""" diff --git a/src/argaze/DataFeatures.py b/src/argaze/DataFeatures.py index 3200190..fdd5720 100644 --- a/src/argaze/DataFeatures.py +++ b/src/argaze/DataFeatures.py @@ -597,6 +597,18 @@ class PipelineStepObject(): if isinstance(item, property): yield name, getattr(self, name) + + for base in self.__class__.__bases__: + + if base != PipelineStepObject and base != SharedObject: + + print(base) + + for name, item in base.__dict__.items(): + + if isinstance(item, property): + + yield name, getattr(self, name) def PipelineStepAttribute(method): diff --git a/src/argaze/utils/demo_aruco_markers_run.py b/src/argaze/utils/demo_aruco_markers_run.py index a5b02f0..1de2b98 100644 --- a/src/argaze/utils/demo_aruco_markers_run.py +++ b/src/argaze/utils/demo_aruco_markers_run.py @@ -24,6 +24,7 @@ current_directory = os.path.dirname(os.path.abspath(__file__)) parser = argparse.ArgumentParser(description=__doc__.split('-')[0]) parser.add_argument('configuration', metavar='CONFIGURATION', type=str, help='configuration filepath') parser.add_argument('-s', '--source', metavar='SOURCE', type=str, default='0', help='video capture source (a number to select camera device or a filepath to load a movie)') +parser.add_argument('-v', '--verbose', action='store_true', default=False, help='enable verbose mode to print information in console') args = parser.parse_args() def main(): @@ -31,6 +32,10 @@ def main(): # Load ArUcoCamera aruco_camera = ArUcoCamera.ArUcoCamera.from_json(args.configuration) + if args.verbose: + + print(aruco_camera) + # Create a window to display ArUcoCamera cv2.namedWindow(aruco_camera.name, cv2.WINDOW_AUTOSIZE) diff --git a/src/argaze/utils/demo_data/demo_aruco_markers_setup.json b/src/argaze/utils/demo_data/demo_aruco_markers_setup.json index 52de261..8e3c5ea 100644 --- a/src/argaze/utils/demo_data/demo_aruco_markers_setup.json +++ b/src/argaze/utils/demo_data/demo_aruco_markers_setup.json @@ -34,7 +34,7 @@ } }, "draw_scenes": { - "ArScene Demo": { + "demo_scene": { "draw_aruco_markers_group": { "draw_axes": { "thickness": 3, @@ -45,7 +45,7 @@ } }, "scenes": { - "ArScene Demo" : { + "demo_scene" : { "aruco_markers_group": "aruco_markers_group.json", "layers": { "demo_layer" : { @@ -65,12 +65,37 @@ "scan_path": { "duration_max": 10000 }, + "scan_path_analyzers": { + "Basic": {}, + "KCoefficient": {}, + "NearestNeighborIndex": { + "size": [1920, 1149] + }, + "ExploreExploitRatio": { + "short_fixation_duration_threshold": 0 + } + }, "layers": { "demo_layer": { "aoi_scene": "aoi_2d_scene.json", "aoi_matcher": { "FocusPointInside": {} - } + }, + "aoi_scan_path": { + "duration_max": 30000 + }, + "aoi_scan_path_analyzers": { + "Basic": {}, + "TransitionMatrix": {}, + "KCoefficient": {}, + "LempelZivComplexity": {}, + "NGram": { + "n_min": 3, + "n_max": 3 + }, + "Entropy":{} + }, + "observers": "demo_layer_logger.py" } }, "image_parameters": { diff --git a/src/argaze/utils/demo_data/demo_layer_logger.py b/src/argaze/utils/demo_data/demo_layer_logger.py index eba7c74..8f69b02 100644 --- a/src/argaze/utils/demo_data/demo_layer_logger.py +++ b/src/argaze/utils/demo_data/demo_layer_logger.py @@ -18,8 +18,6 @@ class AOIScanPathAnalysisLogger(DataFeatures.PipelineStepObserver, UtilsFeatures def on_look(self, timestamp, layer): """Log aoi scan path metrics""" - #print(timestamp, "AOIScanPathAnalysisLogger.on_look:", type(self), type(layer)) - if layer.aoi_scan_path_analyzed: log = ( diff --git a/src/argaze/utils/demo_data/frame_logger.py b/src/argaze/utils/demo_data/frame_logger.py index 256be7f..a633b84 100644 --- a/src/argaze/utils/demo_data/frame_logger.py +++ b/src/argaze/utils/demo_data/frame_logger.py @@ -15,8 +15,6 @@ class FixationLogger(DataFeatures.PipelineStepObserver, UtilsFeatures.FileWriter def on_look(self, timestamp, frame): """Log fixations""" - #print(timestamp, "FixationLogger.on_look:", type(self), type(frame)) - # Log fixations if GazeFeatures.is_fixation(frame.gaze_movement) and frame.gaze_movement.finished: @@ -34,8 +32,6 @@ class ScanPathAnalysisLogger(DataFeatures.PipelineStepObserver, UtilsFeatures.Fi def on_look(self, timestamp, frame): """Log scan path metrics""" - #print(timestamp, "ScanPathAnalysisLogger.on_look:", type(self), type(frame)) - if frame.scan_path_analyzed: log = ( -- cgit v1.1