From 2b64a79dbc676d531004b4a2d70d6076957f4f4c Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Tue, 5 Sep 2023 08:01:48 +0200 Subject: Fixng AR pipeline with new architecture. --- src/argaze/ArFeatures.py | 79 +++++++++++++++++----------------- src/argaze/ArUcoMarkers/ArUcoCamera.py | 33 ++++++++------ 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index b7ac48c..f40377b 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -1003,7 +1003,7 @@ class ArFrame(): # Return look data return identified_gaze_movement, scan_step_analysis, layer_analysis, execution_times, exception - def image(self, background_weight: float = None, heatmap_weight: float = None, draw_scan_path: dict = None, draw_layers: dict = None, draw_gaze_position: dict = None) -> numpy.array: + def __image(self, background_weight: float = None, heatmap_weight: float = None, draw_scan_path: dict = None, draw_layers: dict = None, draw_gaze_position: dict = None) -> numpy.array: """ Get background image with overlaid visualisations. @@ -1015,19 +1015,6 @@ class ArFrame(): draw_gaze_position: [GazeFeatures.GazePosition.draw](argaze.md/#argaze.GazeFeatures.GazePosition.draw) parameters (if None, no gaze position is drawn) """ - print('type', type(self)) - - print('ArFrame.image 1') - - # Use image_parameters attribute if no parameters - if background_weight is None and heatmap_weight is None and draw_scan_path is None and draw_layers is None and draw_gaze_position is None: - - print('ArFrame.image 2') - - return self.image(**self.image_parameters) - - print('ArFrame.image 3') - # Lock frame exploitation self.__look_lock.acquire() @@ -1073,10 +1060,23 @@ class ArFrame(): # Unlock frame exploitation self.__look_lock.release() - print('ArFrame.image', image.shape) - return image + def image(self, **kwargs) -> numpy.array: + """ + Get frame image. + + Parameters: + kwargs: ArFrame.__image parameters + """ + + # Use image_parameters attribute if no kwargs + if kwargs: + + return self.__image(**kwargs) + + return self.__image(**self.image_parameters) + @dataclass class ArScene(): """ @@ -1403,16 +1403,16 @@ class ArCamera(ArFrame): raise NotImplementedError('from_json() method not implemented') @property - def frames(self): - """Iterate over all camera scenes frames""" + def scene_frames(self): + """Iterate over all scenes frames""" # For each scene for scene_name, scene in self.scenes.items(): - # For each frame - for name, frame in scene.frames.items(): + # For each scene frame + for name, scene_frame in scene.frames.items(): - yield frame + yield scene_frame def detect_and_project(self, image: numpy.array) -> Tuple[float, dict]: """Detect AR features from image and project scenes into camera frame.""" @@ -1432,23 +1432,23 @@ class ArCamera(ArFrame): # PB: This would imply to also store frame projections !!! self.ignored_gaze_positions[timestamp] = gaze_position - return + return None, None # Lock camera frame exploitation self._frame_lock.acquire() # Project gaze position into camera frame - yield self, self.look(timestamp, gaze_position) + yield self, super().look(timestamp, gaze_position) # Project gaze position into each scene frames if possible - for frame in self.frames: + for scene_frame in self.scene_frames: - # Is there an AOI inside camera frame layers projection which its name equals to a frame name? - for camera_layer_name, camera_layer in self.camera_frame.layers.items(): + # Is there an AOI inside camera frame layers projection which its name equals to a scene frame name? + for camera_layer_name, camera_layer in self.layers.items(): try: - aoi_2d = camera_layer.aoi_scene[frame.name] + aoi_2d = camera_layer.aoi_scene[scene_frame.name] # TODO?: Should we prefer to use camera frame AOIMatcher object? if aoi_2d.contains_point(gaze_position.value): @@ -1458,7 +1458,7 @@ class ArCamera(ArFrame): # QUESTION: How to project gaze precision? inner_gaze_position = GazeFeatures.GazePosition((inner_x, inner_y)) - yield frame, frame.look(timestamp, inner_gaze_position * frame.size) + yield scene_frame, scene_frame.look(timestamp, inner_gaze_position * scene_frame.size) # Ignore missing aoi in camera frame layer projection except KeyError: @@ -1469,7 +1469,7 @@ class ArCamera(ArFrame): self._frame_lock.release() def map(self): - """Project camera frame background into frames background. + """Project camera frame background into scene frames background. .. warning:: detect_and_project method needs to be called first. """ @@ -1481,11 +1481,11 @@ class ArCamera(ArFrame): # Lock camera frame exploitation self._frame_lock.acquire() - # Project image into each frame if possible - for frame in self.frames: + # Project camera frame background into each scene frame if possible + for frame in self.scene_frames: - # Is there an AOI inside camera frame layers projection which its name equals to a frame name? - for camera_layer_name, camera_layer in self.camera_frame.layers.items(): + # Is there an AOI inside camera frame layers projection which its name equals to a scene frame name? + for camera_layer_name, camera_layer in self.layers.items(): try: @@ -1495,7 +1495,7 @@ class ArCamera(ArFrame): width, height = frame.size destination = numpy.float32([[0, height],[width, height],[width, 0],[0, 0]]) mapping = cv2.getPerspectiveTransform(aoi_2d.astype(numpy.float32), destination) - frame.background = cv2.warpPerspective(self.camera_frame.background, mapping, (width, height)) + frame.background = cv2.warpPerspective(self.background, mapping, (width, height)) # Ignore missing frame projection except KeyError: @@ -1505,14 +1505,15 @@ class ArCamera(ArFrame): # Unlock camera frame exploitation self._frame_lock.release() - def image(self, **frame_image_parameters) -> numpy.array: - """ - Get camera frame image. + def image(self, **kwargs) -> numpy.array: """ + Get frame image. - print('ArCamera.image') + Parameters: + kwargs: ArFrame.image parameters + """ - return super().image(**frame_image_parameters) + return super().image(**kwargs) def to_json(self, json_filepath): """Save camera to .json file.""" diff --git a/src/argaze/ArUcoMarkers/ArUcoCamera.py b/src/argaze/ArUcoMarkers/ArUcoCamera.py index 453c18b..6479896 100644 --- a/src/argaze/ArUcoMarkers/ArUcoCamera.py +++ b/src/argaze/ArUcoMarkers/ArUcoCamera.py @@ -192,7 +192,7 @@ class ArUcoCamera(ArFeatures.ArCamera): try: # Build AOI scene directly from detected ArUco marker corners - self.camera_frame.aoi_2d_scene |= scene.build_aruco_aoi_scene(self.aruco_detector.detected_markers) + self.layers[??].aoi_2d_scene |= scene.build_aruco_aoi_scene(self.aruco_detector.detected_markers) except SceneProjectionFailed: @@ -212,7 +212,7 @@ class ArUcoCamera(ArFeatures.ArCamera): try: - self.camera_frame.layers[layer_name].aoi_scene |= layer_projection + self.layers[layer_name].aoi_scene |= layer_projection except KeyError: @@ -229,16 +229,14 @@ class ArUcoCamera(ArFeatures.ArCamera): # Return dection time and exceptions return detection_time, exceptions - def image(self, draw_detected_markers: dict = None, **frame_image_parameters): - """Get camera frame projections with ArUco detection visualisation. + def __image(self, draw_detected_markers: dict = None, **kwargs) -> numpy.array: + """Get frame image with ArUco detection visualisation. Parameters: draw_detected_markers: ArucoMarker.draw parameters (if None, no marker drawn) - draw_frame: draw ArFrame image + kwargs: ArCamera.image parameters """ - print('ArUcoCamera.image 1') - # Can't use camera frame when it is locked if self._frame_lock.locked(): return @@ -246,12 +244,8 @@ class ArUcoCamera(ArFeatures.ArCamera): # Lock camera frame exploitation self._frame_lock.acquire() - print('ArUcoCamera.image 2') - # Get camera frame image - image = super().image(**frame_image_parameters) - - print('ArUcoCamera.image 3') + image = super().image(**kwargs) # Draw detected markers if required if draw_detected_markers is not None: @@ -262,3 +256,18 @@ class ArUcoCamera(ArFeatures.ArCamera): self._frame_lock.release() return image + + def image(self, **kwargs) -> numpy.array: + """ + Get frame image. + + Parameters: + kwargs: ArUcoCamera.__image parameters + """ + + # Use image_parameters attribute if no kwargs + if kwargs: + + return self.__image(**kwargs) + + return self.__image(**self.image_parameters) -- cgit v1.1