Source code for ms_camera_model.image_visualiser

'''
Multispectral Camera Model - Image Visualiser
=============================================

Dataclasses and their methods for visualising image data
'''

from __future__ import annotations

import logging

import matplotlib.pyplot as plt
from matplotlib.pylab import isin

from ms_camera_model import AreaLocation, ImageData
from ms_camera_model.errors import IncompatibleBandChoice

logger = logging.getLogger(__name__)


[docs] class ImageVisualiser: """ Image Visualiser class :param image_data: ImageData class :method imshow: view the img_data as an RGB interpretation of selected bands or as a brightness plot :method plot_area_spectrum: visualize the mean spectrum of an area """
[docs] @staticmethod 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 bands: list of band numbers, if the list is not provided, brightness plot will be used instead :raises IncompatibleBandChoice: if 'bands' is not [], len(bands) != 3 or the number is out-of-bounds """ if not bands: bands = [] if not isinstance(bands, list): raise TypeError(f"Expected list[int] or None, got {type(bands)}") if len(bands) == 3: logger.info( f"[ImageData] 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"[ImageData] 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("[ImageData] 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"[ImageData] Wrong band choice was provided. Expected [] or len(bands) == 3, got {bands}") raise IncompatibleBandChoice
[docs] @staticmethod def plot_area_spectrum(image_data: ImageData, coordinates: AreaLocation) -> None: """ Plot spectrum of pixels :param coordinates: list[ulx, uly, lrx, lry] - ulx means upper left x, lry means lower right y, etc. """ ulx, uly, lrx, lry = coordinates.as_tuple() logger.info(f"[ImageData] Plotting mean spectrum of area x {ulx}:{lrx}, y {lry}:{uly}") if image_data.band_centers is None: logger.error("[ImageData] Cannot plot spectrum - band_centers are missing.") return area_data = image_data.mean_spectrum_area(image_data.img_data, coordinates.as_tuple()) plt.plot(image_data.band_centers, area_data, label="Spectral response") plt.xlabel("Band") plt.ylabel("Reflectance")