aboutsummaryrefslogtreecommitdiff
path: root/src/argaze/ArFeatures.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/argaze/ArFeatures.py')
-rw-r--r--src/argaze/ArFeatures.py90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py
index 4aedb2b..3101a45 100644
--- a/src/argaze/ArFeatures.py
+++ b/src/argaze/ArFeatures.py
@@ -24,6 +24,9 @@ ArEnvironmentType = TypeVar('ArEnvironment', bound="ArEnvironment")
ArSceneType = TypeVar('ArScene', bound="ArScene")
# Type definition for type annotation convenience
+ArScreenType = TypeVar('ArScreen', bound="ArScreen")
+# Type definition for type annotation convenience
+
@dataclass
class ArEnvironment():
"""
@@ -95,6 +98,7 @@ class ArEnvironment():
new_aruco_detector = ArUcoDetector.ArUcoDetector(new_aruco_dictionary, new_marker_size, new_optic_parameters, new_aruco_detector_parameters)
+ # Build scenes
new_scenes = {}
for scene_name, scene_data in data.pop('scenes').items():
@@ -129,7 +133,17 @@ class ArEnvironment():
new_aoi_scene = AOI3DScene.AOI3DScene(aoi_scene_value)
- new_scenes[scene_name] = ArScene(new_aruco_scene, new_aoi_scene, **scene_data)
+ # Build screens
+ new_screens = {}
+ for screen_name, screen_data in scene_data.pop('screens').items():
+
+ new_screen_size = screen_data.pop('size')
+
+ # Append new screen
+ new_screens[screen_name] = ArScreen.from_scene(new_aoi_scene, screen_name, new_screen_size)
+
+ # Append new scene
+ new_scenes[scene_name] = ArScene(new_aruco_scene, new_aoi_scene, new_screens, **scene_data)
return ArEnvironment(new_name, new_aruco_detector, new_scenes)
@@ -184,6 +198,8 @@ class ArScene():
aoi_scene: AOI 3D scene description that will be projected onto estimated scene once its pose will be estimated : see [project][argaze.ArFeatures.ArScene.project] function below.
+ screens: All scene screens
+
aruco_axis: Optional dictionary to define orthogonal axis where each axis is defined by list of 3 markers identifier (first is origin). \
This pose estimation strategy is used by [estimate_pose][argaze.ArFeatures.ArScene.estimate_pose] function when at least 3 markers are detected.
@@ -196,6 +212,7 @@ class ArScene():
aruco_scene: ArUcoScene.ArUcoScene = field(default_factory=ArUcoScene.ArUcoScene)
aoi_scene: AOI3DScene.AOI3DScene = field(default_factory=AOI3DScene.AOI3DScene)
+ screens: dict = field(default_factory=dict)
aruco_axis: dict = field(default_factory=dict)
aruco_aoi: dict = field(default_factory=dict)
angle_tolerance: float = field(default=0.)
@@ -207,7 +224,11 @@ class ArScene():
self._environment = None
# Preprocess orthogonal projection to speed up further aruco aoi processings
- self.__orthogonal_projection_cache = self.orthogonal_projection
+ self.__orthogonal_projection_cache = self.aoi_scene.orthogonal_projection
+
+ # Setup screens scene after screen creation
+ for name, screen in self.screens.items():
+ screen._scene = self
def __str__(self) -> str:
"""
@@ -221,27 +242,6 @@ class ArScene():
return output
- @property
- def orthogonal_projection(self) -> AOI2DScene.AOI2DScene:
- """
- Orthogonal projection of whole AOI scene.
-
- Returns:
- projected AOI 2D scene
- """
-
- scene_size = self.aoi_scene.size
- scene_center = self.aoi_scene.center
-
- # Center, step back and rotate pose to get whole scene into field of view
- tvec = scene_center*[-1, 1, 0] + [0, 0, scene_size[1]]
- rvec = numpy.array([[-numpy.pi, 0.0, 0.0]])
-
- # Edit optic intrinsic parameter to capture whole scene
- K = numpy.array([[scene_size[1]/scene_size[0], 0.0, 0.5], [0.0, 1., 0.5], [0.0, 0.0, 1.0]])
-
- return self.aoi_scene.project(tvec, rvec, K)
-
def estimate_pose(self, detected_markers) -> Tuple[numpy.array, numpy.array, str, dict]:
"""Estimate scene pose from detected ArUco markers.
@@ -405,4 +405,46 @@ class ArScene():
self.aruco_scene.draw_places(image, self._environment.aruco_detector.optic_parameters.K, self._environment.aruco_detector.optic_parameters.D)
-
+@dataclass
+class ArScreen():
+ """
+ Define Augmented Reality screen as an AOI2DScene made from a projected then reframed parent AOI3DScene.
+
+ Parameters:
+ name: name of the screen
+ size: screen dimension in pixel.
+ aoi_screen: AOI 2D scene description ... : see [orthogonal_projection][argaze.ArFeatures.ArScene.orthogonal_projection] and [reframe][argaze.AreaOfInterest.AOI2DScene.reframe] functions.
+ """
+
+ name: str
+ size: tuple[int] = field(default=(1, 1))
+ aoi_screen: AOI2DScene.AOI2DScene = field(default_factory=AOI2DScene.AOI2DScene)
+
+ def __post_init__(self):
+
+ # Define scene attribute: it will be setup by parent scene later
+ self._scene = None
+
+ # Init screen
+ self.init()
+
+ @classmethod
+ def from_scene(self, aoi_scene, aoi_name, size) -> ArScreenType:
+
+ return ArScreen(aoi_name, size, aoi_scene.orthogonal_projection.reframe(aoi_name, size))
+
+ @property
+ def image(self):
+ """Get screen image."""
+
+ return self.__image
+
+ def init(self) -> ArScreenType:
+ """Initialize screen image."""
+
+ self.__image = numpy.zeros((self.size[1], self.size[0], 3)).astype(numpy.uint8)
+
+ def draw_aoi(self, color=(255, 255, 255)) -> ArScreenType:
+ """Draw aoi into screen image."""
+
+ self.aoi_screen.draw(self.__image, color)