31 """!Return a naive total intensity from the red, blue, and green intensities 32 @param imageR intensity of image that'll be mapped to red; or intensity if imageG and imageB are None 33 @param imageG intensity of image that'll be mapped to green; or None 34 @param imageB intensity of image that'll be mapped to blue; or None 36 Inputs may be MaskedImages, Images, or numpy arrays and the return is of the same type 38 if imageG
is None or imageB
is None:
39 assert imageG
is None and imageB
is None, \
40 "Please specify either a single image or red, green, and blue images" 43 imageRGB = [imageR, imageG, imageB]
45 for i, c
in enumerate(imageRGB):
46 if hasattr(c,
"getImage"):
47 c = imageRGB[i] = c.getImage()
48 if hasattr(c,
"getArray"):
49 imageRGB[i] = c.getArray()
51 intensity = (imageRGB[0] + imageRGB[1] + imageRGB[2])/
float(3)
55 Image = afwImage.ImageU
if intensity.dtype ==
'uint16' else afwImage.ImageF
57 if hasattr(imageR,
"getImage"):
59 elif hasattr(imageR,
"getArray"):
60 intensity = Image(intensity)
66 """!Baseclass to map red, blue, green intensities into uint8 values""" 70 @param minimum Intensity that should be mapped to black (a scalar or array for R, G, B) 71 @param image The image to be used to calculate the mapping. 73 If provided, also the default for makeRgbImage() 81 assert len(minimum) == 3,
"Please provide 1 or 3 values for minimum" 86 def makeRgbImage(self, imageR=None, imageG=None, imageB=None,
87 xSize=None, ySize=None, rescaleFactor=None):
88 """!Convert 3 arrays, imageR, imageG, and imageB into a numpy RGB image 89 @param imageR Image to map to red (if None, use the image passed to the ctor) 90 @param imageG Image to map to green (if None, use imageR) 91 @param imageB Image to map to blue (if None, use imageR) 92 @param xSize Desired width of RGB image (or None). If ySize is None, preserve aspect ratio 93 @param ySize Desired height of RGB image (or None) 94 @param rescaleFactor Make size of output image rescaleFactor*size of the input image (or None) 96 N.b. images may be afwImage.Images or numpy arrays 101 "You must provide an image (or pass one to the constructor)")
109 imageRGB = [imageR, imageG, imageB]
110 for i, c
in enumerate(imageRGB):
111 if hasattr(c,
"getImage"):
112 c = imageRGB[i] = c.getImage()
113 if hasattr(c,
"getArray"):
114 imageRGB[i] = c.getArray()
116 if xSize
is not None or ySize
is not None:
117 assert rescaleFactor
is None,
"You may not specify a size and rescaleFactor" 118 h, w = imageRGB[0].shape
124 size = (ySize, xSize)
125 elif rescaleFactor
is not None:
126 size =
float(rescaleFactor)
133 except ImportError
as e:
135 "Unable to rescale as scipy.misc is unavailable: %s" % e)
137 for i, im
in enumerate(imageRGB):
138 imageRGB[i] = scipy.misc.imresize(
139 im, size, interp=
'bilinear', mode=
'F')
144 """!Return the total intensity from the red, blue, and green intensities 146 This is a naive computation, and may be overridden by subclasses 151 """Map an intensity into the range of a uint8, [0, 255] (but not converted to uint8)""" 152 with np.errstate(invalid=
'ignore', divide=
'ignore'):
153 return np.where(intensity <= 0, 0,
156 def _convertImagesToUint8(self, imageR, imageG, imageB):
157 """Use the mapping to convert images imageR, imageG, and imageB to a triplet of uint8 images""" 158 imageR = imageR - self.
minimum[0]
159 imageG = imageG - self.
minimum[1]
160 imageB = imageB - self.
minimum[2]
164 imageRGB = [imageR, imageG, imageB]
165 with np.errstate(invalid=
"ignore"):
173 r0, g0, b0 = imageRGB
176 with np.errstate(invalid=
'ignore', divide=
'ignore'):
177 for i, c
in enumerate(imageRGB):
178 c = np.where(r0 > g0,
180 np.where(r0 >= pixmax, c*pixmax/r0, c),
181 np.where(b0 >= pixmax, c*pixmax/b0, c)),
183 np.where(g0 >= pixmax, c*pixmax/g0, c),
184 np.where(b0 >= pixmax, c*pixmax/b0, c))).astype(np.uint8)
185 c[c > pixmax] = pixmax
193 """!A linear map map of red, blue, green intensities into uint8 values""" 195 def __init__(self, minimum=None, maximum=None, image=None):
196 """!A linear stretch from [minimum, maximum]; if one or both are omitted use image minimum/maximum to set them 198 @param minimum Intensity that should be mapped to black (a scalar or array for R, G, B) 199 @param maximum Intensity that should be mapped to white (a scalar) 200 @param image Image to estimate minimum/maximum if not explicitly set 203 if minimum
is None or maximum
is None:
204 assert image
is not None,
"You must provide an image if you don't set both minimum and maximum" 208 minimum = stats.getValue(afwMath.MIN)
210 maximum = stats.getValue(afwMath.MAX)
212 Mapping.__init__(self, minimum, image)
218 assert maximum - minimum != 0,
"minimum and maximum values must not be equal" 222 """Return an array which, when multiplied by an image, returns that image mapped to the range of a 223 uint8, [0, 255] (but not converted to uint8) 225 The intensity is assumed to have had minimum subtracted (as that can be done per-band) 227 with np.errstate(invalid=
'ignore', divide=
'ignore'):
228 return np.where(intensity <= 0, 0,
229 np.where(intensity >= self.
_range,
234 """!A mapping for a linear stretch chosen by the zscale algorithm 235 (preserving colours independent of brightness) 237 x = (I - minimum)/range 240 def __init__(self, image, nSamples=1000, contrast=0.25):
241 """!A linear stretch from [z1, z2] chosen by the zscale algorithm 242 @param image Image whose parameters are desired 243 @param nSamples The number of samples to use to estimate the zscale parameters 244 @param contrast The number of samples to use to estimate the zscale parameters 247 if not hasattr(image,
"getArray"):
248 image = afwImage.ImageF(image)
249 z1, z2 =
getZScale(image, nSamples, contrast)
251 LinearMapping.__init__(self, z1, z2, image)
255 """!A mapping for an asinh stretch (preserving colours independent of brightness) 257 x = asinh(Q (I - minimum)/range)/Q 259 This reduces to a linear stretch if Q == 0 261 See http://adsabs.harvard.edu/abs/2004PASP..116..133L 265 Mapping.__init__(self, minimum)
285 """Return an array which, when multiplied by an image, returns that image mapped to the range of a 286 uint8, [0, 255] (but not converted to uint8) 288 The intensity is assumed to have had minimum subtracted (as that can be done per-band) 290 with np.errstate(invalid=
'ignore', divide=
'ignore'):
291 return np.where(intensity <= 0, 0, np.arcsinh(intensity*self.
_soften)*self.
_slope/intensity)
295 """!A mapping for an asinh stretch, estimating the linear stretch by zscale 297 x = asinh(Q (I - z1)/(z2 - z1))/Q 304 Create an asinh mapping from an image, setting the linear part of the stretch using zscale 306 @param image The image to analyse, or a list of 3 images to be converted to an intensity image 307 @param Q The asinh softening parameter 308 @param pedestal The value, or array of 3 values, to subtract from the images; or None 310 N.b. pedestal, if not None, is removed from the images when calculating the zscale 311 stretch, and added back into Mapping.minimum[] 314 assert len(image)
in (1, 3,),
"Please provide 1 or 3 images" 318 if pedestal
is not None:
320 assert len(pedestal)
in (
321 1, 3,),
"Please provide 1 or 3 pedestals" 323 pedestal = 3*[pedestal]
326 for i, im
in enumerate(image):
327 if pedestal[i] != 0.0:
328 if hasattr(im,
"getImage"):
330 if hasattr(im,
"getArray"):
333 image[i] = im - pedestal[i]
335 pedestal = len(image)*[0.0]
341 dataRange = zscale.maximum - zscale.minimum[0]
342 minimum = zscale.minimum
344 for i, level
in enumerate(pedestal):
347 AsinhMapping.__init__(self, minimum, dataRange, Q)
351 def makeRGB(imageR, imageG=None, imageB=None, minimum=0, dataRange=5, Q=8, fileName=None,
352 saturatedBorderWidth=0, saturatedPixelValue=None,
353 xSize=None, ySize=None, rescaleFactor=None):
354 """Make a set of three images into an RGB image using an asinh stretch and optionally write it to disk 356 If saturatedBorderWidth is non-zero, replace saturated pixels with saturatedPixelValue. Note 357 that replacing saturated pixels requires that the input images be MaskedImages. 364 if saturatedBorderWidth:
365 if saturatedPixelValue
is None:
367 "saturatedPixelValue must be set if saturatedBorderWidth is set")
369 saturatedBorderWidth, saturatedPixelValue)
372 rgb = asinhMap.makeRgbImage(imageR, imageG, imageB,
373 xSize=xSize, ySize=ySize, rescaleFactor=rescaleFactor)
382 """!Display an rgb image using matplotlib 383 @param rgb The RGB image in question 384 @param show If true, call plt.show() 386 import matplotlib.pyplot
as plt
387 plt.imshow(rgb, interpolation=
'nearest', origin=
"lower")
394 """!Write an RGB image to disk 395 @param fileName The output file. The suffix defines the format, and must be supported by matplotlib 396 @param rgbImage The image, as made by e.g. makeRGB 398 Most versions of matplotlib support png and pdf (although the eps/pdf/svg writers may be buggy, 399 possibly due an interaction with useTeX=True in the matplotlib settings). 401 If your matplotlib bundles pil/pillow you should also be able to write jpeg and tiff files. 403 import matplotlib.image
404 matplotlib.image.imsave(fileName, rgbImage)
412 """!@deprecated Object used to support legacy API""" 415 self.minimum = minimum
416 self.dataRange = dataRange
421 """!@deprecated Object used to support legacy API""" 423 def __init__(self, imageR, imageG, imageB, mapping):
424 """!@deprecated Legacy API""" 425 asinh =
AsinhMapping(mapping.minimum, mapping.dataRange, mapping.Q)
426 self.
rgb = asinh.makeRgbImage(imageR, imageG, imageB)
429 """!@deprecated Legacy API""" 434 """!@deprecated Legacy API""" 435 return _RgbImageF(imageR, imageG, imageB, mapping)
Angle abs(Angle const &a)
def __init__(self, minimum=None, image=None)
Create a mapping.
std::pair< double, double > getZScale(image::Image< T > const &image, int const nSamples=1000, double const contrast=0.25)
Calculate an IRAF/ds9-style zscaling.
def __init__(self, minimum, dataRange, Q=8)
def __init__(self, image, Q=8, pedestal=None)
Create an asinh mapping from an image, setting the linear part of the stretch using zscale...
def __init__(self, image, nSamples=1000, contrast=0.25)
A linear stretch from [z1, z2] chosen by the zscale algorithm.
def computeIntensity(imageR, imageG=None, imageB=None)
Return a naive total intensity from the red, blue, and green intensities.
def __init__(self, imageR, imageG, imageB, mapping)
Baseclass to map red, blue, green intensities into uint8 values.
void replaceSaturatedPixels(ImageT &rim, ImageT &gim, ImageT &bim, int borderWidth=2, float saturatedPixelValue=65535)
def makeRGB(imageR, imageG=None, imageB=None, minimum=0, dataRange=5, Q=8, fileName=None, saturatedBorderWidth=0, saturatedPixelValue=None, xSize=None, ySize=None, rescaleFactor=None)
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > * makeMaskedImage(typename std::shared_ptr< Image< ImagePixelT >> image, typename std::shared_ptr< Mask< MaskPixelT >> mask=Mask< MaskPixelT >(), typename std::shared_ptr< Image< VariancePixelT >> variance=Image< VariancePixelT >())
A function to return a MaskedImage of the correct type (cf.
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<>
def mapIntensityToUint8(self, intensity)
A linear map map of red, blue, green intensities into uint8 values.
def displayRGB(rgb, show=True)
Display an rgb image using matplotlib.
def write(self, fileName)
def makeRgbImage(self, imageR=None, imageG=None, imageB=None, xSize=None, ySize=None, rescaleFactor=None)
Convert 3 arrays, imageR, imageG, and imageB into a numpy RGB image.
def mapIntensityToUint8(self, intensity)
A mapping for an asinh stretch, estimating the linear stretch by zscale.
A mapping for a linear stretch chosen by the zscale algorithm (preserving colours independent of brig...
A mapping for an asinh stretch (preserving colours independent of brightness)
def mapIntensityToUint8(self, intensity)
def __init__(self, minimum, dataRange, Q)
def _convertImagesToUint8(self, imageR, imageG, imageB)
daf::base::PropertyList * list
def RgbImageF(imageR, imageG, imageB, mapping)
def intensity(self, imageR, imageG, imageB)
Return the total intensity from the red, blue, and green intensities.
def writeRGB(fileName, rgbImage)
Write an RGB image to disk.
def __init__(self, minimum=None, maximum=None, image=None)
A linear stretch from [minimum, maximum]; if one or both are omitted use image minimum/maximum to set...