Source code for visionsim.utils.imgproc

from __future__ import annotations

import numpy as np
import numpy.typing as npt
from scipy.ndimage import gaussian_filter


[docs] def unsharp_mask( img: npt.ArrayLike, sigma: float = 1.0, amount: float = 1.0, ) -> npt.NDArray: """Unsharp-masking to sharpen an image Borrows interface from scikit-image's version: <https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.unsharp_mask> Args: img (npt.ArrayLike, required): input image, can be 2-, 3-, or 4-channel sigma (float, default = 1.0): controls extent of blurring amount (float, default = 1.0): controls how much details are amplified by Returns: output (npt.NDArray): img with unsharp mask applied, same shape and dtype as img References: .. [1] Wikipedia. Unsharp masking. <https://en.wikipedia.org/wiki/Unsharp_masking> """ def _unsharp_mask1(img): img_smooth = gaussian_filter(img, sigma) if np.issubdtype(img.dtype, np.floating): np.clip(img + (amount * (img - img_smooth)), 0, 1, out=img) else: # work with copy and convert back if not isinstance(img, np.uint8): raise NotImplementedError("_unsharp_mask1 expects (float | uint8)") img_float = (1.0 / 255) * img.astype(np.float) img_smooth_float = (1.0 / 255) * img_smooth.astype(np.float) np.clip(img_float + (amount * (img_float - img_smooth_float)), 0, 1, out=img_float) img[...] = (255 * img_float).astype(np.uint8) return has_alpha = (img.ndim == 3) and (img.shape[2] in [2, 4]) if has_alpha: alpha_channel = img[:, :, -1:] img = img[:, :, :-1] has_color = (img.ndim == 3) and (img.shape[2] == 3) if has_color: # do each channel individually for c in range(3): _unsharp_mask1(img[:, :, c]) else: _unsharp_mask1(img) if has_alpha: img = np.concatenate((img, alpha_channel), axis=-1) return img