Exemple #1
0
    def load_file(self, filespec, dstobj=None, **kwargs):
        info = iohelper.get_fileinfo(filespec)
        if not info.ondisk:
            raise ValueError("File does not appear to be on disk: %s" %
                             (info.url))

        filepath = info.filepath
        if dstobj is None:
            # Put here to avoid circular import
            from ginga.RGBImage import RGBImage
            dstobj = RGBImage(logger=self.logger)

        header = Header()
        metadata = {'header': header, 'path': filepath}

        data_np = self.imload(filepath, header)

        # TODO: set up the channel order correctly
        dstobj.set_data(data_np, metadata=metadata)

        if dstobj.name is not None:
            dstobj.set(name=dstobj.name)
        else:
            name = iohelper.name_image_from_path(filepath, idx=None)
            dstobj.set(name=name)

        dstobj.set(path=filepath, idx=None, image_loader=self.load_file)
        return dstobj
Exemple #2
0
    def load_idx(self, idx, **kwargs):
        if self.rgb_f is None:
            raise ValueError("Please call open_file() first!")

        self.rgb_f.seek(0)
        self.rgb_f.seek(idx)
        image = self.rgb_f

        kwds = {}
        try:
            self._get_header(image, kwds)
        except Exception as e:
            self.logger.warning("Failed to get image metadata: %s" % (str(e)))
        metadata = dict(header=kwds)

        # convert to working color profile, if can
        if self.clr_mgr.can_profile():
            image = self.clr_mgr.profile_to_working_pil(image, kwds)

        # convert from PIL to numpy
        data_np = np.array(image)

        from ginga.RGBImage import RGBImage
        data_obj = RGBImage(data_np=data_np, logger=self.logger)
        data_obj.io = self

        name = self.fileinfo.name + '[{}]'.format(idx)
        data_obj.set(name=name,
                     path=self.fileinfo.filepath,
                     idx=idx,
                     header=kwds)

        return data_obj
Exemple #3
0
    def load_idx(self, idx, **kwargs):
        if self.rgb_f is None:
            raise ValueError("Please call open_file() first!")

        if idx is None:
            idx = 0

        self.rgb_f.set(cv2.CAP_PROP_POS_FRAMES, idx)
        okay, data_np = self.rgb_f.read()
        if not okay:
            raise ValueError("Error reading index {}".format(idx))

        metadata = {}
        data_np = self._process_opencv_array(data_np, metadata,
                                             self.fileinfo.filepath)

        from ginga.RGBImage import RGBImage
        data_obj = RGBImage(data_np=data_np, logger=self.logger,
                            order=metadata['order'], metadata=metadata)
        data_obj.io = self

        name = self.fileinfo.name + '[{}]'.format(idx)
        data_obj.set(name=name, path=self.fileinfo.filepath, idx=idx)

        return data_obj
Exemple #4
0
def png_to_colormap(png_file):

    from ginga.RGBImage import RGBImage
    img = RGBImage()
    img.load_file(png_file)
    data = img.get_data()

    return rgbarr_to_colormap(data)
Exemple #5
0
def png_to_colormap(png_file):

    from ginga.RGBImage import RGBImage
    img = RGBImage()
    img.load_file(png_file)
    data = img.get_data()

    return rgbarr_to_colormap(data)
Exemple #6
0
    def load_file(self, filespec, dstobj=None, **kwargs):
        info = iohelper.get_fileinfo(filespec)
        if not info.ondisk:
            raise ValueError("File does not appear to be on disk: %s" % (
                info.url))

        filepath = info.filepath
        if dstobj is None:
            # Put here to avoid circular import
            from ginga.RGBImage import RGBImage
            dstobj = RGBImage(logger=self.logger)

        header = Header()
        metadata = {'header': header, 'path': filepath}

        data_np = self._imload(filepath, header)

        # TODO: set up the channel order correctly
        dstobj.set_data(data_np, metadata=metadata)

        if dstobj.name is not None:
            dstobj.set(name=dstobj.name)
        else:
            name = iohelper.name_image_from_path(filepath, idx=None)
            dstobj.set(name=name)

        dstobj.set(path=filepath, idx=None, image_loader=self.load_file)
        return dstobj
Exemple #7
0
    def snap_cb(self, w):
        format = self.tosave_type
        # snap image
        self.fv.error_wrap(self.fitsimage.save_rgb_image_as_file,
                           self.tmpname,
                           format=format)
        self.saved_type = format

        img = RGBImage(logger=self.logger)
        img.load_file(self.tmpname)

        self.scrnimage.set_image(img)
Exemple #8
0
def masktorgb(mask, color='lightgreen', alpha=1.0):
    """Convert boolean mask to RGB image object for canvas overlay.

    Parameters
    ----------
    mask : ndarray
        Boolean mask to overlay. 2D image only.

    color : str
        Color name accepted by Ginga.

    alpha : float
        Opacity. Unmasked data are always transparent.

    Returns
    -------
    rgbobj : RGBImage
        RGB image for canvas Image object.

    Raises
    ------
    ValueError
        Invalid mask dimension.

    """
    mask = np.asarray(mask)

    if mask.ndim != 2:
        raise ValueError('ndim={0} is not supported'.format(mask.ndim))

    ht, wd = mask.shape
    r, g, b = colors.lookup_color(color)
    rgbobj = RGBImage(data_np=np.zeros((ht, wd, 4), dtype=np.uint8))

    rc = rgbobj.get_slice('R')
    gc = rgbobj.get_slice('G')
    bc = rgbobj.get_slice('B')
    ac = rgbobj.get_slice('A')
    ac[:] = 0  # Transparent background

    rc[mask] = int(r * 255)
    gc[mask] = int(g * 255)
    bc[mask] = int(b * 255)
    ac[mask] = int(alpha * 255)

    # For debugging
    #rgbobj.save_as_file('ztmp_rgbobj.png')

    return rgbobj
Exemple #9
0
def masktorgb(mask, color='lightgreen', alpha=1.0):
    """Convert boolean mask to RGB image object for canvas overlay.

    Parameters
    ----------
    mask : ndarray
        Boolean mask to overlay. 2D image only.

    color : str
        Color name accepted by Ginga.

    alpha : float
        Opacity. Unmasked data are always transparent.

    Returns
    -------
    rgbobj : RGBImage
        RGB image for canvas Image object.

    Raises
    ------
    ValueError
        Invalid mask dimension.

    """
    mask = numpy.asarray(mask)

    if mask.ndim != 2:
        raise ValueError('ndim={0} is not supported'.format(mask.ndim))

    ht, wd = mask.shape
    r, g, b = colors.lookup_color(color)
    rgbobj = RGBImage(data_np = numpy.zeros((ht, wd, 4), dtype=numpy.uint8))

    rc = rgbobj.get_slice('R')
    gc = rgbobj.get_slice('G')
    bc = rgbobj.get_slice('B')
    ac = rgbobj.get_slice('A')
    ac[:] = 0  # Transparent background

    rc[mask] = int(r * 255)
    gc[mask] = int(g * 255)
    bc[mask] = int(b * 255)
    ac[mask] = int(alpha * 255)

    # For debugging
    #rgbobj.save_as_file('ztmp_rgbobj.png')

    return rgbobj
Exemple #10
0
    def load_idx(self, idx, **kwargs):
        if self.rgb_f is None:
            raise ValueError("Please call open_file() first!")

        # TODO: idx ignored for now for RGB images!

        #self.rgb_f.seek(0)
        #print(dir(self.rgb_f))
        okay, data_np = self.rgb_f.read()
        if not okay:
            raise ValueError("Error reading index {}".format(idx))

        # funky indexing because opencv returns BGR images,
        # whereas PIL and others return RGB
        if len(data_np.shape) >= 3 and data_np.shape[2] >= 3:
            data_np = data_np[..., ::-1]

        # OpenCv doesn't "do" image metadata, so we punt to piexif
        # library (if installed)
        kwds = {}
        self.piexif_getexif(self._path, kwds)

        # OpenCv added a feature to do auto-orientation when loading
        # (see https://github.com/opencv/opencv/issues/4344)
        # So reset these values to prevent auto-orientation from
        # happening later
        kwds['Orientation'] = 1
        kwds['Image Orientation'] = 1

        # convert to working color profile, if can
        if self.clr_mgr.can_profile():
            data_np = self.clr_mgr.profile_to_working_numpy(data_np, kwds)

        from ginga.RGBImage import RGBImage
        data_obj = RGBImage(data_np=data_np, logger=self.logger)
        data_obj.io = self

        name = self.fileinfo.name + '[{}]'.format(idx)
        data_obj.set(name=name,
                     path=self.fileinfo.filepath,
                     idx=idx,
                     header=kwds)

        return data_obj
Exemple #11
0
    def overlay_mask(self, maskImage, maskDict, maskAlpha):
        import numpy as np
        from ginga.RGBImage import RGBImage
        from ginga import colors

        maskArray = maskImage.getArray()
        height, width = maskArray.shape
        maskRGBA = np.zeros((height, width, 4), dtype=np.uint8)
        nSet = np.zeros_like(maskArray, dtype=np.uint8)

        for maskValue, maskColor in maskDict.items():
            r, g, b = colors.lookup_color(maskColor)
            isSet = (maskArray & maskValue) != 0
            if (isSet == 0).all():
                continue

            maskRGBA[:, :, 0][isSet] = 255 * r
            maskRGBA[:, :, 1][isSet] = 255 * g
            maskRGBA[:, :, 2][isSet] = 255 * b

            nSet[isSet] += 1

        maskRGBA[:, :, 3][nSet == 0] = 0
        maskRGBA[:, :, 3][nSet != 0] = 255 * maskAlpha

        nSet[nSet == 0] = 1
        for C in (0, 1, 2):
            maskRGBA[:, :, C] //= nSet

        rgb_img = RGBImage(data_np=maskRGBA)
        Image = self._viewer.canvas.get_draw_class('image')
        maskImageRGBA = Image(0, 0, rgb_img)

        if "mask_overlay" in self._gingaViewer.canvas.get_tags():
            self._gingaViewer.canvas.delete_object_by_tag("mask_overlay")
        self._gingaViewer.canvas.add(maskImageRGBA, tag="mask_overlay")
Exemple #12
0
    def _snap_cb(self, w):
        """This function is called when the user clicks the 'Snap' button.
        """
        # Clear the snap image viewer
        self.scrnimage.clear()
        self.scrnimage.redraw_now(whence=0)
        self.fv.update_pending()

        format = self.tosave_type

        if self._screen_size:
            # snap image using actual viewer
            self.fv.error_wrap(self.fitsimage.save_rgb_image_as_file,
                               self.tmpname,
                               format=format)

        else:
            # we will be using shot generator, not actual viewer.
            # check that shot generator size matches UI params
            self.check_and_adjust_dimensions()

            # copy background color of viewer to shot generator
            bg = self.fitsimage.get_bg()
            self.shot_generator.set_bg(*bg)

            # add the main canvas from channel viewer to shot generator
            c1 = self.fitsimage.get_canvas()
            c2 = self.shot_generator.get_canvas()
            c2.delete_all_objects(redraw=False)
            c2.add(c1, redraw=False)
            # hack to fix a few problem graphics
            self.shot_generator._imgobj = self.fitsimage._imgobj

            # scale of the shot generator should be the scale of channel
            # viewer multiplied by the ratio of window sizes
            scale_x, scale_y = self.fitsimage.get_scale_xy()
            c1_wd, c1_ht = self.fitsimage.get_window_size()
            c2_wd, c2_ht = self.shot_generator.get_window_size()

            scale_wd = float(c2_wd) / float(c1_wd)
            scale_ht = float(c2_ht) / float(c1_ht)
            scale = max(scale_wd, scale_ht)
            scale_x *= scale
            scale_y *= scale
            self.shot_generator.scale_to(scale_x, scale_y)

            self.fitsimage.copy_attributes(self.shot_generator,
                                           self.transfer_attrs)

            # snap image
            self.fv.error_wrap(self.shot_generator.save_rgb_image_as_file,
                               self.tmpname,
                               format=format)

            c2.delete_all_objects(redraw=False)
            self.shot_generator._imgobj = None

        self.saved_type = format
        img = RGBImage(logger=self.logger)
        img.load_file(self.tmpname)

        # load the snapped image into the screenshot viewer
        self.scrnimage.set_image(img)
    def _mtv(self, image, mask=None, wcs=None, title=""):
        """Display an Image and/or Mask on a ginga display"""
        self._erase()
        self._canvas.delete_all_objects()
        if image:
            # We'd call
            #   self._viewer.load_data(image.getArray())
            # except that we want to include the wcs
            #
            # Still need to handle the title
            #
            from ginga import AstroImage

            astroImage = AstroImage.AstroImage(logger=self._viewer.logger,
                                               data_np=image.getArray())
            if wcs is not None:
                astroImage.set_wcs(WcsAdaptorForGinga(wcs))

            self._viewer.set_image(astroImage)

        if mask:
            import numpy as np
            from matplotlib.colors import colorConverter
            from ginga.RGBImage import RGBImage  # 8 bpp RGB[A] images

            # create a 3-channel RGB image + alpha
            maskRGB = np.zeros((mask.getHeight(), mask.getWidth(), 4),
                               dtype=np.uint8)
            maska = mask.getArray()
            nSet = np.zeros_like(maska, dtype='uint8')

            R, G, B, A = 0, 1, 2, 3  # names for colours and alpha plane
            colorGenerator = self.display.maskColorGenerator(omitBW=True)

            for maskPlaneName, maskPlaneNum in mask.getMaskPlaneDict().items():
                isSet = maska & (1 << maskPlaneNum) != 0
                if (isSet == 0).all():  # no bits set; nowt to do
                    continue

                color = self.display.getMaskPlaneColor(maskPlaneName)

                if not color:  # none was specified
                    color = next(colorGenerator)
                elif color.lower() == "ignore":
                    continue

                r, g, b = colorConverter.to_rgb(color)
                maskRGB[:, :, R][isSet] = 255 * r
                maskRGB[:, :, G][isSet] = 255 * g
                maskRGB[:, :, B][isSet] = 255 * b

                nSet[isSet] += 1

            alpha = self.display.getMaskTransparency(
            )  # Bug!  Fails to return a value
            if alpha is None:
                alpha = self._getMaskTransparency()

            maskRGB[:, :, A] = 255 * (1 - alpha)
            maskRGB[:, :, A][nSet == 0] = 0

            nSet[nSet == 0] = 1  # avoid division by 0
            for C in (R, G, B):
                maskRGB[:, :, C] //= nSet

            rgb_img = RGBImage(data_np=maskRGB)

            Image = self._canvas.get_draw_class(
                'image')  # the appropriate class
            maskImageRGBA = Image(0, 0, rgb_img)

            self._canvas.add(maskImageRGBA)
Exemple #14
0
    def _snap_cb(self, w):
        """This function is called when the user clicks the 'Snap' button.
        """
        # Clear the snap image viewer
        self.scrnimage.clear()
        self.scrnimage.redraw_now(whence=0)
        self.fv.update_pending()

        format = self.tosave_type

        if self._screen_size:
            # snap image using actual viewer
            self.fv.error_wrap(self.fitsimage.save_rgb_image_as_file,
                               self.tmpname, format=format)

        else:
            # we will be using shot generator, not actual viewer.
            # check that shot generator size matches UI params
            self.check_and_adjust_dimensions()

            # copy background color of viewer to shot generator
            bg = self.fitsimage.get_bg()
            self.shot_generator.set_bg(*bg)

            # add the main canvas from channel viewer to shot generator
            c1 = self.fitsimage.get_canvas()
            c2 = self.shot_generator.get_canvas()
            c2.delete_all_objects(redraw=False)
            c2.add(c1, redraw=False)
            # hack to fix a few problem graphics
            self.shot_generator._imgobj = self.fitsimage._imgobj

            # scale of the shot generator should be the scale of channel
            # viewer multiplied by the ratio of window sizes
            scale_x, scale_y = self.fitsimage.get_scale_xy()
            c1_wd, c1_ht = self.fitsimage.get_window_size()
            c2_wd, c2_ht = self.shot_generator.get_window_size()

            scale_wd = float(c2_wd) / float(c1_wd)
            scale_ht = float(c2_ht) / float(c1_ht)
            scale = max(scale_wd, scale_ht)
            scale_x *= scale
            scale_y *= scale
            self.shot_generator.scale_to(scale_x, scale_y)

            self.fitsimage.copy_attributes(self.shot_generator,
                                           self.transfer_attrs)

            # snap image
            self.fv.error_wrap(self.shot_generator.save_rgb_image_as_file,
                               self.tmpname, format=format)

            c2.delete_all_objects(redraw=False)
            self.shot_generator._imgobj = None

        self.saved_type = format
        img = RGBImage(logger=self.logger)
        img.load_file(self.tmpname)

        # load the snapped image into the screenshot viewer
        self.scrnimage.set_image(img)