You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -275,9 +275,9 @@ In contrast, discrete axes (`"discrete" : true`) may be indexed only by integers
275
275
Axes representing a channel, coordinate, or displacement are usually discrete.
276
276
277
277
```{note}
278
-
The most common methods for interpolation are "nearest neighbor", "linear", "cubic", and "windowed sinc".
278
+
The most common methods for interpolation are "nearest", "linear", "bspline-cubic", and "windowed sinc" (see {cite:t}`thevenaz2000image`, section 8).
279
279
Here, we refer to any method that obtains values at real-valued coordinates using discrete samples as an "interpolator".
280
-
As such, label images may be interpolated using "nearest neighbor" to obtain labels at points along the continuum.
280
+
As such, label images may be interpolated using "nearest" to obtain labels at points along the continuum.
281
281
```
282
282
283
283
#### Coordinate convention
@@ -420,8 +420,8 @@ The following transformations are supported:
420
420
|[`affine`](#affine-md)| one of:<br>`"affine":List[List[number]]`,<br>`"path":str`| 2D affine transformation matrix stored either with JSON (`affine`) or as a Zarr array at a location in this container (`path`). |
421
421
|[`rotation`](#rotation-md)| one of:<br>`"rotation":List[List[number]]`,<br>`"path":str`| 2D rotation transformation matrix stored as an array stored either with json (`rotation`) or as a Zarr array at a location in this container (`path`).|
422
422
|[`sequence`](#sequence-md)|`"transformations":List[Transformation]`| sequence of transformations. Applying the sequence applies the composition of all transforms in the list, in order. |
423
-
|[`displacements`](#coordinates-displacements-md)|`"path":str`| Displacement field transformation located at `path`. |
424
-
|[`coordinates`](#coordinates-displacements-md)|`"path":str`| Coordinate field transformation located at `path`. |
423
+
|[`displacements`](#coordinates-displacements-md)|`"path":str`<br> `"interpolation":str`| Displacement field transformation located at `path`. |
424
+
|[`coordinates`](#coordinates-displacements-md)|`"path":str`<br> `"interpolation":str`| Coordinate field transformation located at `path`. |
425
425
|[`bijection`](#bijection-md)|`"forward":Transformation`<br>`"inverse":Transformation`| An invertible transformation providing an explicit forward transformation and its inverse. |
426
426
|[`byDimension`](#bydimension-md)|`"transformations":List[Transformation]`.<br>Transformations in the array MUST have<br>`"input_axes": List[number]`, <br> and `"output_axes": List[number]`| A high dimensional transformation using lower dimensional transformations on subsets of dimensions. |
427
427
@@ -462,7 +462,7 @@ i.e., the mapping from the first input axis to the first output axis is determin
462
462
Conforming readers:
463
463
- MUST parse `identity`, `scale`, `translation` transformations;
464
464
- SHOULD parse `mapAxis`, `affine`, `rotation` transformations;
465
-
- SHOULD display an informative warning if encountering transformations that cannot be parsed or displayed by a viewer;
465
+
- SHOULD display an informative warning if encountering transformations that cannot be parsed or displayed by a consumer;
466
466
- SHOULD be able to apply transformations to points;
467
467
- SHOULD be able to apply transformations to images;
468
468
@@ -562,6 +562,12 @@ to do so by estimating the transformations' inverse if they choose to.
562
562
```
563
563
:::
564
564
565
+
```{note}
566
+
Exact reproducibility of pixel values for images transformed and resampled by
567
+
the transformation types here may differ across implementation and is therefore
568
+
out of the scope of this specification.
569
+
```
570
+
565
571
**Transformations in array coordinate units**:
566
572
Some applications might prefer to define points, regions-of-interest or transformation parameters
567
573
in array coordinates (also referred to as pixel coordinates) rather than physical units.
@@ -1011,100 +1017,155 @@ and is invertible.
1011
1017
##### coordinates and displacements
1012
1018
(coordinates-displacements-md)=
1013
1019
1014
-
`coordinates` and `displacements` transformations store coordinates or displacements in an array
1015
-
and interpret them as a vector field that defines a transformation.
1016
-
The arrays must have a dimension corresponding to every axis of the input coordinate system
1017
-
and one additional dimension to hold components of the vector.
1018
-
Applying the transformation amounts to looking up the appropriate vector in the array,
1019
-
interpolating if necessary,
1020
-
and treating it either as a position directly (`coordinates`)
1021
-
or a displacement of the input point (`displacements`).
1022
-
1023
-
These transformation types refer to an array at location specified by the `path` parameter.
1024
-
The input and output coordinate systems for these transformations (`input` / `output` coordinate systems)
1025
-
constrain the array size and the coordinate system metadata for the array (field `coordinateSystem`).
1026
-
1027
-
* If the input coordinate system has `N` axes,
1028
-
the array at location path MUST have `N+1` dimensions
1029
-
* The field coordinate system MUST contain an axis identical to every axis
1030
-
of its input coordinate system in the same order.
1031
-
* The field coordinate system MUST contain an axis with type `coordinate` or `displacement`, respectively,
1032
-
for transformations of type `coordinates` or `displacements`.
1033
-
* This SHOULD be the last axis (contiguous on disk when c-order).
1034
-
* If the output coordinate system has `M` axes,
1035
-
the length of the array along the `coordinate`/`displacement` dimension MUST be of length `M`.
1036
-
1037
-
The `i`th value of the array along the `coordinate` or `displacement` axis refers to the coordinate or displacement
1038
-
of the `i`th output axis. See the example below.
1039
-
1040
-
`coordinates` and `displacements` transformations are not invertible in general,
1020
+
`coordinates` and `displacements` transformations store a vector field of arbitrary sampling density in an array,
1021
+
defining a mapping from an input coordinate system to an output coordinate system.
1022
+
The array contains either coordinates (absolute positions)
1023
+
or displacements (relative shifts) for each point in the input space.
1024
+
1025
+
```{hint}
1026
+
The `coordinates` and `displacements` transformations are not invertible in general,
1041
1027
but implementations MAY approximate their inverses.
1028
+
```
1029
+
1030
+
**Array Structure**
1031
+
1032
+
The array containing the coordinates or displacements MUST:
1033
+
- be a regular grid of vectors.
1034
+
The vectors are stored in an array, the coordinates of which can be mapped
1035
+
to the corresponding coordinates in the input coordinate system via a coordinate transformation (see details below).
1036
+
- have one dimension corresponding to every axis of the input coordinate system
1037
+
- have one additional dimension to hold components of the vector (either coordinates or displacements)
1038
+
- only be used to represent transformations between coordinate systems that are defined in smooth, regularly sampled coordinate arrays.
1039
+
1042
1040
Metadata for these coordinate transforms have the following fields:
1043
1041
1044
1042
**path**
1045
1043
: The location of the coordinate array in this (or another) container.
1046
1044
1045
+
**interpolation**
1046
+
: The interpolation attributes MAY be provided.
1047
+
Its value indicates the interpolation to use if transforming points not on the array's discrete grid.
1048
+
1049
+
The interpolation methods listed in this specification document refer to the methods described in {cite:t}`thevenaz2000image` and are not exhaustive.
1050
+
- `nearest` for nearest neighbor interpolation (see {cite:t}`thevenaz2000image`, section 8.1),
1051
+
- `linear` for linear interpolation (default, see {cite:t}`thevenaz2000image`, section 8.2),
1052
+
- `bspline-cubic` for cubic interpolation (see {cite:t}`thevenaz2000image`, section 8.3 on "cubic B-splines).
1053
+
1054
+
Consumers SHOULD clearly communicate to users if a different interpolation method is used.
1055
+
1056
+
```{hint}
1057
+
The `interpolation` field refers to the method that is used to interpolate the `coordinate` or `displacement` array,
1058
+
*not* the method used to interpolate the image when applying the transformation to an image.
1059
+
The `interpolation` field, if provided, is not normative in the sense that usage of a different method is invalid under the spec.
1060
+
Implementations may prefer to use faster methods for rendering (i.e., `linear` or `nearest`) but this may lead to pathological cases:
1061
+
- If `nearest` interpolation is used for a `coordinates` transformation,
1062
+
the transformed image collapses into a single point at the nearest coordinate in the coordinate field.
1063
+
- If `nearest` interpolation is used for a `displacements` transformation,
1064
+
the transformed image is piecewise constant with discontinuities at the boundaries between nearest neighbor regions.
1065
+
1066
+
While choosing the specified interpolation methods can help to avoid these pathologies,
1067
+
implementations of the specified interpolation methods may still differ in their results.
1068
+
An exact reproducibility of pixel values for images transformed and resampled by this transformation is therefore out of the scope of this specification.
1069
+
```
1070
+
1071
+
**Array metadata**
1047
1072
1048
1073
For both `coordinates` and `displacements`,
1049
-
the array data at referred to by `path` MUST define coordinate system
1050
-
and coordinate transform metadata:
1051
-
1052
-
* Every axis name in the `coordinateTransform`'s `input`
1053
-
MUST appear in the coordinate system.
1054
-
* The array dimension corresponding to the `coordinate` or `displacement` axis
1055
-
MUST have length equal to the number of dimensions of the `coordinateTransform``output`
1056
-
* If the input coordinate system `N` axes,
1057
-
then the array data at `path` MUST have `(N + 1)` dimensions.
1058
-
* SHOULD have a `name` identical to the `name` of the corresponding `coordinateTransform`.
1059
-
1060
-
For `coordinates`:
1061
-
1062
-
*`coordinateSystem` metadata MUST have exactly one axis with `"type" : "coordinate"`
1063
-
* the shape of the array along the "coordinate" axis must be exactly `N`
1064
-
1065
-
For `displacements`:
1066
-
1067
-
*`coordinateSystem` metadata MUST have exactly one axis with `"type" : "displacement"`
1068
-
* the shape of the array along the "displacement" axis must be exactly `N`
1069
-
* input and output coordinate systems MUST have an equal number of dimensions.
1070
-
1071
-
:::{dropdown} Example 1
1072
-
For example, in 1D:
1074
+
the array data referred to by `path` MUST define the following metadata fields:
1075
+
1076
+
*`coordinateSystems`: MUST contain a [coordinate system](#coordinatesystems-metadata) with the following properties:
1077
+
- Include all axes of the input coordinate system (in the same order).
1078
+
- Include one additional axis of `"type": "coordinate"` (for coordinates transformations) or `"type": "displacement"` (for displacements transformations).
1079
+
- The additional axis should be the last axis (for contiguous memory layout in C-order).
1080
+
- The `name` of this coordinate system SHOULD be the same as the `name` of the corresponding coordinate transformation.
1081
+
1082
+
*`coordinateTransformations`: Defines how to map from the coordinate system of the array into a physical coordinate system
1083
+
(e.g. the resolution at which the vector field is sampled). MUST contain a single transformation with the following properties:
1084
+
-`type`: The type of the transformation; MUST be one of [`identity`](#identity-md), [`scale`](#scale-md)
1085
+
or a [`sequence`](#sequence-md) of a [scale](#scale-md) followed by a [translation](#translation-md).
1086
+
-`output`: The name of the coordinate system defined in the `coordinateSystems` field of the array metadata.
1087
+
1088
+
*Note*: The `input` field is omitted, as it is implicitly the pixel coordinate system of the array
1089
+
(defined by the first `N` axes of the array's `coordinateSystem`).
1090
+
1091
+
**Constraints**
1092
+
1093
+
The array at `path` MUST satisfy:
1094
+
1095
+
-**Dimensionality**: If the input coordinate system has `N` axes, the array at location `path` MUST have `N+1` dimensions.
1096
+
-**Vector dimension length**:
1097
+
- For `coordinates` transformations, the length of the array along the `coordinate` dimension (last axis) MUST equal `M`,
1098
+
the number of axes in the output coordinate system.
1099
+
- For `displacements` transformations, the length of the array along the `displacement` dimension (last axis) MUST equal `N`,
1100
+
the number of axes in the input (and output) coordinate system. `displacements` require `M=N`.
1101
+
-**Vector component mapping**: The `i`th value of the array along the `coordinate` or `displacement` axis refers to the `i`th output axis.
1102
+
1103
+
```{hint}
1104
+
Applying the transformation to a point `x` in the input coordinate system amounts to following the following steps:
1105
+
1. Use the inverse of the transformation found in the vector field's metadata under `coordinateTransformations`
1106
+
to map the input point `x` into the corresponding array coordinate `a`.
1107
+
2. Look up the vector in the array corresponding to that point's coordinates in the array's coordinate system.
1108
+
3. If the point (`a`) does not correspond to a discrete point in the `coordinate` or `displacement` array,
1109
+
interpolate the vector field to obtain a vector for the input point.
1110
+
4. Treat the result either as
1111
+
- an absolute position (`coordinates`) or
1112
+
- a displacement to add to the input point `x` (`displacements`).
1113
+
```
1114
+
1115
+
:::{dropdown} Example 1: 1D coordinate transformation
1116
+
For example, in 1D, a coordinate field transformation mapping from an input coordinate system `input`
1117
+
to an output coordinate system `output` would have metadata such as:
0 commit comments