Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
fslpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michiel Cottaar
fslpy
Commits
c30f1c74
Commit
c30f1c74
authored
5 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
RF: Push srcToRefMat up to the NonLinearTransform class, so it can also be
used by the DisplacementField class.
parent
2de38f86
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
fsl/transform/nonlinear.py
+76
-53
76 additions, 53 deletions
fsl/transform/nonlinear.py
with
76 additions
and
53 deletions
fsl/transform/nonlinear.py
+
76
−
53
View file @
c30f1c74
...
@@ -53,6 +53,17 @@ class NonLinearTransform(fslimage.Image):
...
@@ -53,6 +53,17 @@ class NonLinearTransform(fslimage.Image):
the corresponding location in the source image space. Therefore, these
the corresponding location in the source image space. Therefore, these
non-linear transformation effectively encode a transformation *from* the
non-linear transformation effectively encode a transformation *from* the
reference image *to* the source image.
reference image *to* the source image.
A FNIRT nonlinear transformation often contains a *premat*, a global
affine transformation from the source space to the reference space, which
was calculated with FLIRT, and used as the starting point for the
non-linear optimisation performed by FNIRT.
This affine may be provided when creating a ``NonLinearTransform`` as the
``srcToRefMat`` argument to :meth:`__init__`, and is subsequently accessed
via the :meth:`srcToRefMat` attribute.
"""
"""
...
@@ -62,28 +73,40 @@ class NonLinearTransform(fslimage.Image):
...
@@ -62,28 +73,40 @@ class NonLinearTransform(fslimage.Image):
ref
,
ref
,
srcSpace
=
None
,
srcSpace
=
None
,
refSpace
=
None
,
refSpace
=
None
,
srcToRefMat
=
None
,
**
kwargs
):
**
kwargs
):
"""
Create a ``NonLinearTransform``.
"""
Create a ``NonLinearTransform``.
:arg image: A string containing the name of an image file to
load,
:arg image:
A string containing the name of an image file to
or a :mod:`numpy` array, or a :mod:`nibabel`
image
load,
or a :mod:`numpy` array, or a :mod:`nibabel`
object.
image
object.
:arg src: :class:`.Nifti` representing the source image.
:arg src:
:class:`.Nifti` representing the source image.
:arg ref: :class:`.Nifti` representing the reference image.
:arg ref:
:class:`.Nifti` representing the reference image.
:arg srcSpace: Coordinate system in the source image that this
:arg srcSpace: Coordinate system in the source image that this
``NonLinearTransform`` maps to. Defaults to ``
'
fsl
'
``.
``NonLinearTransform`` maps to. Defaults to
``
'
fsl
'
``.
:arg refSpace: Coordinate system in the reference image that this
:arg refSpace: Coordinate system in the reference image that this
``NonLinearTransform`` maps from. Defaults to ``
'
fsl
'
``.
``NonLinearTransform`` maps from. Defaults to
``
'
fsl
'
``.
:arg srcToRefMat: Optional initial global affine transformation from
the source image to the reference image. This is
assumed to be a FLIRT-style matrix, i.e. it
transforms from source image ``srcSpace`` coordinates
into reference image ``srcSpace`` coordinates
(typically ``
'
fsl
'
`` coordinates, i.e. scaled voxels
potentially with a left-right flip).
All other arguments are passed through to :meth:`.Image.__init__`.
All other arguments are passed through to :meth:`.Image.__init__`.
"""
"""
if
srcSpace
is
None
:
srcSpace
=
'
fsl
'
if
srcSpace
is
None
:
srcSpace
=
'
fsl
'
if
refSpace
is
None
:
refSpace
=
'
fsl
'
if
refSpace
is
None
:
refSpace
=
'
fsl
'
if
srcToRefMat
is
not
None
:
srcToRefMat
=
np
.
copy
(
srcToRefMat
)
if
srcSpace
not
in
(
'
fsl
'
,
'
voxel
'
,
'
world
'
)
or
\
if
srcSpace
not
in
(
'
fsl
'
,
'
voxel
'
,
'
world
'
)
or
\
refSpace
not
in
(
'
fsl
'
,
'
voxel
'
,
'
world
'
):
refSpace
not
in
(
'
fsl
'
,
'
voxel
'
,
'
world
'
):
...
@@ -92,10 +115,15 @@ class NonLinearTransform(fslimage.Image):
...
@@ -92,10 +115,15 @@ class NonLinearTransform(fslimage.Image):
fslimage
.
Image
.
__init__
(
self
,
image
,
**
kwargs
)
fslimage
.
Image
.
__init__
(
self
,
image
,
**
kwargs
)
self
.
__src
=
fslimage
.
Nifti
(
src
.
header
.
copy
())
self
.
__src
=
fslimage
.
Nifti
(
src
.
header
.
copy
())
self
.
__ref
=
fslimage
.
Nifti
(
ref
.
header
.
copy
())
self
.
__ref
=
fslimage
.
Nifti
(
ref
.
header
.
copy
())
self
.
__srcSpace
=
srcSpace
self
.
__srcSpace
=
srcSpace
self
.
__refSpace
=
refSpace
self
.
__refSpace
=
refSpace
self
.
__srcToRefMat
=
srcToRefMat
self
.
__refToSrcMat
=
None
if
srcToRefMat
is
not
None
:
self
.
__refToSrcMat
=
affine
.
invert
(
srcToRefMat
)
@property
@property
...
@@ -130,6 +158,22 @@ class NonLinearTransform(fslimage.Image):
...
@@ -130,6 +158,22 @@ class NonLinearTransform(fslimage.Image):
return
self
.
__refSpace
return
self
.
__refSpace
@property
def
srcToRefMat
(
self
):
"""
Return the initial source-to-reference affine, or ``None`` if
there isn
'
t one.
"""
return
self
.
__srcToRefMat
@property
def
refToSrcMat
(
self
):
"""
Return the inverse of the initial source-to-reference affine, or
``None`` if there isn
'
t one.
"""
return
self
.
__refToSrcMat
def
transform
(
self
,
coords
,
from_
=
None
,
to
=
None
):
def
transform
(
self
,
coords
,
from_
=
None
,
to
=
None
):
"""
Transform coordinates from the reference image space to the source
"""
Transform coordinates from the reference image space to the source
image space. Implemented by sub-classes.
image space. Implemented by sub-classes.
...
@@ -254,11 +298,18 @@ class DisplacementField(NonLinearTransform):
...
@@ -254,11 +298,18 @@ class DisplacementField(NonLinearTransform):
if
self
.
absolute
:
disps
=
self
.
data
[
xs
,
ys
,
zs
,
:]
if
self
.
absolute
:
disps
=
self
.
data
[
xs
,
ys
,
zs
,
:]
else
:
disps
=
self
.
data
[
xs
,
ys
,
zs
,
:]
+
coords
[
voxmask
]
else
:
disps
=
self
.
data
[
xs
,
ys
,
zs
,
:]
+
coords
[
voxmask
]
# Make sure the coordinates
# Make sure the coordinates are
# are in the requested
# in the requested source image
# source image space
# space, and apply the initial
# inv(srcToRefMat) if it there
# is one
postmat
=
self
.
refToSrcMat
if
to
!=
self
.
srcSpace
:
if
to
!=
self
.
srcSpace
:
xform
=
self
.
src
.
getAffine
(
self
.
srcSpace
,
to
)
xform
=
self
.
src
.
getAffine
(
self
.
srcSpace
,
to
)
if
postmat
is
not
None
:
postmat
=
affine
.
concat
(
xform
,
postmat
)
else
:
postmat
=
xform
if
postmat
is
not
None
:
disps
=
affine
.
transform
(
disps
,
xform
)
disps
=
affine
.
transform
(
disps
,
xform
)
# Nans for input coordinates
# Nans for input coordinates
...
@@ -276,16 +327,6 @@ class CoefficientField(NonLinearTransform):
...
@@ -276,16 +327,6 @@ class CoefficientField(NonLinearTransform):
The :meth:`displacements` method can be used to calculate relative
The :meth:`displacements` method can be used to calculate relative
displacements for a set of reference space voxel coordinates.
displacements for a set of reference space voxel coordinates.
A FNIRT coefficient field typically contains a *premat*, a global affine
transformation from the source space to the reference space, which was
used as the starting point for the non-linear optimisation performed by
FNIRT.
This affine must be provided when creating a ``CoefficientField``, and is
subsequently accessed via the :meth:`srcToRefMat` or :meth:`premat`
attributes.
"""
"""
...
@@ -297,7 +338,6 @@ class CoefficientField(NonLinearTransform):
...
@@ -297,7 +338,6 @@ class CoefficientField(NonLinearTransform):
refSpace
,
refSpace
,
fieldType
,
fieldType
,
knotSpacing
,
knotSpacing
,
srcToRefMat
,
fieldToRefMat
,
fieldToRefMat
,
**
kwargs
):
**
kwargs
):
"""
Create a ``CoefficientField``.
"""
Create a ``CoefficientField``.
...
@@ -307,13 +347,6 @@ class CoefficientField(NonLinearTransform):
...
@@ -307,13 +347,6 @@ class CoefficientField(NonLinearTransform):
:arg knotSpacing: A tuple containing the spline knot spacings along
:arg knotSpacing: A tuple containing the spline knot spacings along
each axis.
each axis.
:arg srcToRefMat: Initial global affine transformation from the
source image to the reference image. This is
assumed to be a FLIRT-style matrix, i.e. it
transforms from source image FSL coordinates
into reference image FSL coordinates (scaled
voxels).
:arg fieldToRefMat: Affine transformation which can transform reference
:arg fieldToRefMat: Affine transformation which can transform reference
image voxel coordinates into coefficient field
image voxel coordinates into coefficient field
voxel coordinates.
voxel coordinates.
...
@@ -335,7 +368,6 @@ class CoefficientField(NonLinearTransform):
...
@@ -335,7 +368,6 @@ class CoefficientField(NonLinearTransform):
self
.
__fieldType
=
fieldType
self
.
__fieldType
=
fieldType
self
.
__knotSpacing
=
tuple
(
knotSpacing
)
self
.
__knotSpacing
=
tuple
(
knotSpacing
)
self
.
__srcToRefMat
=
np
.
copy
(
srcToRefMat
)
self
.
__fieldToRefMat
=
np
.
copy
(
fieldToRefMat
)
self
.
__fieldToRefMat
=
np
.
copy
(
fieldToRefMat
)
self
.
__refToFieldMat
=
affine
.
invert
(
self
.
__fieldToRefMat
)
self
.
__refToFieldMat
=
affine
.
invert
(
self
.
__fieldToRefMat
)
...
@@ -348,14 +380,6 @@ class CoefficientField(NonLinearTransform):
...
@@ -348,14 +380,6 @@ class CoefficientField(NonLinearTransform):
return
self
.
__fieldType
return
self
.
__fieldType
@property
def
srcToRefMat
(
self
):
"""
Return an initial global affine transformation from the source
image to the reference image.
"""
return
np
.
copy
(
self
.
__srcToRefMat
)
@property
@property
def
knotSpacing
(
self
):
def
knotSpacing
(
self
):
"""
Return a tuple containing spline knot spacings along the x, y, and
"""
Return a tuple containing spline knot spacings along the x, y, and
...
@@ -688,20 +712,19 @@ def coefficientFieldToDisplacementField(field,
...
@@ -688,20 +712,19 @@ def coefficientFieldToDisplacementField(field,
# Apply the premat if requested -
# Apply the premat if requested -
# this will transform the coordinates
# this will transform the coordinates
# from aligned-src to orig-src space.
# from aligned-src to orig-src space.
if
premat
:
if
premat
and
field
.
srcToRefMat
is
not
None
:
# We apply the premat in the same way
# We apply the premat in the same way
# that fnirtfileutils does - applying
# that fnirtfileutils does - applying
# the inverse affine to every ref space
# the inverse affine to every ref space
# voxel coordinate, then adding it to
# voxel coordinate, then adding it to
# the existing displacements.
# the existing displacements.
shape
=
disps
.
shape
shape
=
disps
.
shape
disps
=
disps
.
reshape
(
-
1
,
3
)
disps
=
disps
.
reshape
(
-
1
,
3
)
refToSrc
=
affine
.
invert
(
field
.
srcToRefMat
)
premat
=
affine
.
concat
(
field
.
refToSrcMat
-
np
.
eye
(
4
),
premat
=
affine
.
concat
(
refToSrc
-
np
.
eye
(
4
),
field
.
ref
.
getAffine
(
'
voxel
'
,
'
fsl
'
))
field
.
ref
.
getAffine
(
'
voxel
'
,
'
fsl
'
))
disps
=
disps
+
affine
.
transform
(
xyz
,
premat
)
disps
=
disps
+
affine
.
transform
(
xyz
,
premat
)
disps
=
disps
.
reshape
(
shape
)
disps
=
disps
.
reshape
(
shape
)
# note that convertwarp applies a premat
# note that convertwarp applies a premat
# differently - its method is equivalent
# differently - its method is equivalent
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment