Skip to content

Transform List

John Bogovic edited this page Feb 17, 2022 · 11 revisions

A list of transform types.

Must-have transformation types

Types of transformations that are essential to support.

type fields description
identity identity transformation, is the default transformation, and may accept inputs of any dimension.
translation one of:
number[]:translation
String:path
translation vector, stored either as a number[] (translation) or as binary data at a location in this container (path). If both are present, path is preferred. length of vector defines number of dimensions
scale one of:
number[]:scale
String:path
scale vector, stored either as a number[] (scale) or as binary data at a location in this container (path). If both are present, path is preferred. length of vector defines number of dimensions
affine one of:
number[]:affine
String:path
affine transformation matrix defined as list consisting of n sets of n + 1 scalar numbers, stored either as a number[] (affine) or as binary data at a location in this container (path). If both are present, path is preferred. n is number of dimensions
rigid one of:
number[]:angles
String:path
rigid transformation or as binary data at a location in this container (path). If both are present, path is preferred. n is number of dimensions
displacement_field String:url
String:path(null)
deformation / displacement field storing one offset for each grid coordinate, url points to the data container (e.g. "/field.hdf5" or "/field.tif" and path points to the dataset if the container can hold multiple datasets or is empty for single dataset containers
position_field String:url
String:path(null)
position field storing one absolute position for each grid coordinate, url points to the data container (e.g. "/field.hdf5" or "/field.tif" and path points to the dataset if the container can hold multiple datasets or is empty for single dataset containers
inverse_of Transformation:transformation inverse of a transformation
sequence Transformation[]:transformations sequence of transformations, an empty sequence is the identity
bijection Transformation:forward
Transformation:inverse
explicitly provide two transforms that are each others' inverses
axis_permutation number[]:permutation permute the axes indexes of the input
the value of permutation must be an array of integers

Maybe-have transformation types

Types of transformations that may be useful to support.

type fields description
cartesian_to_polar cartesian to polar coordinates, 2D inputs, 2D outputs
polar_to_cartesian polar to cartesian coordinates, 2D inputs, 2D outputs
cartesian_to_spherical cartesian to polar coordinates, 3D inputs, 3D outputs
polar_to_spherical polar to cartesian coordinates, 3D inputs, 3D outputs
cartesian_to_cylindrical cartesian to cylindrical coordinates, 3D inputs, 3D outputs
polar_to_cylindrical cylindrical to cartesian coordinates, 3D inputs, 3D outputs
exp number:base exponential
log number:base logarithm
gamma number:A
number:gamma
the 1d transformation y = a*x^gamma

Details

Some specific considerations for particular transformation types.

Rigid

What parametrization should we used? Sensible choices

  • Quaternions
  • Rodrigues vector
  • axis + angle
  • Euler angles
  • Tait–Bryan angles

Displacement and position fields

Displacement and position fields are not closed-form invertible. Therefore, when used to transform images, they should be wrapped in an inverse_of transformation, for example:

{
  "type" : "inverse_of",
  "transformation" : {
    "type" : "displacement_field"
    "url" : ".",
    "path" : "dfield"
  }
}

The paths that store displacement and position fields should be valid ome-ngff datasets, with coordinate spaces defined appropriately. Displacement fields should have exactly one axis of "type" : "displacements"; ; position fields should have exactly one axis of "type" : "positions". These axes should be discrete, and their lengths MUST be greater than or equal to the number of other dimensions, but SHOULD equal the number of other dimensions (see example below).

The displacement/position axis type SHOULD be the first or last dimension, call it d

  • If first, d[i] is the displacement/position along axis i+1
  • If last, d[i] is the displacement/position along axis i
  • Otherwise, d[i] is the displacement/position along axis i+1 if i >= d, or i otherwise (NOT RECOMMENDED)

These values are in the units of the axes to which they correspond (usually physical), see below.

These transformations SHOULD be applied only to points / images in the space they define, see below.

{
  "name" : "dfield_space",
  "axes" : [
    { "name" : "d", "type" : "displacements", "unit" : "none", "discrete" : true },
    { "name" : "x", "type" : "space", "unit" : "mm"},
    { "name" : "y", "type" : "space", "unit" : "mm"},
  ]
}

then

  • the first dimension should be of length 2.
  • d[0] is the displacement along the x axis in "mm"
  • d[1] is the displacement along the y axis in "mm"

This transform SHOULD be applied on images in the space:

{
  "name" : "spatial",
  "axes" : [
    { "name" : "x", "type" : "space", "unit" : "mm"},
    { "name" : "y", "type" : "space", "unit" : "mm"},
  ]
}

This transform SHOULD NOT be applied on images in any other space, e.g.:

{
  "name" : "array",
  "axes" : [
    { "name" : "dim_0"},
    { "name" : "dim_1"},
  ]
}

Inverse_of

inverse_of enables us to express that a given transformation may be applied to images, but that there does not exist a corresponding "forward" transformation that can be applied to points.

We define transforms between spaces as being "in the forward direction", but inverse transforms are needed for rendering transformed images. This is why many image registration methods return inverse transforms, especially when the transform is non-linear, and not closed-form invertible. In this or similar situations, the resulting transform should be wrapped in an inverse_of.

If the forward transform is requested, implementations may either throw an error or attempt to estimate it.

Permutation

Axes may also be permuted by making a new space with permuted axes as shown below. However, making new axes identified with the permuted axes names is not possible that way. Therefore, including the axis_permutation type will be useful.

Given the space:

{ "name" : "orig",
  "axes" : [
    { "name" : "x" },
    { "name" : "y" },
    { "name" : "z" },
  ]
}

a permutation might be achievable by creating a new space with permuted axes:

{ "name" : "permuted",
  "axes" : [
    { "name" : "z" },
    { "name" : "x" },
    { "name" : "y" },
  ]
}