22__all__ = [
"MultibandFootprint"]
32from .
import Footprint, makeHeavyFootprint
36 """Create a Footprint from a set of Images
41 Images to extract the footprint
from
43 All pixels above `thresh` will be included
in the footprint
45 Location of the minimum value of the images bounding box
46 (
if images
is an array, otherwise the image bounding box
is used).
51 Union of all spans
in the images above the threshold
52 imageBBox : `lsst.afw.detection.Box2I`
53 Bounding box
for the input images.
56 if not hasattr(thresh,
"__len__"):
57 thresh = [thresh] * len(images)
61 if isinstance(images, MultibandBase)
or isinstance(images[0], Image):
63 for n, image
in enumerate(images):
64 mask = image.array > thresh[n]
65 mask =
Mask(mask.astype(np.int32), xy0=image.getBBox().getMin())
66 spans = spans.union(SpanSet.fromMask(mask))
67 imageBBox = images[0].getBBox()
70 thresh = np.array(thresh)
73 mask = np.any(images > thresh[:,
None,
None], axis=0)
74 mask =
Mask(mask.astype(np.int32), xy0=xy0)
75 spans = SpanSet.fromMask(mask)
76 imageBBox = mask.getBBox()
77 return spans, imageBBox
81 """Create an image of a HeavyFootprint
85 heavy : `HeavyFootprint`
86 The HeavyFootprint to insert into the image
88 Number to fill the pixels in the image that are
not
91 Bounding box of the output image.
93 This should be either a `MaskedImage`
or `Image`
and describes
94 the type of the output image.
99 An image defined by `bbox`
and padded
with `fill` that
100 contains the projected flux
in `heavy`.
103 bbox = heavy.getBBox()
104 image = imageType(bbox, dtype=heavy.getImageArray().dtype)
111 """Multiband Footprint class
113 A `MultibandFootprint` is a collection of HeavyFootprints that have
114 the same `SpanSet`
and `peakCatalog` but different flux
in each band.
119 List of filter names.
121 A list of single band `HeavyFootprint` objects.
122 Each `HeavyFootprint` should have the same `PeakCatalog`
123 and the same `SpanSet`, however to save CPU cycles there
124 is no internal check
for consistency of the peak catalog.
130 if not all([heavy.getSpans() == spans
for heavy
in singles]):
131 raise ValueError(
"All HeavyFootprints in singles are expected to have the same SpanSet")
135 footprint.setPeakCatalog(singles[0].
getPeaks())
139 def fromArrays(filters, image, mask=None, variance=None, footprint=None, xy0=None, thresh=0, peaks=None):
140 """Create a `MultibandFootprint` from an `image`, `mask`, `variance`
145 List of filter names.
148 Only pixels above the `thresh` value for at least one band
149 will be included
in the `SpanSet`
and resulting footprints.
151 Mask
for the `image` array.
153 Variance of the `image` array.
154 footprint : `Footprint`
155 `Footprint` that contains the `SpanSet`
and `PeakCatalog`
156 to use
for the `HeavyFootprint`
in each band.
157 If `footprint`
is `
None` then the `thresh`
is used to create a
158 `Footprint` based on the pixels above the `thresh` value.
160 If `image`
is an array
and `footprint`
is `
None` then specifying
161 `xy0` gives the location of the minimum `x`
and `y` value of the
163 thresh : `float`
or list of floats
164 Threshold
in each band (
or the same threshold to be used
in all bands)
165 to include a pixel
in the `SpanSet` of the `MultibandFootprint`.
166 If `Footprint`
is not `
None` then `thresh`
is ignored.
167 peaks : `PeakCatalog`
168 Catalog containing information about the peaks located
in the
173 result : `MultibandFootprint`
174 MultibandFootprint created
from the arrays
177 if footprint
is None:
181 imageBBox = footprint.getBBox()
183 if peaks
is not None:
184 footprint.setPeakCatalog(peaks)
185 mMaskedImage = MultibandMaskedImage.fromArrays(filters, image, mask, variance, imageBBox)
186 singles = [
makeHeavyFootprint(footprint, maskedImage)
for maskedImage
in mMaskedImage]
190 def fromImages(filters, image, mask=None, variance=None, footprint=None, thresh=0, peaks=None):
191 """Create a `MultibandFootprint` from an `image`, `mask`, `variance`
196 List of filter names.
199 to convert into `HeavyFootprint` objects.
200 Only pixels above the `thresh` value
for at least one band
201 will be included
in the `SpanSet`
and resulting footprints.
202 mask : `MultibandMask`
or list of `Mask`
203 Mask
for the `image`.
205 Variance of the `image`.
206 thresh : `float`
or `list` of floats
207 Threshold
in each band (
or the same threshold to be used
in all bands)
208 to include a pixel
in the `SpanSet` of the `MultibandFootprint`.
209 If `Footprint`
is not `
None` then `thresh`
is ignored.
210 peaks : `PeakCatalog`
211 Catalog containing information about the peaks located
in the
216 result : `MultibandFootprint`
217 MultibandFootprint created
from the image, mask,
and variance
220 if footprint
is None:
224 if peaks
is not None:
225 footprint.setPeakCatalog(peaks)
227 singles = [
makeHeavyFootprint(footprint, maskedImage)
for maskedImage
in mMaskedImage]
232 """Create a `MultibandFootprint` from a list of `MaskedImage`
234 See `fromImages` for a description of the parameters
not listed below
239 MaskedImages to extract the single band heavy footprints
from.
240 Like `fromImages`,
if a `footprint`
is not specified then all
241 pixels above `thresh` will be used,
and `peaks` will be added
242 to the `PeakCatalog`.
246 result : `MultibandFootprint`
247 MultibandFootprint created
from the image, mask,
and variance
249 image = [maskedImage.image for maskedImage
in maskedImages]
250 mask = [maskedImage.mask
for maskedImage
in maskedImages]
251 variance = [maskedImage.variance
for maskedImage
in maskedImages]
252 return MultibandFootprint.fromImages(filters, image, mask, variance, footprint, thresh, peaks)
255 """Get the full `SpanSet`"""
260 """Common SpanSet and peak catalog for the single band footprints"""
265 """MultibandMaskedImage that the footprints present a view into"""
266 return self._mMaskedImage
270 """`SpanSet` of the `MultibandFootprint`"""
274 """Get the `PeakCatalog`"""
279 """`PeakCatalog` of the `MultibandFootprint`"""
282 def _slice(self, filters, filterIndex, indices):
283 """Slice the current object and return the result
285 `MultibandFootprint` objects cannot be sliced along the image
286 dimension, so an error is thrown
if `indices` has any elements.
288 See `Multiband._slice`
for a list of the parameters.
291 raise IndexError(
"MultibandFootprints can only be sliced in the filter dimension")
293 if isinstance(filterIndex, slice):
294 singles = self.
singlessingles[filterIndex]
296 singles = [self.
singlessingles[idx]
for idx
in filterIndex]
300 def getImage(self, bbox=None, fill=np.nan, imageType=MultibandMaskedImage):
301 """Convert a `MultibandFootprint` to a `MultibandImage`
303 This returns the heavy footprints converted into an `MultibandImage` or
304 `MultibandMaskedImage` (depending on `imageType`).
305 This might be different than the internal `mMaskedImage` property
306 of the `MultibandFootprint`,
as the `mMaskedImage` might contain
307 some non-zero pixels
not contained
in the footprint but present
in
313 Bounding box of the resulting image.
314 If no bounding box
is specified, then the bounding box
315 of the footprint
is used.
317 Value to use
for any pixel
in the resulting image
318 outside of the `SpanSet`.
320 This should be either a `MultibandMaskedImage`
321 or `MultibandImage`
and describes the type of the output image.
325 result : `MultibandBase`
326 The resulting `MultibandImage`
or `MultibandMaskedImage` created
327 from the `MultibandHeavyFootprint`.
329 if imageType == MultibandMaskedImage:
330 singleType = MaskedImage
331 elif imageType == MultibandImage:
334 raise TypeError(
"Expected imageType to be either MultibandImage or MultibandMaskedImage")
336 mMaskedImage = imageType.fromImages(self.
filtersfilters, maskedImages)
340 """Copy the current object
345 Whether or not to make a deep copy
349 result : `MultibandFootprint`
350 The cloned footprint.
355 footprint.addPeak(peak.getX(), peak.getY(), peak.getValue())
356 mMaskedImage = self.
getImagegetImage()
357 filters = tuple([f
for f
in self.
filtersfilters])
358 result = MultibandFootprint.fromMaskedImages(filters, mMaskedImage, footprint)
A compact representation of a collection of pixels.
A class to represent a 2-dimensional array of pixels.
A class to manipulate images, masks, and variance as a single object.
def heavyFootprintToImage(heavy, fill=np.nan, bbox=None, imageType=MaskedImage)
def getSpanSetFromImages(images, thresh=0, xy0=None)
HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > makeHeavyFootprint(Footprint const &foot, lsst::afw::image::MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > const &img, HeavyFootprintCtrl const *ctrl=nullptr)
Create a HeavyFootprint with footprint defined by the given Footprint and pixel values from the given...
lsst::afw::detection::Footprint Footprint