Source code for phenotypic.core._image

from __future__ import annotations

from typing import Literal, TYPE_CHECKING

import colour
import numpy as np

if TYPE_CHECKING:
    from phenotypic import Image

from ._image_parts._image_io_handler import ImageIOHandler


[docs] class Image(ImageIOHandler): """Comprehensive image processing class with integrated data, color, and I/O management. The `Image` class is the primary interface for image processing, analysis, and manipulation within the PhenoTypic framework. It combines: - Data management (image arrays, enhanced versions, object maps) - Color space handling (RGB, grayscale, HSV, XYZ, Lab with color corrections) - Object detection and analysis (object masks, labels, measurements) - File I/O and metadata management (loading, saving, metadata extraction) - Image manipulation (rotation, slicing, copying, visualization) Image data can be provided as: - NumPy arrays (2-D grayscale or 3-D RGB/RGBA) - Another Image instance (copies all data) - Loaded from file via imread() The class automatically manages format conversions and maintains internal consistency across multiple data representations. RGB and grayscale forms are kept synchronized, and additional representations (enhanced grayscale, object maps) support analysis workflows. Notes: - 2-D input arrays are treated as grayscale; rgb form remains empty. - 3-D input arrays are treated as RGB; grayscale is computed automatically. - Color space properties (gamma_encoding, illuminant, _observer) are inherited. - Object detection and measurements require an ObjectDetector first. - HSV color space support added in v0.5.0. Examples: .. dropdown:: Create from array .. code-block:: python import numpy as np from phenotypic import Image arr = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8) img = Image(arr, name='sample') img.show() .. dropdown:: Load from file .. code-block:: python img = Image.imread('photo.jpg') print(img.shape) # Image dimensions img.save2pickle('saved.pkl') """
[docs] def __init__( self, arr: np.ndarray | Image | None = None, name: str | None = None, bit_depth: Literal[8, 16] | None = None, gamma_encoding: str | None = "sRGB", illuminant: str | None = "D65", ): """Initialize an Image instance with optional image data and color properties. Creates a new Image with complete initialization of all data management, color space, I/O, and object handling capabilities. The image can be initialized empty or with data from a NumPy array or another Image instance. Args: arr (np.ndarray | Image | None): Optional image data. Can be: - A NumPy array of shape (height, width) for grayscale or (height, width, channels) for RGB/RGBA - An existing Image instance to copy from - None to create an empty image Defaults to None. name (str | None): Optional human-readable name for the image. If not provided, the image UUID will be used as the name. Defaults to None. bit_depth (Literal[8, 16] | None): The bit depth of the image data (8 or 16 bits). If not specified and arr is provided, bit depth is automatically inferred from the array dtype. Defaults to None. gamma_encoding (str | None): The gamma encoding used for color correction. 'sRGB': applies sRGB gamma correction (standard display gamma) None: assumes linear RGB data Only 'sRGB' and None are supported. Defaults to 'sRGB'. illuminant (str | None): The reference illuminant for color calculations. 'D65': standard daylight illuminant (recommended) 'D50': standard illumination for imaging Defaults to 'D65'. Raises: ValueError: If gamma_encoding is not 'sRGB' or None. ValueError: If illuminant is not 'D65' or 'D50'. TypeError: If arr is provided but is not a NumPy array or Image instance. Examples: .. dropdown:: Create empty image .. code-block:: python img = Image(name='empty_image') .. dropdown:: Create from grayscale array .. code-block:: python gray_arr = np.random.randint(0, 256, (480, 640), dtype=np.uint8) img = Image(gray_arr, name='grayscale_photo') .. dropdown:: Create from RGB array .. code-block:: python rgb_arr = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8) img = Image(rgb_arr, name='color_photo', gamma_encoding='sRGB') .. dropdown:: Copy another image .. code-block:: python img1 = Image.imread('original.jpg') img2 = Image(img1, name='copy_of_original') """ super().__init__( arr=arr, name=name, bit_depth=bit_depth, gamma_encoding=gamma_encoding, illuminant=illuminant, )