Source code for large_image.tilesource.stylefuncs
# This module contains functions for use in styles
from types import SimpleNamespace
from typing import List, Optional, Tuple, Union
import numpy as np
from .utilities import _imageToNumpy, _imageToPIL
[docs]
def maskPixelValues(
image: np.ndarray, context: SimpleNamespace,
values: List[Union[int, List[int], Tuple[int, ...]]],
negative: Optional[int] = None, positive: Optional[int] = None) -> np.ndarray:
"""
This is a style utility function that returns a black-and-white 8-bit image
where the image is white if the pixel of the source image is in a list of
values and black otherwise. The values is a list where each entry can
either be a tuple the same length as the band dimension of the output image
or a single value which is handled as 0xBBGGRR.
:param image: a numpy array of Y, X, Bands.
:param context: the style context. context.image is the source image
:param values: an array of values, each of which is either an array of the
same number of bands as the source image or a single value of the form
0xBBGGRR assuming uint8 data.
:param negative: None to use [0, 0, 0, 255], or an RGBA uint8 value for
pixels not in the value list.
:param positive: None to use [255, 255, 255, 0], or an RGBA uint8 value for
pixels in the value list.
:returns: an RGBA numpy image which is exactly black or transparent white.
"""
src = context.image
mask = np.full(src.shape[:2], False)
for val in values:
vallist: List[float]
if not isinstance(val, (list, tuple)):
if src.shape[-1] == 1:
vallist = [val]
else:
vallist = [val % 256, val // 256 % 256, val // 65536 % 256]
else:
vallist = list(val)
vallist = (vallist + [255] * src.shape[2])[:src.shape[2]]
match = np.array(vallist)
mask = mask | (src == match).all(axis=-1)
image[mask != True] = negative or [0, 0, 0, 255] # noqa E712
image[mask] = positive or [255, 255, 255, 0]
image = image.astype(np.uint8)
return image
[docs]
def medianFilter(
image: np.ndarray, context: Optional[SimpleNamespace] = None,
kernel: int = 5, weight: float = 1.0) -> np.ndarray:
"""
This is a style utility function that applies a median rank filter to the
image to sharpen it.
:param image: a numpy array of Y, X, Bands.
:param context: the style context. context.image is the source image
:param kernel: the filter kernel size.
:param weight: the weight of the difference between the image and the
filtered image that is used to add into the image. 0 is no effect/
:returns: an numpy image which is the filtered version of the source.
"""
import PIL.ImageFilter
filt = PIL.ImageFilter.MedianFilter(kernel)
if len(image.shape) != 3:
pilimg = _imageToPIL(image)
elif image.shape[2] >= 3:
pilimg = _imageToPIL(image[:, :, :3])
else:
pilimg = _imageToPIL(image[:, :, :1])
fimg = _imageToNumpy(pilimg.filter(filt))[0]
mul: float = 0
clip = 0
if image.dtype == np.uint8 or (
image.dtype.kind == 'f' and 1 < np.max(image) < 256 and np.min(image) >= 0):
mul = 1
clip = 255
elif image.dtype == np.uint16 or (
image.dtype.kind == 'f' and 1 < np.max(image) < 65536 and np.min(image) >= 0):
mul = 257
clip = 65535
elif image.dtype == np.uint32:
mul = (2 ** 32 - 1) / 255
clip = 2 ** 32 - 1
elif image.dtype.kind == 'f':
mul = 1
if mul:
pimg: np.ndarray = image.astype(float)
if len(pimg.shape) == 2:
pimg = np.resize(pimg, (pimg.shape[0], pimg.shape[1], 1))
pimg = pimg[:, :, :fimg.shape[2]] # type: ignore[index,misc]
dimg = (pimg - fimg.astype(float) * mul) * weight
pimg = pimg[:, :, :fimg.shape[2]] + dimg # type: ignore[index,misc]
if clip:
pimg = pimg.clip(0, clip)
if len(image.shape) != 3:
image[:, :] = np.resize(pimg.astype(image.dtype), (pimg.shape[0], pimg.shape[1]))
else:
image[:, :, :fimg.shape[2]] = pimg.astype(image.dtype)
return image