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
@@ -422,8 +422,8 @@ The following transformations are supported:
422
422
|[`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`). |
423
423
|[`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`).|
424
424
|[`sequence`](#sequence-md)|`"transformations":List[Transformation]`| sequence of transformations. Applying the sequence applies the composition of all transforms in the list, in order. |
425
-
|[`displacements`](#coordinates-displacements-md)|`"path":str`| Displacement field transformation located at `path`. |
426
-
|[`coordinates`](#coordinates-displacements-md)|`"path":str`| Coordinate field transformation located at `path`. |
425
+
|[`displacements`](#coordinates-displacements-md)|`"path":str`<br> `"interpolation":str`| Displacement field transformation located at `path`. |
426
+
|[`coordinates`](#coordinates-displacements-md)|`"path":str`<br> `"interpolation":str`| Coordinate field transformation located at `path`. |
427
427
|[`bijection`](#bijection-md)|`"forward":Transformation`<br>`"inverse":Transformation`| An invertible transformation providing an explicit forward transformation and its inverse. |
428
428
|[`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. |
429
429
@@ -464,7 +464,7 @@ i.e., the mapping from the first input axis to the first output axis is determin
464
464
Conforming readers:
465
465
- MUST parse `identity`, `scale`, `translation` transformations;
466
466
- SHOULD parse `mapAxis`, `affine`, `rotation` transformations;
467
-
- SHOULD display an informative warning if encountering transformations that cannot be parsed or displayed by a viewer;
467
+
- SHOULD display an informative warning if encountering transformations that cannot be parsed or displayed by a consumer;
468
468
- SHOULD be able to apply transformations to points;
469
469
- SHOULD be able to apply transformations to images;
470
470
@@ -579,6 +579,12 @@ to do so by estimating the transformations' inverse if they choose to.
579
579
```
580
580
:::
581
581
582
+
```{note}
583
+
Exact reproducibility of pixel values for images transformed and resampled by
584
+
the transformation types here may differ across implementation and is therefore
585
+
out of the scope of this specification.
586
+
```
587
+
582
588
**Transformations in array coordinate units**:
583
589
Some applications might prefer to define points, regions-of-interest or transformation parameters
584
590
in array coordinates (also referred to as pixel coordinates) rather than physical units.
@@ -1026,65 +1032,104 @@ and is invertible.
1026
1032
##### coordinates and displacements
1027
1033
(coordinates-displacements-md)=
1028
1034
1029
-
`coordinates` and `displacements` transformations store coordinates or displacements in an array
1030
-
and interpret them as a vector field that defines a transformation.
1031
-
The arrays must have a dimension corresponding to every axis of the input coordinate system
1032
-
and one additional dimension to hold components of the vector.
1033
-
Applying the transformation amounts to looking up the appropriate vector in the array,
1034
-
interpolating if necessary,
1035
-
and treating it either as a position directly (`coordinates`)
1036
-
or a displacement of the input point (`displacements`).
1037
-
1038
-
These transformation types refer to an array at location specified by the `path` parameter.
1039
-
The input and output coordinate systems for these transformations (`input` / `output` coordinate systems)
1040
-
constrain the array size and the coordinate system metadata for the array (field `coordinateSystem`).
1041
-
1042
-
* If the input coordinate system has `N` axes,
1043
-
the array at location path MUST have `N+1` dimensions
1044
-
* The field coordinate system MUST contain an axis identical to every axis
1045
-
of its input coordinate system in the same order.
1046
-
* The field coordinate system MUST contain an axis with type `coordinate` or `displacement`, respectively,
1047
-
for transformations of type `coordinates` or `displacements`.
1048
-
* This SHOULD be the last axis (contiguous on disk when c-order).
1049
-
* If the output coordinate system has `M` axes,
1050
-
the length of the array along the `coordinate`/`displacement` dimension MUST be of length `M`.
1051
-
1052
-
The `i`th value of the array along the `coordinate` or `displacement` axis refers to the coordinate or displacement
1053
-
of the `i`th output axis. See the example below.
1054
-
1055
-
`coordinates` and `displacements` transformations are not invertible in general,
1035
+
`coordinates` and `displacements` transformations store a vector field of arbitrary sampling density in an array,
1036
+
defining a mapping from an input coordinate system to an output coordinate system.
1037
+
The array contains either coordinates (absolute positions)
1038
+
or displacements (relative shifts) for each point in the input space.
1039
+
1040
+
```{hint}
1041
+
The `coordinates` and `displacements` transformations are not invertible in general,
1056
1042
but implementations MAY approximate their inverses.
1043
+
```
1044
+
1045
+
**Array Structure**
1046
+
1047
+
The array containing the coordinates or displacements MUST:
1048
+
- be a regular grid of vectors.
1049
+
The vectors are stored in an array, the coordinates of which can be mapped
1050
+
to the corresponding coordinates in the input coordinate system via a coordinate transformation (see details below).
1051
+
- have one dimension corresponding to every axis of the input coordinate system
1052
+
- have one additional dimension to hold components of the vector (either coordinates or displacements)
1053
+
- only be used to represent transformations between coordinate systems that are defined in smooth, regularly sampled coordinate arrays.
1054
+
1057
1055
Metadata for these coordinate transforms have the following fields:
1058
1056
1059
1057
**path**
1060
1058
: The location of the coordinate array in this (or another) container.
1061
1059
1060
+
**interpolation**
1061
+
: The interpolation attributes MAY be provided.
1062
+
Its value indicates the interpolation to use if transforming points not on the array's discrete grid.
1063
+
1064
+
The interpolation methods listed in this specification document refer to the methods described in {cite:t}`thevenaz2000image` and are not exhaustive.
1065
+
- `nearest` for nearest neighbor interpolation (see {cite:t}`thevenaz2000image`, section 8.1),
1066
+
- `linear` for linear interpolation (default, see {cite:t}`thevenaz2000image`, section 8.2),
1067
+
- `bspline-cubic` for cubic interpolation (see {cite:t}`thevenaz2000image`, section 8.3 on "cubic B-splines).
1068
+
1069
+
Consumers SHOULD clearly communicate to users if a different interpolation method is used.
1062
1070
1063
-
For both `coordinates` and `displacements`,
1064
-
the array data at referred to by `path` MUST define coordinate system
1065
-
and coordinate transform metadata:
1071
+
```{hint}
1072
+
The `interpolation` field refers to the method that is used to interpolate the `coordinate` or `displacement` array,
1073
+
*not* the method used to interpolate the image when applying the transformation to an image.
1074
+
The `interpolation` field, if provided, is not normative in the sense that usage of a different method is invalid under the spec.
1075
+
Implementations may prefer to use faster methods for rendering (i.e., `linear` or `nearest`) but this may lead to pathological cases:
1076
+
- If `nearest` interpolation is used for a `coordinates` transformation,
1077
+
the transformed image collapses into a single point at the nearest coordinate in the coordinate field.
1078
+
- If `nearest` interpolation is used for a `displacements` transformation,
1079
+
the transformed image is piecewise constant with discontinuities at the boundaries between nearest neighbor regions.
1066
1080
1067
-
* Every axis name in the `coordinateTransform`'s `input`
1068
-
MUST appear in the coordinate system.
1069
-
* The array dimension corresponding to the `coordinate` or `displacement` axis
1070
-
MUST have length equal to the number of dimensions of the `coordinateTransform``output`
1071
-
* If the input coordinate system `N` axes,
1072
-
then the array data at `path` MUST have `(N + 1)` dimensions.
1073
-
* SHOULD have a `name` identical to the `name` of the corresponding `coordinateTransform`.
1081
+
While choosing the specified interpolation methods can help to avoid these pathologies,
1082
+
implementations of the specified interpolation methods may still differ in their results.
1083
+
An exact reproducibility of pixel values for images transformed and resampled by this transformation is therefore out of the scope of this specification.
1084
+
```
1074
1085
1075
-
For `coordinates`:
1086
+
**Array metadata**
1076
1087
1077
-
*`coordinateSystem` metadata MUST have exactly one axis with `"type" : "coordinate"`
1078
-
* the shape of the array along the "coordinate" axis must be exactly `N`
1088
+
For both `coordinates` and `displacements`,
1089
+
the array data referred to by `path` MUST define the following metadata fields:
1090
+
1091
+
*`coordinateSystems`: MUST contain a [coordinate system](#coordinatesystems-metadata) with the following properties:
1092
+
- Include all axes of the input coordinate system (in the same order).
1093
+
- Include one additional axis of `"type": "coordinate"` (for coordinates transformations) or `"type": "displacement"` (for displacements transformations).
1094
+
- The additional axis should be the last axis (for contiguous memory layout in C-order).
1095
+
- The `name` of this coordinate system SHOULD be the same as the `name` of the corresponding coordinate transformation.
1096
+
1097
+
*`coordinateTransformations`: Defines how to map from the coordinate system of the array into a physical coordinate system
1098
+
(e.g. the resolution at which the vector field is sampled). MUST contain a single transformation with the following properties:
1099
+
-`type`: The type of the transformation; MUST be one of [`identity`](#identity-md), [`scale`](#scale-md)
1100
+
or a [`sequence`](#sequence-md) of a [scale](#scale-md) followed by a [translation](#translation-md).
1101
+
-`output`: The name of the coordinate system defined in the `coordinateSystems` field of the array metadata.
1102
+
1103
+
*Note*: The `input` field is omitted, as it is implicitly the pixel coordinate system of the array
1104
+
(defined by the first `N` axes of the array's `coordinateSystem`).
1079
1105
1080
-
For `displacements`:
1106
+
**Constraints**
1081
1107
1082
-
*`coordinateSystem` metadata MUST have exactly one axis with `"type" : "displacement"`
1083
-
* the shape of the array along the "displacement" axis must be exactly `N`
1084
-
* input and output coordinate systems MUST have an equal number of dimensions.
1108
+
The array at `path` MUST satisfy:
1085
1109
1086
-
:::{dropdown} Example 1
1087
-
For example, in 1D:
1110
+
-**Dimensionality**: If the input coordinate system has `N` axes, the array at location `path` MUST have `N+1` dimensions.
1111
+
-**Vector dimension length**:
1112
+
- For `coordinates` transformations, the length of the array along the `coordinate` dimension (last axis) MUST equal `M`,
1113
+
the number of axes in the output coordinate system.
1114
+
- For `displacements` transformations, the length of the array along the `displacement` dimension (last axis) MUST equal `N`,
1115
+
the number of axes in the input (and output) coordinate system. `displacements` require `M=N`.
1116
+
-**Vector component mapping**: The `i`th value of the array along the `coordinate` or `displacement` axis refers to the `i`th output axis.
1117
+
1118
+
```{hint}
1119
+
Applying the transformation to a point `x` in the input coordinate system amounts to following the following steps:
1120
+
1. Use the inverse of the transformation found in the vector field's metadata under `coordinateTransformations`
1121
+
to map the input point `x` into the corresponding array coordinate `a`.
1122
+
2. Look up the vector in the array corresponding to that point's coordinates in the array's coordinate system.
1123
+
3. If the point (`a`) does not correspond to a discrete point in the `coordinate` or `displacement` array,
1124
+
interpolate the vector field to obtain a vector for the input point.
1125
+
4. Treat the result either as
1126
+
- an absolute position (`coordinates`) or
1127
+
- a displacement to add to the input point `x` (`displacements`).
1128
+
```
1129
+
1130
+
:::{dropdown} Example 1: 1D coordinate transformation
1131
+
For example, in 1D, a coordinate field transformation mapping from an input coordinate system `input`
1132
+
to an output coordinate system `output` would have metadata such as:
1088
1133
```json
1089
1134
{
1090
1135
"name" : "a coordinate field transform",
@@ -1096,30 +1141,46 @@ For example, in 1D:
1096
1141
}
1097
1142
```
1098
1143
1099
-
where we assume input spaces `i` and `x` are defined elsewhere.
1100
-
Example metadata for the array data at path `coordinates` above:
1144
+
where we assume input coordinate systems `input` and `output` are defined elsewhere.
1145
+
Example metadata under the attributes of the zarr array at path `coordinateTransformations/i2xCoordinates` above:
0 commit comments