Source code for ms_camera_model.image_visualiser

"""
Multispectral Camera Model - Image Visualisation
================================================

* **Description:** Functions for image visualisation
* **Author:** Tomas Vacek
* **Year:** 2026
* **License:** MIT License
"""

from __future__ import annotations

import logging

import matplotlib.pyplot as plt

from ms_camera_model.errors import (
    IncompatibleBandChoice,
    NoBandCenters,
)
from ms_camera_model.image_data import AreaLocation, ImageData

logger = logging.getLogger(__name__)


[docs] def imshow(image_data: ImageData, bands: list[int] | None = None) -> None: """ View image as an RGB interpretation of selected bands or as a brightness plot :param image_data: ImageData instance :param bands: list of band numbers, if the list is not provided, brightness plot will be used instead :raises TypeError: if provided bands are not a list or None :raises IncompatibleBandChoice: if 'bands' is not [], len(bands) != 3 or the number is out-of-bounds """ if bands is None: bands = [] if not isinstance(bands, list): raise TypeError(f"Expected list[int] or None, got {type(bands)}") if len(bands) == 3: logger.info( f"[ImageVisualiser] Showing RGB interpretation from bands -> R:{bands[0]}, G:{bands[1]}, B:{bands[2]}") plot_data = image_data.img_data[:, :, bands] plot_data /= (plot_data.max(axis=(0, 1)) + 1e-10) plt.imshow(plot_data) elif len(bands) == 1: logger.info(f"[ImageVisualiser] Showing band -> {bands[0]}") plot_data = image_data.img_data[:, :, bands] plot_data[:, :, 0] *= (1.0 / plot_data[:, :, 0].max()) plt.imshow(plot_data) elif len(bands) == 0: logger.info("[ImageVisualiser] Showing image as a brightness plot") non_empty_bands = image_data.img_data.max(axis=(0, 1)) > 1e-2 bands = [i for i, x in enumerate(non_empty_bands) if x] plot_data = image_data.img_data[:, :, (bands)] plot_data = plot_data.sum(axis=2) plot_data /= len(bands) plot_data *= (1.0 / plot_data.max()) plt.imshow(plot_data, cmap='gray', vmin=0.0, vmax=1.0) else: logger.info(f"[ImageVisualiser] Wrong band choice was provided. Expected [] or len(bands) == 3, got {bands}") raise IncompatibleBandChoice
[docs] def plot_area_spectrum(image_data: ImageData, coordinates: AreaLocation) -> None: """ Plot spectrum of pixels :param image_data: ImageData instance :param coordinates: AreaLocation instance :raises NoBandCenters: if provided ImageData contains no band_centers """ ulx, uly, lrx, lry = coordinates.as_tuple() logger.info(f"[ImageVisualiser] Plotting mean spectrum of area x {ulx}:{lrx}, y {lry}:{uly}") if not image_data.band_centers: raise NoBandCenters("[ImageVisualiser] Cannot plot spectrum - band_centers are missing.") area_data = ImageData.mean_spectrum_area(image_data.img_data, coordinates.as_tuple()) plt.plot(image_data.band_centers, area_data, label="Spectral response") plt.xlabel("Wavelength [nm]") plt.ylabel("Spectral reflectance [-]")