def show_patch()

in geospatial/visualization/imagery_visualizer.py [0:0]


    def show_patch(tile: Union[rasterio.DatasetReader, np.ndarray],
                   bands: Union[Iterable, int],
                   window: Union[rasterio.windows.Window, Tuple] = None,
                   band_min: Numeric = 0,
                   band_max: Numeric = 7000,
                   gamma: Numeric = 1.0,
                   size: Tuple[Numeric, Numeric] = (256, 256),
                   return_array: bool = False) -> Union[np.ndarray, Image.Image]:
        """Show a patch of imagery.

        Args:
            tile:
                - a rasterio.io.DatasetReader object returned by rasterio.open(), or
                - a numpy array of dims (height, width, bands)
            bands: list or tuple of ints, or a single int, indicating which band(s) to read. See notes
                below regarding the order of band numbers to pass in
            window: a tuple of four (col_off x, row_off y, width delta_x, height delta_y)
                to specify the section of the tile to return,
                or a rasterio Window object.
            band_min: minimum value the pixels are clipped tp
            band_max: maximum value the pixels are clipped to
            gamma: the gamma value to use in gamma correction. Output is darker for gamma > 1, lighter if gamma < 1.
                This is not the same as GEE visParams' gamma!
            size: Used when this function is called to produce a PIL Image, i.e. only when
                `return_array` is False.
                None if do not resize, otherwise a (w, h) tuple in pixel unit.
                Default is (256, 256). (500, 500) looks better in notebooks
            return_array: True will cause this function to return a numpy array, with dtype the same as
                the original data;
                False (default) to get a PIL Image object (values scaled to be uint8 values)

        Returns:
            - a PIL Image object, resized to `size`
            - or the (not resized, original data type) numpy array if `return_array` is true.
            The dims start with (height, width), optionally with the channel dim at the end if greater than 1.

            rasterio read() does not pad with 0. The array returned may be smaller than the window specified

        Notes:
            - PIL renders the bands in RGB order; keep that in mind when passing in `bands` as a list or tuple
              so that the bands are mapped to Red, Green and Blue in the desired order.

            - Band index starts with 1, for both types of input (rasterio.io.DatasetReader or numpy array).
            If `tile` is a numpy array, this function will subtract 1 from the band indices before
            extracting the desired bands.
        """
        if isinstance(bands, int):
            bands = [bands]  # otherwise rasterio read and numpy indexing will return a 2D array instead of 3D

        for b in bands:
            assert b > 0, 'bands should be 1-indexed'

        if isinstance(tile, rasterio.io.DatasetReader):
            if window and isinstance(window, Tuple):
                window = rasterio.windows.Window(window[0], window[1], window[2], window[3])
            # read as (bands, rows, columns) or (channel, height, width)
            tile_bands = tile.read(bands, window=window, boundless=True, fill_value=0)
            # rearrange to (height, width, channel/bands)
            tile_bands = np.transpose(tile_bands, axes=[1, 2, 0])

        elif isinstance(tile, np.ndarray):
            if window and isinstance(window, rasterio.windows.Window):
                window = [window.col_off, window.row_off, window.width, window.height]

            bands = [b - 1 for b in bands]  # rasterio indexes bands from 1, here we subtract 1 for numpy

            if window:
                tile_bands = tile[
                                 window[1]: window[1] + window[3],
                                 window[0]: window[0] + window[2],
                                 bands
                             ]
            else:
                tile_bands = tile[:, :, bands]

        # tile_bands is of dims (height, width, channel/bands), last dim is 1 if only one band requested
        tile_bands = ImageryVisualizer.norm_band(tile_bands, band_min=band_min, band_max=band_max, gamma=gamma)

        tile_bands = tile_bands.squeeze()  # PIL accepts (h, w, 3) or (h, w), not (h, w, 1)

        if return_array:
            return tile_bands

        # skimage.img_as_ubyte: negative input values will be clipped. Positive values are scaled between 0 and 255
        # fine to use here as we already got rid of negative values by normalizing above
        tile_bands = img_as_ubyte(tile_bands)

        im = Image.fromarray(tile_bands)
        if size:
            im = im.resize(size)
        return im