nornir_imageregistration

alignment_record

class nornir_imageregistration.alignment_record.AlignmentRecord(peak: ndarray[tuple[Any, ...], dtype[floating]] | tuple[float, float], weight: float, angle: float = 0.0, flipped_ud: bool = False, scale: float = 1.0, peak_ratio: float | None = None)[source]

Bases: object

Records basic registration information as an angle and offset between a fixed and moving image If the offset is zero the center of both images occupy the same point. The offset determines the translation of the moving image over the fixed image. There is no support for scale, and there should not be unless added as another variable to the alignment record

Parameters:
  • peak (array) – Translation vector for moving image

  • weight (float) – The strength of the alignment

  • angle (float) – Angle to rotate moving image in degrees

CorrectPeakForOriginalImageSize(TargetImageShape: ndarray[tuple[Any, ...], dtype[integer]], SourceImageShape: ndarray[tuple[Any, ...], dtype[integer]])[source]
GetTransformedCornerPoints(warpedImageSize: ndarray[tuple[Any, ...], dtype[integer]]) → ndarray[tuple[Any, ...], dtype[floating]][source]

Return the corners of a bounding box in the target space after the transform is applied.

Invert()[source]

Returns a new alignment record with the coordinates of the peak reversed Used to change the frame of reference of the alignment from one tile to another

ToImageTransform(target_image_shape: ndarray[tuple[Any, ...], dtype[integer]] | tuple[int, int], source_image_shape: ndarray[tuple[Any, ...], dtype[integer]] | tuple[int, int] | None = None) → ITransform[source]

Generates a rigid transform for the alignment record in the context of two images of the specified size. Because images are indexed starting at zero, the center of a 10x10 image is 4.5,4.5. The center of a 9x9 image is 4,4.

Parameters:
  • target_image_shape ((Height, Width)) – Size of translated image in fixed space

  • source_image_shape ((Height, Width)) – Size of translated image in warped space. If unspecified defaults to fixedImageSize

Returns:

A rigid rotation+translation transform described by the alignment record

ToSpatialTransform(target_shape: ndarray[tuple[Any, ...], dtype[integer]] | tuple[int, int], source_shape: ndarray[tuple[Any, ...], dtype[integer]] | tuple[int, int] | None = None) → ITransform[source]

Generates a rigid transform for the alignment record in the context of two images of the specified size. The center is not adjusted as it would be for an image transform.

Parameters:
  • target_image_shape ((Height, Width)) – Size of translated image in fixed space

  • source_image_shape ((Height, Width)) – Size of translated image in warped space. If unspecified defaults to fixedImageSize

Returns:

A rigid rotation+translation transform described by the alignment record

ToStos(ImagePath: str, WarpedImagePath: str, FixedImageMaskPath: str | None = None, WarpedImageMaskPath: str | None = None, PixelSpacing: float | int = 1)[source]

Convert the alignment record to a StosFile

WeightKey() → float[source]
property angle: float

Rotation in degrees

property flippedud: bool

True if the warped image was flipped vertically for the alignment

property peak: ndarray[tuple[Any, ...], dtype[floating]]

Translation vector for the alignment

property peak_ratio: float | None

Primary / masked-2nd-peak uniqueness, or None if not measured.

property rangle: float

Rotation in radians

property scale: float
translate(value: ndarray[tuple[Any, ...], dtype[floating]])[source]

Translates the peak position using tuple (Y,X)

property weight: float

Quantifies the quality of the alignment

core

Core image I/O, ROI, tiling, shared memory, and array utilities. Re-exports from _core for backward compatibility.

nornir_imageregistration.core.ApproxEqual(a: float, b: float, epsilon=None) → bool[source]

Return True if |a - b| < epsilon (default 0.01).

nornir_imageregistration.core.BuildTilePyramidsMemoryCpu(tiles: dict[str, list[str | None]], shrink_factors: list[float], num_threads: int | None = None) → None[source]

Build pyramid levels in memory for many tiles (CPU, threaded).

Parameters:
  • tiles – Maps each finest-level input path to a list of output paths, one per downsample step in order. Use None for a step that should run in memory but not be written (downstream level still updated in the chain).

  • shrink_factors – Downsample factor for each step (typically 0.5).

  • num_threads – Worker count; defaults to cpu_count * 2.

nornir_imageregistration.core.BuildTilePyramidsMemoryGpu(tiles: dict[str, list[str | None]], shrink_factors: list[float]) → None[source]

Build pyramid levels in memory for many tiles (GPU, one tile at a time).

Falls back to BuildTilePyramidsMemoryCpu() when CuPy is unavailable.

nornir_imageregistration.core.ConstrainedRange(start: int, count: int, maxVal: int, minVal: int = 0) → list[int][source]

Return a range of count integers starting at start, clamped to [minVal, maxVal).

nornir_imageregistration.core.ConvertImagesInDict(ImagesToConvertDict, Flip: bool = False, Flop: bool = False, InputBpp: int | None = None, OutputBpp: int | None = None, Invert: bool = False, bDeleteOriginal: bool = False, RightLeftShift: int | None = None, AndValue: int | None = None, MinMax: tuple[float, float] | None = None, Gamma: float | None = None, progress_name: str | None = None, progress_task_key: str | None = None)[source]

The key and value in the dictionary have the full path of an image to convert. MinMax is a tuple [Min,Max] passed to the -level parameter if it is not None RightLeftShift is a tuple containing a right then left then return to center shift which should be done to remove useless bits from the data I do not use an and because I do not calculate ImageMagick’s quantum size yet. Every image must share the same colorspace

Returns:

True if images were converted

Return type:

bool

nornir_imageregistration.core.ConvertImagesInDictGpu(ImagesToConvertDict: dict[str, str], Flip: bool = False, Flop: bool = False, InputBpp: int | None = None, OutputBpp: int | None = None, MinMax: tuple[float, float] | None = None, Gamma: float | None = None, batch_bytes: int | None = None, progress_name: str | None = None, progress_task_key: str | None = None) → bool[source]

GPU-accelerated contrast conversion using a chunked pipeline.

Submits load tasks to a thread pool through a window sized by the CONVERT_IMAGES_GPU_LOAD_BUDGET_BYTES host-memory budget – the whole section upfront when it fits (maximum NFS concurrency), otherwise a sliding window – then processes tiles in chunks sized by batch_bytes. Each chunk:

  1. Collects loaded arrays from the pool (nearly zero-wait — tasks are already running in the background).

  2. Copies them into a reused pinned-memory buffer with a single-pass np.multiply(src, scale, out=pinned_buf[i], casting='unsafe') — this combines dtype conversion and normalisation with no intermediate allocations.

  3. H→D transfers the entire pinned slab in one DMA operation.

  4. Optionally flips/flops on device, then applies level / gamma / clip vectorised over the batch axis on the GPU.

  5. D→H downloads the result, then dispatches per-tile saves to a second thread pool so saving chunk N overlaps with GPU work on chunk N+1. Saves hold views into the chunk’s D→H buffer, so at most CONVERT_IMAGES_GPU_SAVE_LOOKAHEAD_CHUNKS chunks stay outstanding.

Host memory — decoded tiles resident ahead of the GPU are capped by CONVERT_IMAGES_GPU_LOAD_BUDGET_BYTES (NORNIR_GPU_CONTRAST_LOAD_BUDGET_MB), so in-flight memory scales with worker count rather than with section size.

Chunk sizing — batch_bytes controls how many tiles fit in one GPU round-trip. Smaller batches allow load/compute/save overlap to start sooner; larger batches amortise H→D/D→H latency but stall the pipeline waiting for the full chunk to load. See the CONVERT_IMAGES_GPU_BATCH_BYTES module constant and the NORNIR_GPU_CONTRAST_BATCH_MB environment variable for process-wide override without touching call sites.

Falls back to ConvertImagesInDict() when: - CuPy is unavailable or not the active backend. - The tile set is empty. - Mixed tile shapes are detected after the first chunk.

Parameters:
  • ImagesToConvertDict – Mapping of input path → output path.

  • Flip – If True, flip each tile vertically (axis 0), matching _ConvertSingleImage().

  • Flop – If True, flip each tile horizontally (axis 1).

  • InputBpp – Bits-per-pixel of input tiles (auto-detected when None).

  • OutputBpp – Bits-per-pixel for output tiles (matches InputBpp when None).

  • MinMax – (min, max) intensity cutoff tuple for contrast stretch.

  • Gamma – Gamma correction value (None or 1.0 means no correction).

  • batch_bytes – Target float32 byte budget per GPU chunk. Defaults to CONVERT_IMAGES_GPU_BATCH_BYTES (64 MB unless overridden by the NORNIR_GPU_CONTRAST_BATCH_MB environment variable). chunk_size = max(1, batch_bytes // tile_float32_bytes).

Returns:

True if any images were converted.

nornir_imageregistration.core.ConvertImagesInDictGpuPyramid(ImagesToConvertDict: dict[str, str], PyramidOutputDicts: list[dict[str, str]], InputBpp: int | None = None, OutputBpp: int | None = None, MinMax: tuple[float, float] | None = None, Gamma: float | None = None, batch_bytes: int | None = None, progress_name: str | None = None, progress_task_key: str | None = None) → bool[source]

GPU contrast + all pyramid levels in a single per-tile pass.

Each source tile is loaded once, transferred to the GPU, contrast-adjusted, then downsampled in a 2× area-average chain via _downsample2x_gpu() for every requested pyramid level. Saves are dispatched per level so NFS writes overlap with GPU work on the next tile.

Load-pool width (cpu×2 workers) is independent of batch_bytes, which caps how many decoded source tiles may be prefetched ahead of the GPU tile.

Compared to running ConvertImagesInDictGpu() followed by BuildTilePyramids(), this approach:

  • Reads each source tile once regardless of the number of pyramid levels.

  • Keeps contrast-adjusted float32 data on the GPU for free downsampling.

  • Eliminates all intermediate NFS read-write cycles between pyramid levels.

Falls back to ConvertImagesInDictPyramid() (CPU) when CuPy is unavailable or tiles have mixed shapes.

Parameters:
  • ImagesToConvertDict – {input_path → output_path} for the finest level.

  • PyramidOutputDicts – List of {input_path → output_path} dicts, one per coarser pyramid level in ascending order (level 2, 4, 8, …). Keys must be a subset of ImagesToConvertDict keys.

  • InputBpp – Bits-per-pixel of input images (auto-detected when None).

  • OutputBpp – Bits-per-pixel for outputs (matches InputBpp when None).

  • MinMax – (min, max) intensity cutoff tuple.

  • Gamma – Gamma correction value (None or 1.0 = no correction).

  • batch_bytes – Host-memory budget for decoded source tiles resident ahead of the GPU. When the whole section fits (section_bytes <= batch_bytes) all loads are submitted upfront; otherwise cpu_count() loader threads feed a result queue capped at prefetch_count = batch_bytes // tile_float32_bytes. Defaults to CONVERT_IMAGES_GPU_PYRAMID_BATCH_BYTES (2 GB unless overridden by the NORNIR_GPU_PYRAMID_BATCH_MB environment variable).

Returns:

True if any images were converted.

nornir_imageregistration.core.ConvertImagesInDictPyramid(ImagesToConvertDict: dict[str, str], PyramidOutputDicts: list[dict[str, str]], InputBpp: int | None = None, OutputBpp: int | None = None, MinMax: tuple[float, float] | None = None, Gamma: float | None = None, progress_name: str | None = None, progress_task_key: str | None = None) → bool[source]

CPU contrast + all pyramid levels in one tile pass.

For each tile, loads it once from NFS, applies contrast via _ConvertSingleImage(), then chains _downsample2x_cpu() for each entry in PyramidOutputDicts. All tiles are processed concurrently by a thread pool (Pillow PNG encode/decode release the GIL).

This eliminates the per-level NFS reads that ConvertImagesInDict() + BuildTilePyramids() would require: N reads instead of N × num_levels.

Parameters:
  • ImagesToConvertDict – {input_path → output_path} for the finest level.

  • PyramidOutputDicts – List of {input_path → output_path} dicts, one per coarser pyramid level in ascending order (level 2, 4, 8, …).

  • InputBpp – Bits-per-pixel of input images (auto-detected when None).

  • OutputBpp – Bits-per-pixel for outputs (matches InputBpp when None).

  • MinMax – (min, max) intensity cutoff tuple.

  • Gamma – Gamma correction value (None or 1.0 = no correction).

Returns:

True if any images were converted.

nornir_imageregistration.core.CreateExtremaMask(image: ndarray, mask: ndarray | None = None, size_cutoff=0.001, minima=None, maxima=None)[source]

Returns a mask for features above a set size that are at max or min pixel value :param image: :param mask: Valid-pixel mask (True = include in analysis). Invalid regions are

excluded from min/max and treated as extrema candidates for size filtering.

Parameters:
  • minima

  • maxima

  • size_cutoff – Determines how large a continuous region must be before it is masked. If 0 to 1 this is a fraction of total area. If > 1 it is an absolute count of pixels. If None all min/max are masked regardless of size

Returns:

Mask of extrema pixels, pixels that are FALSE are extrema to be excluded

nornir_imageregistration.core.CropImage(imageparam: ndarray[tuple[Any, ...], dtype[_ScalarT]] | str, Xo: int, Yo: int, Width: int, Height: int, cval: float | int | str | None = None, image_stats: ImageStats | None = None)[source]

Crop the image at the passed bounds and returns the cropped ndarray. If the requested area is outside the bounds of the array then the correct region is returned with a background color set

Parameters:
  • imageparam (ndarray) – An ndarray image to crop. A string containing a path to an image is also acceptable.e

  • Xo (int) – X origin for crop

  • Yo (int) – Y origin for crop

  • Width (int) – New width of image

  • Height (int) – New height of image

  • cval (int) – default value for regions outside the original image boundaries. Defaults to 0. Use ‘random’ to fill with random noise matching images statistical profile

Returns:

Cropped image

Return type:

ndarray

nornir_imageregistration.core.CropImageRect(imageparam, bounding_rect, cval=None)[source]
nornir_imageregistration.core.DimensionWithOverlap(val, overlap=1.0)[source]
Parameters:
  • val (float) – Original dimension

  • overlap (float) – Amount of overlap possible between images, from 0 to 1

Returns:

Required dimension size to unambiguously determine the offset in an fft image

nornir_imageregistration.core.EnsureMatchingImageMaskShape(image: ndarray[tuple[Any, ...], dtype[_ScalarT]], mask: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]

Crop image and mask to their overlapping top-left region when shapes differ.

Pyramid / downsample rounding can leave image and mask off by one pixel; boolean indexing then fails. Prefer keeping the shared content over aborting registration.

nornir_imageregistration.core.ExtractROI(image: ndarray[tuple[Any, ...], dtype[_ScalarT]], center, area) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Returns an ROI around a center point with the area, if the area passes a boundary the ROI maintains the same area, but is shifted so the entire area remains in the image. USES NUMPY (Y,X) INDEXING

nornir_imageregistration.core.ForceGrayscale(image: ndarray)[source]

Ensure that the image is a 2d array. This function does not do any intelligent conversion to grayscale, it simple eliminates extra dimensions if they exist. :param: ndarray with 3 dimensions :returns: grayscale data :rtype: ndarray with 2 dimensions

nornir_imageregistration.core.GenRandomData(height: int, width: int, mean: float, standardDev: float, min_val: float, max_val: float, dtype: DTypeLike | None = None, xp: Any | None = None, rng: Any | None = None) → ndarray[tuple[Any, ...], dtype[floating]][source]

Generate random data of shape with the specified mean and standard deviation. If xp is None, uses GetComputationModule(); otherwise uses that array module so output matches a caller-provided array (numpy vs cupy).

Parameters:

rng – Generator to draw from. Defaults to a module-level generator with a fixed starting seed, so a given run reproduces. See seed_random_data().

nornir_imageregistration.core.GetImageSize(image_param: str | ndarray | Iterable) → ndarray[tuple[Any, ...], dtype[integer]][source]
Parameters:

image_param – Either a path to an image file, an ndarray, or a list

of paths/ndimages :returns: The image’s (height, width) or [(height,width),…] for a list :rtype: tuple

nornir_imageregistration.core.GetImageTile(source_image, iRow, iCol, tile_size)[source]
nornir_imageregistration.core.ImageIntensityAtPercent(image, Percent=0.995)[source]

Return the intensity at the given percentile (default 99.5%) of pixel values in the image.

nornir_imageregistration.core.ImageParamToImageArray(imageparam: ndarray[tuple[Any, ...], dtype[_ScalarT]] | str | memmap_metadata | Shared_Mem_Metadata, dtype=None) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]
nornir_imageregistration.core.ImageParamToNumpyImageArray(imageparam: ndarray[tuple[Any, ...], dtype[_ScalarT]] | str | memmap_metadata | Shared_Mem_Metadata, dtype=None) → ndarray[tuple[Any, ...], dtype[_ScalarT]] | memmap[source]
nornir_imageregistration.core.ImageToTiles(source_image: ndarray[tuple[Any, ...], dtype[_ScalarT]], tile_size: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]], grid_shape: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]] | None = None, cval: int | None = 0)[source]
Parameters:
  • source_image (ndarray) – Image to cut into tiles

  • tile_size (array) – Shape of each tile

  • grid_shape (array) – Dimensions of grid, if None the grid is large enough to reproduce the source_image with zero padding if needed

  • cval (object) – Fill value for images that are padded. Default is zero. Use ‘random’ to generate random noise

Returns:

Dictionary of images indexed by tuples

nornir_imageregistration.core.ImageToTilesGenerator(source_image: ndarray[tuple[Any, ...], dtype[_ScalarT]], tile_size: ndarray[tuple[Any, ...], dtype[_ScalarT]], grid_shape: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None, coord_offset: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None, cval: float | int | str | None = 0, coverage_mask: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None)[source]

An iterator generating that divides a large image into a collection of smaller non-overlapping tiles. :param source_image: The image to divide :param tile_size: Shape of each tile :param grid_shape: Dimensions of grid, if None the grid is large enough to reproduce the source_image with zero padding if needed :param tuple coord_offset: Add this amount to coordinates returned by this function, used if the image passed is part of a larger image :param object cval: Fill value for images that are padded. Default is zero. Use ‘random’ to generate random noise :param coverage_mask: When set, only yield tiles where this boolean mask has any True pixels in the tile ROI :return: (iRow, iCol, tile_image)

class nornir_imageregistration.core.Iterable[source]

Bases: object

nornir_imageregistration.core.LoadImage(ImageFullPath: str, ImageMaskFullPath: str | None = None, MaxDimension: float | None = None, dtype: DTypeLike | None = None, backend: Literal['numpy', 'cupy'] | None = None)[source]

Loads an image converts to greyscale, masks it, and removes extrema pixels.

Parameters:
  • dtype

  • ImageFullPath (str) – Path to image

  • ImageMaskFullPath (str) – Path to mask, dimension should match input image

  • MaxDimension – Limit the largest dimension of the returned image to this size. Downsample if necessary.

  • backend – If “numpy”, return a NumPy array (error if conversion fails). If “cupy”, return a CuPy array (error if CuPy not available). If None, use the active computation backend (current behaviour).

Returns:

Loaded image. Masked areas and extrema pixel values are replaced with gaussian noise matching the median and std. dev. of the unmasked image.

Return type:

ndimage

nornir_imageregistration.core.NearestPowerOfTwoWithOverlap(val: float, overlap: float = 1.0) → int[source]
Parameters:
  • val

  • overlap (float) – Minimum amount of overlap possible between images, from 0 to 1. Values greater than 0.5 require no increase to image size.

Returns:

Same as DimensionWithOverlap, but output dimension is increased to the next power of two for faster FFT operations

nornir_imageregistration.core.NextSmoothFFTSize(val: float) → int[source]

Smallest even 5-smooth integer >= val.

A cheaper alternative to NearestPowerOfTwo() for sizing an FFT frame. Both pocketfft and cuFFT are fast for any size factorable into small primes, so rounding a 6000px requirement up to 8192 pays 1.86x the area for nothing. Since powers of two are themselves even and 5-smooth, the result is never larger than NearestPowerOfTwo(), so frame memory cannot regress.

Measured on float32 fft2 across eleven required sizes spanning 4100..8000, the smooth frame is 1.21x to 4.62x faster on numpy and 1.06x to 2.95x on CuPy – with one exception: a requirement near 7300 selects 7500, which is 5.7% slower than 8192 on CuPy while still 1.39x faster on numpy. Frame area still falls, so that band trades a little GPU throughput for less memory. It was not worth a special case: the crossover was measured on a single card, and hardcoding a size exception is exactly the mistake #228 recorded for batch budgets.

Even sizes only, as a defense in depth with #238: find_peak now uses the fftshift DC index n // 2 (so odd frames are unbiased), but smooth sizing still prefers even candidates so assessment scripts and older call sites that assumed power-of-two parity keep matching production frames. Power-of-two sizes are always even; a smooth rule has to exclude odd candidates explicitly. This costs a little – 6075 is 1.5x faster than 6144 on numpy – and remains worthwhile for consistency.

See review #234 / #238.

nornir_imageregistration.core.NormalizeImage(image: ndarray[tuple[Any, ...], dtype[_ScalarT]])[source]

Adjusts the image to have a range of 0 to 1.0

nornir_imageregistration.core.OneBit_img_from_bool_array(data)[source]

Convert a boolean numpy array to a Pillow 1-bit image (workaround for Pillow bit-image handling).

nornir_imageregistration.core.RandomNoiseMask(image: ndarray[tuple[Any, ...], dtype[_ScalarT]], Mask: ndarray[tuple[Any, ...], dtype[bool]], imagestats: ImageStats | None = None, Copy=False) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Fill the masked area with random noise with gaussian distribution about the image mean and with standard deviation matching the image’s standard deviation. Mask pixels that are False will be replaced with random noise

Parameters:
  • image (ndimage) – Input image

  • Mask (ndimage) – Mask, zeros are replaced with noise. Ones pull values from input image

  • imagestats (ImageStats) – Image stats. Calculated from image if none

  • Copy (bool) – Returns a copy of input image if true, otherwise write noise to the input image

Return type:

ndimage

nornir_imageregistration.core.ReplaceImageExtremaWithNoise(image: ndarray, imagemask: ndarray | None = None, imagestats: ImageStats | None = None, size_cutoff: float = 0.001, Copy=True)[source]

Replaced the min/max values in the image with random noise. This is useful when aligning images composed mostly of dark or bright regions. It is usually best to pass None for statistical parameters since the function will calculate the statistics with the extrema removed. :param image: :param Copy: :param numpy.ndarray imagemask: Additional pixels we wish to be included in the extrema mask :param nornir_imageregistration.ImageStats imagestats: Image statistics. Will be calculated if not passed. :param size_cutoff: 0 to 1.0, determines how large a continuos min or max region must be before it is masked. If None all min/max are masked regardless of size. Defaults to 0.001, None will mask all min/max

nornir_imageregistration.core.ResizeImage(image: ndarray[tuple[Any, ...], dtype[_ScalarT]], scalar: float | Iterable[float] | ndarray[tuple[Any, ...], dtype[floating]]) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Change image size by scalar

nornir_imageregistration.core.RgbLikeToGrayscaleLuminance(image: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], bool][source]

Convert RGB/RGBA (or HxWx2 grayscale+alpha) stacks to a single 2D plane.

Uses Rec. 601 luma coefficients on the first three channels when image is HxWx3 or HxWx4. HxWx1 is squeezed to 2D (returns False — not treated as an RGB file). Already-2D arrays are returned unchanged with False.

Works with NumPy or CuPy arrays (cp.get_array_module).

nornir_imageregistration.core.SafeROIRange(start: int, count: int, maxVal: int, minVal: int = 0) → list[int][source]

Returns a range cropped within min and max values, but always attempts to have count entries in the ROI. If minVal or maxVal would crop the list then start is shifted to ensure the resulting value has the correct number of entries. :param int start: Starting value :param int count: Number of items in the list, incremented by 1, to return. :param int maxVal: Maximum value allowed to be returned. Output list will be cropped if it equals or exceeds this value. :param int minVal: Minimum value allowed to be returned. Output list will be cropped below this value. :return: [start start+1, start+2, …, start+count] :raises ValueError: If maxVal < minVal or maxVal - minVal < count

nornir_imageregistration.core.SaveImage(ImageFullPath: str, image: ndarray[tuple[Any, ...], dtype[_ScalarT]], bpp: int | None = None, **kwargs)[source]

Saves the image as greyscale with no contrast-stretching :param str ImageFullPath: The filename to save :param ndarray image: The image data to save :param int bpp: The bit depth to save, if the image data bpp is higher than this value it will be reduced. Otherwise only the bpp required to preserve the image data will be used. (8-bit data will not be upsampled to 16-bit)

nornir_imageregistration.core.SaveImage_JPeg2000(ImageFullPath, image, tile_dim=None)[source]

Saves the image as greyscale with no contrast-stretching

nornir_imageregistration.core.ScalarForMaxDimension(max_dim: float, shapes)[source]

Returns the scalar value to use so the largest dimensions in a list of shapes has the maximum value

nornir_imageregistration.core.ScaleImage(image: ndarray[tuple[Any, ...], dtype[_ScalarT]], scalar: float) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Returns a scaled array using spline interpolation (CPU/GPU agnostic function)

class nornir_imageregistration.core.Sequence[source]

Bases: Reversible, Collection

All the operations on a read-only sequence.

Concrete subclasses must override __new__ or __init__, __getitem__, and __len__.

count(value) → integer -- return number of occurrences of value[source]
index(value[, start[, stop]]) → integer -- return first index of value.[source]

Raises ValueError if the value is not present.

Supporting start and stop arguments is optional, but recommended.

class nornir_imageregistration.core.SharedMemory(name=None, create=False, size=0, *, track=True)[source]

Bases: object

Creates a new shared memory block or attaches to an existing shared memory block.

Every shared memory block is assigned a unique name. This enables one process to create a shared memory block with a particular name so that a different process can attach to that same shared memory block using that same name.

As a resource for sharing data across processes, shared memory blocks may outlive the original process that created them. When one process no longer needs access to a shared memory block that might still be needed by other processes, the close() method should be called. When a shared memory block is no longer needed by any process, the unlink() method should be called to ensure proper cleanup.

property buf

A memoryview of contents of the shared memory block.

close()[source]

Closes access to the shared memory from this instance but does not destroy the shared memory block.

property name

Unique name that identifies the shared memory block.

property size

Size in bytes.

Requests that the underlying shared memory block be destroyed.

Unlink should be called once (and only once) across all handles which have access to the shared memory block, even if these handles belong to different processes. Closing and unlinking may happen in any order, but trying to access data inside a shared memory block after unlinking may result in memory errors, depending on platform.

This method has no effect on Windows, where the only way to delete a shared memory block is to close all handles.

nornir_imageregistration.core.Shrink(InFile: str, OutFile: str, Scalar: float, **kwargs)[source]

Shrinks the passed image file. If Pool is not None the task is returned. kwargs are passed on to Pillow’s image save function :param Scalar: :param str InFile: Path to input file :param str OutFile: Path to output file

nornir_imageregistration.core.SmoothFFTSizeWithOverlap(val: float, overlap: float = 1.0) → int[source]
Parameters:
  • val – Original dimension

  • overlap (float) – Minimum amount of overlap possible between images, from 0 to 1. Values greater than 0.5 require no increase to image size.

Returns:

Same as NearestPowerOfTwoWithOverlap(), but rounded up to the next even 5-smooth size rather than the next power of two. See NextSmoothFFTSize().

nornir_imageregistration.core.TileGridShape(source_image_shape: Rectangle | tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], tile_size: tuple[float, float] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[_ScalarT]])[source]

Given an image and tile size, return the dimensions of the grid

nornir_imageregistration.core.array_distance(array: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Compute Euclidean norm for each row of an Mx2 (or MxD) array.

Parameters:

array – Mx2 (or MxD) array of vectors.

Returns:

1D array of length M (euclidean distance per row); scalar if array is 1D.

nornir_imageregistration.core.cast(typ, val)[source]

Cast a value to a type.

This returns the value unchanged. To the type checker this signals that the return value has the designated type, but at runtime we intentionally don’t check anything (we want this to be as fast as possible).

nornir_imageregistration.core.close_shared_memory(input: Shared_Mem_Metadata | SharedMemory)[source]

Checks if the input is shared memory, if it is, closes it to indicate this process is done using it, but others may still be using it. Note that once this function executes the dictionary entry is removed and the memory cannot be unlinked. So make sure the array does not go out of scope if you are responsible for unlinking it.

nornir_imageregistration.core.create_shared_memory_array(shape: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]], dtype: DTypeLike, read_only: bool = True) → tuple[Shared_Mem_Metadata, ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]

Creates a shared memory block and copies the input array to shared memory. This memory block must be unlinked when it is no longer in use.

Parameters:

shape – Output shape. Any shape-like is accepted: tuple, list, NumPy array or CuPy array. The backing buffer is always host memory, so a device-resident shape is brought across here rather than at every call site.

Returns:

The name of the shared memory and a shared memory array. Used to reduce memory footprint when passing parameters to multiprocess pools

class nornir_imageregistration.core.deque

Bases: object

A list-like sequence optimized for data accesses near its endpoints.

append(item, /)

Add an element to the right side of the deque.

appendleft(item, /)

Add an element to the left side of the deque.

clear()

Remove all elements from the deque.

copy()

Return a shallow copy of a deque.

count(value, /)

Return number of occurrences of value.

extend(iterable, /)

Extend the right side of the deque with elements from the iterable.

extendleft(iterable, /)

Extend the left side of the deque with elements from the iterable.

index()

Return first index of value.

Raises ValueError if the value is not present.

insert(index, value, /)

Insert value before index.

maxlen

maximum size of a deque or None if unbounded

pop()

Remove and return the rightmost element.

popleft()

Remove and return the leftmost element.

remove(value, /)

Remove first occurrence of value.

reverse()

Reverse IN PLACE.

rotate(n=1, /)

Rotate the deque n steps to the right. If n is negative, rotates left.

nornir_imageregistration.core.image_to_uint8(image)[source]

Convert image to uint8. If input is float, scale to 0-255; if int and max > 255, scale down.

nornir_imageregistration.core.index_with_array(image: ndarray[tuple[Any, ...], dtype[_ScalarT]], indices: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Return image values at the given pixel coordinates.

Parameters:
  • image – 2D (or ND) array to index into.

  • indices – Nx2 array of (x, y) or (col, row) pixel coordinates.

Returns:

1D array of values at those indices (same backend as image).

class nornir_imageregistration.core.memmap_metadata(path: str, shape: ndarray[tuple[Any, ...], dtype[_ScalarT]], dtype: DTypeLike, mode: str | None = None)[source]

Bases: object

meta-data for a memmap array

property dtype: DTypeLike
property mode: str
property path: str
property shape: ndarray[tuple[Any, ...], dtype[_ScalarT]]
nornir_imageregistration.core.npArrayToSharedArray(input: ndarray[tuple[Any, ...], dtype[_ScalarT]], read_only: bool = True) → tuple[Shared_Mem_Metadata | memmap_metadata, ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]

Creates a shared memory block (or a file-backed memmap if /dev/shm is too small) and copies the input array into it. This block must be released with unlink_shared_memory() when no longer needed.

Returns:

Metadata (Shared_Mem_Metadata or memmap_metadata) and a NumPy array view of the backing storage for use in the current process.

nornir_imageregistration.core.promote_dtype_for_value_range(preferred_dtype: DTypeLike, min_val: float, max_val: float) → dtype[source]

Choose a dtype that can represent min_val and max_val, preferring types at least as wide as preferred_dtype when it is floating.

For floating preferences, tries float16 → float32 → float64. For integer preferences, tries wider integers then falls back to float promotion.

nornir_imageregistration.core.random_generator(xp: Any | None = None) → Any[source]

The generator backing every noise fill, so all of them seed together.

nornir_imageregistration.core.ravel_index(idx: ndarray[tuple[Any, ...], dtype[integer]], shp: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → ndarray[tuple[Any, ...], dtype[integer]][source]

Convert an NxD array of coordinates into flat indices for an array of shape shp.

Parameters:
  • idx – Nx2 (or NxD) array of coordinates [[x1,y1], [x2,y2], …].

  • shp – Shape of the target array (e.g. image shape).

Returns:

1D array of flat indices (numpy or cupy depending on idx).

nornir_imageregistration.core.remove_duplicate_points(points: ndarray[tuple[Any, ...], dtype[_ScalarT]], columns: Iterable[int] = ()) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Remove rows who have equal values in the specified columns. Result will be sorted using the column order provided. Lexsort is used, so the last column entry is the primary sort key.

nornir_imageregistration.core.seed_random_data(seed: int | None = 1852797550) → None[source]

Reset the generators backing GenRandomData().

Pass None to seed from entropy, restoring the old non-reproducible behaviour for callers that genuinely want a fresh draw each run.

nornir_imageregistration.core.uint16_img_from_float_array(image)[source]

Convert a float image (0-1 or 0-max) to a Pillow 16-bit image.

nornir_imageregistration.core.uint16_img_from_uint16_array(data)[source]

Convert a uint16 numpy array to a Pillow 16-bit image (workaround for Pillow I;16 handling).

Checks if the input is shared memory, if it is, closes it to indicate this process is done using it and unlinks it to free the underlying memory block. This renders it unusable for all other processes as well. Make sure the array does not go out of scope if you are responsible for unlinking it.

For memmap_metadata (file-backed pool buffers), removes the backing file.

assemble

Created on Apr 22, 2013

class nornir_imageregistration.assemble.Any(*args, **kwargs)[source]

Bases: object

Special type indicating an unconstrained type.

  • Any is compatible with every type.

  • Any assumed to have all methods.

  • All values assumed to be instances of Any.

Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance checks.

nornir_imageregistration.assemble.FixedImageToWarpedSpace(transform: ITransform, DataToTransform, botleft=None, area=None, cval=None, extrapolate=False)[source]
nornir_imageregistration.assemble.GetROICoords(botleft: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], area: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], *, xp=None) → ndarray[tuple[Any, ...], dtype[floating]][source]

Integer YX meshgrid for a rectangle origin and area.

Accepts NumPy or CuPy via the xp argument (defaults to GetComputationModule).

class nornir_imageregistration.assemble.IRigidTransform[source]

Bases: ITransform, ABC

A transform that encodes a rigid transformation: The order of operations should be: 1. Scaling 2. Rotation 3. Translation 4. Flip

abstractmethod GetRigidState() → dict[str, Any][source]

Snapshot the registration parameters for a later in-place restore.

Interactive editors share one model instance across views and mutate it in place, so undoing a gesture needs a parameter snapshot rather than a reference to the model.

abstractmethod SetRigidState(state: dict[str, Any]) → None[source]

Restore parameters from GetRigidState onto this instance.

Must preserve object identity and change subscribers, unlike __setstate__, which is for unpickling a fresh object.

abstract property angle: float

Angle of rotation in radians

abstract property flip_ud: bool

Whether to flip the Y axis

abstract property scalar: float

Scaling factor

abstract property source_space_center_of_rotation: ndarray[tuple[Any, ...], dtype[floating]]

Center of rotation in source space

abstract property target_offset: ndarray[tuple[Any, ...], dtype[floating]]

Translation from source to target space

class nornir_imageregistration.assemble.ITransform[source]

Bases: ABC

abstractmethod InverseTransform(point: ndarray[tuple[Any, ...], dtype[floating]], **kwargs) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Map points from the fixed space to mapped space. Nornir is gradually transitioning to a target space to source space naming convention.

abstractmethod Load(TransformString: str, pixelSpacing=None)[source]

Creates an instance of the transform from the TransformString

abstractmethod ToITKString() → str[source]

Serialize the transform to an ITK-compatible string representation.

abstractmethod Transform(point: ndarray[tuple[Any, ...], dtype[floating]], **kwargs) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Map points from the mapped space to fixed space. Nornir is gradually transitioning to a source space to target space naming convention.

abstract property type: TransformType
class nornir_imageregistration.assemble.IgnoreUnderflow(log_msg: str | Callable[[], str] | None = None)[source]

Bases: IgnoreRuntimeWarnings

nornir_imageregistration.assemble.InvalidIndices(points: ndarray[tuple[Any, ...], dtype[floating]]) → tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[bool]]][source]

Remove rows that are not finite, i.e. containing NaN or +-Inf.

Parameters:

points – NxM array of points (e.g. Nx2 or Nx4).

Returns:

Tuple of (points_with_non_finite_rows_removed, invalid_row_mask). Callers that need the valid side can invert with ~invalid_mask. Returning a bool mask avoids CuPy flatnonzero index materialization and the host syncs that come with integer index arrays on the GPU path.

Inf counts as invalid, not just NaN. An infinite coordinate is no more usable than NaN: callers either route these rows to a continuous fallback transform or drop them before scattering, and an Inf that reads as valid becomes a garbage sample index instead. On the host np.seterr(invalid='raise', divide='raise') makes most ways of producing Inf raise first, but CuPy ignores seterr, so on the GPU path an overflowing float64->float32 downcast or a divide by zero yields Inf silently.

nornir_imageregistration.assemble.ParameterToStosTransform(transformData: str | ITransform | StosFile)[source]
Parameters:

transformData (object) – Either a full path to a .stos file, a stosfile, or a transform object

Returns:

A transform

nornir_imageregistration.assemble.SourceImageToTargetSpace(transform: ITransform, DataToTransform, output_botleft: ndarray[tuple[Any, ...], dtype[_ScalarT]] | tuple[float, float] | None = None, output_area: ndarray[tuple[Any, ...], dtype[_ScalarT]] | tuple[float, float] | None = None, cval=None, extrapolate=False, return_shared_memory: bool = False, return_valid_mask: bool = False, clamp_source_coords: bool = False, interpolation_order: int | None = None)[source]

Warps every image in the DataToTransform list using the provided transform. :param transform: transform to pass warped space coordinates through to obtain fixed space coordinates :param output_shape: shape of the output image :param DataToTransform: Images to read pixel values from while creating fixed space images. A list of images can be passed to map multiple images using the same coordinates. A list may contain filename strings or numpy.ndarrays :param output_botleft: Origin of region to map data into, in target space coordinates :param output_area: Area of region to map data into, in target space coordinates :param cval: Value to place in unmappable regions, defaults to zero. :Param transform: transform to pass warped space coordinates through to obtain fixed space coordinates :Param FixedImageArea: Size of fixed space region to map pixels into :Param DataToTransform: Images to read pixel values from while creating fixed space images. A list of images can be passed to map multiple images using the same coordinates. A list may contain filename strings or numpy.ndarrays :Param botleft: Origin of region to map :Param area: Expected dimensions of output :Param cval: Value to place in unmappable regions, defaults to zero. :param bool extrapolate: If true map points that fall outside the bounding box of the transform

nornir_imageregistration.assemble.TargetImageToSourceSpace(transform: ITransform, DataToTransform, output_botleft: ndarray[tuple[Any, ...], dtype[_ScalarT]] | tuple[float, float] | None = None, output_area: ndarray[tuple[Any, ...], dtype[_ScalarT]] | tuple[float, float] | None = None, cval=None, extrapolate: bool = False, return_shared_memory: bool = False)[source]

Warps every image in the DataToTransform list using the provided transform. :param transform: transform to pass fixed space coordinates through to obtain warped space coordinates :param DataToTransform: Images to read pixel values from while creating fixed space images. A list of images can be passed to map multiple images using the same coordinates. A list may contain filename strings or numpy.ndarrays :param output_botleft: Origin of region to map data into, in source Space coordinates :param output_area: Area of region to map data into, in source space coordinates :param cval: Value to place in unmappable regions, defaults to zero. :param bool extrapolate: If true map points that fall outside the bounding box of the transform

nornir_imageregistration.assemble.TransformImage(transform: ITransform, fixedImageShape: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], warpedImage: ndarray[tuple[Any, ...], dtype[_ScalarT]], CropUndefined: bool, interpolation_order: int | None = None, extrapolate: bool | None = None, enforce_background_cval: float | int | None = None) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Cut image into tiles, assemble small chunks :param transform: Transform to apply to point to map from warped image to fixed space :param fixedImageShape: Width and Height of the image to create :param warpedImage: Image to transform to fixed space :param CropUndefined: If true exclude areas outside the convex hull of the transform, if it exists :param extrapolate: When set, controls whether transforms extrapolate outside their hull during assembly.

Defaults to not CropUndefined when omitted.

Parameters:

enforce_background_cval – When set (typically 0 for export), only scatter samples whose inverse map lands inside the source image; all other output pixels are set to this value.

Returns:

An ndimage array of the transformed image

nornir_imageregistration.assemble.TransformStos(transformData: str | ITransform | StosFile, OutputFilename: str | None = None, fixedImage: str | ndarray | None = None, warpedImage: str | ndarray | None = None, scalar: float = 1.0, CropUndefined: bool = False)[source]

Assembles an image based on the passed transform. :param transformData: :param OutputFilename: :param str fixedImage: Image describing the size we want the warped image to fill, either a string or ndarray :param str warpedImage: Image we will warp into fixed space, either a string or ndarray :param float scalar: Amount to scale the transform before passing the image through :param bool CropUndefined: If true exclude areas outside the convex hull of the transform, if it exists

nornir_imageregistration.assemble.WarpedImageToFixedSpace(transform: ITransform, DataToTransform, botleft=None, area=None, cval=None, extrapolate=False)[source]
nornir_imageregistration.assemble.WriteStosPreviewImages(transformData, *, overlay_path: str | None = None, diff_path: str | None = None, warped_path: str | None = None, fixedImage=None, warpedImage=None, scalar: float = 1.0, CropUndefined: bool = False) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Warp mapped→control and optionally write overlay, difference, and warped PNGs.

Overlay uses Pyre ChannelDodge colors: mapped/source → magenta (R+B), control/target → green (G). Diff is |control − warped| as grayscale. Any of overlay_path, diff_path, or warped_path that is None skips that product. Performs a single warp regardless of how many outputs are requested.

Returns:

Host NumPy warped image array (control/target space).

nornir_imageregistration.assemble.assembly_source_sample_mask(transform: ITransform, fixed_image_shape: ndarray[tuple[Any, ...], dtype[_ScalarT]] | tuple[int, int] | list[int], source_image_shape: ndarray[tuple[Any, ...], dtype[_ScalarT]] | tuple[int, int] | list[int], *, extrapolate: bool = False) → ndarray[tuple[Any, ...], dtype[bool]][source]

Return True at fixed pixels whose inverse transform lands inside the source image.

class nornir_imageregistration.assemble.floating

Bases: inexact

Abstract base class of all floating-point scalar types.

nornir_imageregistration.assemble.get_valid_coords(coords: ndarray[tuple[Any, ...], dtype[_ScalarT]], image_shape, origin=(0, 0), area=None) → tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]

Given an Nx2 array off image coordinates, remove the coordinates that fall outside the image_shape boundaries. :param coords: Nx2 array of image coordinates :param image_shape: 1x2 array of image dimensions :param origin: 1x2 array with minimum valid coordinate :parm area: 1x2 array of expected area, which may exceed image_shape. coords will be cropped to whatever is less :return: The coordinates greater than or equal to origin and less than origin + area and a mask indicating (== True) which coordinates met the criteria

nornir_imageregistration.assemble.my_cheesy_map_coordinates(image, coords)[source]

Sample image at integer floor of coords; returns image values at those indices.

nornir_imageregistration.assemble.transform_for_host_assembly(transform: ITransform) → ITransform[source]

Return a CPU/pickle-safe transform for tiled host assembly and image export.

nornir_imageregistration.assemble.write_to_source_roi_coords(transform: ITransform, botleft: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], area: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], extrapolate: bool = False) → tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]

This function is used to generate coordinates to transform image data in target space backwards into source space.

Given a transform and a region in source space, create uniform integer coordinates over the region of interest in source space for each pixel. Then run an forward transform to determine those coordinates in target space. The target space coordinates will be used later to interpolate pixel values for each integer pixel valued destination space coordinates.

Parameters:
  • extrapolate

  • transform (transform) – The transform used to map points between fixed and mapped space

  • botleft – The (Y,X) coordinates of the bottom left corner in source space

  • area – The (Height, Width) of the region of interest coordinates.

Returns:

(read_space_coords, write_space_coords)

nornir_imageregistration.assemble.write_to_target_roi_coords(transform: ITransform, botleft: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], area: tuple[float, float] | ndarray[tuple[Any, ...], dtype[_ScalarT]], extrapolate: bool = False) → tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]

This function is used to generate coordinates to transform image data in source space forward into target space.

Given a transform and a region in target space, create uniform integer coordinates over the region of interest in source space for each pixel. Then run a inverse transform to map target coordinates back in source space. The source space coordinates will be used later to interpolate pixel values for each integer pixel valued destination target coordinates.

param extrapolate:

param transform transform:

The transform used to map points between fixed and mapped space

param botleft:

The (Y,X) coordinates of the bottom left corner in target space

param area:

The (Height, Width) of the region of interest

e coordinates.
return:

(read_space_coords, write_space_coords)

assemble_tiles

Created on Oct 28, 2013

Deals with assembling images composed of mosaics or dividing images into tiles

nornir_imageregistration.assemble_tiles.CompositeImage(FullImage, SubImage, offset)[source]
nornir_imageregistration.assemble_tiles.CompositeImageWithZBuffer(FullImage, FullZBuffer, SubImage, SubZBuffer, offset)[source]
nornir_imageregistration.assemble_tiles.CreateDistanceImage(shape: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]], dtype: DTypeLike | None = None)[source]

Create a distance image where the value at each pixel is the distance from the center of the image. Distances are measured in pixels, and the distance is zero at the center pixel. Distances are measured to the center of each pixel.

nornir_imageregistration.assemble_tiles.EmptyDistanceBuffer(shape: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]], dtype: DTypeLike | None = None)[source]
class nornir_imageregistration.assemble_tiles.Future[source]

Bases: object

Represents the result of an asynchronous computation.

add_done_callback(fn)[source]

Attaches a callable that will be called when the future finishes.

Parameters:

fn – A callable that will be called with this future as its only argument when the future completes or is cancelled. The callable will always be called by a thread in the same process in which it was added. If the future has already completed or been cancelled then the callable will be called immediately. These callables are called in the order that they were added.

cancel()[source]

Cancel the future if possible.

Returns True if the future was cancelled, False otherwise. A future cannot be cancelled if it is running or has already completed.

cancelled()[source]

Return True if the future was cancelled.

done()[source]

Return True if the future was cancelled or finished executing.

exception(timeout=None)[source]

Return the exception raised by the call that the future represents.

Parameters:

timeout – The number of seconds to wait for the exception if the future isn’t done. If None, then there is no limit on the wait time.

Returns:

The exception raised by the call that the future represents or None if the call completed without raising.

Raises:
  • CancelledError – If the future was cancelled.

  • TimeoutError – If the future didn’t finish executing before the given timeout.

result(timeout=None)[source]

Return the result of the call that the future represents.

Parameters:

timeout – The number of seconds to wait for the result if the future isn’t done. If None, then there is no limit on the wait time.

Returns:

The result of the call that the future represents.

Raises:
  • CancelledError – If the future was cancelled.

  • TimeoutError – If the future didn’t finish executing before the given timeout.

  • Exception – If the call raised then that exception will be raised.

running()[source]

Return True if the future is currently executing.

set_exception(exception)[source]

Sets the result of the future as being the given exception.

Should only be used by Executor implementations and unit tests.

set_result(result)[source]

Sets the return value of work associated with the future.

Should only be used by Executor implementations and unit tests.

set_running_or_notify_cancel()[source]

Mark the future as running or process any cancel notifications.

Should only be used by Executor implementations and unit tests.

If the future has been cancelled (cancel() was called and returned True) then any threads waiting on the future completing (though calls to as_completed() or wait()) are notified and False is returned.

If the future was not cancelled then it is put in the running state (future calls to running() will return True) and True is returned.

This method should be called by Executor implementations before executing the work associated with this future. If this method returns False then the work should not be executed.

Returns:

False if the Future was cancelled, True otherwise.

Raises:

RuntimeError – if this method was already called or if set_result() or set_exception() was called.

nornir_imageregistration.assemble_tiles.GetProcessAndThreadUniqueString()[source]

We use the index because if the same thread makes a new tile of the same size and the original has not been garbage collected yet we get errors

class nornir_imageregistration.assemble_tiles.ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=(), **ctxkwargs)[source]

Bases: Executor

BROKEN

alias of BrokenThreadPool

classmethod prepare_context(initializer, initargs)[source]
shutdown(wait=True, *, cancel_futures=False)[source]

Clean-up the resources associated with the Executor.

It is safe to call this method several times. Otherwise, no other methods can be called after this one.

Parameters:
  • wait – If True then shutdown will not return until all running futures have finished executing and the resources used by the executor have been reclaimed.

  • cancel_futures – If True then shutdown will cancel all pending futures. Futures that are completed or running will not be cancelled.

submit(fn, /, *args, **kwargs)[source]

Submits a callable to be executed with the given arguments.

Schedules the callable to be executed as fn(*args, **kwargs) and returns a Future instance representing the execution of the callable.

Returns:

A Future representing the given call.

nornir_imageregistration.assemble_tiles.TilesToImage(mosaic_tileset: MosaicTileset, TargetRegion: Rectangle | List[float] | None = None, target_space_scale: float | None = None, use_cp: bool = False) → Tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]] | None, ndarray[tuple[Any, ...], dtype[_ScalarT]] | None][source]

Generate an image of the TargetRegion. :param MosaicTileset mosaic_tileset: Tileset to assemble :param tuple TargetRegion: (MinX, MinY, Width, Height) or Rectangle class. Specifies the SourceSpace to render from :param float target_space_scale: Scalar for the target space coordinates. Used to downsample or upsample the output image. Changes the coordinates of the target space control points of the transform. :param use_cp: use CuPy library for GPU processing

nornir_imageregistration.assemble_tiles.TilesToImageParallel(mosaic_tileset: MosaicTileset, TargetRegion: Rectangle | List[float] | None = None, target_space_scale: float | None = None, pool=None) → Tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]] | None, ndarray[tuple[Any, ...], dtype[_ScalarT]] | None][source]

Assembles a set of transforms and imagepaths to a single image using parallel techniques. :param pool: :param MosaicTileset mosaic_tileset: Tileset to assemble :param tuple TargetRegion: (MinX, MinY, Width, Height) or Rectangle class. Specifies the SourceSpace to render from :param float target_space_scale: Scalar for the target space coordinates. Used to downsample or upsample the output image. Changes the coordinates of the target space control points of the transform. :param float target_space_scale: Scalar for the source space coordinates. Must match the change in scale of input images relative to the transform source space coordinates. So if downsampled by 4 images are used, this value should be 0.25. Calculated to be correct if None. Specifying is an optimization to reduce I/O of reading image files to calculate.

nornir_imageregistration.assemble_tiles.TilesToImageThreaded(mosaic_tileset: MosaicTileset, TargetRegion: Rectangle | List[float] | None = None, target_space_scale: float | None = None, use_cp: bool = False) → Tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]] | None, ndarray[tuple[Any, ...], dtype[_ScalarT]] | None][source]

GPU-oriented assemble: thread-parallel per-tile pipeline with serialised GPU warps.

Workers overlap disk I/O and CPU-side inverse-transform work while assemble._gpu_warp_lock serialises map_coordinates dispatches. Compositing into the shared output canvas is serialised by _composite_lock.

nornir_imageregistration.assemble_tiles.TransformTile(tile: Tile, distanceImage: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None, target_space_scale: float | None = None, TargetRegion: Rectangle | Tuple[float] | ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None, SingleThreadedInvoke: bool = False) → ITransformedImageData[source]

Transform the passed image. DistanceImage is an existing image recording the distance to the center of the image for each pixel. target_space_scale is used when the image size does not match the image size encoded in the transform. A scale will be calculated in this case and if it does not match the required scale the tile will not be transformed.

get_space_scale: Optional pre-calculated scalar to apply to the transforms target space control points. If None the scale is calculated based on the difference

between input image size and the image size of the transform. i.e. If the source_space is downsampled by 4 then the target_space will be downsampled to match

param tile:

param SingleThreadedInvoke:

param use_cp:

use CuPy library for GPU processing

param TargetRegion:

[MinY MinX MaxY MaxX] If specified only the specified region is populated. Otherwise transform the entire image.’’’

class nornir_imageregistration.assemble_tiles.WindowFilterCache(name: str, creation_function: Callable[[Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]], DTypeLike | None], ndarray[tuple[Any, ...], dtype[floating]]], dtype: DTypeLike | None = None)[source]

Bases: object

A generic class that creates and caches filter windows for use in image processing based on size. Cached images are saved to disk in a temporary directory for easy access in multiprocessing. T The images in the cache are read-only.

GetOrCreate(image_shape: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]], **kwargs) → ndarray[tuple[Any, ...], dtype[floating]][source]

Get or create a cached image filter of the expected shape

KeepGetOrCreate(image: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None, image_shape: Sequence[int] | tuple[int, int] | ndarray[tuple[Any, ...], dtype[integer]])[source]

If image is the expected shape, returns image. Otherwise returns or generates a cached image of the expected shape :param image: Existing image to return if it is the correct shape :param image_shape: Shape of the image to return :return:

cache_dir: str
nornir_imageregistration.assemble_tiles.as_completed(fs, timeout=None)[source]

An iterator over the given futures that yields each as it completes.

Parameters:
  • fs – The sequence of Futures (possibly created by different Executors) to iterate over.

  • timeout – The maximum number of seconds to wait. If None, then there is no limit on the wait time.

Returns:

An iterator that yields the given Futures as they complete (finished or cancelled). If any given Futures are duplicated, they will be returned once.

Raises:

TimeoutError – If the entire result iterator could not be generated before the given timeout.

class nornir_imageregistration.assemble_tiles.deque

Bases: object

A list-like sequence optimized for data accesses near its endpoints.

append(item, /)

Add an element to the right side of the deque.

appendleft(item, /)

Add an element to the left side of the deque.

clear()

Remove all elements from the deque.

copy()

Return a shallow copy of a deque.

count(value, /)

Return number of occurrences of value.

extend(iterable, /)

Extend the right side of the deque with elements from the iterable.

extendleft(iterable, /)

Extend the left side of the deque with elements from the iterable.

index()

Return first index of value.

Raises ValueError if the value is not present.

insert(index, value, /)

Insert value before index.

maxlen

maximum size of a deque or None if unbounded

pop()

Remove and return the rightmost element.

popleft()

Remove and return the leftmost element.

remove(value, /)

Remove first occurrence of value.

reverse()

Reverse IN PLACE.

rotate(n=1, /)

Rotate the deque n steps to the right. If n is negative, rotates left.

nornir_imageregistration.HasCuVS() → bool[source]

Return True if the GPU distance stack needed by cupyx cdist is available.

Matches cupyx.scipy.spatial.distance soft dependencies: cuvs.distance or legacy pylibraft.distance. CuPy must be active.

GPU cdist uses this stack whenever inputs are CuPy. Nearest-neighbor search is gated separately in nearest_neighbor (cKDTree below 4096 points) because CuVS brute-force is O(N²) in 2D.

Returns:

True if pairwise distance primitives are importable, False otherwise.

nornir_imageregistration.HasCupy() → bool[source]

Return True if the cupy package is available on this system.

Returns:

True if cupy can be imported, False otherwise.

class nornir_imageregistration.IControlPoints[source]

Bases: ABC

Interface for transforms that use control points

abstractmethod GetPointPairsInSourceRect(bounds: Rectangle) → ndarray[tuple[Any, ...], dtype[floating]][source]

Return the point pairs inside the rectangle defined in source space

abstractmethod GetPointPairsInTargetRect(bounds: Rectangle) → ndarray[tuple[Any, ...], dtype[floating]][source]

Return the point pairs inside the rectangle defined in target space

abstractmethod NearestFixedPoint(points: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → tuple[float | ndarray[tuple[Any, ...], dtype[floating]], int | ndarray[tuple[Any, ...], dtype[integer]]][source]

Return the fixed points nearest to the query points :return: Distance, Index

abstractmethod NearestWarpedPoint(points: ndarray[tuple[Any, ...], dtype[_ScalarT]]) → tuple[float | ndarray[tuple[Any, ...], dtype[floating]], int | ndarray[tuple[Any, ...], dtype[integer]]][source]

Return the warped points nearest to the query points :return: Distance, Index

abstract property NumControlPoints: int
abstractmethod PointPairsToTargetPoints(points: ndarray[tuple[Any, ...], dtype[floating]]) → ndarray[tuple[Any, ...], dtype[floating]][source]

Return the target points from a set of target-source point pairs

abstractmethod PointPairsToWarpedPoints(points: ndarray[tuple[Any, ...], dtype[floating]]) → ndarray[tuple[Any, ...], dtype[floating]][source]

Return the warped points from a set of target-source point pairs

abstract property SourceBoundingBox: Rectangle

Bounding box of source space points

abstract property SourcePoints: ndarray[tuple[Any, ...], dtype[_ScalarT]]

The source points of the transform. Order matches the results of SourcePoints and points

abstract property TargetBoundingBox: Rectangle

Bounding box of target space points

abstract property TargetPoints: ndarray[tuple[Any, ...], dtype[_ScalarT]]

The target points of the transform. Order matches the results of SourcePoints and points

abstract property points: ndarray[tuple[Any, ...], dtype[_ScalarT]]

Points is a 4xN array of corresponding control points in this format [[TargetY, TargetX, SourceY, SourceX],]. Order matches the results of SourcePoints and TargetPoints

class nornir_imageregistration.IDiscreteTransform[source]

Bases: ITransform, ABC

abstract property FixedBoundingBox: Rectangle

Bounding box of fixed space points (target-space alias)

abstract property MappedBoundingBox: Rectangle

Bounding box of mapped space points (source-space alias)

abstract property TargetBoundingBox: Rectangle

Bounding box of target space points

class nornir_imageregistration.ITransform[source]

Bases: ABC

abstractmethod InverseTransform(point: ndarray[tuple[Any, ...], dtype[floating]], **kwargs) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Map points from the fixed space to mapped space. Nornir is gradually transitioning to a target space to source space naming convention.

abstractmethod Load(TransformString: str, pixelSpacing=None)[source]

Creates an instance of the transform from the TransformString

abstractmethod ToITKString() → str[source]

Serialize the transform to an ITK-compatible string representation.

abstractmethod Transform(point: ndarray[tuple[Any, ...], dtype[floating]], **kwargs) → ndarray[tuple[Any, ...], dtype[_ScalarT]][source]

Map points from the mapped space to fixed space. Nornir is gradually transitioning to a source space to target space naming convention.

abstract property type: TransformType
class nornir_imageregistration.ITransformChangeEvents[source]

Bases: ABC

abstractmethod AddOnChangeEventListener(func: Callable)[source]

Call func whenever the transform changes

abstractmethod RemoveOnChangeEventListener(func: Callable)[source]

Stop calling func whenever the transform changes

class nornir_imageregistration.ITransformScaling[source]

Bases: ABC

Supports scaling target and source space together (changing image downsample level for example)

abstractmethod Scale(scalar: float) → None[source]

Scale both spaces by the specified amount

class nornir_imageregistration.ITransformTranslation[source]

Bases: ABC

abstractmethod TranslateFixed(offset: ndarray[tuple[Any, ...], dtype[_ScalarT]])[source]

Translate all fixed points by the specified amount

abstractmethod TranslateWarped(offset: ndarray[tuple[Any, ...], dtype[_ScalarT]])[source]

Translate all warped points by the specified amount