Skip to content

Transform Examples

John Bogovic edited this page Oct 4, 2022 · 15 revisions

Transform examples

These examples correspond to those stories / use cases here.

Native resolution

A transformation that describes pixel spacing / offset in physical units

resolution example

This transform specification would be appropriate in the metadata for a 3D dataset called "/volume". Note that the input for the transformation could be omitted because empty or missing coordinate system default to the array-space, which in this case has the name "/volume".;

"coordinateSystems" : [
  {
    "name" : "volume_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  }
],
"coordinateTransformations": [
  { "name": "to_micrometers",
    "type": "scale",
    "scale" : [1.1, 2.2, 3.3],
    "input" : "/volume/0/image",
    "output" : "volume_micrometers"
  }
]

Crop

A transformation that describes the relationship of a subset ("crop" or "cutout") to a whole.

crop example 1

Assume two 3D datasets exist, one called "/volume/0/image" (the whole image) and "/crop/0/image", a subset of volume.

store.zarr                   # Root folder of the zarr store
│
├── .zattrs                  # coordinate transformations describing the relationship between two image coordinate systems
│                            # are stored in the attributes of their parent group.
│                            # transformations between 'volume' and 'crop' coordinate systems are stored here.
│
├── transformations          # transformations that use array storage go in a "transformations" zarr group.
│   └── displacements        # for example, a zarray containing a displacement field
│       ├── .zattrs
│       └── .zarray
│                             
├── volume
│   ├── .zattrs              # group level attributes (multiscales)
│   └── 0                    # a group containing the 0th scale
│       └── image            # a zarr array 
│           ├── .zattrs      # physical coordinate system goes here
│           └── .zarray      # the array attributes
└── crop                    
    ├── .zattrs              # group level attributes (multiscales)
    └── 0                    # a group containing the 0th scale
        └── image            # a zarr array 
            ├── .zattrs      # physical coordinate system goes here
            └── .zarray      # the array attributes

/volume/0/image/.zattrs contains:

"coordinateSystems" : [
  {
    "name" : "volume_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  }
],
"coordinateTransformations": [
  {
    "name": "to_volume_micrometers",
    "type": "scale",
    "scale" : [1.1, 2.2, 3.3],
    "input" : "/volume/0/image",
    "output" : "volume_micrometers"
  }
]

/crop/0/image/.zattrs contains:

"coordinateSystems" : [
  {
    "name" : "crop_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  }
],
"coordinateTransformations": [
  {
    "name": "to_crop_micrometers",
    "type": "scale",
    "scale" : [1.1, 2.2, 3.3],
    "input" : "/crop/0/image",
    "output" : "crop_micrometers"
  }
]

/.zattrs contains:

"coordinateSystems" : [
  {
    "name" : "volume_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  },
  {
    "name" : "crop_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  }
],
"coordinateTransformations": [
  {
    "name": "crop_um",
    "type": "translation",
    "scale" : [11, 22, 33],
    "input" : "crop_micrometers",
    "output" : "volume_micrometers"
  }
]

To correctly display the crop in the original "volume" space, we need a sequence transforms that take the dataset from "array space" to "volume" space. In this case, that path is "crop" -> crop_micrometers -> volume_micrometers, so the the sequence of transforms is would be ["to_crop_micrometers", "crop_um"]

crop example 2

In example 1 above, the crop translation is given in physical units. It is possible specify the offset in pixel units.

"coordinateSystems" : [
  {
    "name" : "volume_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  },
  {
    "name" : "crop_micrometers",
    "axes" : [
      {"name": "x", "type": "space", "unit": "micrometer"},
      {"name": "y", "type": "space", "unit": "micrometer"},
      {"name": "z", "type": "space", "unit": "micrometer"}
    ]
  }
],
"coordinateTransformations": [
  {
    "name": "crop_offset",
    "type": "translation",
    "scale" : [10, 10, 10],
    "input" : "/crop/0/image",
    "output" : "/volume/0/image"
  },
  {
    "name": "to_micrometers",
    "type": "scale",
    "scale" : [1.1, 2.2, 3.3],
    "input" : "/volume",
    "output" : "volume_micrometers"
  }
]

Just as above, we want a sequence transforms that take the dataset from "array space" to "volume" space. In this case, that path is /crop/0/image -> /volume/0/image -> volume_micrometers, so the the sequence of transforms is would be ["crop_offset", "to_micrometers"]

Affine registration

A transformation that represents an image being registered to another image.

The examples below will assume the "volume" dataset as in native-resolution, and a "target" dataset with this metadata:

"coordinateSystems" : [
  {
    "name" : "target_micrometers",
    "axes" : [
      {"name": "tgt-z", "type": "space", "unit": "micrometer"},
      {"name": "tgt-y", "type": "space", "unit": "micrometer"},
      {"name": "tgt-x", "type": "space", "unit": "micrometer"}
    ]
  }
],
"coordinateTransformations": [
  {
    "name": "to_target_micrometers",
    "type": "scale",
    "scale" : [1.1, 1.1, 1.1],
    "input" : "target",
    "output" : "target_micrometers"
  }
]

affine example

An affine registration from volume to target is simply a transformation between the two spaces:

{
  "name": "volume-to-target",
  "type": "affine",
  "affine" : [1.1, 0.2, 0.3, 40,   0.5, 1.6, 0.7, 80,  0.9, 0.10, 1.11, 120],
  "input" : "volume_micrometers",
  "output" : "target_micrometers"
}

Given this and the prerequisite transforms, a user / algorithm / viewer can correctly show the "volume" dataset in

  1. "raw" pixel coordinates
  2. "native physical" coordinates in micrometers
  3. the physical coordinate space of the "target"
  4. the pixel coordinate space of the "target" (using the inverse of to_target_micrometers transform)