Source code for nav.annotation.annotation

from nav.config import DEFAULT_CONFIG, Config
from nav.obs import ObsSnapshot
from nav.support.image import shift_array
from nav.support.types import NDArrayBoolType

from .annotation_text_info import AnnotationTextInfo


[docs] class Annotation: """Represents an annotation for an observation image. This class handles overlays and text annotations to be displayed on observation images. Parameters: obs: The observation snapshot to annotate overlay: Boolean mask indicating where the overlay should appear overlay_color: RGB color tuple for the overlay thicken_overlay: Number of pixels to thicken the overlay by text_info: Text annotation information avoid_mask: Boolean mask indicating areas where text should not be placed config: Configuration object """ def __init__( self, obs: ObsSnapshot, overlay: NDArrayBoolType, overlay_color: tuple[int, int, int], *, thicken_overlay: int = 0, text_info: AnnotationTextInfo | list[AnnotationTextInfo] | tuple[AnnotationTextInfo, ...] | None = None, avoid_mask: NDArrayBoolType | None = None, config: Config | None = None, ) -> None: self._config = config or DEFAULT_CONFIG self._obs = obs self._overlay = overlay self._overlay_color = overlay_color self._avoid_mask = avoid_mask if thicken_overlay > 0: for u_offset in range(-thicken_overlay, thicken_overlay + 1): for v_offset in range(-thicken_overlay, thicken_overlay + 1): if u_offset == 0 and v_offset == 0: continue self._overlay = self._overlay | shift_array(overlay, (v_offset, u_offset)) if text_info is not None: if isinstance(text_info, (list, tuple)): self._text_info: list[AnnotationTextInfo] = list(text_info) else: self._text_info = [text_info] else: self._text_info = [] if overlay.shape != obs.extdata_shape_vu: raise ValueError( f'Annotation overlay shape ({overlay.shape}) does not agree with Obs ' f'shape ({obs.extdata_shape_vu})' ) @property def config(self) -> Config: """Returns the configuration object for this annotation.""" return self._config @property def obs(self) -> ObsSnapshot: """Returns the observation snapshot associated with this annotation.""" return self._obs @property def overlay(self) -> NDArrayBoolType: """Returns the boolean mask representing the overlay area.""" return self._overlay @property def overlay_color(self) -> tuple[int, int, int]: """Returns the RGB color tuple for the overlay.""" return self._overlay_color @property def avoid_mask(self) -> NDArrayBoolType | None: """Returns the mask indicating areas where text should not be placed, if any.""" return self._avoid_mask @property def text_info_list(self) -> list[AnnotationTextInfo]: """Returns the list of text annotation information objects.""" return self._text_info
[docs] def add_text_info( self, text_info: (AnnotationTextInfo | list[AnnotationTextInfo] | tuple[AnnotationTextInfo, ...]), ) -> None: """Adds text annotation information to this annotation. Parameters: text_info: One or more text annotation information objects to add """ if not isinstance(text_info, (list, tuple)): text_info = [text_info] self._text_info.extend(text_info)