skimage.util.compare 源代码
import functools
import warnings
from itertools import product
import numpy as np
from .dtype import img_as_float
def _rename_image_params(func):
wm_images = (
"Since version 0.24, the two input images are named `image0` and "
"`image1` (instead of `image1` and `image2`, respectively). Please use "
"`image0, image1` to avoid this warning for now, and avoid an error "
"from version 0.26 onwards."
)
wm_method = (
"Starting in version 0.24, all arguments following `image0, image1` "
"(including `method`) will be keyword-only. Please pass `method=` "
"in the function call to avoid this warning for now, and avoid an error "
"from version 0.26 onwards."
)
@functools.wraps(func)
def wrapper(*args, **kwargs):
# Turn all args into kwargs
for i, (value, param) in enumerate(
zip(args, ["image0", "image1", "method", "n_tiles"])
):
if i >= 2:
warnings.warn(wm_method, category=FutureWarning, stacklevel=2)
if param in kwargs:
raise ValueError(
f"{param} passed both as positional and keyword argument."
)
else:
kwargs[param] = value
args = tuple()
# Account for `image2` if given
if "image2" in kwargs.keys():
warnings.warn(wm_images, category=FutureWarning, stacklevel=2)
# Safely move `image2` to `image1` if that's empty
if "image1" in kwargs.keys():
# Safely move `image1` to `image0`
if "image0" in kwargs.keys():
raise ValueError(
"Three input images given; please use only `image0` "
"and `image1`."
)
kwargs["image0"] = kwargs.pop("image1")
kwargs["image1"] = kwargs.pop("image2")
return func(*args, **kwargs)
return wrapper
[文档]
@_rename_image_params
def compare_images(image0, image1, *, method='diff', n_tiles=(8, 8)):
"""
Return an image showing the differences between two images.
.. versionadded:: 0.16
Parameters
----------
image0, image1 : ndarray, shape (M, N)
Images to process, must be of the same shape.
.. versionchanged:: 0.24
`image1` and `image2` were renamed into `image0` and `image1`
respectively.
method : string, optional
Method used for the comparison.
Valid values are {'diff', 'blend', 'checkerboard'}.
Details are provided in the note section.
.. versionchanged:: 0.24
This parameter and following ones are keyword-only.
n_tiles : tuple, optional
Used only for the `checkerboard` method. Specifies the number
of tiles (row, column) to divide the image.
Returns
-------
comparison : ndarray, shape (M, N)
Image showing the differences.
Notes
-----
``'diff'`` computes the absolute difference between the two images.
``'blend'`` computes the mean value.
``'checkerboard'`` makes tiles of dimension `n_tiles` that display
alternatively the first and the second image. Note that images must be
2-dimensional to be compared with the checkerboard method.
"""
if image1.shape != image0.shape:
raise ValueError('Images must have the same shape.')
img1 = img_as_float(image0)
img2 = img_as_float(image1)
if method == 'diff':
comparison = np.abs(img2 - img1)
elif method == 'blend':
comparison = 0.5 * (img2 + img1)
elif method == 'checkerboard':
if img1.ndim != 2:
raise ValueError(
'Images must be 2-dimensional to be compared with the '
'checkerboard method.'
)
shapex, shapey = img1.shape
mask = np.full((shapex, shapey), False)
stepx = int(shapex / n_tiles[0])
stepy = int(shapey / n_tiles[1])
for i, j in product(range(n_tiles[0]), range(n_tiles[1])):
if (i + j) % 2 == 0:
mask[i * stepx : (i + 1) * stepx, j * stepy : (j + 1) * stepy] = True
comparison = np.zeros_like(img1)
comparison[mask] = img1[mask]
comparison[~mask] = img2[~mask]
else:
raise ValueError(
'Wrong value for `method`. '
'Must be either "diff", "blend" or "checkerboard".'
)
return comparison