Class ImgUtils

java.lang.Object
sc.fiji.snt.util.ImgUtils

public class ImgUtils extends Object
Static utilities for handling and manipulation of RandomAccessibleIntervals
Author:
Cameron Arshadi
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final record 
    ImgUtils.SliceResult<T extends net.imglib2.type.numeric.RealType<T>>
    Result of a channel/time slice extraction from an ImgPlus.
  • Method Summary

    Modifier and Type
    Method
    Description
    static String
    axisReport(net.imagej.ImgPlus<?> img)
    Builds a one-line diagnostic string listing all axes of an ImgPlus with their type, size, and scale.
    static double[]
    computeIntensityStats(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> source)
    Computes basic intensity statistics of an image.
    static double
    computeMeanIntensity(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> source)
    Computes the mean intensity of an image.
    static double
    computePercentile(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> source, double percentile)
    Computes an approximate percentile by random sampling.
    static List<net.imglib2.Interval>
    createIntervals(long[] sourceDimensions, long[] blockDimensions)
    Partition the source dimensions into a list of Intervals with given dimensions.
    static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>>
    net.imagej.ImgPlus<T>
    crop(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, boolean materialize)
    Crop a region from an ImgPlus using (x, y, z) pixel coordinates.
    static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>>
    net.imagej.ImgPlus<T>
    crop(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, long padPixels, boolean materialize)
    Crop a region from an ImgPlus using (x, y, z) pixel coordinates.
    static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>>
    net.imagej.ImgPlus<T>
    crop(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, long padPixels, boolean materialize, boolean dropSingletonDimensions)
    Crop a region from an ImgPlus using (x, y, z) pixel coordinates.
    static <T> net.imglib2.RandomAccessibleInterval<T>
    crop(net.imglib2.RandomAccessibleInterval<T> rai, long[] bboxMin, long[] bboxMax, long padPixels)
    Crop a region from a RandomAccessibleInterval using (x, y, z) pixel coordinates.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imagej.ImgPlus<T>
    downsampleToFit(net.imagej.ImgPlus<T> imgPlus, int maxDimSize)
    Downsamples an ImgPlus so that no spatial dimension exceeds maxDimSize.
    static <T extends net.imglib2.type.numeric.NumericType<T>>
    net.imagej.ImgPlus<T>
    dropSingletonDimensions(net.imagej.ImgPlus<T> img)
    Remove singleton dimensions from an ImgPlus, preserving axis metadata.
    static boolean
    exceedsDimension(net.imagej.ImgPlus<?> imgPlus, int maxDimSize)
    Checks whether any spatial dimension of an ImgPlus exceeds the given limit.
    static int[]
    findSpatialAxisIndices(net.imagej.ImgPlus<?> img)
    Find dimension indices for X, Y, Z axes in an ImgPlus.
    static int[]
    findSpatialAxisIndicesWithFallback(net.imagej.ImgPlus<?> img)
    Find dimension indices for X, Y, Z axes, with fallback to assumed ZYX order.
    static ij.measure.Calibration
    getCalibration(net.imagej.ImgPlus<?> imgPlus)
    Extracts ImageJ1 Calibration from ImgPlus axes, including origin offsets.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<T>
    getCtSlice(ij.ImagePlus imp)
     
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<T>
    getCtSlice(net.imagej.Dataset dataset, int channelIndex, int frameIndex)
    Get a view of the Dataset at the specified channel and frame.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    ImgUtils.SliceResult<T>
    getCtSlice(net.imagej.ImgPlus<T> imgPlus)
    Extracts a channel/time slice by squeezing singleton dimensions.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    ImgUtils.SliceResult<T>
    getCtSlice(net.imagej.ImgPlus<T> imgPlus, int channel, int time)
    Extract a specific channel/time slice from an ImgPlus.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<T>
    getCtSlice3d(ij.ImagePlus imp, int channel, int frame)
    Get a view of the ImagePlus at the specified channel and frame.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<T>
    getCtSlice3d(net.imagej.Dataset dataset, int channelIndex, int frameIndex)
    Get a 3D view of a Dataset at the specified channel and frame.
    static double
    getOrigin(net.imagej.ImgPlus<?> img, net.imagej.axis.AxisType axisType)
    Get the origin offset for a specific axis from an ImgPlus.
    static double[]
    getOrigins(net.imagej.ImgPlus<?> img)
    Get the origin offsets as {xOrigin, yOrigin, zOrigin} from an ImgPlus.
    static double[]
    getSpacing(net.imagej.ImgPlus<?> img)
    Extracts voxel spacing from ImgPlus axis metadata.
    static String
    getSpacingUnits(net.imagej.ImgPlus<?> img)
    Extracts spacing units from an ImgPlus.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<T>
    getXYZCImage(ij.ImagePlus imp)
    Gets a 4D (X, Y, Z, C) view of the ImagePlus at the current time frame, retaining all channels.
    static boolean
    haveSameSpatialDimensions(ij.ImagePlus imp, net.imglib2.RandomAccessibleInterval<?> rai)
    Checks whether an ImagePlus and a RandomAccessibleInterval have compatible spatial dimensions (width, height, and optionally depth).
    static boolean
    haveSameSpatialDimensions(net.imglib2.RandomAccessibleInterval<?> img1, net.imglib2.RandomAccessibleInterval<?> img2)
    Checks whether two images have compatible spatial dimensions (width, height, and optionally depth).
    static ij.measure.Calibration
    imgPlusToCalibration(net.imagej.ImgPlus<?> imgPlus)
    Deprecated.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<T>
    impToRealRai5d(ij.ImagePlus imp)
    Wrap an ImagePlus to a RandomAccessibleInterval such that the number of dimensions in the resulting rai is 5 and the axis order is XYCZT.
    static boolean
    isBinary(net.imglib2.RandomAccessibleInterval<?> rai)
     
    static boolean
    isLabelImage(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img)
    Checks whether a RandomAccessibleInterval appears to be a label image, using a default maximum of 500 classes.
    static boolean
    isLabelImage(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img, int maxClasses)
    Checks whether a RandomAccessibleInterval appears to be a label (segmentation) image.
    static boolean
    isMultiChannelRGB(net.imagej.ImgPlus<?> img)
    Checks if an ImgPlus appears to be a multi-channel RGB image (3 channels of 8-bit data, not packed ARGB).
    static boolean
    isRGB(net.imagej.ImgPlus<?> img)
    Checks if an ImgPlus contains packed RGB data (ARGBType).
    static int
    maxDimension(long[] dimensions)
     
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.img.Img<net.imglib2.type.numeric.real.FloatType>
    maxIntensityProjection(@UnknownNullability net.imglib2.RandomAccessibleInterval<net.imglib2.type.numeric.RealType<?>> source)
    Computes a max-intensity projection along the third dimension (Z) of a 3D image, returning a 2D Img with the same XY extent.
    static net.imagej.ImgPlus<?>
    open(File file)
    Opens an image file as an ImgPlus.
    static net.imagej.ImgPlus<?>
    open(String filePathOrUrl)
    Opens an image file using SCIFIO, supporting lazy loading for large formats.
    static boolean
    outOfBounds(long[] pos, long[] min, long[] max)
    Checks if pos is outside the bounds given by min and max
    static <T extends net.imglib2.type.Type<T>>
    net.imagej.ImgPlus<T>
    permuteToXYZCT(net.imagej.ImgPlus<T> img)
    Reorders the axes of an ImgPlus to the canonical XYZCT order expected by BVV and most ImageJ tools, applying swaps as needed.
    static <T extends net.imglib2.type.numeric.NumericType<T>>
    ij.ImagePlus
    raiToImp(net.imglib2.RandomAccessibleInterval<T> rai, String title)
    Convert a RandomAccessibleInterval to an ImagePlus.
    static double[]
    resolveSpacing(net.imglib2.RandomAccessibleInterval<?> img, double[] explicit)
    Resolves pixel spacing for a RandomAccessibleInterval.
    static void
    save(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img, String filePath)
    Saves an image to disk as a TIFF file.
    static <T extends net.imglib2.type.numeric.RealType<T> & net.imglib2.type.NativeType<T>>
    void
    save(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img, String filePath, T outType)
    Saves an image to disk as a TIFF file, converting pixel values to the specified output type before writing.
    static <T> List<net.imglib2.view.IntervalView<T>>
    splitIntoBlocks(net.imglib2.RandomAccessibleInterval<T> source, long[] blockDimensions)
    Partition the source rai into a list of IntervalView with given dimensions.
    static <T> net.imglib2.RandomAccessibleInterval<T>
    subInterval(net.imglib2.RandomAccessibleInterval<T> img, net.imglib2.Localizable p1, net.imglib2.Localizable p2, long padPixels)
    Get an N-D sub-interval of an N-D image, given two corner points and specified padding.
    static <T> net.imglib2.RandomAccessibleInterval<T>
    subVolume(net.imglib2.RandomAccessibleInterval<T> img, long x1, long y1, long z1, long x2, long y2, long z2, long padPixels)
    Get a 3D sub-volume of an image, given two corner points and specified padding.
    static <T extends net.imglib2.type.Type<T>>
    net.imagej.ImgPlus<T>
    swapAxes(net.imagej.ImgPlus<T> img, net.imagej.axis.AxisType axis1, net.imagej.axis.AxisType axis2)
    Returns a new ImgPlus with two axes swapped.
    static <T extends net.imglib2.type.numeric.NumericType<T>>
    ij.ImagePlus
    toImagePlus(net.imagej.ImgPlus<T> img)
    Convert an ImgPlus to an ImageJ1 ImagePlus.
    static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>>
    ij.ImagePlus
    toImagePlus(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax)
    Convert an ImgPlus to an ImagePlus, cropping to a bounding box.
    static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>>
    ij.ImagePlus
    toImagePlus(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, long padPixels, boolean materialize)
    Convert an ImgPlus to an ImagePlus, cropping to a bounding box.
    static <T extends net.imglib2.type.numeric.NumericType<T>>
    ij.ImagePlus
    toImagePlus(net.imagej.ImgPlus<T> img, String name)
    Convert an ImgPlus to an ImageJ1 ImagePlus.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>>
    toUnsignedShortIfFloat(net.imglib2.RandomAccessibleInterval<T> rai)
    Returns a 16-bit view of the given RAI if its pixel type is FloatType, normalizing values to the full 16-bit range using the data's actual min/max.
    static <T extends net.imglib2.type.numeric.RealType<T>>
    net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>>
    toUnsignedShortIfFloat(net.imglib2.RandomAccessibleInterval<T> rai, double min, double max)
    Returns a 16-bit view of the given RAI if its pixel type is FloatType, normalizing to the given min/max range.
    static <T extends net.imglib2.type.numeric.NumericType<T>>
    net.imagej.ImgPlus<T>
    wrapWithAxes(net.imglib2.RandomAccessibleInterval<T> rai, net.imagej.ImgPlus<?> source, String name)
    Wrap a RandomAccessibleInterval with axis metadata from a source ImgPlus.
    static net.imagej.ImgPlus<?>
    wrapWithSpacing(net.imglib2.RandomAccessibleInterval<?> rai, double[] spacing)
    Wraps a RandomAccessibleInterval as an ImgPlus with calibrated axes (no unit).
    static net.imagej.ImgPlus<?>
    wrapWithSpacing(net.imglib2.RandomAccessibleInterval<?> rai, double[] spacing, String unit)
    Wraps a RandomAccessibleInterval as an ImgPlus with calibrated axes.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • findSpatialAxisIndices

      public static int[] findSpatialAxisIndices(net.imagej.ImgPlus<?> img)
      Find dimension indices for X, Y, Z axes in an ImgPlus.
      Parameters:
      img - the ImgPlus
      Returns:
      int array {xIdx, yIdx, zIdx}, with -1 for missing axes
    • findSpatialAxisIndicesWithFallback

      public static int[] findSpatialAxisIndicesWithFallback(net.imagej.ImgPlus<?> img)
      Find dimension indices for X, Y, Z axes, with fallback to assumed ZYX order.
      Parameters:
      img - the ImgPlus
      Returns:
      int array {xIdx, yIdx, zIdx}
    • getOrigin

      public static double getOrigin(net.imagej.ImgPlus<?> img, net.imagej.axis.AxisType axisType)
      Get the origin offset for a specific axis from an ImgPlus.
      Parameters:
      img - the ImgPlus
      axisType - the axis type (e.g., Axes.X, Axes.Y, Axes.Z)
      Returns:
      the origin offset in calibrated units, or 0 if not found
    • getSpacing

      public static double[] getSpacing(net.imagej.ImgPlus<?> img)
      Extracts voxel spacing from ImgPlus axis metadata.
      Parameters:
      img - the ImgPlus with calibrated axes
      Returns:
      array of spacing values, one per dimension (e.g., {x, y, z})
    • getOrigins

      public static double[] getOrigins(net.imagej.ImgPlus<?> img)
      Get the origin offsets as {xOrigin, yOrigin, zOrigin} from an ImgPlus.
      Parameters:
      img - the ImgPlus
      Returns:
      array of {xOrigin, yOrigin, zOrigin} in calibrated units
    • getCalibration

      public static ij.measure.Calibration getCalibration(net.imagej.ImgPlus<?> imgPlus)
      Extracts ImageJ1 Calibration from ImgPlus axes, including origin offsets.
      Parameters:
      imgPlus - the source ImgPlus
      Returns:
      Calibration with pixel sizes, unit, and origins
    • toImagePlus

      public static <T extends net.imglib2.type.numeric.NumericType<T>> ij.ImagePlus toImagePlus(net.imagej.ImgPlus<T> img)
      Convert an ImgPlus to an ImageJ1 ImagePlus.

      Transfers calibration (pixel sizes, unit) and origin offsets from ImgPlus axis metadata to ImagePlus Calibration. Handles dimension interpretation so Z is treated as slices rather than channels.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus
      Returns:
      ImagePlus with calibration and origin offsets
    • toImagePlus

      public static <T extends net.imglib2.type.numeric.NumericType<T>> ij.ImagePlus toImagePlus(net.imagej.ImgPlus<T> img, String name)
      Convert an ImgPlus to an ImageJ1 ImagePlus.

      Transfers calibration (pixel sizes, unit) and origin offsets from ImgPlus axis metadata to ImagePlus Calibration. Handles dimension interpretation so Z is treated as slices rather than channels.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus
      name - name for the ImagePlus, or null to use ImgPlus name
      Returns:
      ImagePlus with calibration and origin offsets
    • toImagePlus

      public static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>> ij.ImagePlus toImagePlus(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, long padPixels, boolean materialize)
      Convert an ImgPlus to an ImagePlus, cropping to a bounding box.

      Convenience method that combines crop(ImgPlus, long[], long[], long, boolean) and toImagePlus(ImgPlus, String).

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus
      bboxMin - minimum corner as {x, y, z} in pixel coordinates
      bboxMax - maximum corner as {x, y, z} in pixel coordinates
      padPixels - padding around the bounding box
      Returns:
      ImagePlus with calibration and origin offsets from crop region
    • toImagePlus

      public static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>> ij.ImagePlus toImagePlus(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax)
      Convert an ImgPlus to an ImagePlus, cropping to a bounding box. Convenience overload without padding.
    • imgPlusToCalibration

      @Deprecated public static ij.measure.Calibration imgPlusToCalibration(net.imagej.ImgPlus<?> imgPlus)
      Deprecated.
    • crop

      public static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>> net.imagej.ImgPlus<T> crop(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, boolean materialize)
      Crop a region from an ImgPlus using (x, y, z) pixel coordinates.

      Returns a new ImgPlus with calibration preserved and origin offset stored in the axis metadata. The cropped region maintains lazy loading if the source is lazy. Coordinates are clamped to image bounds.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus
      bboxMin - minimum corner as {x, y, z} in pixel coordinates
      bboxMax - maximum corner as {x, y, z} in pixel coordinates
      materialize - If false, only a view backed by the source ImgPlus is returned. If true, data is copied to a contiguous array
      Returns:
      cropped ImgPlus with origin offset in axis metadata
    • crop

      public static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>> net.imagej.ImgPlus<T> crop(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, long padPixels, boolean materialize)
      Crop a region from an ImgPlus using (x, y, z) pixel coordinates.

      Returns a new ImgPlus with calibration preserved and origin offset stored in the axis metadata. The cropped region maintains lazy loading if the source is lazy. Coordinates are clamped to image bounds.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus
      bboxMin - minimum corner as {x, y, z} in pixel coordinates
      bboxMax - maximum corner as {x, y, z} in pixel coordinates
      padPixels - padding to add around the bounding box (clamped to image bounds)
      materialize - If false, only a view backed by the source ImgPlus is returned. If true, data is copied to a contiguous array, and singleton dimensions removed.
      Returns:
      cropped ImgPlus with origin offset in axis metadata
    • crop

      public static <T extends net.imglib2.type.numeric.NumericType<T> & net.imglib2.type.NativeType<T>> net.imagej.ImgPlus<T> crop(net.imagej.ImgPlus<T> img, long[] bboxMin, long[] bboxMax, long padPixels, boolean materialize, boolean dropSingletonDimensions)
      Crop a region from an ImgPlus using (x, y, z) pixel coordinates.

      Returns a new ImgPlus with calibration preserved and origin offset stored in the axis metadata. The cropped region maintains lazy loading if the source is lazy. Coordinates are clamped to image bounds.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus
      bboxMin - minimum corner as {x, y, z} in pixel coordinates
      bboxMax - maximum corner as {x, y, z} in pixel coordinates
      padPixels - padding to add around the bounding box (clamped to image bounds)
      materialize - If false, only a view backed by the source ImgPlus is returned. If true, data is copied to a contiguous array
      dropSingletonDimensions - If true, singleton dimensions are removed
      Returns:
      cropped ImgPlus with origin offset in axis metadata
    • crop

      public static <T> net.imglib2.RandomAccessibleInterval<T> crop(net.imglib2.RandomAccessibleInterval<T> rai, long[] bboxMin, long[] bboxMax, long padPixels)
      Crop a region from a RandomAccessibleInterval using (x, y, z) pixel coordinates.

      For RAIs without axis metadata, assumes ZYX dimension order. Returns a view (no data copy) with the specified bounds, clamped to image bounds.

      Important: This method assumes ZYX dimension order (dim0=Z, dim1=Y, dim2=X), which is common for OME-ZARR and N5 datasets. For images with different axis orders, wrap as ImgPlus with proper axis metadata and use crop(ImgPlus, long[], long[], boolean).

      Type Parameters:
      T - the pixel type
      Parameters:
      rai - the source RandomAccessibleInterval
      bboxMin - minimum corner as {x, y, z} in pixel coordinates
      bboxMax - maximum corner as {x, y, z} in pixel coordinates
      padPixels - padding to add around the bounding box
      Returns:
      cropped view as RandomAccessibleInterval
    • maxDimension

      public static int maxDimension(long[] dimensions)
      Parameters:
      dimensions -
      Returns:
      the index of the largest dimension
    • subVolume

      public static <T> net.imglib2.RandomAccessibleInterval<T> subVolume(net.imglib2.RandomAccessibleInterval<T> img, long x1, long y1, long z1, long x2, long y2, long z2, long padPixels)
      Get a 3D sub-volume of an image, given two corner points and specified padding.

      Coordinates are in XYZ order. If the input is 2D, a singleton dimension is added. The sub-volume is clamped to image bounds.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source interval
      x1 - x-coordinate of the first corner point
      y1 - y-coordinate of the first corner point
      z1 - z-coordinate of the first corner point
      x2 - x-coordinate of the second corner point
      y2 - y-coordinate of the second corner point
      z2 - z-coordinate of the second corner point
      padPixels - the amount of padding in each dimension, in pixels
      Returns:
      the sub-volume
      See Also:
    • subInterval

      public static <T> net.imglib2.RandomAccessibleInterval<T> subInterval(net.imglib2.RandomAccessibleInterval<T> img, net.imglib2.Localizable p1, net.imglib2.Localizable p2, long padPixels)
      Get an N-D sub-interval of an N-D image, given two corner points and specified padding.

      Works in native dimension order (no XYZ remapping). The sub-interval is clamped to image bounds.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source interval
      p1 - the first corner point
      p2 - the second corner point
      padPixels - the amount of padding in each dimension, in pixels
      Returns:
      the sub-interval
    • splitIntoBlocks

      public static <T> List<net.imglib2.view.IntervalView<T>> splitIntoBlocks(net.imglib2.RandomAccessibleInterval<T> source, long[] blockDimensions)
      Partition the source rai into a list of IntervalView with given dimensions. If the block dimensions are not multiples of the image dimensions, some blocks will have truncated dimensions.
      Type Parameters:
      T -
      Parameters:
      source - the source rai
      blockDimensions - the target block size
      Returns:
      the list of blocks
    • createIntervals

      public static List<net.imglib2.Interval> createIntervals(long[] sourceDimensions, long[] blockDimensions)
      Partition the source dimensions into a list of Intervals with given dimensions. If the block dimensions are not multiples of the image dimensions, some blocks will have slightly different dimensions.
      Parameters:
      sourceDimensions - the source dimensions
      blockDimensions - the target block size
      Returns:
      the list of Intervals
    • raiToImp

      public static <T extends net.imglib2.type.numeric.NumericType<T>> ij.ImagePlus raiToImp(net.imglib2.RandomAccessibleInterval<T> rai, String title)
      Convert a RandomAccessibleInterval to an ImagePlus. If the input has 3 dimensions, the 3rd dimension is treated as depth.
      Type Parameters:
      T -
      Parameters:
      rai - the source rai
      title - the title for the converted ImagePlus
      Returns:
      the ImagePlus
    • getCtSlice3d

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getCtSlice3d(net.imagej.Dataset dataset, int channelIndex, int frameIndex)
      Get a 3D view of a Dataset at the specified channel and frame. If the Dataset is 2D, a singleton dimension is added.
      Type Parameters:
      T -
      Parameters:
      dataset - the input Dataset
      channelIndex - the channel position, 0-indexed
      frameIndex - the time position, 0-indexed
      Returns:
      the view rai
    • getCtSlice

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getCtSlice(net.imagej.Dataset dataset, int channelIndex, int frameIndex)
      Get a view of the Dataset at the specified channel and frame.
      Type Parameters:
      T -
      Parameters:
      dataset - the input Dataset
      channelIndex - the channel position, 0-indexed
      frameIndex - the time position, 0-indexed
      Returns:
      the view RAI
    • getCtSlice

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getCtSlice(ij.ImagePlus imp)
    • getCtSlice

      public static <T extends net.imglib2.type.numeric.RealType<T>> ImgUtils.SliceResult<T> getCtSlice(net.imagej.ImgPlus<T> imgPlus, int channel, int time)
      Extract a specific channel/time slice from an ImgPlus.
      Parameters:
      imgPlus - source image
      channel - channel index to extract, or null to keep all/squeeze singleton
      time - time index to extract, or null to keep all/squeeze singleton
      Returns:
      SliceResult with extracted image and tracked indices
    • getCtSlice

      public static <T extends net.imglib2.type.numeric.RealType<T>> ImgUtils.SliceResult<T> getCtSlice(net.imagej.ImgPlus<T> imgPlus)
      Extracts a channel/time slice by squeezing singleton dimensions.

      Convenience overload that removes any singleton (size=1) channel or time dimensions from the image. Non-singleton C/T dimensions are preserved.

      Type Parameters:
      T - pixel type
      Parameters:
      imgPlus - source image
      Returns:
      result containing the squeezed image and indices of any removed singleton dimensions (0 if squeezed, -1 if axis didn't exist or wasn't squeezed)
      See Also:
    • getCtSlice3d

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getCtSlice3d(ij.ImagePlus imp, int channel, int frame)
      Get a view of the ImagePlus at the specified channel and frame.
      Type Parameters:
      T -
      Parameters:
      imp - the input ImagePlus
      channel - the channel position, 1-indexed (as per ImagePlus convention)
      frame - the time position, 1-indexed (as per ImagePlus convention)
      Returns:
      the view RAI
    • impToRealRai5d

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> impToRealRai5d(ij.ImagePlus imp)
      Wrap an ImagePlus to a RandomAccessibleInterval such that the number of dimensions in the resulting rai is 5 and the axis order is XYCZT. Axes that are not present in the input imp have singleton dimensions in the rai.

      For example, given a 2D, multichannel imp, the dimensions of the result rai are [ |X|, |Y|, |C|, 1, 1 ]

      Type Parameters:
      T -
      Parameters:
      imp -
      Returns:
      the 5D rai
    • getXYZCImage

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<T> getXYZCImage(ij.ImagePlus imp)
      Gets a 4D (X, Y, Z, C) view of the ImagePlus at the current time frame, retaining all channels. This is useful for multichannel/spectral operations that need access to all channel data simultaneously.

      The returned RAI has axis order [X, Y, Z, C], obtained from the canonical 5D [X, Y, C, Z, T] representation by fixing T and permuting C past Z.

      Type Parameters:
      T - the pixel type
      Parameters:
      imp - the input ImagePlus (must have at least 2 channels)
      Returns:
      4D RAI with axis order [X, Y, Z, C], or null if the image has fewer than 2 channels
    • outOfBounds

      public static boolean outOfBounds(long[] pos, long[] min, long[] max)
      Checks if pos is outside the bounds given by min and max
      Parameters:
      pos - the position to check
      min - the minimum of the interval
      max - the maximum of the interval
      Returns:
      true if pos is out of bounds, false otherwise
    • dropSingletonDimensions

      public static <T extends net.imglib2.type.numeric.NumericType<T>> net.imagej.ImgPlus<T> dropSingletonDimensions(net.imagej.ImgPlus<T> img)
      Remove singleton dimensions from an ImgPlus, preserving axis metadata.
      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source ImgPlus (e.g., 5D XYZCT with C=1, T=1)
      Returns:
      ImgPlus with singleton dimensions removed
    • wrapWithAxes

      public static <T extends net.imglib2.type.numeric.NumericType<T>> net.imagej.ImgPlus<T> wrapWithAxes(net.imglib2.RandomAccessibleInterval<T> rai, net.imagej.ImgPlus<?> source, String name)
      Wrap a RandomAccessibleInterval with axis metadata from a source ImgPlus.

      Useful for wrapping op results with proper calibration.

      Type Parameters:
      T - the pixel type
      Parameters:
      rai - the RAI to wrap
      source - the source ImgPlus providing axis metadata
      name - name for the result
      Returns:
      ImgPlus with copied axis metadata
      Throws:
      IllegalArgumentException - if dimensions don't match
    • wrapWithSpacing

      public static net.imagej.ImgPlus<?> wrapWithSpacing(net.imglib2.RandomAccessibleInterval<?> rai, double[] spacing, String unit)
      Wraps a RandomAccessibleInterval as an ImgPlus with calibrated axes.

      Creates an ImgPlus with proper spatial axis metadata (X, Y, Z) and the specified voxel spacing. This is useful when working with RAIs that lack calibration metadata.

      Parameters:
      rai - the source image
      spacing - voxel spacing for each dimension (e.g., [x, y] or [x, y, z]). If null, defaults to 1.0 for all dimensions. If shorter than the number of dimensions, missing values default to 1.0. If longer, extra values are ignored (with warning logged).
      unit - the spatial unit (e.g., "µm", "mm"), or null for no unit
      Returns:
      an ImgPlus with calibrated spatial axes
      Throws:
      IllegalArgumentException - if rai is null or any spacing value is not positive
    • wrapWithSpacing

      public static net.imagej.ImgPlus<?> wrapWithSpacing(net.imglib2.RandomAccessibleInterval<?> rai, double[] spacing)
      Wraps a RandomAccessibleInterval as an ImgPlus with calibrated axes (no unit).
      Parameters:
      rai - the source image
      spacing - voxel spacing for each dimension
      Returns:
      an ImgPlus with calibrated spatial axes
      Throws:
      IllegalArgumentException - if rai is null or any spacing value is not positive
      See Also:
    • maxIntensityProjection

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.img.Img<net.imglib2.type.numeric.real.FloatType> maxIntensityProjection(@UnknownNullability net.imglib2.RandomAccessibleInterval<net.imglib2.type.numeric.RealType<?>> source)
      Computes a max-intensity projection along the third dimension (Z) of a 3D image, returning a 2D Img with the same XY extent. For 2D inputs (2 dimensions or fewer), the source is projected trivially (the single plane is copied).
      Type Parameters:
      T - pixel type
      Parameters:
      source - the input image (2D or 3D)
      Returns:
      a 2D max-intensity projection as an Img<FloatType>
    • computeMeanIntensity

      public static double computeMeanIntensity(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> source)
      Computes the mean intensity of an image.
      Parameters:
      source - the input image
      Returns:
      the mean intensity value
    • computeIntensityStats

      public static double[] computeIntensityStats(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> source)
      Computes basic intensity statistics of an image.
      Parameters:
      source - the input image
      Returns:
      array of [min, max, mean]
    • computePercentile

      public static double computePercentile(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> source, double percentile)
      Computes an approximate percentile by random sampling.
      Parameters:
      source - the input image
      percentile - the percentile to compute (0-100)
      Returns:
      the approximate percentile value
    • isBinary

      public static boolean isBinary(net.imglib2.RandomAccessibleInterval<?> rai)
    • open

      public static net.imagej.ImgPlus<?> open(String filePathOrUrl)
      Opens an image file using SCIFIO, supporting lazy loading for large formats.

      Supports standard formats (TIFF, PNG, JPEG) and big data formats with lazy loading (N5, Zarr, HDF5, OME-TIFF). Large datasets are opened as virtual/lazy images without loading the entire file into memory.

      Parameters:
      filePathOrUrl - path to image file or URL
      Returns:
      ImgPlus (may be lazy-loaded for large formats), or null if opening fails
    • downsampleToFit

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imagej.ImgPlus<T> downsampleToFit(net.imagej.ImgPlus<T> imgPlus, int maxDimSize)
      Downsamples an ImgPlus so that no spatial dimension exceeds maxDimSize. Only spatial axes (X, Y, Z) are downsampled; Channel and Time axes are left untouched.

      Uses nearest-neighbour subsampling (Views.subsample(net.imglib2.RandomAccessibleInterval<T>, long)) for speed. The calibration of downsampled axes is scaled accordingly so that the physical extent of the image is preserved.

      Type Parameters:
      T - pixel type
      Parameters:
      imgPlus - the image to downsample
      maxDimSize - maximum allowed size for any spatial dimension (e.g. GL_MAX_3D_TEXTURE_SIZE)
      Returns:
      a (possibly lazy) downsampled ImgPlus, or the original if no dimension exceeds the limit
    • exceedsDimension

      public static boolean exceedsDimension(net.imagej.ImgPlus<?> imgPlus, int maxDimSize)
      Checks whether any spatial dimension of an ImgPlus exceeds the given limit. Only X, Y, and Z axes are considered.
      Parameters:
      imgPlus - the image to check
      maxDimSize - maximum allowed size (e.g., GL_MAX_3D_TEXTURE_SIZE)
      Returns:
      true if at least one spatial dimension exceeds the limit
    • save

      public static void save(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img, String filePath) throws Exception
      Saves an image to disk as a TIFF file. This is the save counterpart of open(String).

      The image is copied into a 32-bit float representation prior to saving, ensuring compatibility regardless of the source pixel type. For lower bit-depth output use save(RandomAccessibleInterval, String, RealType).

      Parameters:
      img - the image to save; may be virtual or transformed
      filePath - the destination file path; a .tif extension is appended automatically if absent
      Throws:
      Exception - if the image cannot be serialized or written to disk
    • save

      public static <T extends net.imglib2.type.numeric.RealType<T> & net.imglib2.type.NativeType<T>> void save(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img, String filePath, T outType) throws Exception
      Saves an image to disk as a TIFF file, converting pixel values to the specified output type before writing. This is the save counterpart of open(String).

      The image is materialized into a concrete in-memory Img of the requested type, so the caller must ensure sufficient RAM is available. Conversion is done via ComplexType.setReal(double), which clamps values to the target type's range automatically (e.g. 16-bit unsigned values are clamped to [0, 65535]).

      Typical usage:
         ImgUtils.save(rai, "/path/to/out.tif", new UnsignedShortType());
         ImgUtils.save(rai, "/path/to/out.tif", new UnsignedByteType());
         ImgUtils.save(rai, "/path/to/out.tif", new FloatType());
       
      Type Parameters:
      T - the output pixel type; must be a NativeType so that an ArrayImgFactory can allocate it
      Parameters:
      img - the image to save; may be virtual or transformed
      filePath - the destination file path; a .tif extension is appended automatically if absent
      outType - an instance of the desired output pixel type, e.g. new UnsignedShortType() for 16-bit output
      Throws:
      Exception - if the image cannot be serialized or written to disk
    • open

      public static net.imagej.ImgPlus<?> open(File file)
      Opens an image file as an ImgPlus.
      Parameters:
      file - the file to open
      Returns:
      the opened image as ImgPlus, or null if opening fails
      Throws:
      IllegalArgumentException - if file is null
    • isRGB

      public static boolean isRGB(net.imagej.ImgPlus<?> img)
      Checks if an ImgPlus contains packed RGB data (ARGBType).
      Parameters:
      img - the image to check
      Returns:
      true if the image uses ARGBType pixels
    • isMultiChannelRGB

      public static boolean isMultiChannelRGB(net.imagej.ImgPlus<?> img)
      Checks if an ImgPlus appears to be a multi-channel RGB image (3 channels of 8-bit data, not packed ARGB).
    • getSpacingUnits

      public static String getSpacingUnits(net.imagej.ImgPlus<?> img)
      Extracts spacing units from an ImgPlus.
      Parameters:
      img - the image
      Returns:
      the unit string (e.g., "µm"), or null if not calibrated
    • toUnsignedShortIfFloat

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> toUnsignedShortIfFloat(net.imglib2.RandomAccessibleInterval<T> rai)
      Returns a 16-bit view of the given RAI if its pixel type is FloatType, normalizing values to the full 16-bit range using the data's actual min/max. Returns the original RAI unchanged for any other type. No data is copied.
      Parameters:
      rai - the source image
      Returns:
      a 16-bit RAI, or the original RAI if not float
    • toUnsignedShortIfFloat

      public static <T extends net.imglib2.type.numeric.RealType<T>> net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> toUnsignedShortIfFloat(net.imglib2.RandomAccessibleInterval<T> rai, double min, double max)
      Returns a 16-bit view of the given RAI if its pixel type is FloatType, normalizing to the given min/max range.
      Parameters:
      rai - the source image
      min - the minimum value for normalization (maps to 0)
      max - the maximum value for normalization (maps to 65535)
      Returns:
      a 16-bit RAI, or the original RAI if not float
    • axisReport

      public static String axisReport(net.imagej.ImgPlus<?> img)
      Builds a one-line diagnostic string listing all axes of an ImgPlus with their type, size, and scale. Used by open(String) to report the axis layout of freshly opened images.
      Parameters:
      img - the image to describe
      Returns:
      a human-readable axis summary, e.g. "Axes: [X 512 (1.0µm)] [Y 512 (1.0µm)] [Z 60 (2.0µm)] [Channel 3 (1.0)]"
    • swapAxes

      public static <T extends net.imglib2.type.Type<T>> net.imagej.ImgPlus<T> swapAxes(net.imagej.ImgPlus<T> img, net.imagej.axis.AxisType axis1, net.imagej.axis.AxisType axis2)
      Returns a new ImgPlus with two axes swapped. The underlying data is a lazy permuted view (no pixel data is copied). Axis metadata (type, scale, unit) is reordered to match the new dimension order. Example: swap Z and Channel in an XYZCT image:
         
         ImgPlus<?> xyzct = ImgUtils.open("image.tif");
         ImgPlus<?> xyczT = ImgUtils.swapAxes(xyzct, Axes.Z, Axes.CHANNEL);
         
       
      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source image
      axis1 - the first axis type to swap
      axis2 - the second axis type to swap
      Returns:
      a new ImgPlus with the two axes permuted
      Throws:
      IllegalArgumentException - if either axis type is not found in the image
    • permuteToXYZCT

      public static <T extends net.imglib2.type.Type<T>> net.imagej.ImgPlus<T> permuteToXYZCT(net.imagej.ImgPlus<T> img)
      Reorders the axes of an ImgPlus to the canonical XYZCT order expected by BVV and most ImageJ tools, applying swaps as needed. Axes not present in the image are left in place. No pixel data is copied.

      This is useful when SCIFIO opens an image with axis order XYCZT (as ImageJ saves it) but BVV expects XYZCT, causing Z and C to be misinterpreted.

      Type Parameters:
      T - the pixel type
      Parameters:
      img - the source image; may have any axis order
      Returns:
      a new ImgPlus reordered to XYZCT (axes already in canonical order are returned unchanged)
    • haveSameSpatialDimensions

      public static boolean haveSameSpatialDimensions(net.imglib2.RandomAccessibleInterval<?> img1, net.imglib2.RandomAccessibleInterval<?> img2)
      Checks whether two images have compatible spatial dimensions (width, height, and optionally depth). This is useful for verifying that a label/segmentation image matches the image that paths were traced on.
      Parameters:
      img1 - first image
      img2 - second image
      Returns:
      true if the first 2 (or 3, if both are 3D+) dimensions match
    • haveSameSpatialDimensions

      public static boolean haveSameSpatialDimensions(ij.ImagePlus imp, net.imglib2.RandomAccessibleInterval<?> rai)
      Checks whether an ImagePlus and a RandomAccessibleInterval have compatible spatial dimensions (width, height, and optionally depth).
      Parameters:
      imp - the ImagePlus
      rai - the RandomAccessibleInterval (XY or XYZ)
      Returns:
      true if spatial dimensions match
    • isLabelImage

      public static boolean isLabelImage(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img, int maxClasses)
      Checks whether a RandomAccessibleInterval appears to be a label (segmentation) image. A label image is expected to contain non-negative integer values with 0 as background and a bounded number of unique classes.

      The heuristics are:

      • All values must be non-negative and integer-valued (i.e., value == Math.floor(value)).
      • The number of unique non-zero values must not exceed maxClasses.
      The scan terminates early if either condition is violated.
      Parameters:
      img - the image to check
      maxClasses - maximum number of distinct non-zero labels allowed
      Returns:
      true if the image passes all label-image heuristics
    • isLabelImage

      public static boolean isLabelImage(net.imglib2.RandomAccessibleInterval<? extends net.imglib2.type.numeric.RealType<?>> img)
      Checks whether a RandomAccessibleInterval appears to be a label image, using a default maximum of 500 classes.
      Parameters:
      img - the image to check
      Returns:
      true if the image passes label-image heuristics
      See Also:
    • resolveSpacing

      public static double[] resolveSpacing(net.imglib2.RandomAccessibleInterval<?> img, double[] explicit)
      Resolves pixel spacing for a RandomAccessibleInterval. If explicit spacing is provided and has enough dimensions, it is used directly. Otherwise, axis metadata is extracted from ImgPlus if available. Falls back to isotropic spacing of 1.0.
      Parameters:
      img - the image
      explicit - explicit spacing array, or null
      Returns:
      pixel spacing array with one entry per image dimension