27 from ._rgb 
import replaceSaturatedPixels, getZScale
 
   31     """Return a naive total intensity from the red, blue, and green intensities 
   35     imageR : `lsst.afw.image.MaskedImage`, `lsst.afw.image.Image`, or `numpy.ndarray`, (Nx, Ny) 
   36         intensity of image that'll be mapped to red; or intensity if imageG and imageB are None 
   37     imageG : `lsst.afw.image.MaskedImage`, `lsst.afw.image.Image`, or `numpy.ndarray`, (Nx, Ny) 
   38         intensity of image that'll be mapped to green; or None 
   39     imageB : `lsst.afw.image.MaskedImage`, `lsst.afw.image.Image`, or `numpy.ndarray`, (Nx, Ny) 
   40         intensity of image that'll be mapped to blue; or None 
   44     image : type of ``imageR``, ``imageG``, and `imageB`` 
   46     if imageG 
is None or imageB 
is None:
 
   47         assert imageG 
is None and imageB 
is None, \
 
   48             "Please specify either a single image or red, green, and blue images" 
   51     imageRGB = [imageR, imageG, imageB]
 
   53     for i, c 
in enumerate(imageRGB):
 
   54         if hasattr(c, 
"getImage"):
 
   55             c = imageRGB[i] = c.getImage()
 
   56         if hasattr(c, 
"getArray"):
 
   57             imageRGB[i] = c.getArray()
 
   59     intensity = (imageRGB[0] + imageRGB[1] + imageRGB[2])/float(3)
 
   63     Image = afwImage.ImageU 
if intensity.dtype == 
'uint16' else afwImage.ImageF
 
   65     if hasattr(imageR, 
"getImage"):  
 
   67     elif hasattr(imageR, 
"getArray"):
 
   68         intensity = Image(intensity)
 
   74     """Base class to map red, blue, green intensities into uint8 values 
   78     minimum : `float` or sequence of `float` 
   79         Intensity that should be mapped to black. If an array, has three 
   82         The image to be used to calculate the mapping. 
   83         If provided, also the default for makeRgbImage() 
   87         self.
_uint8Max_uint8Max = float(np.iinfo(np.uint8).max)
 
   93         assert len(minimum) == 3, 
"Please provide 1 or 3 values for minimum" 
   99                      xSize=None, ySize=None, rescaleFactor=None):
 
  100         """Convert 3 arrays, imageR, imageG, and imageB into a numpy RGB image 
  102         imageR : `lsst.afw.image.Image` or `numpy.ndarray`, (Nx, Ny) 
  103             Image to map to red (if `None`, use the image passed to the ctor) 
  104         imageG : `lsst.afw.image.Image` or `numpy.ndarray`, (Nx, Ny), optional 
  105             Image to map to green (if `None`, use imageR) 
  106         imageB : `lsst.afw.image.Image` or `numpy.ndarray`, (Nx, Ny), optional 
  107             Image to map to blue (if `None`, use imageR) 
  108         xSize : `int`, optional 
  109             Desired width of RGB image. If ``ySize`` is `None`, preserve aspect ratio 
  110         ySize : `int`, optional 
  111             Desired height of RGB image 
  112         rescaleFactor : `float`, optional 
  113             Make size of output image ``rescaleFactor*size`` of the input image 
  116             if self.
_image_image 
is None:
 
  118                     "You must provide an image (or pass one to the constructor)")
 
  119             imageR = self.
_image_image
 
  126         imageRGB = [imageR, imageG, imageB]
 
  127         for i, c 
in enumerate(imageRGB):
 
  128             if hasattr(c, 
"getImage"):
 
  129                 c = imageRGB[i] = c.getImage()
 
  130             if hasattr(c, 
"getArray"):
 
  131                 imageRGB[i] = c.getArray()
 
  133         if xSize 
is not None or ySize 
is not None:
 
  134             assert rescaleFactor 
is None, 
"You may not specify a size and rescaleFactor" 
  135             h, w = imageRGB[0].shape
 
  137                 ySize = int(xSize*h/float(w) + 0.5)
 
  139                 xSize = int(ySize*w/float(h) + 0.5)
 
  141             size = (ySize, xSize)  
 
  142         elif rescaleFactor 
is not None:
 
  143             size = float(rescaleFactor)  
 
  150             except ImportError 
as e:
 
  152                     f
"Unable to rescale as scipy.misc is unavailable: {e}")
 
  154             for i, im 
in enumerate(imageRGB):
 
  155                 imageRGB[i] = scipy.misc.imresize(
 
  156                     im, size, interp=
'bilinear', mode=
'F')
 
  161         """Return the total intensity from the red, blue, and green intensities 
  165         This is a naive computation, and may be overridden by subclasses 
  170         """Map an intensity into the range of a uint8, [0, 255] (but not converted to uint8) 
  172         with np.errstate(invalid=
'ignore', divide=
'ignore'):  
 
  173             return np.where(intensity <= 0, 0,
 
  176     def _convertImagesToUint8(self, imageR, imageG, imageB):
 
  177         """Use the mapping to convert images imageR, imageG, and imageB to a triplet of uint8 images 
  179         imageR = imageR - self.
minimumminimum[0]  
 
  180         imageG = imageG - self.
minimumminimum[1]
 
  181         imageB = imageB - self.
minimumminimum[2]
 
  185         imageRGB = [imageR, imageG, imageB]
 
  186         with np.errstate(invalid=
"ignore"):  
 
  194         r0, g0, b0 = imageRGB
 
  197         with np.errstate(invalid=
'ignore', divide=
'ignore'):
 
  198             for i, c 
in enumerate(imageRGB):
 
  199                 c = np.where(r0 > g0,
 
  201                                       np.where(r0 >= pixmax, c*pixmax/r0, c),
 
  202                                       np.where(b0 >= pixmax, c*pixmax/b0, c)),
 
  204                                       np.where(g0 >= pixmax, c*pixmax/g0, c),
 
  205                                       np.where(b0 >= pixmax, c*pixmax/b0, c))).astype(np.uint8)
 
  206                 c[c > pixmax] = pixmax
 
  214     """A linear map of red, blue, green intensities into uint8 values 
  218     minimum : `float` or sequence of `float` 
  219         Intensity that should be mapped to black. If an array, has three 
  220         elements for R, G, B. 
  222         Intensity that should be mapped to white 
  224         Image to estimate minimum/maximum if not explicitly set 
  227     def __init__(self, minimum=None, maximum=None, image=None):
 
  228         if minimum 
is None or maximum 
is None:
 
  229             assert image 
is not None, 
"You must provide an image if you don't set both minimum and maximum" 
  233                 minimum = stats.getValue(afwMath.MIN)
 
  235                 maximum = stats.getValue(afwMath.MAX)
 
  237         Mapping.__init__(self, minimum, image)
 
  243             assert maximum - minimum != 0, 
"minimum and maximum values must not be equal" 
  244             self.
_range_range = float(maximum - minimum)
 
  247         """Return an array which, when multiplied by an image, returns that 
  248         image mapped to the range of a uint8, [0, 255] (but not converted to uint8) 
  250         The intensity is assumed to have had ``minimum`` subtracted (as that 
  251         can be done per-band) 
  253         with np.errstate(invalid=
'ignore', divide=
'ignore'):  
 
  254             return np.where(intensity <= 0, 0,
 
  255                             np.where(intensity >= self.
_range_range,
 
  260     """A mapping for a linear stretch chosen by the zscale algorithm 
  261     (preserving colours independent of brightness) 
  263     x = (I - minimum)/range 
  268         Image whose parameters are desired 
  270         The number of samples to use to estimate the zscale parameters 
  274     def __init__(self, image, nSamples=1000, contrast=0.25):
 
  275         if not hasattr(image, 
"getArray"):
 
  276             image = afwImage.ImageF(image)
 
  277         z1, z2 = 
getZScale(image, nSamples, contrast)
 
  279         LinearMapping.__init__(self, z1, z2, image)
 
  283     """A mapping for an asinh stretch (preserving colours independent of brightness) 
  285     x = asinh(Q (I - minimum)/range)/Q 
  289     This reduces to a linear stretch if Q == 0 
  291     See http://adsabs.harvard.edu/abs/2004PASP..116..133L 
  295         Mapping.__init__(self, minimum)
 
  312         self.
_soften_soften = Q/float(dataRange)
 
  315         """Return an array which, when multiplied by an image, returns that image mapped to the range of a 
  316         uint8, [0, 255] (but not converted to uint8) 
  318         The intensity is assumed to have had minimum subtracted (as that can be done per-band) 
  320         with np.errstate(invalid=
'ignore', divide=
'ignore'):  
 
  321             return np.where(intensity <= 0, 0, np.arcsinh(intensity*self.
_soften_soften)*self.
_slope_slope/intensity)
 
  325     """A mapping for an asinh stretch, estimating the linear stretch by zscale 
  327     x = asinh(Q (I - z1)/(z2 - z1))/Q 
  332         The image to analyse, or a list of 3 images to be converted to an intensity image 
  334         The asinh softening parameter 
  335     pedestal : `float` or sequence of `float`, optional 
  336         The value, or array of 3 values, to subtract from the images 
  338         N.b. pedestal, if not None, is removed from the images when calculating the zscale 
  339         stretch, and added back into Mapping.minimum[] 
  348             assert len(image) 
in (1, 3,), 
"Please provide 1 or 3 images" 
  352         if pedestal 
is not None:
 
  354                 assert len(pedestal) 
in (
 
  355                     1, 3,), 
"Please provide 1 or 3 pedestals" 
  357                 pedestal = 3*[pedestal]
 
  360             for i, im 
in enumerate(image):
 
  361                 if pedestal[i] != 0.0:
 
  362                     if hasattr(im, 
"getImage"):
 
  364                     if hasattr(im, 
"getArray"):
 
  367                     image[i] = im - pedestal[i]  
 
  369             pedestal = len(image)*[0.0]
 
  375         dataRange = zscale.maximum - zscale.minimum[0]
 
  376         minimum = zscale.minimum
 
  378         for i, level 
in enumerate(pedestal):
 
  381         AsinhMapping.__init__(self, minimum, dataRange, Q)
 
  385 def makeRGB(imageR, imageG=None, imageB=None, minimum=0, dataRange=5, Q=8, fileName=None,
 
  386             saturatedBorderWidth=0, saturatedPixelValue=None,
 
  387             xSize=None, ySize=None, rescaleFactor=None):
 
  388     """Make a set of three images into an RGB image using an asinh stretch and 
  389     optionally write it to disk 
  396     minimum : `float` or sequence of `float` 
  400         The output file. The suffix defines the format, and must be supported by matplotlib 
  402         If saturatedBorderWidth is non-zero, replace saturated pixels with 
  403         ``saturatedPixelValue``. Note that replacing saturated pixels requires 
  404         that the input images be `lsst.afw.image.MaskedImage`. 
  415     if saturatedBorderWidth:
 
  416         if saturatedPixelValue 
is None:
 
  418                 "saturatedPixelValue must be set if saturatedBorderWidth is set")
 
  420                                saturatedBorderWidth, saturatedPixelValue)
 
  423     rgb = asinhMap.makeRgbImage(imageR, imageG, imageB,
 
  424                                 xSize=xSize, ySize=ySize, rescaleFactor=rescaleFactor)
 
  433     """Display an rgb image using matplotlib 
  438         The RGB image in question 
  440         If `True`, call `matplotlib.pyplot.show()` 
  442     import matplotlib.pyplot 
as plt
 
  443     plt.imshow(rgb, interpolation=
'nearest', origin=
"lower")
 
  450     """Write an RGB image to disk 
  455         The output file. The suffix defines the format, and must be supported by matplotlib 
  457         Most versions of matplotlib support png and pdf (although the eps/pdf/svg writers may be buggy, 
  458         possibly due an interaction with useTeX=True in the matplotlib settings). 
  460         If your matplotlib bundles pil/pillow you should also be able to write jpeg and tiff files. 
  462         The image, as made by e.g. makeRGB 
  464     import matplotlib.image
 
  465     matplotlib.image.imsave(fileName, rgbImage)
 
def __init__(self, minimum, dataRange, Q=8)
def mapIntensityToUint8(self, intensity)
def __init__(self, image, Q=8, pedestal=None)
def mapIntensityToUint8(self, intensity)
def __init__(self, minimum=None, maximum=None, image=None)
def makeRgbImage(self, imageR=None, imageG=None, imageB=None, xSize=None, ySize=None, rescaleFactor=None)
def _convertImagesToUint8(self, imageR, imageG, imageB)
def mapIntensityToUint8(self, intensity)
def intensity(self, imageR, imageG, imageB)
def __init__(self, minimum=None, image=None)
def __init__(self, image, nSamples=1000, contrast=0.25)
daf::base::PropertyList * list
def computeIntensity(imageR, imageG=None, imageB=None)
def writeRGB(fileName, rgbImage)
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)
def displayRGB(rgb, show=True)
void replaceSaturatedPixels(ImageT &rim, ImageT &gim, ImageT &bim, int borderWidth, float saturatedPixelValue)
std::pair< double, double > getZScale(image::Image< T > const &image, int const nSamples, double const contrast)
Calculate an IRAF/ds9-style zscaling.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
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::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Angle abs(Angle const &a)