| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import numpy as np
- from .dtype import dtype_limits
- def invert(image, signed_float=False):
- """Invert an image.
- Invert the intensity range of the input image, so that the dtype maximum
- is now the dtype minimum, and vice-versa. This operation is
- slightly different depending on the input dtype:
- - unsigned integers: subtract the image from the dtype maximum
- - signed integers: subtract the image from -1 (see Notes)
- - floats: subtract the image from 1 (if signed_float is False, so we
- assume the image is unsigned), or from 0 (if signed_float is True).
- See the examples for clarification.
- Parameters
- ----------
- image : ndarray
- Input image.
- signed_float : bool, optional
- If True and the image is of type float, the range is assumed to
- be [-1, 1]. If False and the image is of type float, the range is
- assumed to be [0, 1].
- Returns
- -------
- inverted : ndarray
- Inverted image.
- Notes
- -----
- Ideally, for signed integers we would simply multiply by -1. However,
- signed integer ranges are asymmetric. For example, for np.int8, the range
- of possible values is [-128, 127], so that -128 * -1 equals -128! By
- subtracting from -1, we correctly map the maximum dtype value to the
- minimum.
- Examples
- --------
- >>> img = np.array([[100, 0, 200],
- ... [ 0, 50, 0],
- ... [ 30, 0, 255]], np.uint8)
- >>> invert(img)
- array([[155, 255, 55],
- [255, 205, 255],
- [225, 255, 0]], dtype=uint8)
- >>> img2 = np.array([[ -2, 0, -128],
- ... [127, 0, 5]], np.int8)
- >>> invert(img2)
- array([[ 1, -1, 127],
- [-128, -1, -6]], dtype=int8)
- >>> img3 = np.array([[ 0., 1., 0.5, 0.75]])
- >>> invert(img3)
- array([[1. , 0. , 0.5 , 0.25]])
- >>> img4 = np.array([[ 0., 1., -1., -0.25]])
- >>> invert(img4, signed_float=True)
- array([[-0. , -1. , 1. , 0.25]])
- """
- if image.dtype == 'bool':
- inverted = ~image
- elif np.issubdtype(image.dtype, np.unsignedinteger):
- max_val = dtype_limits(image, clip_negative=False)[1]
- inverted = np.subtract(max_val, image, dtype=image.dtype)
- elif np.issubdtype(image.dtype, np.signedinteger):
- inverted = np.subtract(-1, image, dtype=image.dtype)
- else: # float dtype
- if signed_float:
- inverted = -image
- else:
- inverted = np.subtract(1, image, dtype=image.dtype)
- return inverted
|