Skip to content

Spectral Images

siapy.entities.images.spimage

T module-attribute

T = TypeVar('T', bound=ImageBase)

SpectralImage dataclass

SpectralImage(
    image: T, geometric_shapes: list[Shape] | None = None
)

Bases: Generic[T]

PARAMETER DESCRIPTION
image

The underlying image implementation (e.g., RasterioLibImage, SpectralLibImage, MockImage).

TYPE: T

geometric_shapes

Optional list of geometric shapes associated with this image. Defaults to None.

TYPE: list[Shape] | None DEFAULT: None

Source code in siapy/entities/images/spimage.py
31
32
33
34
35
36
37
38
39
40
41
42
43
def __init__(
    self,
    image: T,
    geometric_shapes: list["Shape"] | None = None,
):
    """Initialize a SpectralImage wrapper around an image backend.

    Args:
        image: The underlying image implementation (e.g., RasterioLibImage, SpectralLibImage, MockImage).
        geometric_shapes: Optional list of geometric shapes associated with this image. Defaults to None.
    """
    self._image = image
    self._geometric_shapes = GeometricShapes(self, geometric_shapes)

image property

image: T

Get the underlying image implementation.

RETURNS DESCRIPTION
T

The wrapped image backend instance (e.g., RasterioLibImage, SpectralLibImage, MockImage).

geometric_shapes property

geometric_shapes: GeometricShapes

Get the geometric shapes associated with this image.

RETURNS DESCRIPTION
GeometricShapes

A GeometricShapes instance containing all shapes linked to this image.

filepath property

filepath: Path

Get the file path of the image.

RETURNS DESCRIPTION
Path

A Path object representing the location of the image file.

metadata property

metadata: dict[str, Any]

Get the image metadata.

RETURNS DESCRIPTION
dict[str, Any]

A dictionary containing image metadata such as coordinate reference system, geotransform information, and other image properties.

shape property

shape: tuple[int, int, int]

Get the dimensions of the image.

RETURNS DESCRIPTION
tuple[int, int, int]

A tuple (height, width, bands) representing the image dimensions.

width property

width: int

Get the width of the image in pixels.

RETURNS DESCRIPTION
int

The number of pixels in the horizontal dimension.

height property

height: int

Get the height of the image in pixels.

RETURNS DESCRIPTION
int

The number of pixels in the vertical dimension.

bands property

bands: int

Get the number of spectral bands in the image.

RETURNS DESCRIPTION
int

The number of spectral bands (channels) in the image.

default_bands property

default_bands: list[int]

Get the default band indices for RGB display.

RETURNS DESCRIPTION
list[int]

A list of band indices typically used for red, green, and blue channels when displaying the image as an RGB composite.

wavelengths property

wavelengths: list[float]

Get the wavelengths corresponding to each spectral band.

RETURNS DESCRIPTION
list[float]

A list of wavelength values (typically in nanometers) for each band. The length of this list equals the number of bands.

camera_id property

camera_id: str

Get the camera or sensor identifier.

RETURNS DESCRIPTION
str

A string identifying the camera or sensor used to capture the image.

spy_open classmethod

spy_open(
    *,
    header_path: str | Path,
    image_path: str | Path | None = None,
) -> SpectralImage[SpectralLibImage]

Open a spectral image using the SpectralPython library backend.

PARAMETER DESCRIPTION
header_path

Path to the header file (.hdr) containing image metadata.

TYPE: str | Path

image_path

Optional path to the image data file. If None, inferred from header_path.

TYPE: str | Path | None DEFAULT: None

RETURNS DESCRIPTION
SpectralImage[SpectralLibImage]

A SpectralImage instance wrapping a SpectralLibImage backend.

Example
# Open an ENVI format image
image = SpectralImage.spy_open(header_path="image.hdr")

# Open with explicit image file path
image = SpectralImage.spy_open(
    header_path="image.hdr",
    image_path="image.dat"
)
Source code in siapy/entities/images/spimage.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@classmethod
def spy_open(
    cls, *, header_path: str | Path, image_path: str | Path | None = None
) -> "SpectralImage[SpectralLibImage]":
    """Open a spectral image using the SpectralPython library backend.

    Args:
        header_path: Path to the header file (.hdr) containing image metadata.
        image_path: Optional path to the image data file. If None, inferred from header_path.

    Returns:
        A SpectralImage instance wrapping a SpectralLibImage backend.

    Example:
        ```python
        # Open an ENVI format image
        image = SpectralImage.spy_open(header_path="image.hdr")

        # Open with explicit image file path
        image = SpectralImage.spy_open(
            header_path="image.hdr",
            image_path="image.dat"
        )
        ```
    """
    image = SpectralLibImage.open(header_path=header_path, image_path=image_path)
    return SpectralImage(image)

rasterio_open classmethod

rasterio_open(
    filepath: str | Path,
) -> SpectralImage[RasterioLibImage]

Open a spectral image using the Rasterio library backend.

PARAMETER DESCRIPTION
filepath

Path to the image file (supports formats like GeoTIFF, etc.).

TYPE: str | Path

RETURNS DESCRIPTION
SpectralImage[RasterioLibImage]

A SpectralImage instance wrapping a RasterioLibImage backend.

Example
# Open a GeoTIFF file
image = SpectralImage.rasterio_open("image.tif")
Source code in siapy/entities/images/spimage.py
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
@classmethod
def rasterio_open(cls, filepath: str | Path) -> "SpectralImage[RasterioLibImage]":
    """Open a spectral image using the Rasterio library backend.

    Args:
        filepath: Path to the image file (supports formats like GeoTIFF, etc.).

    Returns:
        A SpectralImage instance wrapping a RasterioLibImage backend.

    Example:
        ```python
        # Open a GeoTIFF file
        image = SpectralImage.rasterio_open("image.tif")
        ```
    """
    image = RasterioLibImage.open(filepath)
    return SpectralImage(image)

from_numpy classmethod

from_numpy(
    array: NDArray[floating[Any]],
) -> SpectralImage[MockImage]

Create a spectral image from a numpy array using the mock backend.

PARAMETER DESCRIPTION
array

A 3D numpy array with shape (height, width, bands) containing spectral data.

TYPE: NDArray[floating[Any]]

RETURNS DESCRIPTION
SpectralImage[MockImage]

A SpectralImage instance wrapping a MockImage backend.

Example
import numpy as np

# Create a synthetic spectral image
data = np.random.rand(100, 100, 10)  # 100x100 image with 10 bands
image = SpectralImage.from_numpy(data)
Source code in siapy/entities/images/spimage.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@classmethod
def from_numpy(cls, array: NDArray[np.floating[Any]]) -> "SpectralImage[MockImage]":
    """Create a spectral image from a numpy array using the mock backend.

    Args:
        array: A 3D numpy array with shape (height, width, bands) containing spectral data.

    Returns:
        A SpectralImage instance wrapping a MockImage backend.

    Example:
        ```python
        import numpy as np

        # Create a synthetic spectral image
        data = np.random.rand(100, 100, 10)  # 100x100 image with 10 bands
        image = SpectralImage.from_numpy(data)
        ```
    """
    image = MockImage.open(array)
    return SpectralImage(image)

to_display

to_display(equalize: bool = True) -> Image

Convert the image to a PIL Image for display purposes.

PARAMETER DESCRIPTION
equalize

Whether to apply histogram equalization to enhance contrast. Defaults to True.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Image

A PIL Image object suitable for display, typically as an RGB composite.

Example
# Display the image with default settings
pil_image = spectral_image.to_display()
pil_image.show()

# Display without histogram equalization
pil_image = spectral_image.to_display(equalize=False)
Source code in siapy/entities/images/spimage.py
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
def to_display(self, equalize: bool = True) -> Image.Image:
    """Convert the image to a PIL Image for display purposes.

    Args:
        equalize: Whether to apply histogram equalization to enhance contrast. Defaults to True.

    Returns:
        A PIL Image object suitable for display, typically as an RGB composite.

    Example:
        ```python
        # Display the image with default settings
        pil_image = spectral_image.to_display()
        pil_image.show()

        # Display without histogram equalization
        pil_image = spectral_image.to_display(equalize=False)
        ```
    """
    return self.image.to_display(equalize)

to_numpy

to_numpy(
    nan_value: float | None = None,
) -> NDArray[floating[Any]]

Convert the image to a numpy array.

PARAMETER DESCRIPTION
nan_value

Optional value to replace NaN values with. If None, NaN values are preserved.

TYPE: float | None DEFAULT: None

RETURNS DESCRIPTION
NDArray[floating[Any]]

A 3D numpy array with shape (height, width, bands) containing the spectral data.

Example
# Get the raw data with NaN values preserved
data = spectral_image.to_numpy()

# Replace NaN values with zero
data = spectral_image.to_numpy(nan_value=0.0)
Source code in siapy/entities/images/spimage.py
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def to_numpy(self, nan_value: float | None = None) -> NDArray[np.floating[Any]]:
    """Convert the image to a numpy array.

    Args:
        nan_value: Optional value to replace NaN values with. If None, NaN values are preserved.

    Returns:
        A 3D numpy array with shape (height, width, bands) containing the spectral data.

    Example:
        ```python
        # Get the raw data with NaN values preserved
        data = spectral_image.to_numpy()

        # Replace NaN values with zero
        data = spectral_image.to_numpy(nan_value=0.0)
        ```
    """
    return self.image.to_numpy(nan_value)

to_xarray

to_xarray() -> XarrayType

Convert the image to an xarray DataArray.

RETURNS DESCRIPTION
XarrayType

An xarray DataArray with labeled dimensions and coordinates, suitable for advanced analysis and visualization.

Example
# Convert to xarray for analysis
xr_data = spectral_image.to_xarray()

# Access specific bands or wavelengths
red_band = xr_data.sel(wavelength=650, method='nearest')
Source code in siapy/entities/images/spimage.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
def to_xarray(self) -> "XarrayType":
    """Convert the image to an xarray DataArray.

    Returns:
        An xarray DataArray with labeled dimensions and coordinates, suitable for advanced analysis and visualization.

    Example:
        ```python
        # Convert to xarray for analysis
        xr_data = spectral_image.to_xarray()

        # Access specific bands or wavelengths
        red_band = xr_data.sel(wavelength=650, method='nearest')
        ```
    """
    return self.image.to_xarray()

to_signatures

to_signatures(
    pixels: Pixels | DataFrame | Iterable[CoordinateInput],
) -> Signatures

Extract spectral signatures from specific pixel locations.

PARAMETER DESCRIPTION
pixels

Pixel coordinates to extract signatures from. Can be a Pixels object, pandas DataFrame with 'x' and 'y' columns, or an iterable of coordinate tuples.

TYPE: Pixels | DataFrame | Iterable[CoordinateInput]

RETURNS DESCRIPTION
Signatures

A Signatures object containing the spectral data for the specified pixels.

Example
# Extract signatures from specific coordinates
coords = [(10, 20), (30, 40), (50, 60)]
signatures = spectral_image.to_signatures(coords)

# Extract signatures from a DataFrame
import pandas as pd
df = pd.DataFrame({'x': [10, 30, 50], 'y': [20, 40, 60]})
signatures = spectral_image.to_signatures(df)
Source code in siapy/entities/images/spimage.py
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
def to_signatures(self, pixels: Pixels | pd.DataFrame | Iterable[CoordinateInput]) -> Signatures:
    """Extract spectral signatures from specific pixel locations.

    Args:
        pixels: Pixel coordinates to extract signatures from. Can be a Pixels object,
                pandas DataFrame with 'x' and 'y' columns, or an iterable of coordinate tuples.

    Returns:
        A Signatures object containing the spectral data for the specified pixels.

    Example:
        ```python
        # Extract signatures from specific coordinates
        coords = [(10, 20), (30, 40), (50, 60)]
        signatures = spectral_image.to_signatures(coords)

        # Extract signatures from a DataFrame
        import pandas as pd
        df = pd.DataFrame({'x': [10, 30, 50], 'y': [20, 40, 60]})
        signatures = spectral_image.to_signatures(df)
        ```
    """
    pixels = validate_pixel_input(pixels)
    image_arr = self.to_numpy()
    signatures = Signatures.from_array_and_pixels(image_arr, pixels)
    return signatures

to_subarray

to_subarray(
    pixels: Pixels | DataFrame | Iterable[CoordinateInput],
) -> NDArray[floating[Any]]

Extract a rectangular subarray containing the specified pixels.

Creates a new array that encompasses all the specified pixel coordinates, with NaN values for pixels not in the original selection.

PARAMETER DESCRIPTION
pixels

Pixel coordinates defining the region of interest. Can be a Pixels object, pandas DataFrame with 'x' and 'y' columns, or an iterable of coordinate tuples.

TYPE: Pixels | DataFrame | Iterable[CoordinateInput]

RETURNS DESCRIPTION
NDArray[floating[Any]]

A 3D numpy array containing the subregion with shape (height, width, bands). Unselected pixels within the bounding rectangle are filled with NaN.

Example
# Extract a subarray around specific points
coords = [(10, 20), (15, 25), (12, 22)]
subarray = spectral_image.to_subarray(coords)

# The resulting array will be 6x6x{bands} covering the bounding box
# from (10,20) to (15,25) with only the specified pixels having data
Source code in siapy/entities/images/spimage.py
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
def to_subarray(self, pixels: Pixels | pd.DataFrame | Iterable[CoordinateInput]) -> NDArray[np.floating[Any]]:
    """Extract a rectangular subarray containing the specified pixels.

    Creates a new array that encompasses all the specified pixel coordinates,
    with NaN values for pixels not in the original selection.

    Args:
        pixels: Pixel coordinates defining the region of interest. Can be a Pixels object,
                pandas DataFrame with 'x' and 'y' columns, or an iterable of coordinate tuples.

    Returns:
        A 3D numpy array containing the subregion with shape (height, width, bands). Unselected pixels within the bounding rectangle are filled with NaN.

    Example:
        ```python
        # Extract a subarray around specific points
        coords = [(10, 20), (15, 25), (12, 22)]
        subarray = spectral_image.to_subarray(coords)

        # The resulting array will be 6x6x{bands} covering the bounding box
        # from (10,20) to (15,25) with only the specified pixels having data
        ```
    """
    pixels = validate_pixel_input(pixels)
    image_arr = self.to_numpy()
    x_max = pixels.x().max()
    x_min = pixels.x().min()
    y_max = pixels.y().max()
    y_min = pixels.y().min()
    # create new image
    image_arr_area = np.nan * np.ones((int(y_max - y_min + 1), int(x_max - x_min + 1), self.bands))
    # convert original coordinates to coordinates for new image
    y_norm = pixels.y() - y_min
    x_norm = pixels.x() - x_min
    # write values from original image to new image
    image_arr_area[y_norm, x_norm, :] = image_arr[pixels.y(), pixels.x(), :]
    return image_arr_area

average_intensity

average_intensity(
    axis: int
    | tuple[int, ...]
    | Sequence[int]
    | None = None,
) -> float | NDArray[floating[Any]]

Calculate the average intensity across specified dimensions.

PARAMETER DESCRIPTION
axis

Axis or axes along which to compute the mean. If None, computes the mean over the entire array. Can be an integer, tuple of integers, or sequence of integers.
- axis=None: Average over all pixels and bands (returns single float)
- axis=(0,1): Average over spatial dimensions (returns array of band averages)
- axis=2: Average over spectral dimension (returns spatial average image)

TYPE: int | tuple[int, ...] | Sequence[int] | None DEFAULT: None

RETURNS DESCRIPTION
float | NDArray[floating[Any]]

Either a single float (if axis=None) or a numpy array with reduced dimensions. NaN values are ignored in the calculation.

Example
# Get overall average intensity
overall_avg = spectral_image.average_intensity()

# Get average spectrum (average over spatial dimensions)
avg_spectrum = spectral_image.average_intensity(axis=(0, 1))

# Get spatial average (average over spectral dimension)
spatial_avg = spectral_image.average_intensity(axis=2)
Source code in siapy/entities/images/spimage.py
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
def average_intensity(
    self, axis: int | tuple[int, ...] | Sequence[int] | None = None
) -> float | NDArray[np.floating[Any]]:
    """Calculate the average intensity across specified dimensions.

    Args:
        axis: Axis or axes along which to compute the mean. If None, computes the mean over the entire array. Can be an integer, tuple of integers, or sequence of integers. <br>
              - axis=None: Average over all pixels and bands (returns single float) <br>
              - axis=(0,1): Average over spatial dimensions (returns array of band averages) <br>
              - axis=2: Average over spectral dimension (returns spatial average image)

    Returns:
        Either a single float (if axis=None) or a numpy array with reduced dimensions. NaN values are ignored in the calculation.

    Example:
        ```python
        # Get overall average intensity
        overall_avg = spectral_image.average_intensity()

        # Get average spectrum (average over spatial dimensions)
        avg_spectrum = spectral_image.average_intensity(axis=(0, 1))

        # Get spatial average (average over spectral dimension)
        spatial_avg = spectral_image.average_intensity(axis=2)
        ```
    """
    image_arr = self.to_numpy()
    return np.nanmean(image_arr, axis=axis)