Skip to content

API changes for skimage2

Lars Grüter edited this page Mar 17, 2026 · 42 revisions

Other lists and resources that touch and inform this document:

Proposed API changes surrounding skimage2

These changes are difficult to do with deprecations.

Whole library

  • Consistently preserve the range of user-provided inputs #5439 (comment)
  • Functions that take in x/y (transposed) coordinates should take axis-aligned (aka rc) coordinates instead. #5439 (Juan's request), #5439 (Greg's list). related: #2275
  • Unify boundary extension mode names used across the library. #5439 (comment)
    • Currently we have 21 functions that use boundary mode names compatible with scipy.ndimage while we have another set of 12 functions that use names compatible with numpy.pad. Filtering/morphology functions tend to use the scipy.ndimage names while those in restoration/transforms tend to use the NumPy ones. Out of these the subtle difference between reflect/mirror/symmetric can be quite confusing to users with reflect unfortunately being a valid name, but with different behavior in the two conventions!
    • list of specific functions following each convention
    • Sprint: We probably want to follow scipy.ndimage for skimage2!
  • Promote small integer types to float32 instead of float64. Conserves memory and may have some performance benefit, but can change precision of resulting floating point computations #6310. cuCIM already changed to this convention in June 2022 because the benefit of float32 vs. float64 for performance is large on GPU (cucim#278)

skimage.feature

  • skimage.feature.canny's mode argument should not default to constant, since that usually results in an edge on the boundary. #6874 (comment) #5439 (comment)
    • Sprint: still relevant, should be changed to "nearest"
  • Use Euclidean distance in skimage.feature.peak_local_max as new default for the p_norm parameter #6608
    • Sprint: still relevant and agree
    • Implemented in #8039

skimage.filters

  • Switch the sign of the internal Laplace operator in skimage.filters.laplace so that it returns a negative number at the position of a maximum. #7357

skimage.measure

  • Change regionprops so that indices match labels #2755
    • Return a dictionary, keyed on label, instead of a list: {1: RegionProp<label=1>, 2: RegionProp<label=2>, ...}
    • Instead of dictionary, perhaps we return a set.
    • Sprint: come back later with Juan's perspective...

skimage.morphology

  • Update API and behavior of morphological filters as described in #7238. Change default mode to "ignore" to have less impact
    • Sprint: still want this and need skimage2
  • Set mirror to same value for gray and binary morphology operators (see #6695)

skimage.restoration

  • Remove default clipping and switch to clip=False as the new default in deconvolution functions in skimage.restoration #7477 (comment).
    • clip is useful since restoration often produces ringing, but agreed it should not be on by default.
    • Remove clip and encourage user to provide data_range. We need data_range for clipping anyway.
    • Sprint: keep for skimage2

skimage.segmentation

  • In watershed function, compute local minima with ski.morphology.label(ski.morphology.local_minima(image)) #7117?
    • Sprint: keep for skimage2

skimage.transform


Proposed API changes, doable independent of skimage2

These should be doable with normal deprecations, right away.

  • Add a coordinates or similar flag to each function in skimage.transform, to change it from working with xy to rc. For 2.0, we'll change the default from xy to rc.
    • See "Functions that take in x/y (transposed) coordinates should take axis-aligned (aka rc) coordinates instead" above.
  • Maybe consolidate footprint generating functions in their public footprint namespace or even skimage.shapes module? #2538
  • Use consistent API and parameters for footprint generation. #5439 (comment)
    • These are currently a mess of size, width, height, m, n, radius, etc. #4536. I would argue that we really only need a n-dimensional rectangle implementation rather than separate square, rectangle, cube, etc. Likewise an n-dimensional sphere (or more generally an n-dimensinal ellipse) rather than ball and disk.I would argue that the shape is not quite right currently in disk/ball/ellipse generation functions and should be changed (needing adjustment by 0.5 pixels internally): discussion under "Use a consistent API (e.g. using radius) ..."
    • Sprint: Use selem_type(shape=...). Default to 2D name, since that's the most common use-case, but support higher-dimensional (at least 3). For circle disk(shape=(3, 3)) for sphere disk(shape=(3, 3, 3)). disk can also support ellipse/ellipsoid, it's not too confusing. Other names: rectangle Examples from diplib's ShapeCode
  • Prefer composed footprints as default where possible (decomposition="sequence") for performance reasons
  • Create nicer container for decomposed footprints, that's still usable as a primitive tuple or similar
    • E.g., dataclass
    • Must allow for easy conversion to dense footprint
    • Should have repr that renders it intuitively (display dense version)
  • binary_ morphological functions should be deprecated because they use SciPy's (regressed) slow versions under the hood scipy/scipy#13991, #1990
  • Turn skimage.io module into a thin wrapper around imageio #5439 (comment)
  • Unify interface for algorithms that expect binary images. Either, only accept binary images (maybe preferred) or convert implicitly to binary images everywhere. #7095 (comment)
    • Team sense: require user to explicitly convert. This avoids accidentally accepting the wrong argument (user passes in image, instead of mask, e.g.).
    • Not skimage2, can be done right now.
  • Remove legacy property names. We have some properties that have even been renamed twice, leaving a mess of legacy names that are still supported (and, hence, tested), which represents a certain maintenance burden. #5439 (comment)
    • Not documented, so really no problem, and not urgent for skimage2.
    • Sprint: We can deprecate and remove these any time we like (e.g., right now).
  • In skimage.draw, accept coordinates as a single keyword value, e.g. center=(0,1), rather than splitting into row=0 and col=1, as it is currently done. This will allow us to extend to N-D in the future. #2538 (comment)
    • ski.draw.circle_perimeter(r, c, radius, method='bresenham', shape=None)
    • Typically called as circle_perimeter(10, 10, 50)
    • Could change outside of skimage2, but would then become: circle_perimeter(center=(10, 10), radius=50) (via keyword-only arguments)
    • Sprint: deprecate using positional arguments for separate dimensions, use stuff like center
  • Consistently use label_image as the parameter name refering to label images. #5439 (comment)
    • In docstrings, docs, plain English, use "label image" everywhere instead of "labeled image" and "labels image" (unless it's actually part of the meaning of the sentence, e.g., "... and we end up with a labeled image").
  • Consistently use image rather than img, arr, data, etc for image inputs. #5439 (comment)
  • Move skimage.future.graph to skimage.graph. #3105
  • Change output to out in skimage.filters.gaussian for consistency with other skimage functions supporting output to a user-provided array. #5439 (comment)
  • Make functions in skimage.filters.threshold behave consistently. #5439 (comment)
    • Many currently return a numeric threshold value, but some return a thresholded image instead.
    • Sprint:
      • There are three cases to deal with:
        1. Function that returns threshold
        2. Threshold can be scalar or array
        3. Function that computes thresholded image directly
      • Suggested interface: threshold_* -> scalar or array threshold thresholded_image_* -> thresholded image
      • Can be done outside skimage2
      • May want to flesh out the collection of functions so that we can (in most cases) either calculate the threshold image or the threshold value(s).
  • Consistently use num_workers / workers for any parameter related to the number of threads/processes #5439 (comment)
  • Resolve API inconsistency between the parameter names min_size and area_threshold in remove_small_holes and remove_small_objects #4003
    • Sprint: Not a strong preference, but seems like agreement to move back to min_size (for now, will check again)
  • Address nomenclature for perimeter, area, volume in regionprops for 2D and 3D cases #3812.
  • Remove skimage.viewer module as napari is a more actively developed and more powerful third-party alternative. #5439 (comment)
  • Unify API on seed keyword for random seeds / generator #5359
  • Where function signatures still use im1, im2, finally replace them with either image0, image1 or reference_image, target_image. #4187
  • Audit our modules to cluster functions based on purpose and "interchangeability". #5439 (comment)
    • "The "big picture" in this case is to be sklearn-like in that it will enable easier interoperability between skimage and libraries replicating or extending the skimage API."

    • TODO: The comment above missing, and the link in the issue is broken. Please clarify the intent / meaning of this item.
  • Potentially move thresholding functions to their own new submodule, e.g. skimage.binarize. #2538
    • S: binarize doesn't fit for me with other submodule names; threshold would be fine?
      • In this case, we can also immediately rename the functions to whatever we want. Recall threshold_image_* vs threshold_ discussion.
  • Rename skimage.util.img_as_* functions to rescale_to_*. #1234

Clone this wiki locally