"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "skimage/transform/pyramids.py" between
scikit-image-0.19.1.tar.gz and scikit-image-0.19.2.tar.gz

About: scikit-image is a collection of algorithms for image processing in Python.

pyramids.py  (scikit-image-0.19.1):pyramids.py  (scikit-image-0.19.2)
import math import math
import numpy as np import numpy as np
from scipy import ndimage as ndi
from .._shared import utils from .._shared import utils
from .._shared.filters import gaussian from .._shared.filters import gaussian
from .._shared.utils import convert_to_float from .._shared.utils import convert_to_float
from ..transform import resize from ..transform import resize
def _smooth(image, sigma, mode, cval, multichannel=None): def _smooth(image, sigma, mode, cval, channel_axis):
"""Return image with each channel smoothed by the Gaussian filter.""" """Return image with each channel smoothed by the Gaussian filter."""
smoothed = np.empty_like(image) smoothed = np.empty_like(image)
# apply Gaussian filter to all channels independently # apply Gaussian filter to all channels independently
if multichannel: if channel_axis is not None:
sigma = (sigma, ) * (image.ndim - 1) + (0, ) # can rely on gaussian to insert a 0 entry at channel_axis
channel_axis = -1 channel_axis = channel_axis % image.ndim
sigma = (sigma,) * (image.ndim - 1)
else: else:
channel_axis = None channel_axis = None
gaussian(image, sigma, output=smoothed, mode=mode, cval=cval, gaussian(image, sigma, output=smoothed, mode=mode, cval=cval,
channel_axis=channel_axis) channel_axis=channel_axis)
return smoothed return smoothed
def _check_factor(factor): def _check_factor(factor):
if factor <= 1: if factor <= 1:
raise ValueError('scale factor must be greater than 1') raise ValueError('scale factor must be greater than 1')
@utils.channel_as_last_axis()
@utils.deprecate_multichannel_kwarg(multichannel_position=6) @utils.deprecate_multichannel_kwarg(multichannel_position=6)
def pyramid_reduce(image, downscale=2, sigma=None, order=1, def pyramid_reduce(image, downscale=2, sigma=None, order=1,
mode='reflect', cval=0, multichannel=False, mode='reflect', cval=0, multichannel=False,
preserve_range=False, *, channel_axis=-1): preserve_range=False, *, channel_axis=None):
"""Smooth and then downsample image. """Smooth and then downsample image.
Parameters Parameters
---------- ----------
image : ndarray image : ndarray
Input image. Input image.
downscale : float, optional downscale : float, optional
Downscale factor. Downscale factor.
sigma : float, optional sigma : float, optional
Sigma for Gaussian filter. Default is `2 * downscale / 6.0` which Sigma for Gaussian filter. Default is `2 * downscale / 6.0` which
skipping to change at line 81 skipping to change at line 80
------- -------
out : array out : array
Smoothed and downsampled float image. Smoothed and downsampled float image.
References References
---------- ----------
.. [1] http://persci.mit.edu/pub_pdfs/pyramid83.pdf .. [1] http://persci.mit.edu/pub_pdfs/pyramid83.pdf
""" """
_check_factor(downscale) _check_factor(downscale)
multichannel = channel_axis is not None
image = convert_to_float(image, preserve_range) image = convert_to_float(image, preserve_range)
if channel_axis is not None:
out_shape = tuple([math.ceil(d / float(downscale)) for d in image.shape]) channel_axis = channel_axis % image.ndim
if multichannel: out_shape = tuple(
out_shape = out_shape[:-1] math.ceil(d / float(downscale)) if ax != channel_axis else d
for ax, d in enumerate(image.shape)
)
else:
out_shape = tuple(math.ceil(d / float(downscale)) for d in image.shape)
if sigma is None: if sigma is None:
# automatically determine sigma which covers > 99% of distribution # automatically determine sigma which covers > 99% of distribution
sigma = 2 * downscale / 6.0 sigma = 2 * downscale / 6.0
smoothed = _smooth(image, sigma, mode, cval, multichannel) smoothed = _smooth(image, sigma, mode, cval, channel_axis)
out = resize(smoothed, out_shape, order=order, mode=mode, cval=cval, out = resize(smoothed, out_shape, order=order, mode=mode, cval=cval,
anti_aliasing=False) anti_aliasing=False)
return out return out
@utils.channel_as_last_axis()
@utils.deprecate_multichannel_kwarg(multichannel_position=6) @utils.deprecate_multichannel_kwarg(multichannel_position=6)
def pyramid_expand(image, upscale=2, sigma=None, order=1, def pyramid_expand(image, upscale=2, sigma=None, order=1,
mode='reflect', cval=0, multichannel=False, mode='reflect', cval=0, multichannel=False,
preserve_range=False, *, channel_axis=None): preserve_range=False, *, channel_axis=None):
"""Upsample and then smooth image. """Upsample and then smooth image.
Parameters Parameters
---------- ----------
image : ndarray image : ndarray
Input image. Input image.
skipping to change at line 151 skipping to change at line 152
------- -------
out : array out : array
Upsampled and smoothed float image. Upsampled and smoothed float image.
References References
---------- ----------
.. [1] http://persci.mit.edu/pub_pdfs/pyramid83.pdf .. [1] http://persci.mit.edu/pub_pdfs/pyramid83.pdf
""" """
_check_factor(upscale) _check_factor(upscale)
multichannel = channel_axis is not None
image = convert_to_float(image, preserve_range) image = convert_to_float(image, preserve_range)
if channel_axis is not None:
out_shape = tuple([math.ceil(upscale * d) for d in image.shape]) channel_axis = channel_axis % image.ndim
if multichannel: out_shape = tuple(
out_shape = out_shape[:-1] math.ceil(upscale * d) if ax != channel_axis else d
for ax, d in enumerate(image.shape)
)
else:
out_shape = tuple(math.ceil(upscale * d) for d in image.shape)
if sigma is None: if sigma is None:
# automatically determine sigma which covers > 99% of distribution # automatically determine sigma which covers > 99% of distribution
sigma = 2 * upscale / 6.0 sigma = 2 * upscale / 6.0
resized = resize(image, out_shape, order=order, resized = resize(image, out_shape, order=order,
mode=mode, cval=cval, anti_aliasing=False) mode=mode, cval=cval, anti_aliasing=False)
out = _smooth(resized, sigma, mode, cval, multichannel) out = _smooth(resized, sigma, mode, cval, channel_axis)
return out return out
@utils.channel_as_last_axis()
@utils.deprecate_multichannel_kwarg(multichannel_position=7) @utils.deprecate_multichannel_kwarg(multichannel_position=7)
def pyramid_gaussian(image, max_layer=-1, downscale=2, sigma=None, order=1, def pyramid_gaussian(image, max_layer=-1, downscale=2, sigma=None, order=1,
mode='reflect', cval=0, multichannel=False, mode='reflect', cval=0, multichannel=False,
preserve_range=False, *, channel_axis=-1): preserve_range=False, *, channel_axis=None):
"""Yield images of the Gaussian pyramid formed by the input image. """Yield images of the Gaussian pyramid formed by the input image.
Recursively applies the `pyramid_reduce` function to the image, and yields Recursively applies the `pyramid_reduce` function to the image, and yields
the downscaled images. the downscaled images.
Note that the first image of the pyramid will be the original, unscaled Note that the first image of the pyramid will be the original, unscaled
image. The total number of images is `max_layer + 1`. In case all layers image. The total number of images is `max_layer + 1`. In case all layers
are computed, the last image is either a one-pixel image or the image where are computed, the last image is either a one-pixel image or the image where
the reduction does not change its shape. the reduction does not change its shape.
skipping to change at line 250 skipping to change at line 252
yield image yield image
# build downsampled images until max_layer is reached or downscale process # build downsampled images until max_layer is reached or downscale process
# does not change image size # does not change image size
while layer != max_layer: while layer != max_layer:
layer += 1 layer += 1
layer_image = pyramid_reduce(prev_layer_image, downscale, sigma, order, layer_image = pyramid_reduce(prev_layer_image, downscale, sigma, order,
mode, cval, channel_axis=channel_axis) mode, cval, channel_axis=channel_axis)
prev_shape = np.asarray(current_shape) prev_shape = current_shape
prev_layer_image = layer_image prev_layer_image = layer_image
current_shape = np.asarray(layer_image.shape) current_shape = layer_image.shape
# no change to previous pyramid layer # no change to previous pyramid layer
if np.all(current_shape == prev_shape): if current_shape == prev_shape:
break break
yield layer_image yield layer_image
@utils.channel_as_last_axis()
@utils.deprecate_multichannel_kwarg(multichannel_position=7) @utils.deprecate_multichannel_kwarg(multichannel_position=7)
def pyramid_laplacian(image, max_layer=-1, downscale=2, sigma=None, order=1, def pyramid_laplacian(image, max_layer=-1, downscale=2, sigma=None, order=1,
mode='reflect', cval=0, multichannel=False, mode='reflect', cval=0, multichannel=False,
preserve_range=False, *, channel_axis=-1): preserve_range=False, *, channel_axis=None):
"""Yield images of the laplacian pyramid formed by the input image. """Yield images of the laplacian pyramid formed by the input image.
Each layer contains the difference between the downsampled and the Each layer contains the difference between the downsampled and the
downsampled, smoothed image:: downsampled, smoothed image::
layer = resize(prev_layer) - smooth(resize(prev_layer)) layer = resize(prev_layer) - smooth(resize(prev_layer))
Note that the first image of the pyramid will be the difference between the Note that the first image of the pyramid will be the difference between the
original, unscaled image and its smoothed version. The total number of original, unscaled image and its smoothed version. The total number of
images is `max_layer + 1`. In case all layers are computed, the last image images is `max_layer + 1`. In case all layers are computed, the last image
skipping to change at line 327 skipping to change at line 328
pyramid : generator pyramid : generator
Generator yielding pyramid layers as float images. Generator yielding pyramid layers as float images.
References References
---------- ----------
.. [1] http://persci.mit.edu/pub_pdfs/pyramid83.pdf .. [1] http://persci.mit.edu/pub_pdfs/pyramid83.pdf
.. [2] http://sepwww.stanford.edu/data/media/public/sep/morgan/texturematch/ paper_html/node3.html .. [2] http://sepwww.stanford.edu/data/media/public/sep/morgan/texturematch/ paper_html/node3.html
""" """
_check_factor(downscale) _check_factor(downscale)
multichannel = channel_axis is not None
# cast to float for consistent data type in pyramid # cast to float for consistent data type in pyramid
image = convert_to_float(image, preserve_range) image = convert_to_float(image, preserve_range)
if sigma is None: if sigma is None:
# automatically determine sigma which covers > 99% of distribution # automatically determine sigma which covers > 99% of distribution
sigma = 2 * downscale / 6.0 sigma = 2 * downscale / 6.0
current_shape = image.shape current_shape = image.shape
smoothed_image = _smooth(image, sigma, mode, cval, multichannel) smoothed_image = _smooth(image, sigma, mode, cval, channel_axis)
yield image - smoothed_image yield image - smoothed_image
if channel_axis is not None:
channel_axis = channel_axis % image.ndim
shape_without_channels = list(current_shape)
shape_without_channels.pop(channel_axis)
shape_without_channels = tuple(shape_without_channels)
else:
shape_without_channels = current_shape
# build downsampled images until max_layer is reached or downscale process # build downsampled images until max_layer is reached or downscale process
# does not change image size # does not change image size
if max_layer == -1: if max_layer == -1:
max_layer = int(np.ceil(math.log(np.max(current_shape), downscale))) max_layer = math.ceil(math.log(max(shape_without_channels), downscale))
for layer in range(max_layer): for layer in range(max_layer):
out_shape = tuple( if channel_axis is not None:
[math.ceil(d / float(downscale)) for d in current_shape]) out_shape = tuple(
math.ceil(d / float(downscale)) if ax != channel_axis else d
if multichannel: for ax, d in enumerate(current_shape)
out_shape = out_shape[:-1] )
else:
out_shape = tuple(math.ceil(d / float(downscale))
for d in current_shape)
resized_image = resize(smoothed_image, out_shape, order=order, resized_image = resize(smoothed_image, out_shape, order=order,
mode=mode, cval=cval, anti_aliasing=False) mode=mode, cval=cval, anti_aliasing=False)
smoothed_image = _smooth(resized_image, sigma, mode, cval, smoothed_image = _smooth(resized_image, sigma, mode, cval,
multichannel) channel_axis)
current_shape = np.asarray(resized_image.shape) current_shape = resized_image.shape
yield resized_image - smoothed_image yield resized_image - smoothed_image
 End of changes. 25 change blocks. 
38 lines changed or deleted 49 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)