.. -*- mode: rst -*- .. vi: filetype=rst .. _skimage2-migration: ***************************************** Migration guide: from skimage to skimage2 ***************************************** .. hint:: This document is a work in progress and still subject to change. Scikit-image is preparing to release version 2.0 as a new package: ``skimage2``. Alongside skimage2, we will release version 1.0.0. Versions 1.x will be using the current API. Versions 1.1.x will throw a ``FutureWarning`` upon import, as a means to notify users that they should either upgrade to skimage2 or pin to version 1.0.x. We have undertaken this to make some long-outstanding, backward-incomptible changes to the scikit-image API. Most changes were difficult or impossible to make using deprecations alone. To honor the Hinsen principle (that is, never change results silently unless to fix a bug), we introduce a new package, which gives users an explicit way of upgrading. Users also have the option to use the two versions side-by-side while they do so. You can find a more detailed description of our motivation and discussion leading up to this in :doc:`SKIP 4 <../skips/4-transition-to-v2>`. .. _enable-skimage2-warnings: Enable skimage2-related warnings ================================ Even before skimage2 is released, you may enable skimage2-related warnings to prepare for code changes early on. Run the following `warnings filter `__ before you use scikit-image in your code: .. code-block:: python import warnings import skimage as ski warnings.filterwarnings(action="default", category=ski.util.PendingSkimage2Change) This will raise a warning in code that needs to be modified to continue functioning with the new, skimage2 API. Updating existing code ====================== When switching to the new ``skimage2`` namespace, some code will need to be updated to continue working the way it did before. .. note:: For a while, you will be able to use ``skimage`` and ``skimage2`` (the 2.0 API) side-by-side, to facilitate porting. The new API may, for the same function call, return different results—e.g., because of a change in a keyword argument default value. By importing functionality from ``skimage2``, you explicitly opt in to the new behavior. .. _sk2adv-gray-funcs: Grayscale morphological operators in `skimage.morphology` --------------------------------------------------------- The following functions are deprecated in favor of counterparts in `skimage2.morphology`: - :ref:`sk2adv-skimage-morphology-erosion` - :ref:`sk2adv-skimage-morphology-dilation` - :ref:`sk2adv-skimage-morphology-opening` - :ref:`sk2adv-skimage-morphology-closing` - :ref:`sk2adv-skimage-morphology-white-tophat` - :ref:`sk2adv-skimage-morphology-black-tophat` The new counterparts behave differently in the following ways: - All functions now default to ``mode='ignore'`` (was ``mode='reflect'``). - Additionally, ``skimage2.morphology.dilation``, ``skimage2.morphology.closing``, and ``skimage2.morphology.black_tophat`` now also mirror the footprint (invert its order in each dimension). Note this only impacts behavior for asymmetric footprints. .. admonition:: Background for changes :class: note dropdown The new behavior ensures that, with default parameters, ``closing`` and ``opening`` are `extensive and anti-extensive `__ respectively. This change also aligns the behavior for asymmetric footprints with SciPy's ``scipy.ndimage.grey_*`` functions. Refer to `gh-6665 `__, `gh-6676 `__, `gh-8046 `__, and `gh-8060 `__ for more details. .. _sk2adv-skimage-morphology-erosion: ``skimage.morphology.erosion`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.morphology.erosion`` is deprecated in favor of ``skimage2.morphology.erosion``, which changes the default value for parameter `mode` to ``'ignore'`` (was ``'reflect'``). To keep the old (``skimage``, v1.x) behavior, set ``mode='reflect'`` explicitly. If you set it explicitly before, the behavior is unchanged. >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> image = ski1.data.camera() >>> res1 = ski1.morphology.erosion(image) # skimage default is mode='reflect' >>> res2 = ski2.morphology.erosion(image, mode='reflect') >>> assert np.all(res1 == res2) .. _sk2adv-skimage-morphology-dilation: ``skimage.morphology.dilation`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.morphology.dilation`` is deprecated in favor of ``skimage2.morphology.dilation`` which changes the default value for parameter `mode` to ``'ignore'`` (was ``'reflect'``). It also mirrors the `footprint` (inverts its order in each dimension), which aligns its behavior with SciPy's conventions. To keep the old (``skimage``, v1.x) behavior: - Set ``mode='reflect'`` explicitly. If you set it explicitly before, the behavior is unchanged. - If you currently use an asymmetric `footprint`, modify it like this before passing it to ``skimage2.morphology.dilation``: .. code-block:: python footprint = ski2.morphology.pad_footprint(footprint, pad_end=False) footprint = ski2.morphology.mirror_footprint(footprint) For example: >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> image = ski1.data.camera() >>> asym_foot = np.zeros((4, 4)) >>> asym_foot[2:, 2:] = 1 >>> res1 = ski1.morphology.dilation(image, footprint=asym_foot) >>> pad_asym = ski2.morphology.pad_footprint(asym_foot, pad_end=False) >>> mirror_asym = ski2.morphology.mirror_footprint(pad_asym) >>> res2 = ski2.morphology.dilation(image, footprint=mirror_asym, mode='reflect') >>> assert np.all(res1 == res2) .. _sk2adv-skimage-morphology-opening: ``skimage.morphology.opening`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.morphology.opening`` is deprecated in favor of ``skimage2.morphology.opening``, which changes the default value for parameter `mode` to ``'ignore'`` (was ``'reflect'``). To keep the old (``skimage``, v1.x) behavior, set ``mode='reflect'`` explicitly. If you set it explicitly before, the behavior is unchanged. >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> image = ski1.data.camera() >>> res1 = ski1.morphology.opening(image) # skimage default is mode='reflect' >>> res2 = ski2.morphology.opening(image, mode='reflect') >>> assert np.all(res1 == res2) .. _sk2adv-skimage-morphology-closing: ``skimage.morphology.closing`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.morphology.closing`` is deprecated in favor of ``skimage2.morphology.closing`` which changes the default value for parameter `mode` to ``'ignore'`` (was ``'reflect'``). It also mirrors the `footprint` (inverts its order in each dimension), which aligns its behavior with SciPy's conventions. To keep the old (``skimage``, v1.x) behavior: - Set ``mode='reflect'`` explicitly. If you set it explicitly before, the behavior is unchanged. - If you currently use an asymmetric `footprint`, modify it like this before passing it to ``skimage2.morphology.closing``: .. code-block:: python footprint = ski2.morphology.pad_footprint(footprint, pad_end=False) footprint = ski2.morphology.mirror_footprint(footprint) For example: >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> image = ski1.data.camera() >>> asym_foot = np.zeros((4, 4)) >>> asym_foot[2:, 2:] = 1 >>> res1 = ski1.morphology.closing(image, footprint=asym_foot) >>> pad_asym = ski2.morphology.pad_footprint(asym_foot, pad_end=False) >>> mirror_asym = ski2.morphology.mirror_footprint(pad_asym) >>> res2 = ski2.morphology.closing(image, footprint=mirror_asym, mode='reflect') >>> assert np.all(res1 == res2) .. _sk2adv-skimage-morphology-white-tophat: ``skimage.morphology.white_tophat`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.morphology.white_tophat`` is deprecated in favor of ``skimage2.morphology.white_tophat``, which changes the default value for parameter `mode` to ``'ignore'`` (was ``'reflect'``). To keep the old (``skimage``, v1.x) behavior, set ``mode='reflect'`` explicitly. If you set it explicitly before, the behavior is unchanged. >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> image = ski1.data.camera() >>> res1 = ski1.morphology.white_tophat(image) # skimage default is mode='reflect' >>> res2 = ski2.morphology.white_tophat(image, mode='reflect') >>> assert np.all(res1 == res2) .. _sk2adv-skimage-morphology-black-tophat: ``skimage.morphology.black_tophat`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.morphology.black_tophat`` is deprecated in favor of ``skimage2.morphology.black_tophat`` which changes the default value for parameter `mode` to ``'ignore'`` (was ``'reflect'``). It also mirrors the `footprint` (inverts its order in each dimension), which aligns its behavior with SciPy's conventions. To keep the old (``skimage``, v1.x) behavior: - Set ``mode='reflect'`` explicitly. If you set it explicitly before, the behavior is unchanged. - If you currently use an asymmetric `footprint`, modify it like this before passing it to ``skimage2.morphology.black_tophat``: .. code-block:: python footprint = ski2.morphology.pad_footprint(footprint, pad_end=False) footprint = ski2.morphology.mirror_footprint(footprint) For example: >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> image = ski1.data.camera() >>> asym_foot = np.zeros((4, 4)) >>> asym_foot[2:, 2:] = 1 >>> res1 = ski1.morphology.black_tophat(image, footprint=asym_foot) >>> pad_asym = ski2.morphology.pad_footprint(asym_foot, pad_end=False) >>> mirror_asym = ski2.morphology.mirror_footprint(pad_asym) >>> res2 = ski2.morphology.black_tophat(image, footprint=mirror_asym, mode='reflect') >>> assert np.all(res1 == res2) Removal of ``skimage.future`` ----------------------------- There will be no ``future`` submodule in ``skimage2``. If you are using modules in current ``skimage.future``, please either vendor the ``skimage.future`` code in your own code-base, or use other libraries. If you are making heavy use of ``skimage.future`` routines, please feel free to raise an issue at the `scikit-image issues `__ page to ask us to port the function you want to use. .. _sk2adv-skimage-future-TrainableSegmenter: ``skimage.future.TrainableSegmenter`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.future.TrainableSegmenter`` is deprecated, and will be removed in ``skimage2``. Please either vendor the ``skimage.future`` code in your own code-base, or use other libraries. If you are making heavy use of ``skimage.future`` routines, please feel free to raise a scikit-image issue to ask us to port the function you want to use. .. _sk2adv-skimage-future-fit-segmenter: ``skimage.future.fit_segmenter`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.future.fit_segmenter`` is deprecated, and will be removed in ``skimage2``. Please either vendor the ``skimage.future`` code in your own code-base, or use other libraries. If you are making heavy use of ``skimage.future`` routines, please feel free to raise a scikit-image issue to ask us to port the function you want to use. .. _sk2adv-skimage-future-manual-lasso-segmentation: ``skimage.future.manual_lasso_segmentation`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.future.manual_lasso_segmentation`` is deprecated, and will be removed in ``skimage2``. Please either vendor the ``skimage.future`` code in your own code-base, or use other libraries. If you are making heavy use of ``skimage.future`` routines, please feel free to raise a scikit-image issue to ask us to port the function you want to use. .. _sk2adv-skimage-future-manual-polygon-segmentation: ``skimage.future.manual_polygon_segmentation`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.future.manual_polygon_segmentation`` is deprecated, and will be removed in ``skimage2``. Please either vendor the ``skimage.future`` code in your own code-base, or use other libraries. If you are making heavy use of ``skimage.future`` routines, please feel free to raise a scikit-image issue to ask us to port the function you want to use. .. _sk2adv-skimage-future-predict-segmenter: ``skimage.future.predict_segmenter`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``skimage.future.predict_segmenter`` is deprecated, and will be removed in ``skimage2``. Please either vendor the ``skimage.future`` code in your own code-base, or use other libraries. If you are making heavy use of ``skimage.future`` routines, please feel free to raise a scikit-image issue to ask us to port the function you want to use. .. _sk2adv-skimage-data-binary-blobs: ``skimage.data.binary_blobs`` ----------------------------- ``skimage.data.binary_blobs`` is deprecated in favor of ``skimage2.data.binary_blobs``, which has a new signature. Parameters `length` and `n_dim` have been replaced with a new parameter `shape`. Optional `blob_size_fraction` has been replaced with a required parameter `blob_size`, whose behavior is independent of the output image size. The default value of `boundary_mode` has been changed from ``'nearest'`` to ``'wrap'``. To keep the old (``skimage``, v1.x) behavior, use: >>> import numpy as np >>> from numpy.random import default_rng >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> length, n_dim, blob_size_fraction = 512, 2, 0.1 # Default ski1 values. >>> res1 = ski1.data.binary_blobs(rng=default_rng(1939)) # Make reproducible. >>> res2 = ski2.data.binary_blobs( ... shape=(length,) * n_dim, ... blob_size=blob_size_fraction * length, ... boundary_mode='nearest', ... rng=default_rng(1939) ... ) >>> assert np.all(res1 == res2) .. _sk2adv-skimage-feature-canny: ``skimage.feature.canny`` ------------------------- ``skimage.feature.canny`` is deprecated in favor of ``skimage2.feature.canny`` with new behavior. The default of the optional parameter `mode` has changed from 'constant' to 'nearest'. If you did not set this parameter explicitly, and you want the old (``skimage``, v1.x) behavior, add an explicit ``mode='constant'``: >>> import numpy as np >>> import skimage as ski1 >>> import skimage2 as ski2 >>> >>> img = ski1.data.checkerboard() >>> res1 = ski1.feature.canny(img) # ski1 default is mode='constant' >>> res2 = ski2.feature.canny(img, mode='constant') >>> assert np.all(res1 == res2) .. _sk2adv-skimage-feature-corner-peaks: ``skimage.feature.corner_peaks`` -------------------------------- ``skimage.feature.corner_peaks`` will be removed in scikit-image 2. Please use ``skimage2.feature.peak_local_max`` instead. .. _sk2adv-skimage-feature-peak-local-max: ``skimage.feature.peak_local_max`` ---------------------------------- ``skimage.feature.peak_local_max`` is deprecated in favor of ``skimage2.feature.peak_local_max`` with new behavior: * Parameter `p_norm` defaults to 2 (Euclidean distance), was `numpy.inf` (Chebyshev distance) * Parameter `exclude_border` defaults to 1, was ``True`` * Parameter `exclude_border` no longer accepts ``False`` and ``True``; pass 0 instead of ``False``, or `min_distance` instead of ``True`` * Parameters after `image` are keyword-only To keep the old behavior when switching to `skimage2`, update your call according to the following cases: .. list-table:: :header-rows: 1 - - In `skimage` - In `skimage2` - - `exclude_border` not passed (default) - Assign it the same value as `min_distance` which may be its default value ``1``. - - ``exclude_border=True`` - Same as above in the default case. - - ``exclude_border=False`` - Use ``min_distance=0``. - - ``exclude_border=`` - No change necessary. - - `p_norm` not passed (default) - Pass the Skimage 1 default explicitly with ``p_norm=numpy.inf``. - - ``p_norm=`` - No change necessary. Other keyword parameters can be left unchanged. >>> import numpy as np >>> >>> import skimage as ski1 >>> import skimage2 as ski2 >>> image = ski1.data.camera() >>> res1 = ski1.feature.peak_local_max(image) >>> res2 = ski2.feature.peak_local_max(image, exclude_border=1, p_norm=np.inf) >>> assert np.all(res1 == res2) >>> >>> res1 = ski1.feature.peak_local_max(image, min_distance=10) >>> res2 = ski2.feature.peak_local_max( ... image, min_distance=10, exclude_border=10, p_norm=np.inf ... ) >>> assert np.all(res1 == res2) .. _sk2adv-skimage-filters-gaussian: ``skimage.filters.gaussian`` ---------------------------- ``skimage.filters.gaussian`` is deprecated in favor of ``skimage2.filters.gaussian`` with new behavior: * Parameter `preserve_range` was removed * The value range of `image` is now always preserved To keep the old (``skimage``, v1.x) behavior of `preserve_range=False` after switching to ``skimage2``, preprocess `image`:: skimage.filters.gaussian(image, ...) Becomes :: image = skimage2.util.rescale_legacy(image) skimage2.filters.gaussian(image, ...) Other keyword parameters can be left unchanged. .. _sk2adv-skimage-graph-pixel-graph: ``skimage.graph.pixel_graph`` ----------------------------- ``skimage.graph.pixel_graph`` is deprecated in favor of ``skimage2.graph.pixel_graph`` with new behavior: * Parameter `sparse_type` was removed * Returned `graph` is always a `scipy.sparse.csr_array` SciPy 2.0 deprecates the sparse matrix classes and will remove them no earlier than SciPy 2.2. The two types define ``*`` differently: matrix multiplication for `scipy.sparse.csr_matrix`, elementwise multiplication for `scipy.sparse.csr_array`. ``@`` is matrix multiplication for both. To keep the old (``skimage``, v1.x) behavior, convert the result:: graph, nodes = skimage2.graph.pixel_graph(image, ...) graph = scipy.sparse.csr_matrix(graph) .. _sk2adv-skimage-metrics-contingency-table: ``skimage.metrics.contingency_table`` ------------------------------------- ``skimage.metrics.contingency_table`` is deprecated in favor of ``skimage2.metrics.contingency_table`` with new behavior: * Parameter `sparse_type` was removed * Returned `cont` is always a `scipy.sparse.csr_array` SciPy 2.0 deprecates the sparse matrix classes and will remove them no earlier than SciPy 2.2. The two types define ``*`` differently: matrix multiplication for `scipy.sparse.csr_matrix`, elementwise multiplication for `scipy.sparse.csr_array`. ``@`` is matrix multiplication for both. To keep the old (``skimage``, v1.x) behavior, convert the result:: cont = skimage2.metrics.contingency_table(im_true, im_test, ...) cont = scipy.sparse.csr_matrix(cont) .. _sk2adv-skimage-metrics-structural-similarity: ``skimage.metrics.structural_similarity`` ----------------------------------------- ``skimage.metrics.structural_similarity`` is deprecated in favor of ``skimage2.metrics.structural_similarity``, which has a new signature. The parameter `data_range` is now a required parameter. If you didn't provide `data_range` explicitly before and relied on its default behavior, you can keep the old (``skimage``, v1.x) behavior by setting the parameter explicitly. For example: >>> import numpy as np >>> import skimage as ski >>> import skimage2 as ski2 ... >>> im1 = np.arange(20) >>> im2 = im1 // 2 ... >>> result1 = ski.metrics.structural_similarity(im1, im2) ... >>> data_range = np.iinfo(im1.dtype).max - np.iinfo(im1.dtype).min >>> result2 = ski2.metrics.structural_similarity(im1, im2, data_range=data_range) ... >>> np.testing.assert_equal(result1, result2) For floating dtypes, setting `data_range` was already required in ``skimage``/v1.x. .. _sk2adv-skimage-morphology-cube: ``skimage.morphology.cube`` --------------------------- `skimage.morphology.cube` is deprecated in favor of `skimage2.morphology.footprint_rectangle` and `skimage2.morphology.footprint_rectangle_decomposed`. * The new functions expect to be given a ``shape`` instead of the parameter ``width``. * `skimage2.morphology.footprint_rectangle` no longer accepts the ``decompose`` parameter and will return the footprint as a simple array. * `skimage2.morphology.footprint_rectangle_decomposed` uses the new parameter ``method``, which accepts the values of the old ``decomposition`` parameter. To keep the old behavior when switching to `skimage2`, update your call according to the following cases: * Pass the desired shape of the footprint as a 3-element tuple ``(w, w, w)`` where ``w`` is the former ``width`` that was used. * ``decomposition`` not passed, use `skimage2.morphology.footprint_rectangle` with same signature. * ``decomposition='sequence'`` or ``decomposition='separable'``, use `skimage2.morphology.footprint_rectangle_decomposed` and pass the old value of ``decomposition`` to the new parameter ``method``. Other keyword parameters can be left unchanged. >>> import numpy as np >>> import skimage as ski1 >>> import skimage2 as ski2 >>> fp1 = ski1.morphology.cube(3) >>> fp2 = ski2.morphology.footprint_rectangle((3, 3, 3)) >>> np.testing.assert_equal(fp1, fp2) >>> fp1 = ski1.morphology.cube( ... 3, decomposition="sequence" ... ) >>> fp2 = ski2.morphology.footprint_rectangle_decomposed( ... (3, 3, 3), method="sequence" ... ) >>> np.testing.assert_equal(fp1, fp2) .. _sk2adv-skimage-morphology-footprint-rectangle: ``skimage.morphology.footprint_rectangle`` ------------------------------------------ `skimage.morphology.footprint_rectangle` is deprecated in favor of `skimage2.morphology.footprint_rectangle` and `skimage2.morphology.footprint_rectangle_decomposed`. * `skimage2.morphology.footprint_rectangle` no longer accepts the ``decompose`` parameter and will return the footprint as a simple array. * `skimage2.morphology.footprint_rectangle_decomposed` uses the new parameter ``method``, which accepts the values of the old ``decomposition`` parameter. To keep the old behavior when switching to `skimage2`, update your call according to the following cases: * ``decomposition`` not passed, use `skimage2.morphology.footprint_rectangle` with same signature. * ``decomposition='sequence'`` or ``decomposition='separable'``, use `skimage2.morphology.footprint_rectangle_decomposed` and pass the old value of ``decomposition`` to the new parameter ``method``. Other keyword parameters can be left unchanged. >>> import numpy as np >>> import skimage as ski1 >>> import skimage2 as ski2 >>> fp1 = ski1.morphology.footprint_rectangle((3, 3, 3)) >>> fp2 = ski2.morphology.footprint_rectangle((3, 3, 3)) >>> np.testing.assert_equal(fp1, fp2) >>> fp1 = ski1.morphology.footprint_rectangle( ... (3, 3, 3), decomposition="sequence" ... ) >>> fp2 = ski2.morphology.footprint_rectangle_decomposed( ... (3, 3, 3), method="sequence" ... ) >>> np.testing.assert_equal(fp1, fp2) .. _sk2adv-skimage-morphology-rectangle: ``skimage.morphology.rectangle`` -------------------------------- `skimage.morphology.rectangle` is deprecated in favor of `skimage2.morphology.footprint_rectangle` and `skimage2.morphology.footprint_rectangle_decomposed`. * The new functions expect to be given a ``shape`` instead of the parameters ``nrows`` and ``ncols``. * `skimage2.morphology.footprint_rectangle` no longer accepts the ``decompose`` parameter and will return the footprint as a simple array. * `skimage2.morphology.footprint_rectangle_decomposed` uses the new parameter ``method``, which accepts the values of the old ``decomposition`` parameter. To keep the old behavior when switching to `skimage2`, update your call according to the following cases: * Pass the desired shape of the footprint as a 2-element tuple ``(nrows, ncols)`` of the formerly used parameters. * ``decomposition`` not passed, use `skimage2.morphology.footprint_rectangle` with same signature. * ``decomposition='sequence'`` or ``decomposition='separable'``, use `skimage2.morphology.footprint_rectangle_decomposed` and pass the old value of ``decomposition`` to the new parameter ``method``. Other keyword parameters can be left unchanged. >>> import numpy as np >>> import skimage as ski1 >>> import skimage2 as ski2 >>> fp1 = ski1.morphology.rectangle(3, 3) >>> fp2 = ski2.morphology.footprint_rectangle((3, 3)) >>> np.testing.assert_equal(fp1, fp2) >>> fp1 = ski1.morphology.rectangle( ... 3, 3, decomposition="sequence" ... ) >>> fp2 = ski2.morphology.footprint_rectangle_decomposed( ... (3, 3), method="sequence" ... ) >>> np.testing.assert_equal(fp1, fp2) .. _sk2adv-skimage-morphology-square: ``skimage.morphology.square`` ----------------------------- `skimage.morphology.square` is deprecated in favor of `skimage2.morphology.footprint_rectangle` and `skimage2.morphology.footprint_rectangle_decomposed`. * The new functions expect to be given a ``shape`` instead of the parameter ``width``. * `skimage2.morphology.footprint_rectangle` no longer accepts the ``decompose`` parameter and will return the footprint as a simple array. * `skimage2.morphology.footprint_rectangle_decomposed` uses the new parameter ``method``, which accepts the values of the old ``decomposition`` parameter. To keep the old behavior when switching to `skimage2`, update your call according to the following cases: * Pass the desired shape of the footprint as a 2-element tuple ``(w, w)`` where ``w`` is the former ``width`` that was used. * ``decomposition`` not passed, use `skimage2.morphology.footprint_rectangle` with same signature. * ``decomposition='sequence'`` or ``decomposition='separable'``, use `skimage2.morphology.footprint_rectangle_decomposed` and pass the old value of ``decomposition`` to the new parameter ``method``. Other keyword parameters can be left unchanged. >>> import numpy as np >>> import skimage as ski1 >>> import skimage2 as ski2 >>> fp1 = ski1.morphology.square(3) >>> fp2 = ski2.morphology.footprint_rectangle((3, 3)) >>> np.testing.assert_equal(fp1, fp2) >>> fp1 = ski1.morphology.square( ... 3, decomposition="sequence" ... ) >>> fp2 = ski2.morphology.footprint_rectangle_decomposed( ... (3, 3), method="sequence" ... ) >>> np.testing.assert_equal(fp1, fp2) Deprecations prior to skimage2 ============================== We have already introduced a number of changes and deprecations to our API. These are part of the API cleanup for skimage2 but are not breaking. You will simply notice these as the classical deprecation warnings that you are already used to. We list them here, because updating your code to the new API will make it easier to transition to skimage2. *To be defined.*