-
Notifications
You must be signed in to change notification settings - Fork 0
Transform Examples
These examples correspond to those stories / use cases here.
A transformation that describes pixel spacing / offset in physical units
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"
}
]
A transformation that describes the relationship of a subset ("crop" or "cutout") to a whole.
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"]
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"]
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"
}
]
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
- "raw" pixel coordinates
- "native physical" coordinates in micrometers
- the physical coordinate space of the "target"
- the pixel coordinate space of the "target" (using the inverse of
to_target_micrometers
transform)