LSST Applications g04e9c324dd+8c5ae1fdc5,g134cb467dc+b203dec576,g18429d2f64+358861cd2c,g199a45376c+0ba108daf9,g1fd858c14a+dd066899e3,g262e1987ae+ebfced1d55,g29ae962dfc+72fd90588e,g2cef7863aa+aef1011c0b,g35bb328faa+8c5ae1fdc5,g3fd5ace14f+b668f15bc5,g4595892280+3897dae354,g47891489e3+abcf9c3559,g4d44eb3520+fb4ddce128,g53246c7159+8c5ae1fdc5,g67b6fd64d1+abcf9c3559,g67fd3c3899+1f72b5a9f7,g74acd417e5+cb6b47f07b,g786e29fd12+668abc6043,g87389fa792+8856018cbb,g89139ef638+abcf9c3559,g8d7436a09f+bcf525d20c,g8ea07a8fe4+9f5ccc88ac,g90f42f885a+6054cc57f1,g97be763408+06f794da49,g9dd6db0277+1f72b5a9f7,ga681d05dcb+7e36ad54cd,gabf8522325+735880ea63,gac2eed3f23+abcf9c3559,gb89ab40317+abcf9c3559,gbf99507273+8c5ae1fdc5,gd8ff7fe66e+1f72b5a9f7,gdab6d2f7ff+cb6b47f07b,gdc713202bf+1f72b5a9f7,gdfd2d52018+8225f2b331,ge365c994fd+375fc21c71,ge410e46f29+abcf9c3559,geaed405ab2+562b3308c0,gf9a733ac38+8c5ae1fdc5,w.2025.35
LSST Data Management Base Package
Loading...
Searching...
No Matches
lsst.scarlet.lite.image.Image Class Reference

Public Member Functions

 __init__ (self, np.ndarray data, Sequence|None bands=None, tuple[int, int]|None yx0=None)
 
tuple[int,...] shape (self)
 
DTypeLike dtype (self)
 
tuple bands (self)
 
int n_bands (self)
 
bool is_multiband (self)
 
int height (self)
 
int width (self)
 
tuple[int, int] yx0 (self)
 
int y0 (self)
 
int x0 (self)
 
Box bbox (self)
 
np.ndarray data (self)
 
int ndim (self)
 
tuple[int,...]|slice spectral_indices (self, Sequence|slice bands)
 
tuple[tuple[int,...]|slice, tuple[int,...]|slice] matched_spectral_indices (self, Image other)
 
tuple[tuple[slice,...], tuple[slice,...]] matched_slices (self, Box bbox)
 
Image project (self, object|tuple[object]|None bands=None, Box|None bbox=None)
 
tuple[tuple[int,...]|slice, slice, slice] multiband_slices (self)
 
Image insert_into (self, Image image, Callable op=operator.add)
 
Image insert (self, Image image, Callable op=operator.add)
 
Image repeat (self, tuple bands)
 
Image copy (self, order=None)
 
 copy_with (self, np.ndarray|None data=None, str|None order=None, tuple[str,...]|None bands=None, tuple[int, int]|None yx0=None)
 
Image trimmed (self, float threshold=0)
 
ScalarLike|np.ndarray at (self, int y, int x)
 
Image __eq__ (self, object other)
 
Image __ne__ (self, object other)
 
Image __ge__ (self, Image|ScalarLike other)
 
Image __le__ (self, Image|ScalarLike other)
 
Image __gt__ (self, Image|ScalarLike other)
 
Image __lt__ (self, Image|ScalarLike other)
 
 __neg__ (self)
 
 __pos__ (self)
 
 __invert__ (self)
 
Image __add__ (self, Image|ScalarLike other)
 
Image __iadd__ (self, Image|ScalarLike other)
 
Image __radd__ (self, Image|ScalarLike other)
 
Image __sub__ (self, Image|ScalarLike other)
 
Image __isub__ (self, Image|ScalarLike other)
 
Image __rsub__ (self, Image|ScalarLike other)
 
Image __mul__ (self, Image|ScalarLike other)
 
Image __imul__ (self, Image|ScalarLike other)
 
Image __rmul__ (self, Image|ScalarLike other)
 
Image __truediv__ (self, Image|ScalarLike other)
 
Image __itruediv__ (self, Image|ScalarLike other)
 
Image __rtruediv__ (self, Image|ScalarLike other)
 
Image __floordiv__ (self, Image|ScalarLike other)
 
Image __ifloordiv__ (self, Image|ScalarLike other)
 
Image __rfloordiv__ (self, Image|ScalarLike other)
 
Image __pow__ (self, Image|ScalarLike other)
 
Image __ipow__ (self, Image|ScalarLike other)
 
Image __rpow__ (self, Image|ScalarLike other)
 
Image __mod__ (self, Image|ScalarLike other)
 
Image __imod__ (self, Image|ScalarLike other)
 
Image __rmod__ (self, Image|ScalarLike other)
 
Image __and__ (self, Image|ScalarLike other)
 
Image __iand__ (self, Image|ScalarLike other)
 
Image __rand__ (self, Image|ScalarLike other)
 
Image __or__ (self, Image|ScalarLike other)
 
Image __ior__ (self, Image|ScalarLike other)
 
Image __ror__ (self, Image|ScalarLike other)
 
Image __xor__ (self, Image|ScalarLike other)
 
Image __ixor__ (self, Image|ScalarLike other)
 
Image __rxor__ (self, Image|ScalarLike other)
 
Image __lshift__ (self, ScalarLike other)
 
Image __ilshift__ (self, ScalarLike other)
 
Image __rlshift__ (self, ScalarLike other)
 
Image __rshift__ (self, ScalarLike other)
 
Image __irshift__ (self, ScalarLike other)
 
Image __rrshift__ (self, ScalarLike other)
 
 __str__ (self)
 
tuple[tuple[slice,...], tuple[slice,...]] overlapped_slices (self, Box bbox)
 
Image __getitem__ (self, Any indices)
 
Image __setitem__ (self, indices, Image value)
 

Static Public Member Functions

Image from_box (Box bbox, tuple|None bands=None, DTypeLike dtype=float)
 

Public Attributes

tuple bands = 0:
 
int n_bands = 0:
 
Box bbox = bbox:
 
 is_multiband
 
int ndim = 2:
 

Protected Member Functions

Image _i_update (self, Callable op, Image|ScalarLike other)
 
Image _check_equality (self, Image|ScalarLike other, Callable op)
 
bool _is_spectral_index (self, Any index)
 
tuple[slice, slice] _get_box_slices (self, Box bbox)
 
Image _get_sliced (self, Any indices, Image|None value=None)
 

Protected Attributes

np.ndarray _data = data
 
tuple[int, int] _yx0 = yx0
 
tuple _bands = bands
 

Detailed Description

A numpy array with an origin and (optional) bands

This class contains a 2D numpy array with the addition of an
origin (``yx0``) and an optional first index (``bands``) that
allows an immutable named index to be used.

Notes
-----
One of the main limitations of using numpy arrays to store image data
is the lack of an ``origin`` attribute that allows an array to retain
knowledge of it's location in a larger scene.
For example, if a numpy array ``x`` is sliced, eg. ``x[10:20, 30:40]``
the result will be a new ``10x10`` numpy array that has no meta
data to inform the user that it was sliced from a larger image.
In addition, astrophysical images are also multi-band data cubes,
with a 2D image in each band (in fact this is the simplifying
assumption that distinguishes scarlet lite from scarlet main).
However, the ordering of the bands during processing might differ from
the ordering of the bands to display multiband data.
So a mechanism was also desired to simplify the sorting and index of
an image by band name.

Thus, scarlet lite creates a numpy-array like class with the additional
``bands`` and ``yx0`` attributes to keep track of the bands contained
in an array and the origin of that array (we specify ``yx0`` as opposed
to ``xy0`` to be consistent with the default numpy/C++ ``(y, x)``
ordering of arrays as opposed to the traditional cartesian ``(x, y)``
ordering used in astronomy and other modules in the science pipelines.
While this may be a small source of confusion for the user,
it is consistent with the ordering in the original scarlet package and
ensures the consistency of scarlet lite images and python index slicing.

Examples
--------

The easiest way to create a new image is to use ``Image(numpy_array)``,
for example

>>> import numpy as np
>>> from lsst.scarlet.lite import Image
>>>
>>> x = np.arange(12).reshape(3, 4)
>>> image = Image(x)
>>> print(image)
Image:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
  bands=()
  bbox=Box(shape=(3, 4), origin=(0, 0))

This will create a single band :py:class:`~lsst.scarlet.lite.Image` with
origin ``(0, 0)``.
To create a multi-band image the input array must have 3 dimensions and
the ``bands`` property must be specified:

>>> x = np.arange(24).reshape(2, 3, 4)
>>> image = Image(x, bands=("i", "z"))
>>> print(image)
Image:
 [[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]
<BLANKLINE>
 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
  bands=('i', 'z')
  bbox=Box(shape=(3, 4), origin=(0, 0))

It is also possible to create an empty single-band image using the
``from_box`` static method:

>>> from lsst.scarlet.lite import Box
>>> image = Image.from_box(Box((3, 4), (100, 120)))
>>> print(image)
Image:
 [[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
  bands=()
  bbox=Box(shape=(3, 4), origin=(100, 120))

Similarly, an empty multi-band image can be created by passing a tuple
of ``bands``:

>>> image = Image.from_box(Box((3, 4)), bands=("r", "i"))
>>> print(image)
Image:
 [[[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]
<BLANKLINE>
 [[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]]
  bands=('r', 'i')
  bbox=Box(shape=(3, 4), origin=(0, 0))

To select a sub-image use a ``Box`` to select a spatial region in either a
single-band or multi-band image:

>>> x = np.arange(60).reshape(3, 4, 5)
>>> image = Image(x, bands=("g", "r", "i"), yx0=(20, 30))
>>> bbox = Box((2, 2), (21, 32))
>>> print(image[bbox])
Image:
 [[[ 7  8]
  [12 13]]
<BLANKLINE>
 [[27 28]
  [32 33]]
<BLANKLINE>
 [[47 48]
  [52 53]]]
  bands=('g', 'r', 'i')
  bbox=Box(shape=(2, 2), origin=(21, 32))


To select a single-band image from a multi-band image,
pass the name of the band as an index:

>>> print(image["r"])
Image:
 [[20 21 22 23 24]
 [25 26 27 28 29]
 [30 31 32 33 34]
 [35 36 37 38 39]]
  bands=()
  bbox=Box(shape=(4, 5), origin=(20, 30))

Multi-band images can also be sliced in the spatial dimension, for example

>>> print(image["g":"r"])
Image:
 [[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]]
<BLANKLINE>
 [[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]]
  bands=('g', 'r')
  bbox=Box(shape=(4, 5), origin=(20, 30))

and

>>> print(image["r":"r"])
Image:
 [[[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]]
  bands=('r',)
  bbox=Box(shape=(4, 5), origin=(20, 30))

both extract a slice of a multi-band image.

.. warning::
    Unlike numerical indices, where ``slice(x, y)`` will select the
    subset of an array from ``x`` to ``y-1`` (excluding ``y``),
    a spectral slice of an ``Image`` will return the image slice
    including band ``y``.

It is also possible to change the order or index a subset of bands
in an image. For example:

>>> print(image[("r", "g", "i")])
Image:
 [[[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]
<BLANKLINE>
 [[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]]
<BLANKLINE>
 [[40 41 42 43 44]
  [45 46 47 48 49]
  [50 51 52 53 54]
  [55 56 57 58 59]]]
  bands=('r', 'g', 'i')
  bbox=Box(shape=(4, 5), origin=(20, 30))


will return a new image with the bands re-ordered.

Images can be combined using the standard arithmetic operations similar to
numpy arrays, including ``+, -, *, /, **`` etc, however, if two images are
combined with different bounding boxes, the _union_ of the two
boxes is used for the result. For example:

>>> image1 = Image(np.ones((2, 3, 4)), bands=tuple("gr"))
>>> image2 = Image(np.ones((2, 3, 4)), bands=tuple("gr"), yx0=(2, 3))
>>> result = image1 + image2
>>> print(result)
Image:
 [[[1. 1. 1. 1. 0. 0. 0.]
  [1. 1. 1. 1. 0. 0. 0.]
  [1. 1. 1. 2. 1. 1. 1.]
  [0. 0. 0. 1. 1. 1. 1.]
  [0. 0. 0. 1. 1. 1. 1.]]
<BLANKLINE>
 [[1. 1. 1. 1. 0. 0. 0.]
  [1. 1. 1. 1. 0. 0. 0.]
  [1. 1. 1. 2. 1. 1. 1.]
  [0. 0. 0. 1. 1. 1. 1.]
  [0. 0. 0. 1. 1. 1. 1.]]]
  bands=('g', 'r')
  bbox=Box(shape=(5, 7), origin=(0, 0))

If instead you want to additively ``insert`` image 1 into image 2,
so that they have the same bounding box as image 2, use

>>> _ = image2.insert(image1)
>>> print(image2)
Image:
 [[[2. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]
<BLANKLINE>
 [[2. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
  bands=('g', 'r')
  bbox=Box(shape=(3, 4), origin=(2, 3))

To insert an image using a different operation use

>>> from operator import truediv
>>> _ = image2.insert(image1, truediv)
>>> print(image2)
Image:
 [[[2. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]
<BLANKLINE>
 [[2. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
  bands=('g', 'r')
  bbox=Box(shape=(3, 4), origin=(2, 3))


However, depending on the operation you may get unexpected results
since now there could be ``NaN`` and ``inf`` values due to the zeros
in the non-overlapping regions.
Instead, to select only the overlap region one can use

>>> result = image1 / image2
>>> print(result[image1.bbox & image2.bbox])
Image:
 [[[0.5]]
<BLANKLINE>
 [[0.5]]]
  bands=('g', 'r')
  bbox=Box(shape=(1, 1), origin=(2, 3))


Parameters
----------
data:
    The array data for the image.
bands:
    The bands coving the image.
yx0:
    The (y, x) offset for the lower left of the image.

Definition at line 84 of file image.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.scarlet.lite.image.Image.__init__ ( self,
np.ndarray data,
Sequence | None bands = None,
tuple[int, int] | None yx0 = None )

Definition at line 358 of file image.py.

363 ):
364 if bands is None or len(bands) == 0:
365 # Using an empty tuple for the bands will result in a 2D image
366 bands = ()
367 assert data.ndim == 2
368 else:
369 bands = tuple(bands)
370 assert data.ndim == 3
371 if data.shape[0] != len(bands):
372 raise ValueError(f"Array has spectral size {data.shape[0]}, but {bands} bands")
373 if yx0 is None:
374 yx0 = (0, 0)
375 self._data = data
376 self._yx0 = yx0
377 self._bands = bands
378

Member Function Documentation

◆ __add__()

Image lsst.scarlet.lite.image.Image.__add__ ( self,
Image | ScalarLike other )
Combine this image and another image using addition.

Definition at line 912 of file image.py.

912 def __add__(self, other: Image | ScalarLike) -> Image:
913 """Combine this image and another image using addition."""
914 return _operate_on_images(self, other, operator.add)
915

◆ __and__()

Image lsst.scarlet.lite.image.Image.__and__ ( self,
Image | ScalarLike other )
Take the bitwise and of this and other.

Definition at line 1022 of file image.py.

1022 def __and__(self, other: Image | ScalarLike) -> Image:
1023 """Take the bitwise and of this and other."""
1024 return _operate_on_images(self, other, operator.and_)
1025

◆ __eq__()

Image lsst.scarlet.lite.image.Image.__eq__ ( self,
object other )
Check if this image is equal to another.

Definition at line 866 of file image.py.

866 def __eq__(self, other: object) -> Image: # type: ignore
867 """Check if this image is equal to another."""
868 if not isinstance(other, Image) and not isinstance(other, ScalarTypes):
869 raise TypeError(f"Cannot compare an Image to {type(other)}.")
870 return self._check_equality(other, operator.eq) # type: ignore
871

◆ __floordiv__()

Image lsst.scarlet.lite.image.Image.__floordiv__ ( self,
Image | ScalarLike other )
Floor divide this image by `other` in place.

Definition at line 980 of file image.py.

980 def __floordiv__(self, other: Image | ScalarLike) -> Image:
981 """Floor divide this image by `other` in place."""
982 return _operate_on_images(self, other, operator.floordiv)
983

◆ __ge__()

Image lsst.scarlet.lite.image.Image.__ge__ ( self,
Image | ScalarLike other )
Check if this image is greater than or equal to another.

Definition at line 876 of file image.py.

876 def __ge__(self, other: Image | ScalarLike) -> Image:
877 """Check if this image is greater than or equal to another."""
878 if type(other) in ScalarTypes:
879 return self.copy_with(data=self.data >= other)
880 return self._check_equality(other, operator.ge)
881

◆ __getitem__()

Image lsst.scarlet.lite.image.Image.__getitem__ ( self,
Any indices )
Get the subset of an image

Parameters
----------
indices:
    The indices to select a subsection of the image.

Returns
-------
result:
    The resulting image obtained by selecting subsets of the iamge
    based on the `indices`.

Definition at line 1251 of file image.py.

1251 def __getitem__(self, indices: Any) -> Image:
1252 """Get the subset of an image
1253
1254 Parameters
1255 ----------
1256 indices:
1257 The indices to select a subsection of the image.
1258
1259 Returns
1260 -------
1261 result:
1262 The resulting image obtained by selecting subsets of the iamge
1263 based on the `indices`.
1264 """
1265 return self._get_sliced(indices)
1266

◆ __gt__()

Image lsst.scarlet.lite.image.Image.__gt__ ( self,
Image | ScalarLike other )
Check if this image is greater than or equal to another.

Definition at line 888 of file image.py.

888 def __gt__(self, other: Image | ScalarLike) -> Image:
889 """Check if this image is greater than or equal to another."""
890 if type(other) in ScalarTypes:
891 return self.copy_with(data=self.data > other)
892 return self._check_equality(other, operator.ge)
893

◆ __iadd__()

Image lsst.scarlet.lite.image.Image.__iadd__ ( self,
Image | ScalarLike other )
Combine this image and another image using addition and update
in place.

Definition at line 916 of file image.py.

916 def __iadd__(self, other: Image | ScalarLike) -> Image:
917 """Combine this image and another image using addition and update
918 in place.
919 """
920 return self._i_update(self.__add__, other)
921

◆ __iand__()

Image lsst.scarlet.lite.image.Image.__iand__ ( self,
Image | ScalarLike other )
Take the bitwise and of this and other in place.

Definition at line 1026 of file image.py.

1026 def __iand__(self, other: Image | ScalarLike) -> Image:
1027 """Take the bitwise and of this and other in place."""
1028 return self._i_update(self.__and__, other)
1029

◆ __ifloordiv__()

Image lsst.scarlet.lite.image.Image.__ifloordiv__ ( self,
Image | ScalarLike other )
Floor divide this image by `other` in place.

Definition at line 984 of file image.py.

984 def __ifloordiv__(self, other: Image | ScalarLike) -> Image:
985 """Floor divide this image by `other` in place."""
986 return self._i_update(self.__floordiv__, other)
987

◆ __ilshift__()

Image lsst.scarlet.lite.image.Image.__ilshift__ ( self,
ScalarLike other )
Shift this image to the left by other bits in place.

Definition at line 1070 of file image.py.

1070 def __ilshift__(self, other: ScalarLike) -> Image:
1071 """Shift this image to the left by other bits in place."""
1072 self[:] = self.__lshift__(other)
1073 return self
1074

◆ __imod__()

Image lsst.scarlet.lite.image.Image.__imod__ ( self,
Image | ScalarLike other )
Take the modulus of this % other in place.

Definition at line 1012 of file image.py.

1012 def __imod__(self, other: Image | ScalarLike) -> Image:
1013 """Take the modulus of this % other in place."""
1014 return self._i_update(self.__mod__, other)
1015

◆ __imul__()

Image lsst.scarlet.lite.image.Image.__imul__ ( self,
Image | ScalarLike other )
Combine this image and another image using multiplication,
with this image on the right.

Definition at line 952 of file image.py.

952 def __imul__(self, other: Image | ScalarLike) -> Image:
953 """Combine this image and another image using multiplication,
954 with this image on the right.
955 """
956 return self._i_update(self.__mul__, other)
957

◆ __invert__()

lsst.scarlet.lite.image.Image.__invert__ ( self)
Take the inverse (~) of the image.

Definition at line 908 of file image.py.

908 def __invert__(self):
909 """Take the inverse (~) of the image."""
910 return self.copy_with(data=~self._data)
911

◆ __ior__()

Image lsst.scarlet.lite.image.Image.__ior__ ( self,
Image | ScalarLike other )
Take the binary or of this or other in place.

Definition at line 1040 of file image.py.

1040 def __ior__(self, other: Image | ScalarLike) -> Image:
1041 """Take the binary or of this or other in place."""
1042 return self._i_update(self.__or__, other)
1043

◆ __ipow__()

Image lsst.scarlet.lite.image.Image.__ipow__ ( self,
Image | ScalarLike other )
Raise this image to the `other` power in place.

Definition at line 998 of file image.py.

998 def __ipow__(self, other: Image | ScalarLike) -> Image:
999 """Raise this image to the `other` power in place."""
1000 return self._i_update(self.__pow__, other)
1001

◆ __irshift__()

Image lsst.scarlet.lite.image.Image.__irshift__ ( self,
ScalarLike other )
Shift this image to the right by other bits in place.

Definition at line 1085 of file image.py.

1085 def __irshift__(self, other: ScalarLike) -> Image:
1086 """Shift this image to the right by other bits in place."""
1087 self[:] = self.__rshift__(other)
1088 return self
1089

◆ __isub__()

Image lsst.scarlet.lite.image.Image.__isub__ ( self,
Image | ScalarLike other )
Combine this image and another image using subtraction,
with this image on the right.

Definition at line 934 of file image.py.

934 def __isub__(self, other: Image | ScalarLike) -> Image:
935 """Combine this image and another image using subtraction,
936 with this image on the right.
937 """
938 return self._i_update(self.__sub__, other)
939

◆ __itruediv__()

Image lsst.scarlet.lite.image.Image.__itruediv__ ( self,
Image | ScalarLike other )
Divide this image by `other` in place.

Definition at line 970 of file image.py.

970 def __itruediv__(self, other: Image | ScalarLike) -> Image:
971 """Divide this image by `other` in place."""
972 return self._i_update(self.__truediv__, other)
973

◆ __ixor__()

Image lsst.scarlet.lite.image.Image.__ixor__ ( self,
Image | ScalarLike other )
Take the binary xor of this xor other in place.

Definition at line 1054 of file image.py.

1054 def __ixor__(self, other: Image | ScalarLike) -> Image:
1055 """Take the binary xor of this xor other in place."""
1056 return self._i_update(self.__xor__, other)
1057

◆ __le__()

Image lsst.scarlet.lite.image.Image.__le__ ( self,
Image | ScalarLike other )
Check if this image is less than or equal to another.

Definition at line 882 of file image.py.

882 def __le__(self, other: Image | ScalarLike) -> Image:
883 """Check if this image is less than or equal to another."""
884 if type(other) in ScalarTypes:
885 return self.copy_with(data=self.data <= other)
886 return self._check_equality(other, operator.le)
887

◆ __lshift__()

Image lsst.scarlet.lite.image.Image.__lshift__ ( self,
ScalarLike other )
Shift this image to the left by other bits.

Definition at line 1064 of file image.py.

1064 def __lshift__(self, other: ScalarLike) -> Image:
1065 """Shift this image to the left by other bits."""
1066 if not issubclass(np.dtype(type(other)).type, np.integer):
1067 raise TypeError("Bit shifting an image can only be done with integers")
1068 return self.copy_with(data=self.data << other)
1069

◆ __lt__()

Image lsst.scarlet.lite.image.Image.__lt__ ( self,
Image | ScalarLike other )
Check if this image is less than or equal to another.

Definition at line 894 of file image.py.

894 def __lt__(self, other: Image | ScalarLike) -> Image:
895 """Check if this image is less than or equal to another."""
896 if type(other) in ScalarTypes:
897 return self.copy_with(data=self.data < other)
898 return self._check_equality(other, operator.le)
899

◆ __mod__()

Image lsst.scarlet.lite.image.Image.__mod__ ( self,
Image | ScalarLike other )
Take the modulus of this % other.

Definition at line 1008 of file image.py.

1008 def __mod__(self, other: Image | ScalarLike) -> Image:
1009 """Take the modulus of this % other."""
1010 return _operate_on_images(self, other, operator.mod)
1011

◆ __mul__()

Image lsst.scarlet.lite.image.Image.__mul__ ( self,
Image | ScalarLike other )
Combine this image and another image using multiplication.

Definition at line 948 of file image.py.

948 def __mul__(self, other: Image | ScalarLike) -> Image:
949 """Combine this image and another image using multiplication."""
950 return _operate_on_images(self, other, operator.mul)
951

◆ __ne__()

Image lsst.scarlet.lite.image.Image.__ne__ ( self,
object other )
Check if this image is not equal to another.

Definition at line 872 of file image.py.

872 def __ne__(self, other: object) -> Image: # type: ignore
873 """Check if this image is not equal to another."""
874 return ~self.__eq__(other)
875

◆ __neg__()

lsst.scarlet.lite.image.Image.__neg__ ( self)
Take the negative of the image.

Definition at line 900 of file image.py.

900 def __neg__(self):
901 """Take the negative of the image."""
902 return self.copy_with(data=-self._data)
903

◆ __or__()

Image lsst.scarlet.lite.image.Image.__or__ ( self,
Image | ScalarLike other )
Take the binary or of this or other.

Definition at line 1036 of file image.py.

1036 def __or__(self, other: Image | ScalarLike) -> Image:
1037 """Take the binary or of this or other."""
1038 return _operate_on_images(self, other, operator.or_)
1039

◆ __pos__()

lsst.scarlet.lite.image.Image.__pos__ ( self)
Make a copy using of the image.

Definition at line 904 of file image.py.

904 def __pos__(self):
905 """Make a copy using of the image."""
906 return self.copy()
907

◆ __pow__()

Image lsst.scarlet.lite.image.Image.__pow__ ( self,
Image | ScalarLike other )
Raise this image to the `other` power.

Definition at line 994 of file image.py.

994 def __pow__(self, other: Image | ScalarLike) -> Image:
995 """Raise this image to the `other` power."""
996 return _operate_on_images(self, other, operator.pow)
997

◆ __radd__()

Image lsst.scarlet.lite.image.Image.__radd__ ( self,
Image | ScalarLike other )
Combine this image and another image using addition,
with this image on the right.

Definition at line 922 of file image.py.

922 def __radd__(self, other: Image | ScalarLike) -> Image:
923 """Combine this image and another image using addition,
924 with this image on the right.
925 """
926 if type(other) in ScalarTypes:
927 return self.copy_with(data=other + self.data)
928 return cast(Image, other).__add__(self)
929

◆ __rand__()

Image lsst.scarlet.lite.image.Image.__rand__ ( self,
Image | ScalarLike other )
Take the bitwise and of other and this.

Definition at line 1030 of file image.py.

1030 def __rand__(self, other: Image | ScalarLike) -> Image:
1031 """Take the bitwise and of other and this."""
1032 if type(other) in ScalarTypes:
1033 return self.copy_with(data=other & self.data)
1034 return cast(Image, other).__and__(self)
1035

◆ __rfloordiv__()

Image lsst.scarlet.lite.image.Image.__rfloordiv__ ( self,
Image | ScalarLike other )
Floor divide this image by `other` with this on the right.

Definition at line 988 of file image.py.

988 def __rfloordiv__(self, other: Image | ScalarLike) -> Image:
989 """Floor divide this image by `other` with this on the right."""
990 if type(other) in ScalarTypes:
991 return self.copy_with(data=other // self.data)
992 return cast(Image, other).__floordiv__(self)
993

◆ __rlshift__()

Image lsst.scarlet.lite.image.Image.__rlshift__ ( self,
ScalarLike other )
Shift other to the left by this image bits.

Definition at line 1075 of file image.py.

1075 def __rlshift__(self, other: ScalarLike) -> Image:
1076 """Shift other to the left by this image bits."""
1077 return self.copy_with(data=other << self.data)
1078

◆ __rmod__()

Image lsst.scarlet.lite.image.Image.__rmod__ ( self,
Image | ScalarLike other )
Take the modulus of other % this.

Definition at line 1016 of file image.py.

1016 def __rmod__(self, other: Image | ScalarLike) -> Image:
1017 """Take the modulus of other % this."""
1018 if type(other) in ScalarTypes:
1019 return self.copy_with(data=other % self.data)
1020 return cast(Image, other).__mod__(self)
1021

◆ __rmul__()

Image lsst.scarlet.lite.image.Image.__rmul__ ( self,
Image | ScalarLike other )
Combine this image and another image using multiplication,
with this image on the right.

Definition at line 958 of file image.py.

958 def __rmul__(self, other: Image | ScalarLike) -> Image:
959 """Combine this image and another image using multiplication,
960 with this image on the right.
961 """
962 if type(other) in ScalarTypes:
963 return self.copy_with(data=other * self.data)
964 return cast(Image, other).__mul__(self)
965

◆ __ror__()

Image lsst.scarlet.lite.image.Image.__ror__ ( self,
Image | ScalarLike other )
Take the binary or of other or this.

Definition at line 1044 of file image.py.

1044 def __ror__(self, other: Image | ScalarLike) -> Image:
1045 """Take the binary or of other or this."""
1046 if type(other) in ScalarTypes:
1047 return self.copy_with(data=other | self.data)
1048 return cast(Image, other).__or__(self)
1049

◆ __rpow__()

Image lsst.scarlet.lite.image.Image.__rpow__ ( self,
Image | ScalarLike other )
Raise this other to the power of this image.

Definition at line 1002 of file image.py.

1002 def __rpow__(self, other: Image | ScalarLike) -> Image:
1003 """Raise this other to the power of this image."""
1004 if type(other) in ScalarTypes:
1005 return self.copy_with(data=other**self.data)
1006 return cast(Image, other).__pow__(self)
1007

◆ __rrshift__()

Image lsst.scarlet.lite.image.Image.__rrshift__ ( self,
ScalarLike other )
Shift other to the right by this image bits.

Definition at line 1090 of file image.py.

1090 def __rrshift__(self, other: ScalarLike) -> Image:
1091 """Shift other to the right by this image bits."""
1092 return self.copy_with(data=other >> self.data)
1093

◆ __rshift__()

Image lsst.scarlet.lite.image.Image.__rshift__ ( self,
ScalarLike other )
Shift this image to the right by other bits.

Definition at line 1079 of file image.py.

1079 def __rshift__(self, other: ScalarLike) -> Image:
1080 """Shift this image to the right by other bits."""
1081 if not issubclass(np.dtype(type(other)).type, np.integer):
1082 raise TypeError("Bit shifting an image can only be done with integers")
1083 return self.copy_with(data=self.data >> other)
1084

◆ __rsub__()

Image lsst.scarlet.lite.image.Image.__rsub__ ( self,
Image | ScalarLike other )
Combine this image and another image using subtraction,
with this image on the right.

Definition at line 940 of file image.py.

940 def __rsub__(self, other: Image | ScalarLike) -> Image:
941 """Combine this image and another image using subtraction,
942 with this image on the right.
943 """
944 if type(other) in ScalarTypes:
945 return self.copy_with(data=other - self.data)
946 return cast(Image, other).__sub__(self)
947

◆ __rtruediv__()

Image lsst.scarlet.lite.image.Image.__rtruediv__ ( self,
Image | ScalarLike other )
Divide this image by `other` with this on the right.

Definition at line 974 of file image.py.

974 def __rtruediv__(self, other: Image | ScalarLike) -> Image:
975 """Divide this image by `other` with this on the right."""
976 if type(other) in ScalarTypes:
977 return self.copy_with(data=other / self.data)
978 return cast(Image, other).__truediv__(self)
979

◆ __rxor__()

Image lsst.scarlet.lite.image.Image.__rxor__ ( self,
Image | ScalarLike other )
Take the binary xor of other xor this.

Definition at line 1058 of file image.py.

1058 def __rxor__(self, other: Image | ScalarLike) -> Image:
1059 """Take the binary xor of other xor this."""
1060 if type(other) in ScalarTypes:
1061 return self.copy_with(data=other ^ self.data)
1062 return cast(Image, other).__xor__(self)
1063

◆ __setitem__()

Image lsst.scarlet.lite.image.Image.__setitem__ ( self,
indices,
Image value )
Set a subset of an image to a given value

Parameters
----------
indices:
    The indices to select a subsection of the image.
value:
    The value to use for the subset of the image.

Returns
-------
result:
    The resulting image obtained by selecting subsets of the image
    based on the `indices`.

Definition at line 1267 of file image.py.

1267 def __setitem__(self, indices, value: Image) -> Image:
1268 """Set a subset of an image to a given value
1269
1270 Parameters
1271 ----------
1272 indices:
1273 The indices to select a subsection of the image.
1274 value:
1275 The value to use for the subset of the image.
1276
1277 Returns
1278 -------
1279 result:
1280 The resulting image obtained by selecting subsets of the image
1281 based on the `indices`.
1282 """
1283 return self._get_sliced(indices, value)
1284
1285

◆ __str__()

lsst.scarlet.lite.image.Image.__str__ ( self)
Display the image array, bands, and bounding box.

Definition at line 1094 of file image.py.

1094 def __str__(self):
1095 """Display the image array, bands, and bounding box."""
1096 return f"Image:\n {str(self.data)}\n bands={self.bands}\n bbox={self.bbox}"
1097

◆ __sub__()

Image lsst.scarlet.lite.image.Image.__sub__ ( self,
Image | ScalarLike other )
Combine this image and another image using subtraction.

Definition at line 930 of file image.py.

930 def __sub__(self, other: Image | ScalarLike) -> Image:
931 """Combine this image and another image using subtraction."""
932 return _operate_on_images(self, other, operator.sub)
933

◆ __truediv__()

Image lsst.scarlet.lite.image.Image.__truediv__ ( self,
Image | ScalarLike other )
Divide this image by `other`.

Definition at line 966 of file image.py.

966 def __truediv__(self, other: Image | ScalarLike) -> Image:
967 """Divide this image by `other`."""
968 return _operate_on_images(self, other, operator.truediv)
969

◆ __xor__()

Image lsst.scarlet.lite.image.Image.__xor__ ( self,
Image | ScalarLike other )
Take the binary xor of this xor other.

Definition at line 1050 of file image.py.

1050 def __xor__(self, other: Image | ScalarLike) -> Image:
1051 """Take the binary xor of this xor other."""
1052 return _operate_on_images(self, other, operator.xor)
1053

◆ _check_equality()

Image lsst.scarlet.lite.image.Image._check_equality ( self,
Image | ScalarLike other,
Callable op )
protected
Compare this array to another.

This performs an element by element equality check.

Parameters
----------
other:
    The image to compare this image to.
op:
    The operator used for the comparision (==, !=, >=, <=).

Returns
-------
image: Image
    An image made by checking all of the elements in this array with
    another.

Raises
------
TypeError:
    If `other` is not an `Image`.
MismatchedBandsError:
    If `other` has different bands.
MismatchedBoxError:
    if `other` exists in a different bounding box.

Definition at line 823 of file image.py.

823 def _check_equality(self, other: Image | ScalarLike, op: Callable) -> Image:
824 """Compare this array to another.
825
826 This performs an element by element equality check.
827
828 Parameters
829 ----------
830 other:
831 The image to compare this image to.
832 op:
833 The operator used for the comparision (==, !=, >=, <=).
834
835 Returns
836 -------
837 image: Image
838 An image made by checking all of the elements in this array with
839 another.
840
841 Raises
842 ------
843 TypeError:
844 If `other` is not an `Image`.
845 MismatchedBandsError:
846 If `other` has different bands.
847 MismatchedBoxError:
848 if `other` exists in a different bounding box.
849 """
850 if isinstance(other, Image) and other.bands == self.bands and other.bbox == self.bbox:
851 return self.copy_with(data=op(self.data, other.data))
852
853 if not isinstance(other, Image):
854 if type(other) in ScalarTypes:
855 return self.copy_with(data=op(self.data, other))
856 raise TypeError(f"Cannot compare images to {type(other)}")
857
858 if other.bands != self.bands:
859 msg = f"Cannot compare images with mismatched bands: {self.bands} vs {other.bands}"
860 raise MismatchedBandsError(msg)
861
862 raise MismatchedBoxError(
863 f"Cannot compare images with different bounds boxes: {self.bbox} vs. {other.bbox}"
864 )
865

◆ _get_box_slices()

tuple[slice, slice] lsst.scarlet.lite.image.Image._get_box_slices ( self,
Box bbox )
protected
Get the slices of the image to insert it into the overlapping
region with `bbox`.

Definition at line 1122 of file image.py.

1122 def _get_box_slices(self, bbox: Box) -> tuple[slice, slice]:
1123 """Get the slices of the image to insert it into the overlapping
1124 region with `bbox`."""
1125 overlap = self.bbox & bbox
1126 if overlap != bbox:
1127 raise IndexError("Bounding box is outside of the image")
1128 origin = bbox.origin
1129 shape = bbox.shape
1130 y_start = origin[0] - self.yx0[0]
1131 y_stop = origin[0] + shape[0] - self.yx0[0]
1132 x_start = origin[1] - self.yx0[1]
1133 x_stop = origin[1] + shape[1] - self.yx0[1]
1134 y_index = slice(y_start, y_stop)
1135 x_index = slice(x_start, x_stop)
1136 return y_index, x_index
1137

◆ _get_sliced()

Image lsst.scarlet.lite.image.Image._get_sliced ( self,
Any indices,
Image | None value = None )
protected
Select a subset of an image

Parameters
----------
indices:
    The indices to select a subsection of the image.
    The spectral index can either be a tuple of indices,
    a slice of indices, or a single index used to select a
    single-band 2D image.
    The spatial index (if present) is a `Box`.

value:
    The value used to set this slice of the image.
    This allows the single `_get_sliced` method to be used for
    both getting a slice of an image and setting it.

Returns
-------
result: Image | np.ndarray
    The resulting image obtained by selecting subsets of the iamge
    based on the `indices`.

Definition at line 1138 of file image.py.

1138 def _get_sliced(self, indices: Any, value: Image | None = None) -> Image:
1139 """Select a subset of an image
1140
1141 Parameters
1142 ----------
1143 indices:
1144 The indices to select a subsection of the image.
1145 The spectral index can either be a tuple of indices,
1146 a slice of indices, or a single index used to select a
1147 single-band 2D image.
1148 The spatial index (if present) is a `Box`.
1149
1150 value:
1151 The value used to set this slice of the image.
1152 This allows the single `_get_sliced` method to be used for
1153 both getting a slice of an image and setting it.
1154
1155 Returns
1156 -------
1157 result: Image | np.ndarray
1158 The resulting image obtained by selecting subsets of the iamge
1159 based on the `indices`.
1160 """
1161 if not isinstance(indices, tuple):
1162 indices = (indices,)
1163
1164 if self.is_multiband:
1165 if self._is_spectral_index(indices[0]):
1166 if len(indices) > 1 and indices[1] in self.bands:
1167 # The indices are all band names,
1168 # so use them all as a spectral indices
1169 bands = indices
1170 spectral_index = self.spectral_indices(bands)
1171 y_index = x_index = slice(None)
1172 elif self._is_spectral_index(indices[0]):
1173 # The first index is a spectral index
1174 spectral_index = self.spectral_indices(indices[0])
1175 if isinstance(spectral_index, slice):
1176 bands = self.bands[spectral_index]
1177 elif len(spectral_index) == 1:
1178 bands = ()
1179 spectral_index = spectral_index[0] # type: ignore
1180 else:
1181 bands = tuple(self.bands[idx] for idx in spectral_index)
1182 indices = indices[1:]
1183 if len(indices) == 1:
1184 # The spatial index must be a bounding box
1185 if not isinstance(indices[0], Box):
1186 raise IndexError(f"Expected a Box for the spatial index but got {indices[1]}")
1187 y_index, x_index = self._get_box_slices(indices[0])
1188 elif len(indices) == 0:
1189 y_index = x_index = slice(None)
1190 else:
1191 raise IndexError(f"Too many spatial indices, expeected a Box bot got {indices}")
1192 full_index = (spectral_index, y_index, x_index)
1193 elif isinstance(indices[0], Box):
1194 bands = self.bands
1195 y_index, x_index = self._get_box_slices(indices[0])
1196 full_index = (slice(None), y_index, x_index)
1197 else:
1198 error = f"3D images can only be indexed by spectral indices or bounding boxes, got {indices}"
1199 raise IndexError(error)
1200 else:
1201 if len(indices) != 1 or not isinstance(indices[0], Box):
1202 raise IndexError(f"2D images can only be sliced by bounding box, got {indices}")
1203 bands = ()
1204 y_index, x_index = self._get_box_slices(indices[0])
1205 full_index = (y_index, x_index) # type: ignore
1206
1207 y0 = y_index.start
1208 if y0 is None:
1209 y0 = 0
1210
1211 x0 = x_index.start
1212 if x0 is None:
1213 x0 = 0
1214
1215 if value is None:
1216 # This is a getter,
1217 # so return an image with the data sliced properly
1218 yx0 = (y0 + self.yx0[0], x0 + self.yx0[1])
1219
1220 data = self.data[full_index]
1221
1222 if data.ndim == 2:
1223 # Only a single band was selected, so return that band
1224 return Image(data, yx0=yx0)
1225 return Image(data, bands=bands, yx0=yx0)
1226
1227 # Set the data
1228 self._data[full_index] = value.data
1229 return self
1230

◆ _i_update()

Image lsst.scarlet.lite.image.Image._i_update ( self,
Callable op,
Image | ScalarLike other )
protected
Update the data array in place.

This is typically implemented by `__i<op>__` methods,
like `__iadd__`, to apply an operator and update this image
with the data in place.

Parameters
----------
op:
    Operator used to combine this image with the `other` image.
other:
    The other image that is combined with this one using the operator
    `op`.

Returns
-------
image: Image
    This image, after being updated by the operator

Definition at line 789 of file image.py.

789 def _i_update(self, op: Callable, other: Image | ScalarLike) -> Image:
790 """Update the data array in place.
791
792 This is typically implemented by `__i<op>__` methods,
793 like `__iadd__`, to apply an operator and update this image
794 with the data in place.
795
796 Parameters
797 ----------
798 op:
799 Operator used to combine this image with the `other` image.
800 other:
801 The other image that is combined with this one using the operator
802 `op`.
803
804 Returns
805 -------
806 image: Image
807 This image, after being updated by the operator
808 """
809 dtype = get_combined_dtype(self.data, other)
810 if self.dtype != dtype:
811 if hasattr(other, "dtype"):
812 _dtype = cast(np.ndarray, other).dtype
813 else:
814 _dtype = type(other) # type: ignore
815 msg = f"Cannot update an array with type {self.dtype} with {_dtype}"
816 raise ValueError(msg)
817 result = op(other)
818 self._data[:] = result.data
819 self._bands = result.bands
820 self._yx0 = result.yx0
821 return self
822

◆ _is_spectral_index()

bool lsst.scarlet.lite.image.Image._is_spectral_index ( self,
Any index )
protected
Check to see if an index is a spectral index.

Parameters
----------
index:
    Either a slice, a tuple, or an element in `Image.bands`.

Returns
-------
result:
    ``True`` if `index` is band or tuple of bands.

Definition at line 1098 of file image.py.

1098 def _is_spectral_index(self, index: Any) -> bool:
1099 """Check to see if an index is a spectral index.
1100
1101 Parameters
1102 ----------
1103 index:
1104 Either a slice, a tuple, or an element in `Image.bands`.
1105
1106 Returns
1107 -------
1108 result:
1109 ``True`` if `index` is band or tuple of bands.
1110 """
1111 bands = self.bands
1112 if isinstance(index, slice):
1113 if index.start in bands or index.stop in bands or (index.start is None and index.stop is None):
1114 return True
1115 return False
1116 if index in self.bands:
1117 return True
1118 if isinstance(index, tuple) and index[0] in self.bands:
1119 return True
1120 return False
1121

◆ at()

ScalarLike | np.ndarray lsst.scarlet.lite.image.Image.at ( self,
int y,
int x )
The value of the image at a given location.

Image does not implment single index access because the
result is a scalar, while indexing an image returns another image.

Parameters
----------
y:
    The y-coordinate of the location.
x:
    The x-coordinate of the location.

Returns
-------
value:
    The value of the image at the given location.

Definition at line 765 of file image.py.

765 def at(self, y: int, x: int) -> ScalarLike | np.ndarray:
766 """The value of the image at a given location.
767
768 Image does not implment single index access because the
769 result is a scalar, while indexing an image returns another image.
770
771 Parameters
772 ----------
773 y:
774 The y-coordinate of the location.
775 x:
776 The x-coordinate of the location.
777
778 Returns
779 -------
780 value:
781 The value of the image at the given location.
782 """
783 _y = y - self.y0
784 _x = x - self.x0
785 if self.ndim == 2:
786 return self.data[_y, _x]
787 return self.data[:, _y, _x]
788

◆ bands()

tuple lsst.scarlet.lite.image.Image.bands ( self)
The bands used in the image.

Definition at line 419 of file image.py.

419 def bands(self) -> tuple:
420 """The bands used in the image."""
421 return self._bands
422

◆ bbox()

Box lsst.scarlet.lite.image.Image.bbox ( self)
Bounding box for the special dimensions in the image.

Definition at line 463 of file image.py.

463 def bbox(self) -> Box:
464 """Bounding box for the special dimensions in the image."""
465 return Box(self.shape[-2:], self._yx0)
466

◆ copy()

Image lsst.scarlet.lite.image.Image.copy ( self,
order = None )
Make a copy of this image.

Parameters
----------
order:
    The ordering to use for storing the bytes.
    This is unlikely to be needed, and just defaults to
    the numpy behavior (C) ordering.

Returns
-------
image: Image
    The copy of this image.

Definition at line 685 of file image.py.

685 def copy(self, order=None) -> Image:
686 """Make a copy of this image.
687
688 Parameters
689 ----------
690 order:
691 The ordering to use for storing the bytes.
692 This is unlikely to be needed, and just defaults to
693 the numpy behavior (C) ordering.
694
695 Returns
696 -------
697 image: Image
698 The copy of this image.
699 """
700 return self.copy_with(order=order)
701

◆ copy_with()

lsst.scarlet.lite.image.Image.copy_with ( self,
np.ndarray | None data = None,
str | None order = None,
tuple[str, ...] | None bands = None,
tuple[int, int] | None yx0 = None )
Copy of this image with some parameters updated.

Any parameters not specified by the user will be copied from the
current image.

Parameters
----------
data:
    An update for the data in the image.
order:
    The ordering for stored bytes, from numpy.copy.
bands:
    The bands that the resulting image will have.
    The number of bands must be the same as the first dimension
    in the data array.
yx0:
    The lower-left of the image bounding box.

Returns
-------
image: Image
    The copied image.

Definition at line 702 of file image.py.

708 ):
709 """Copy of this image with some parameters updated.
710
711 Any parameters not specified by the user will be copied from the
712 current image.
713
714 Parameters
715 ----------
716 data:
717 An update for the data in the image.
718 order:
719 The ordering for stored bytes, from numpy.copy.
720 bands:
721 The bands that the resulting image will have.
722 The number of bands must be the same as the first dimension
723 in the data array.
724 yx0:
725 The lower-left of the image bounding box.
726
727 Returns
728 -------
729 image: Image
730 The copied image.
731 """
732 if order is None:
733 order = "C"
734 if data is None:
735 data = self.data.copy(order) # type: ignore
736 if bands is None:
737 bands = self.bands
738 if yx0 is None:
739 yx0 = self.yx0
740 return Image(data, bands, yx0)
741

◆ data()

np.ndarray lsst.scarlet.lite.image.Image.data ( self)
The image viewed as a numpy array.

Definition at line 468 of file image.py.

468 def data(self) -> np.ndarray:
469 """The image viewed as a numpy array."""
470 return self._data
471

◆ dtype()

DTypeLike lsst.scarlet.lite.image.Image.dtype ( self)
The numpy dtype of the image.

Definition at line 414 of file image.py.

414 def dtype(self) -> DTypeLike:
415 """The numpy dtype of the image."""
416 return self._data.dtype
417

◆ from_box()

Image lsst.scarlet.lite.image.Image.from_box ( Box bbox,
tuple | None bands = None,
DTypeLike dtype = float )
static
Initialize an empty image from a bounding Box and optional bands

Parameters
----------
bbox:
    The bounding box that contains the image.
bands:
    The bands for the image.
    If bands is `None` then a 2D image is created.
dtype:
    The numpy dtype of the image.

Returns
-------
image:
    An empty image contained in ``bbox`` with ``bands`` bands.

Definition at line 380 of file image.py.

380 def from_box(bbox: Box, bands: tuple | None = None, dtype: DTypeLike = float) -> Image:
381 """Initialize an empty image from a bounding Box and optional bands
382
383 Parameters
384 ----------
385 bbox:
386 The bounding box that contains the image.
387 bands:
388 The bands for the image.
389 If bands is `None` then a 2D image is created.
390 dtype:
391 The numpy dtype of the image.
392
393 Returns
394 -------
395 image:
396 An empty image contained in ``bbox`` with ``bands`` bands.
397 """
398 if bands is not None and len(bands) > 0:
399 shape = (len(bands),) + bbox.shape
400 else:
401 shape = bbox.shape
402 data = np.zeros(shape, dtype=dtype)
403 return Image(data, bands=bands, yx0=cast(tuple[int, int], bbox.origin))
404

◆ height()

int lsst.scarlet.lite.image.Image.height ( self)
Height of the image.

Definition at line 438 of file image.py.

438 def height(self) -> int:
439 """Height of the image."""
440 return self.shape[-2]
441

◆ insert()

Image lsst.scarlet.lite.image.Image.insert ( self,
Image image,
Callable op = operator.add )
Insert another image into this image in place.

Parameters
----------
image:
    The image to insert this image into.
op:
    The operator to use when combining the images.

Returns
-------
result:
    This instance with `image` inserted.

Definition at line 647 of file image.py.

647 def insert(self, image: Image, op: Callable = operator.add) -> Image:
648 """Insert another image into this image in place.
649
650 Parameters
651 ----------
652 image:
653 The image to insert this image into.
654 op:
655 The operator to use when combining the images.
656
657 Returns
658 -------
659 result:
660 This instance with `image` inserted.
661 """
662 return insert_image(self, image, op)
663

◆ insert_into()

Image lsst.scarlet.lite.image.Image.insert_into ( self,
Image image,
Callable op = operator.add )
Insert this image into another image in place.

Parameters
----------
image:
    The image to insert this image into.
op:
    The operator to use when combining the images.

Returns
-------
result:
    `image` updated by inserting this instance.

Definition at line 626 of file image.py.

630 ) -> Image:
631 """Insert this image into another image in place.
632
633 Parameters
634 ----------
635 image:
636 The image to insert this image into.
637 op:
638 The operator to use when combining the images.
639
640 Returns
641 -------
642 result:
643 `image` updated by inserting this instance.
644 """
645 return insert_image(image, self, op)
646

◆ is_multiband()

bool lsst.scarlet.lite.image.Image.is_multiband ( self)
Whether or not the image has a spectral dimension.

Definition at line 433 of file image.py.

433 def is_multiband(self) -> bool:
434 """Whether or not the image has a spectral dimension."""
435 return self.n_bands > 0
436

◆ matched_slices()

tuple[tuple[slice, ...], tuple[slice, ...]] lsst.scarlet.lite.image.Image.matched_slices ( self,
Box bbox )
Get the slices to match this image to a given bounding box

Parameters
----------
bbox:
    The bounding box to match this image to.

Returns
-------
result:
    Tuple of indices/slices to match this image to the given bbox.

Definition at line 553 of file image.py.

553 def matched_slices(self, bbox: Box) -> tuple[tuple[slice, ...], tuple[slice, ...]]:
554 """Get the slices to match this image to a given bounding box
555
556 Parameters
557 ----------
558 bbox:
559 The bounding box to match this image to.
560
561 Returns
562 -------
563 result:
564 Tuple of indices/slices to match this image to the given bbox.
565 """
566 if self.bbox == bbox:
567 # No need to slice, since the boxes match
568 _slice = (slice(None),) * bbox.ndim
569 return _slice, _slice
570
571 slices = self.bbox.overlapped_slices(bbox)
572 return slices
573

◆ matched_spectral_indices()

tuple[tuple[int, ...] | slice, tuple[int, ...] | slice] lsst.scarlet.lite.image.Image.matched_spectral_indices ( self,
Image other )
Match bands between two images

Parameters
----------
other:
    The other image to match spectral indices to.

Returns
-------
result:
    A tuple with a tuple of indices/slices for each dimension,
    including the spectral dimension.

Definition at line 518 of file image.py.

521 ) -> tuple[tuple[int, ...] | slice, tuple[int, ...] | slice]:
522 """Match bands between two images
523
524 Parameters
525 ----------
526 other:
527 The other image to match spectral indices to.
528
529 Returns
530 -------
531 result:
532 A tuple with a tuple of indices/slices for each dimension,
533 including the spectral dimension.
534 """
535 if self.bands == other.bands and self.n_bands != 0:
536 # The bands match
537 return slice(None), slice(None)
538 if self.n_bands == 0 and other.n_bands == 0:
539 # The images are 2D, so no spectral slicing is necessary
540 return (), ()
541 if self.n_bands == 0 and other.n_bands > 1:
542 err = "Attempted to insert a monochromatic image into a mutli-band image"
543 raise ValueError(err)
544 if other.n_bands == 0:
545 err = "Attempted to insert a multi-band image into a monochromatic image"
546 raise ValueError(err)
547
548 self_indices = cast(tuple[int, ...], self.spectral_indices(other.bands))
549 matched_bands = tuple(self.bands[bidx] for bidx in self_indices)
550 other_indices = cast(tuple[int, ...], other.spectral_indices(matched_bands))
551 return other_indices, self_indices
552

◆ multiband_slices()

tuple[tuple[int, ...] | slice, slice, slice] lsst.scarlet.lite.image.Image.multiband_slices ( self)
Return the slices required to slice a multiband image

Definition at line 622 of file image.py.

622 def multiband_slices(self) -> tuple[tuple[int, ...] | slice, slice, slice]:
623 """Return the slices required to slice a multiband image"""
624 return (self.spectral_indices(self.bands),) + self.bbox.slices # type: ignore
625

◆ n_bands()

int lsst.scarlet.lite.image.Image.n_bands ( self)
Number of bands in the image.

If `n_bands == 0` then the image is 2D and does not have a spectral
dimension.

Definition at line 424 of file image.py.

424 def n_bands(self) -> int:
425 """Number of bands in the image.
426
427 If `n_bands == 0` then the image is 2D and does not have a spectral
428 dimension.
429 """
430 return len(self._bands)
431

◆ ndim()

int lsst.scarlet.lite.image.Image.ndim ( self)
Number of dimensions in the image.

Definition at line 473 of file image.py.

473 def ndim(self) -> int:
474 """Number of dimensions in the image."""
475 return self._data.ndim
476

◆ overlapped_slices()

tuple[tuple[slice, ...], tuple[slice, ...]] lsst.scarlet.lite.image.Image.overlapped_slices ( self,
Box bbox )
Get the slices needed to insert this image into a bounding box.

Parameters
----------
bbox:
    The region to insert this image into.

Returns
-------
overlap:
    The slice of this image and the slice of the `bbox` required to
    insert the overlapping portion of this image.

Definition at line 1231 of file image.py.

1231 def overlapped_slices(self, bbox: Box) -> tuple[tuple[slice, ...], tuple[slice, ...]]:
1232 """Get the slices needed to insert this image into a bounding box.
1233
1234 Parameters
1235 ----------
1236 bbox:
1237 The region to insert this image into.
1238
1239 Returns
1240 -------
1241 overlap:
1242 The slice of this image and the slice of the `bbox` required to
1243 insert the overlapping portion of this image.
1244
1245 """
1246 overlap = self.bbox.overlapped_slices(bbox)
1247 if self.is_multiband:
1248 overlap = (slice(None),) + overlap[0], (slice(None),) + overlap[1]
1249 return overlap
1250

◆ project()

Image lsst.scarlet.lite.image.Image.project ( self,
object | tuple[object] | None bands = None,
Box | None bbox = None )
Project this image into a different set of bands

 Parameters
 ----------
 bands:
    Spectral bands to project this image into.
    Not all bands have to be contained in the image, and not all
    bands contained in the image have to be used in the projection.
 bbox:
    A bounding box to project the image into.

Results
-------
image:
    A new image creating by projecting this image into
    `bbox` and `bands`.

Definition at line 574 of file image.py.

578 ) -> Image:
579 """Project this image into a different set of bands
580
581 Parameters
582 ----------
583 bands:
584 Spectral bands to project this image into.
585 Not all bands have to be contained in the image, and not all
586 bands contained in the image have to be used in the projection.
587 bbox:
588 A bounding box to project the image into.
589
590 Results
591 -------
592 image:
593 A new image creating by projecting this image into
594 `bbox` and `bands`.
595 """
596 if bands is None:
597 bands = self.bands
598 if not isinstance(bands, tuple):
599 bands = (bands,)
600 if self.is_multiband:
601 indices = self.spectral_indices(bands)
602 data = self.data[indices, :]
603 else:
604 data = self.data
605
606 if bbox is None:
607 return Image(data, bands=bands, yx0=self.yx0)
608
609 if self.is_multiband:
610 image = np.zeros((len(bands),) + bbox.shape, dtype=data.dtype)
611 slices = bbox.overlapped_slices(self.bbox)
612 # Insert a slice for the spectral dimension
613 image[(slice(None),) + slices[0]] = data[(slice(None),) + slices[1]]
614 return Image(image, bands=bands, yx0=cast(tuple[int, int], bbox.origin))
615
616 image = np.zeros(bbox.shape, dtype=data.dtype)
617 slices = bbox.overlapped_slices(self.bbox)
618 image[slices[0]] = data[slices[1]]
619 return Image(image, bands=bands, yx0=cast(tuple[int, int], bbox.origin))
620

◆ repeat()

Image lsst.scarlet.lite.image.Image.repeat ( self,
tuple bands )
Project a 2D image into the spectral dimension

Parameters
----------
bands:
    The bands in the projected image.

Returns
-------
result: Image
    The 2D image repeated in each band in the spectral dimension.

Definition at line 664 of file image.py.

664 def repeat(self, bands: tuple) -> Image:
665 """Project a 2D image into the spectral dimension
666
667 Parameters
668 ----------
669 bands:
670 The bands in the projected image.
671
672 Returns
673 -------
674 result: Image
675 The 2D image repeated in each band in the spectral dimension.
676 """
677 if self.is_multiband:
678 raise ValueError("Image.repeat only works with 2D images")
679 return self.copy_with(
680 np.repeat(self.data[None, :, :], len(bands), axis=0),
681 bands=bands,
682 yx0=self.yx0,
683 )
684

◆ shape()

tuple[int, ...] lsst.scarlet.lite.image.Image.shape ( self)
The shape of the image.

This includes the spectral dimension, if there is one.

Definition at line 406 of file image.py.

406 def shape(self) -> tuple[int, ...]:
407 """The shape of the image.
408
409 This includes the spectral dimension, if there is one.
410 """
411 return self._data.shape
412

◆ spectral_indices()

tuple[int, ...] | slice lsst.scarlet.lite.image.Image.spectral_indices ( self,
Sequence | slice bands )
The indices to extract each band in `bands` in order from the image

This converts a band name, or list of band names,
into numerical indices that can be used to slice the internal numpy
`data` array.

Parameters
---------
bands:
    If `bands` is a list of band names, then the result will be an
    index corresponding to each band, in order.
    If `bands` is a slice, then the ``start`` and ``stop`` properties
    should be band names, and the result will be a slice with the
    appropriate indices to start at `bands.start` and end at
    `bands.stop`.

Returns
-------
band_indices:
    Tuple of indices for each band in this image.

Definition at line 477 of file image.py.

477 def spectral_indices(self, bands: Sequence | slice) -> tuple[int, ...] | slice:
478 """The indices to extract each band in `bands` in order from the image
479
480 This converts a band name, or list of band names,
481 into numerical indices that can be used to slice the internal numpy
482 `data` array.
483
484 Parameters
485 ---------
486 bands:
487 If `bands` is a list of band names, then the result will be an
488 index corresponding to each band, in order.
489 If `bands` is a slice, then the ``start`` and ``stop`` properties
490 should be band names, and the result will be a slice with the
491 appropriate indices to start at `bands.start` and end at
492 `bands.stop`.
493
494 Returns
495 -------
496 band_indices:
497 Tuple of indices for each band in this image.
498 """
499 if isinstance(bands, slice):
500 # Convert a slice of band names into a slice of array indices
501 # to select the appropriate slice.
502 if bands.start is None:
503 start = None
504 else:
505 start = self.bands.index(bands.start)
506 if bands.stop is None:
507 stop = None
508 else:
509 stop = self.bands.index(bands.stop) + 1
510 return slice(start, stop, bands.step)
511
512 if isinstance(bands, str):
513 return (self.bands.index(bands),)
514
515 band_indices = tuple(self.bands.index(band) for band in bands if band in self.bands)
516 return band_indices
517

◆ trimmed()

Image lsst.scarlet.lite.image.Image.trimmed ( self,
float threshold = 0 )
Return a copy of the image trimmed to a threshold.

This is essentially the smallest image that contains all of the
pixels above the threshold.

Parameters
----------
threshold:
    The threshold to use for trimming the image.

Returns
-------
image:
    A copy of the image trimmed to the threshold.

Definition at line 742 of file image.py.

742 def trimmed(self, threshold: float = 0) -> Image:
743 """Return a copy of the image trimmed to a threshold.
744
745 This is essentially the smallest image that contains all of the
746 pixels above the threshold.
747
748 Parameters
749 ----------
750 threshold:
751 The threshold to use for trimming the image.
752
753 Returns
754 -------
755 image:
756 A copy of the image trimmed to the threshold.
757 """
758 data = self.data.copy()
759 bbox = Box.from_data(data, threshold=threshold)
760 data = data[bbox.slices]
761 y0, x0 = bbox.origin
762
763 return Image(data, yx0=(y0 + self.y0, x0 + self.x0))
764

◆ width()

int lsst.scarlet.lite.image.Image.width ( self)
Width of the image.

Definition at line 443 of file image.py.

443 def width(self) -> int:
444 """Width of the image."""
445 return self.shape[-1]
446

◆ x0()

int lsst.scarlet.lite.image.Image.x0 ( self)
Location of the x-offset.

Definition at line 458 of file image.py.

458 def x0(self) -> int:
459 """Location of the x-offset."""
460 return self._yx0[1]
461

◆ y0()

int lsst.scarlet.lite.image.Image.y0 ( self)
location of the y-offset.

Definition at line 453 of file image.py.

453 def y0(self) -> int:
454 """location of the y-offset."""
455 return self._yx0[0]
456

◆ yx0()

tuple[int, int] lsst.scarlet.lite.image.Image.yx0 ( self)
Origin of the image, in numpy/C++ y,x ordering.

Definition at line 448 of file image.py.

448 def yx0(self) -> tuple[int, int]:
449 """Origin of the image, in numpy/C++ y,x ordering."""
450 return self._yx0
451

Member Data Documentation

◆ _bands

lsst.scarlet.lite.image.Image._bands = bands
protected

Definition at line 377 of file image.py.

◆ _data

np.ndarray lsst.scarlet.lite.image.Image._data = data
protected

Definition at line 375 of file image.py.

◆ _yx0

lsst.scarlet.lite.image.Image._yx0 = yx0
protected

Definition at line 376 of file image.py.

◆ bands

lsst.scarlet.lite.image.Image.bands = 0:

Definition at line 535 of file image.py.

◆ bbox

Box lsst.scarlet.lite.image.Image.bbox = bbox:

Definition at line 566 of file image.py.

◆ is_multiband

lsst.scarlet.lite.image.Image.is_multiband

Definition at line 600 of file image.py.

◆ n_bands

int lsst.scarlet.lite.image.Image.n_bands = 0:

Definition at line 538 of file image.py.

◆ ndim

int lsst.scarlet.lite.image.Image.ndim = 2:

Definition at line 785 of file image.py.


The documentation for this class was generated from the following file: