elasticdeform

repository·master·Indexed 41 days ago

https://github.com/gvtulder/elasticdeform

A library for implementing elastic grid-based deformations for N-dimensional images, primarily used for data augmentation. It provides functions like deform_random_grid and deform_grid, as well as deform_grid_gradient for differentiable pipelines. The library includes wrappers for TensorFlow and PyTorch to integrate deformations directly into deep learning models.

Tokens
2.9K
Snippets
14
Records
14
Agent score
52%

What's inside elasticdeform

  1. Handle multi-channel images with the axis parameter

    master

    By default, deformation is applied to every dimension. For multi-channel images (e.g., RGB), use the axis parameter to specify which axes should be deformed. The same deformation is applied across all channels.

    When deforming multiple inputs, axis can accept a list of tuples, allowing different axis specifications for each input.

    # Deform an RGB image across the first two dimensions
    X_deformed = elasticdeform.deform_random_grid(X, axis=(0, 1))
    
    # Deform multiple inputs with different axis configurations
    X = numpy.random.rand(3, 200, 300)
    Y = numpy.random.rand(200, 300)
    [X_deformed, Y_deformed] = elasticdeform.deform_random_grid([X, Y], axis=[(1, 2), (0, 1)])
  2. Optimize deformation with cropping

    master

    If you only need a subpatch of the deformed image, provide a crop argument (a tuple of slice objects) to deform_grid. This computes only the pixels in the cropped region while still basing the deformation grid on the full image dimensions, saving computation time.

    X = numpy.random.rand(200, 300)
    
    # define a crop region
    crop = (slice(50, 150), slice(0, 100))
    
    # generate a deformation grid
    displacement = numpy.random.randn(2, 3, 3) * 25
    
    # deform full image
    X_deformed = elasticdeform.deform_grid(X, displacement)
    # compute only the cropped region
    X_deformed_crop = elasticdeform.deform_grid(X, displacement, crop=crop)
    
    # the deformation is the same
    numpy.testing.assert_equal(X_deformed[crop], X_deformed_crop)
  3. Combine deformation with rotation and zoom

    master

    The deformation functions support rotate (in degrees) and zoom (scaling factor) parameters. These are applied to the output coordinates using the center pixel of the output patch as the origin. The output shape remains unchanged. If used with crop, rotation and scaling are relative to the center of the cropped output.

    # apply deformation with a random 3 x 3 grid, rotate by 30 degrees and rescale with a factor 1.5
    X_deformed = elasticdeform.deform_random_grid(X, sigma=25, points=3, rotate=30, zoom=1.5)
  4. Install elasticdeform

    master

    Install the library via pip. This requires Python 3 and NumPy development headers. On Windows, use precompiled binaries via pip or alternative precompiled packages if the standard installation fails.

    pip install elasticdeform
    # or
    pip install git+https://github.com/gvtulder/elasticdeform
  5. Deform an image with a random grid

    master

    Use elasticdeform.deform_random_grid to apply an elastic deformation using a randomly generated grid. You can specify the smoothing sigma and the number of points in the grid.

    import numpy, imageio, elasticdeform
    X = numpy.zeros((200, 300))
    X[::10, ::10] = 1
    
    # apply deformation with a random 3 x 3 grid
    X_deformed = elasticdeform.deform_random_grid(X, sigma=25, points=3)
    
    imageio.imsave('test_X.png', X)
    imageio.imsave('test_X_deformed.png', X_deformed)
  6. Deform multiple inputs simultaneously

    master

    To deform multiple images (e.g., an image and its segmentation mask) using the same displacement field, pass them as a list to deform_random_grid. You can provide a list of spline orders via the order parameter to use different interpolation methods for each input.

    # apply deformation to inputs X and Y
    [X_deformed, Y_deformed] = elasticdeform.deform_random_grid([X, Y])
    
    # apply deformation to inputs X and Y, with a different interpolation for each input
    [X_deformed, Y_deformed] = elasticdeform.deform_random_grid([X, Y], order=[3, 0])
  7. Use the PyTorch wrapper

    master

    The elasticdeform.torch module provides a wrapper for deform_grid that accepts and returns PyTorch Tensors. This allows the deformation to be used as a layer in a PyTorch model with automatic differentiation.

    import numpy
    import torch
    import elasticdeform.torch as etorch
    
    displacement_val = numpy.random.randn(2, 3, 3) * 5
    X_val = numpy.random.rand(200, 300)
    dY_val = numpy.random.rand(200, 300)
    
    # construct PyTorch input and top gradient
    displacement = torch.tensor(displacement_val)
    X = torch.tensor(X_val, requires_grad=True)
    dY = torch.tensor(dY_val)
    
    # the deform_grid function is similar to the plain Python equivalent, but accepts and returns PyTorch Tensors
    X_deformed = etorch.deform_grid(X, displacement, order=3)
    
    # the gradient w.r.t. X can be computed in the normal PyTorch manner
    X_deformed.backward(dY)
    print(X.grad)
  8. Use the TensorFlow wrapper

    master

    The elasticdeform.tf module provides a wrapper for deform_grid that accepts and returns TensorFlow Tensors. This allows the deformation to be used as a layer in a TensorFlow model with automatic differentiation.

    import numpy
    import elasticdeform.tf as etf
    import tensorflow as tf
    
    displacement_val = numpy.random.randn(2, 3, 3) * 5
    X_val = numpy.random.rand(200, 300)
    dY_val = numpy.random.rand(200, 300)
    
    # construct TensorFlow input and top gradient
    displacement = tf.Variable(displacement_val)
    X = tf.Variable(X_val)
    dY = tf.Variable(dY_val)
    
    # the deform_grid function is similar to the plain Python equivalent, but accepts and returns TensorFlow Tensors
    X_deformed = etf.deform_grid(X, displacement, order=3)
    
    # the gradient w.r.t. X can be computed in the normal TensorFlow manner
    [dX] = tf.gradients(X_deformed, X, dY)
  9. Apply elastic deformation using a random grid

    master

    Use elasticdeform.deform_random_grid to apply an elastic deformation to an N-dimensional image using a randomly generated grid. This is useful for data augmentation where you want stochastic variations of your input data.

    # Example usage (conceptual based on function name)
    elasticdeform.deform_random_grid(image, ...)
  10. Use the TensorFlow wrapper function deform_grid

    master
    The elasticdeform.tf.deform_grid function provides a TensorFlow-compatible wrapper for applying elastic deformations to N-dimensional tensors. This allows you to integrate elastic deformation operations directly into TensorFlow computational graphs or data pipelines.
    elasticdeform.tf.deform_grid
  11. Compute gradients for elastic deformation

    master

    To use elastic deformation in a differentiable pipeline, use deform_grid_gradient to backpropagate the gradient of the output with respect to the input.

    Note: If you used the crop parameter during the forward pass, you must provide the original, uncropped input shape to the X_shape parameter in the gradient function.

    X = numpy.random.rand(200, 300)
    
    # generate a deformation grid
    displacement = numpy.random.randn(2, 3, 3) * 25
    
    # perform forward deformation
    X_deformed = elasticdeform.deform_grid(X, displacement)
    
    # obtain the gradient w.r.t. X_deformed (e.g., with backpropagation)
    dX_deformed = numpy.random.randn(*X_deformed.shape)
    
    # compute the gradient w.r.t. X
    dX = elasticdeform.deform_grid_gradient(dX_deformed, displacement)