22__all__ = [
"MultibandFootprint"]
35from .
import Footprint, makeHeavyFootprint
39 """Create a Footprint from a set of Images
43 images : `lsst.afw.image.MultibandImage` or list of `lsst.afw.image.Image`, array
44 Images to extract the footprint from
46 All pixels above `thresh` will be included in the footprint
47 xy0 : `lsst.geom.Point2I`
48 Location of the minimum value of the images bounding box
49 (if images is an array, otherwise the image bounding box is used).
53 spans : `lsst.afw.geom.SpanSet`
54 Union of all spans in the images above the threshold
55 imageBBox : `lsst.afw.detection.Box2I`
56 Bounding box for the input images.
59 if not hasattr(thresh,
"__len__"):
60 thresh = [thresh] * len(images)
64 if isinstance(images, MultibandBase)
or isinstance(images[0], Image):
66 for n, image
in enumerate(images):
67 mask = image.array > thresh[n]
68 mask =
Mask(mask.astype(np.int32), xy0=image.getBBox().getMin())
69 spans = spans.union(SpanSet.fromMask(mask))
70 imageBBox = images[0].getBBox()
73 thresh = np.array(thresh)
76 mask = np.any(images > thresh[:,
None,
None], axis=0)
77 mask =
Mask(mask.astype(np.int32), xy0=xy0)
78 spans = SpanSet.fromMask(mask)
79 imageBBox = mask.getBBox()
80 return spans, imageBBox
84 """Multiband Footprint class
86 A `MultibandFootprint` is a collection of HeavyFootprints that have
87 the same `SpanSet` and `peakCatalog` but different flux in each band.
94 A list of single band `HeavyFootprint` objects.
95 Each `HeavyFootprint` should have the same `PeakCatalog`
96 and the same `SpanSet`, however to save CPU cycles there
97 is no internal check for consistency of the peak catalog.
103 if not all([heavy.getSpans() == spans
for heavy
in singles]):
104 raise ValueError(
"All HeavyFootprints in singles are expected to have the same SpanSet")
107 footprint = Footprint(spans)
108 footprint.setPeakCatalog(singles[0].
getPeaks())
112 def fromArrays(filters, image, mask=None, variance=None, footprint=None, xy0=None, thresh=0, peaks=None):
113 """Create a `MultibandFootprint` from an `image`, `mask`, `variance`
118 List of filter names.
120 An array to convert into `lsst.afw.detection.HeavyFootprint` objects.
121 Only pixels above the `thresh` value for at least one band
122 will be included in the `SpanSet` and resulting footprints.
124 Mask for the `image` array.
126 Variance of the `image` array.
127 footprint : `Footprint`
128 `Footprint` that contains the `SpanSet` and `PeakCatalog`
129 to use for the `HeavyFootprint` in each band.
130 If `footprint` is `None` then the `thresh` is used to create a
131 `Footprint` based on the pixels above the `thresh` value.
133 If `image` is an array and `footprint` is `None` then specifying
134 `xy0` gives the location of the minimum `x` and `y` value of the
136 thresh : `float` or list of floats
137 Threshold in each band (or the same threshold to be used in all bands)
138 to include a pixel in the `SpanSet` of the `MultibandFootprint`.
139 If `Footprint` is not `None` then `thresh` is ignored.
140 peaks : `PeakCatalog`
141 Catalog containing information about the peaks located in the
146 result : `MultibandFootprint`
147 MultibandFootprint created from the arrays
150 if footprint
is None:
152 footprint = Footprint(spans)
154 imageBBox = footprint.getBBox()
156 if peaks
is not None:
157 footprint.setPeakCatalog(peaks)
158 mMaskedImage = MultibandMaskedImage.fromArrays(filters, image, mask, variance, imageBBox)
159 singles = [makeHeavyFootprint(footprint, maskedImage)
for maskedImage
in mMaskedImage]
163 def fromImages(filters, image, mask=None, variance=None, footprint=None, thresh=0, peaks=None):
164 """Create a `MultibandFootprint` from an `image`, `mask`, `variance`
169 List of filter names.
170 image : `lsst.afw.image.MultibandImage`, or list of `lsst.afw.image.Image`
171 A `lsst.afw.image.MultibandImage` (or collection of images in each band)
172 to convert into `HeavyFootprint` objects.
173 Only pixels above the `thresh` value for at least one band
174 will be included in the `SpanSet` and resulting footprints.
175 mask : `MultibandMask` or list of `Mask`
176 Mask for the `image`.
177 variance : `lsst.afw.image.MultibandImage`, or list of `lsst.afw.image.Image`
178 Variance of the `image`.
179 thresh : `float` or `list` of floats
180 Threshold in each band (or the same threshold to be used in all bands)
181 to include a pixel in the `SpanSet` of the `MultibandFootprint`.
182 If `Footprint` is not `None` then `thresh` is ignored.
183 peaks : `PeakCatalog`
184 Catalog containing information about the peaks located in the
189 result : `MultibandFootprint`
190 MultibandFootprint created from the image, mask, and variance
193 if footprint
is None:
195 footprint = Footprint(spans)
197 if peaks
is not None:
198 footprint.setPeakCatalog(peaks)
200 singles = [makeHeavyFootprint(footprint, maskedImage)
for maskedImage
in mMaskedImage]
205 """Create a `MultibandFootprint` from a list of `MaskedImage`
207 See `fromImages` for a description of the parameters not listed below
211 maskedImages : `list` of `lsst.afw.image.MaskedImage`
212 MaskedImages to extract the single band heavy footprints from.
213 Like `fromImages`, if a `footprint` is not specified then all
214 pixels above `thresh` will be used, and `peaks` will be added
215 to the `PeakCatalog`.
219 result : `MultibandFootprint`
220 MultibandFootprint created from the image, mask, and variance
222 image = [maskedImage.image
for maskedImage
in maskedImages]
223 mask = [maskedImage.mask
for maskedImage
in maskedImages]
224 variance = [maskedImage.variance
for maskedImage
in maskedImages]
225 return MultibandFootprint.fromImages(filters, image, mask, variance, footprint, thresh, peaks)
228 """Get the full `SpanSet`"""
233 """Common SpanSet and peak catalog for the single band footprints"""
238 """MultibandMaskedImage that the footprints present a view into"""
239 return self._mMaskedImage
243 """`SpanSet` of the `MultibandFootprint`"""
247 """Get the `PeakCatalog`"""
252 """`PeakCatalog` of the `MultibandFootprint`"""
255 def _slice(self, filters, filterIndex, indices):
256 """Slice the current object and return the result
258 `MultibandFootprint` objects cannot be sliced along the image
259 dimension, so an error is thrown if `indices` has any elements.
261 See `Multiband._slice` for a list of the parameters.
264 raise IndexError(
"MultibandFootprints can only be sliced in the filter dimension")
266 if isinstance(filterIndex, slice):
267 singles = self.
singles[filterIndex]
269 singles = [self.
singles[idx]
for idx
in filterIndex]
273 def getImage(self, bbox=None, fill=np.nan, imageType=MultibandMaskedImage):
274 """Convert a `MultibandFootprint` to a `MultibandImage`
276 This returns the heavy footprints converted into an `MultibandImage` or
277 `MultibandMaskedImage` (depending on `imageType`).
278 This might be different than the internal `mMaskedImage` property
279 of the `MultibandFootprint`, as the `mMaskedImage` might contain
280 some non-zero pixels not contained in the footprint but present in
286 Bounding box of the resulting image.
287 If no bounding box is specified, then the bounding box
288 of the footprint is used.
290 Value to use for any pixel in the resulting image
291 outside of the `SpanSet`.
293 This should be either a `MultibandMaskedImage`
294 or `MultibandImage` and describes the type of the output image.
298 result : `MultibandBase`
299 The resulting `MultibandImage` or `MultibandMaskedImage` created
300 from the `MultibandHeavyFootprint`.
302 if imageType == MultibandMaskedImage:
303 singleType = MaskedImage
304 elif imageType == MultibandImage:
307 raise TypeError(
"Expected imageType to be either MultibandImage or MultibandMaskedImage")
308 maskedImages = [heavy.extractImage(fill, bbox, singleType)
for heavy
in self.
singles]
309 mMaskedImage = imageType.fromImages(self.
filtersfilters, maskedImages)
313 """Copy the current object
318 Whether or not to make a deep copy
322 result : `MultibandFootprint`
323 The cloned footprint.
328 footprint.addPeak(peak.getX(), peak.getY(), peak.getValue())
331 result = MultibandFootprint.fromMaskedImages(filters, mMaskedImage, footprint)
A compact representation of a collection of pixels.
getSpanSetFromImages(images, thresh=0, xy0=None)