Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
fslpy
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Analyze
Contributor analytics
CI/CD 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
Evan Edmond
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):
the corresponding location in the source image space. Therefore, these
non-linear transformation effectively encode a transformation *from* the
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):
ref
,
srcSpace
=
None
,
refSpace
=
None
,
srcToRefMat
=
None
,
**
kwargs
):
"""
Create a ``NonLinearTransform``.
:arg image: A string containing the name of an image file to
load,
or a :mod:`numpy` array, or a :mod:`nibabel`
image
object.
:arg image:
A string containing the name of an image file to
load,
or a :mod:`numpy` array, or a :mod:`nibabel`
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
``NonLinearTransform`` maps to. Defaults to ``
'
fsl
'
``.
:arg srcSpace: Coordinate system in the source image that this
``NonLinearTransform`` maps to. Defaults to
``
'
fsl
'
``.
:arg refSpace: Coordinate system in the reference image that this
``NonLinearTransform`` maps from. Defaults to ``
'
fsl
'
``.
:arg refSpace: Coordinate system in the reference image that this
``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__`.
"""
if
srcSpace
is
None
:
srcSpace
=
'
fsl
'
if
refSpace
is
None
:
refSpace
=
'
fsl
'
if
srcSpace
is
None
:
srcSpace
=
'
fsl
'
if
refSpace
is
None
:
refSpace
=
'
fsl
'
if
srcToRefMat
is
not
None
:
srcToRefMat
=
np
.
copy
(
srcToRefMat
)
if
srcSpace
not
in
(
'
fsl
'
,
'
voxel
'
,
'
world
'
)
or
\
refSpace
not
in
(
'
fsl
'
,
'
voxel
'
,
'
world
'
):
...
...
@@ -92,10 +115,15 @@ class NonLinearTransform(fslimage.Image):
fslimage
.
Image
.
__init__
(
self
,
image
,
**
kwargs
)
self
.
__src
=
fslimage
.
Nifti
(
src
.
header
.
copy
())
self
.
__ref
=
fslimage
.
Nifti
(
ref
.
header
.
copy
())
self
.
__srcSpace
=
srcSpace
self
.
__refSpace
=
refSpace
self
.
__src
=
fslimage
.
Nifti
(
src
.
header
.
copy
())
self
.
__ref
=
fslimage
.
Nifti
(
ref
.
header
.
copy
())
self
.
__srcSpace
=
srcSpace
self
.
__refSpace
=
refSpace
self
.
__srcToRefMat
=
srcToRefMat
self
.
__refToSrcMat
=
None
if
srcToRefMat
is
not
None
:
self
.
__refToSrcMat
=
affine
.
invert
(
srcToRefMat
)
@property
...
...
@@ -130,6 +158,22 @@ class NonLinearTransform(fslimage.Image):
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
):
"""
Transform coordinates from the reference image space to the source
image space. Implemented by sub-classes.
...
...
@@ -254,11 +298,18 @@ class DisplacementField(NonLinearTransform):
if
self
.
absolute
:
disps
=
self
.
data
[
xs
,
ys
,
zs
,
:]
else
:
disps
=
self
.
data
[
xs
,
ys
,
zs
,
:]
+
coords
[
voxmask
]
# Make sure the coordinates
# are in the requested
# source image space
# Make sure the coordinates are
# in the requested source image
# space, and apply the initial
# inv(srcToRefMat) if it there
# is one
postmat
=
self
.
refToSrcMat
if
to
!=
self
.
srcSpace
:
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
)
# Nans for input coordinates
...
...
@@ -276,16 +327,6 @@ class CoefficientField(NonLinearTransform):
The :meth:`displacements` method can be used to calculate relative
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):
refSpace
,
fieldType
,
knotSpacing
,
srcToRefMat
,
fieldToRefMat
,
**
kwargs
):
"""
Create a ``CoefficientField``.
...
...
@@ -307,13 +347,6 @@ class CoefficientField(NonLinearTransform):
:arg knotSpacing: A tuple containing the spline knot spacings along
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
image voxel coordinates into coefficient field
voxel coordinates.
...
...
@@ -335,7 +368,6 @@ class CoefficientField(NonLinearTransform):
self
.
__fieldType
=
fieldType
self
.
__knotSpacing
=
tuple
(
knotSpacing
)
self
.
__srcToRefMat
=
np
.
copy
(
srcToRefMat
)
self
.
__fieldToRefMat
=
np
.
copy
(
fieldToRefMat
)
self
.
__refToFieldMat
=
affine
.
invert
(
self
.
__fieldToRefMat
)
...
...
@@ -348,14 +380,6 @@ class CoefficientField(NonLinearTransform):
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
def
knotSpacing
(
self
):
"""
Return a tuple containing spline knot spacings along the x, y, and
...
...
@@ -688,20 +712,19 @@ def coefficientFieldToDisplacementField(field,
# Apply the premat if requested -
# this will transform the coordinates
# 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
# that fnirtfileutils does - applying
# the inverse affine to every ref space
# voxel coordinate, then adding it to
# the existing displacements.
shape
=
disps
.
shape
disps
=
disps
.
reshape
(
-
1
,
3
)
refToSrc
=
affine
.
invert
(
field
.
srcToRefMat
)
premat
=
affine
.
concat
(
refToSrc
-
np
.
eye
(
4
),
field
.
ref
.
getAffine
(
'
voxel
'
,
'
fsl
'
))
disps
=
disps
+
affine
.
transform
(
xyz
,
premat
)
disps
=
disps
.
reshape
(
shape
)
shape
=
disps
.
shape
disps
=
disps
.
reshape
(
-
1
,
3
)
premat
=
affine
.
concat
(
field
.
refToSrcMat
-
np
.
eye
(
4
),
field
.
ref
.
getAffine
(
'
voxel
'
,
'
fsl
'
))
disps
=
disps
+
affine
.
transform
(
xyz
,
premat
)
disps
=
disps
.
reshape
(
shape
)
# note that convertwarp applies a premat
# 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