unsharp_mask(image, radius=1.0, amount=1.0, multichannel=False, preserve_range=False)
The sharp details are identified as the difference between the original image and its blurred version. These details are then scaled, and added back to the original image.
Unsharp masking is an image sharpening technique. It is a linear image operation, and numerically stable, unlike deconvolution which is an ill-posed problem. Because of this stability, it is often preferred over deconvolution.
The main idea is as follows: sharp details are identified as the difference between the original image and its blurred version. These details are added back to the original image after a scaling step:
enhanced image = original + amount * (original - blurred)
When applying this filter to several color layers independently, color bleeding may occur. More visually pleasing result can be achieved by processing only the brightness/lightness/intensity channel in a suitable color space such as HSV, HSL, YUV, or YCbCr.
Unsharp masking is described in most introductory digital image processing books. This implementation is based on .
Input image.
If a scalar is given, then its value is used for all dimensions. If sequence is given, then there must be exactly one radius for each dimension except the last dimension for multichannel images. Note that 0 radius means no blurring, and negative values are not allowed.
The details will be amplified with this factor. The factor could be 0 or negative. Typically, it is a small positive number, e.g. 1.0.
If True, the last image
dimension is considered as a color channel, otherwise as spatial. Color channels are processed individually.
Whether to keep the original range of values. Otherwise, the input image is converted according to the conventions of img_as_float
. Also see https://scikit-image.org/docs/dev/user_guide/data_types.html
Image with unsharp mask applied.
Unsharp masking filter.
>>> array = np.ones(shape=(5,5), dtype=np.uint8)*100This example is valid syntax, but we were not able to check execution
... array[2,2] = 120
... array array([[100, 100, 100, 100, 100], [100, 100, 100, 100, 100], [100, 100, 120, 100, 100], [100, 100, 100, 100, 100], [100, 100, 100, 100, 100]], dtype=uint8)
>>> np.around(unsharp_mask(array, radius=0.5, amount=2),2) array([[0.39, 0.39, 0.39, 0.39, 0.39], [0.39, 0.39, 0.38, 0.39, 0.39], [0.39, 0.38, 0.53, 0.38, 0.39], [0.39, 0.39, 0.38, 0.39, 0.39], [0.39, 0.39, 0.39, 0.39, 0.39]])This example is valid syntax, but we were not able to check execution
>>> array = np.ones(shape=(5,5), dtype=np.int8)*100This example is valid syntax, but we were not able to check execution
... array[2,2] = 127
... np.around(unsharp_mask(array, radius=0.5, amount=2),2) array([[0.79, 0.79, 0.79, 0.79, 0.79], [0.79, 0.78, 0.75, 0.78, 0.79], [0.79, 0.75, 1. , 0.75, 0.79], [0.79, 0.78, 0.75, 0.78, 0.79], [0.79, 0.79, 0.79, 0.79, 0.79]])
>>> np.around(unsharp_mask(array, radius=0.5, amount=2, preserve_range=True), 2) array([[100. , 100. , 99.99, 100. , 100. ], [100. , 99.39, 95.48, 99.39, 100. ], [ 99.99, 95.48, 147.59, 95.48, 99.99], [100. , 99.39, 95.48, 99.39, 100. ], [100. , 100. , 99.99, 100. , 100. ]])See :
The following pages refer to to this document either explicitly or contain code examples using this.
skimage.filters._unsharp_mask.unsharp_mask
Hover to see nodes names; edges to Self not shown, Caped at 50 nodes.
Using a canvas is more power efficient and can get hundred of nodes ; but does not allow hyperlinks; , arrows or text (beyond on hover)
SVG is more flexible but power hungry; and does not scale well to 50 + nodes.
All aboves nodes referred to, (or are referred from) current nodes; Edges from Self to other have been omitted (or all nodes would be connected to the central node "self" which is not useful). Nodes are colored by the library they belong to, and scaled with the number of references pointing them