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
Model registry
Operate
Environments
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
FSL
fslpy
Commits
9d5c986e
Commit
9d5c986e
authored
6 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Plain Diff
Merge branch 'rf/resample_$d' into 'master'
Rf/resample $d See merge request fsl/fslpy!86
parents
16496d1d
9b9d4460
No related branches found
No related tags found
No related merge requests found
Pipeline
#2959
canceled
6 years ago
Stage: test
Stage: style
Stage: doc
Stage: deploy
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
CHANGELOG.rst
+3
-0
3 additions, 0 deletions
CHANGELOG.rst
fsl/data/image.py
+9
-8
9 additions, 8 deletions
fsl/data/image.py
fsl/data/imagewrapper.py
+8
-1
8 additions, 1 deletion
fsl/data/imagewrapper.py
tests/test_image.py
+40
-2
40 additions, 2 deletions
tests/test_image.py
with
60 additions
and
11 deletions
CHANGELOG.rst
+
3
−
0
View file @
9d5c986e
...
@@ -21,6 +21,8 @@ Changed
...
@@ -21,6 +21,8 @@ Changed
* Minimum required version of ``nibabel`` is now 2.3.
* Minimum required version of ``nibabel`` is now 2.3.
* The :class:`.Image` class now fully delegates to ``nibabel`` for managing
* The :class:`.Image` class now fully delegates to ``nibabel`` for managing
file handles.
file handles.
* The :meth:`.Image.resample` method now supports images with more than three
dimensions.
Removed
Removed
...
@@ -38,6 +40,7 @@ Fixed
...
@@ -38,6 +40,7 @@ Fixed
* Make sure that FEAT ``Cluster`` objects (created by the
* Make sure that FEAT ``Cluster`` objects (created by the
:func:`.loadClusterResults` function) contain ``p`` and ``logp`` attributes,
:func:`.loadClusterResults` function) contain ``p`` and ``logp`` attributes,
even when cluster thresholding was not used.
even when cluster thresholding was not used.
* Fix to the :class:`.ImageWrapper` regarding complex data types.
1.13.0 (Thursday 22nd November 2018)
1.13.0 (Thursday 22nd November 2018)
...
...
This diff is collapsed.
Click to expand it.
fsl/data/image.py
+
9
−
8
View file @
9d5c986e
...
@@ -1173,7 +1173,7 @@ class Image(Nifti):
...
@@ -1173,7 +1173,7 @@ class Image(Nifti):
order
=
1
,
order
=
1
,
smooth
=
True
):
smooth
=
True
):
"""
Returns a copy of the data in this ``Image``, resampled to the
"""
Returns a copy of the data in this ``Image``, resampled to the
specified ``
s
hape``.
specified ``
newS
hape``.
:arg newShape: Desired shape. May containg floating point values,
:arg newShape: Desired shape. May containg floating point values,
in which case the resampled image will have shape
in which case the resampled image will have shape
...
@@ -1182,7 +1182,7 @@ class Image(Nifti):
...
@@ -1182,7 +1182,7 @@ class Image(Nifti):
:arg sliceobj: Slice into this ``Image``. If ``None``, the whole
:arg sliceobj: Slice into this ``Image``. If ``None``, the whole
image is resampled, and it is assumed that it has the
image is resampled, and it is assumed that it has the
same number of dimensions as ``
s
hape``. A
same number of dimensions as ``
newS
hape``. A
:exc:`ValueError` is raised if this is not the case.
:exc:`ValueError` is raised if this is not the case.
:arg dtype: ``numpy`` data type of the resampled data. If ``None``,
:arg dtype: ``numpy`` data type of the resampled data. If ``None``,
...
@@ -1201,12 +1201,12 @@ class Image(Nifti):
...
@@ -1201,12 +1201,12 @@ class Image(Nifti):
:returns: A tuple containing:
:returns: A tuple containing:
- A ``numpy`` array of shape ``
s
hape``, containing
an
- A ``numpy`` array of shape ``
newS
hape``, containing
interpolated copy of the data in this ``Image``.
an
interpolated copy of the data in this ``Image``.
- A ``numpy`` array of shape ``(4, 4)``, containing the
- A ``numpy`` array of shape ``(4, 4)``, containing the
adjusted voxel-to-world transformation for the
resampled
adjusted voxel-to-world transformation for the
spatial
data.
dimensions of the resampled
data.
"""
"""
if
sliceobj
is
None
:
sliceobj
=
slice
(
None
)
if
sliceobj
is
None
:
sliceobj
=
slice
(
None
)
...
@@ -1225,7 +1225,7 @@ class Image(Nifti):
...
@@ -1225,7 +1225,7 @@ class Image(Nifti):
ratio
=
oldShape
/
newShape
ratio
=
oldShape
/
newShape
newShape
=
np
.
array
(
np
.
round
(
newShape
),
dtype
=
np
.
int
)
newShape
=
np
.
array
(
np
.
round
(
newShape
),
dtype
=
np
.
int
)
scale
=
transform
.
scaleOffsetXform
(
ratio
,
0
)
scale
=
np
.
diag
(
ratio
)
# If interpolating and smoothing, we apply a
# If interpolating and smoothing, we apply a
# gaussian filter along axes with a resampling
# gaussian filter along axes with a resampling
...
@@ -1242,7 +1242,7 @@ class Image(Nifti):
...
@@ -1242,7 +1242,7 @@ class Image(Nifti):
data
=
ndimage
.
gaussian_filter
(
data
,
sigma
)
data
=
ndimage
.
gaussian_filter
(
data
,
sigma
)
data
=
ndimage
.
affine_transform
(
data
,
data
=
ndimage
.
affine_transform
(
data
,
scale
[:
3
,
:
3
]
,
scale
,
output_shape
=
newShape
,
output_shape
=
newShape
,
order
=
order
)
order
=
order
)
...
@@ -1250,6 +1250,7 @@ class Image(Nifti):
...
@@ -1250,6 +1250,7 @@ class Image(Nifti):
# puts the resampled image into the
# puts the resampled image into the
# same world coordinate system as this
# same world coordinate system as this
# image.
# image.
scale
=
transform
.
scaleOffsetXform
(
ratio
[:
3
],
0
)
xform
=
transform
.
concat
(
self
.
voxToWorldMat
,
scale
)
xform
=
transform
.
concat
(
self
.
voxToWorldMat
,
scale
)
else
:
else
:
xform
=
self
.
voxToWorldMat
xform
=
self
.
voxToWorldMat
...
...
This diff is collapsed.
Click to expand it.
fsl/data/imagewrapper.py
+
8
−
1
View file @
9d5c986e
...
@@ -301,7 +301,14 @@ class ImageWrapper(notifier.Notifier):
...
@@ -301,7 +301,14 @@ class ImageWrapper(notifier.Notifier):
# Internally, we calculate and store the
# Internally, we calculate and store the
# data range for each volume/slice/vector
# data range for each volume/slice/vector
self
.
__volRanges
=
np
.
zeros
((
nvols
,
2
),
dtype
=
np
.
float32
)
#
# We use nan as a placeholder, so the
# dtype must be non-integral
dtype
=
self
.
__image
.
get_data_dtype
()
if
np
.
issubdtype
(
dtype
,
np
.
integer
):
dtype
=
np
.
float32
self
.
__volRanges
=
np
.
zeros
((
nvols
,
2
),
dtype
=
dtype
)
self
.
__coverage
[
:]
=
np
.
nan
self
.
__coverage
[
:]
=
np
.
nan
self
.
__volRanges
[:]
=
np
.
nan
self
.
__volRanges
[:]
=
np
.
nan
...
...
This diff is collapsed.
Click to expand it.
tests/test_image.py
+
40
−
2
View file @
9d5c986e
...
@@ -1078,6 +1078,12 @@ def test_image_resample(seed):
...
@@ -1078,6 +1078,12 @@ def test_image_resample(seed):
make_random_image
(
fname
,
shape
)
make_random_image
(
fname
,
shape
)
img
=
fslimage
.
Image
(
fname
,
mmap
=
False
)
img
=
fslimage
.
Image
(
fname
,
mmap
=
False
)
# bad shape
with
pytest
.
raises
(
ValueError
):
img
.
resample
((
10
,
10
))
with
pytest
.
raises
(
ValueError
):
img
.
resample
((
10
,
10
,
10
,
10
))
# resampling to the same shape should be a no-op
# resampling to the same shape should be a no-op
samei
,
samex
=
img
.
resample
(
shape
)
samei
,
samex
=
img
.
resample
(
shape
)
assert
np
.
all
(
samei
==
img
[:])
assert
np
.
all
(
samei
==
img
[:])
...
@@ -1134,18 +1140,50 @@ def test_image_resample(seed):
...
@@ -1134,18 +1140,50 @@ def test_image_resample(seed):
assert
np
.
all
(
np
.
isclose
(
resvals
,
origvals
))
assert
np
.
all
(
np
.
isclose
(
resvals
,
origvals
))
# Test a 4D image
del
img
img
=
None
def
test_image_resample_4d
(
seed
):
fname
=
'
test.nii.gz
'
with
tempdir
():
make_random_image
(
fname
,
(
10
,
10
,
10
,
10
))
make_random_image
(
fname
,
(
10
,
10
,
10
,
10
))
# resample one volume
img
=
fslimage
.
Image
(
fname
)
img
=
fslimage
.
Image
(
fname
)
slc
=
(
slice
(
None
),
slice
(
None
),
slice
(
None
),
3
)
slc
=
(
slice
(
None
),
slice
(
None
),
slice
(
None
),
3
)
resampled
=
img
.
resample
(
img
.
shape
[:
3
],
slc
)[
0
]
resampled
=
img
.
resample
(
img
.
shape
[:
3
],
slc
)[
0
]
assert
np
.
all
(
resampled
==
img
[...,
3
])
assert
np
.
all
(
resampled
==
img
[...,
3
])
# resample up
resampled
=
img
.
resample
((
15
,
15
,
15
),
slc
)[
0
]
resampled
=
img
.
resample
((
15
,
15
,
15
),
slc
)[
0
]
assert
tuple
(
resampled
.
shape
)
==
(
15
,
15
,
15
)
assert
tuple
(
resampled
.
shape
)
==
(
15
,
15
,
15
)
# resample down
resampled
=
img
.
resample
((
5
,
5
,
5
),
slc
)[
0
]
assert
tuple
(
resampled
.
shape
)
==
(
5
,
5
,
5
)
# resample the entire image
resampled
=
img
.
resample
((
15
,
15
,
15
,
10
),
None
)[
0
]
assert
tuple
(
resampled
.
shape
)
==
(
15
,
15
,
15
,
10
)
resampled
=
img
.
resample
((
5
,
5
,
5
,
10
),
None
)[
0
]
assert
tuple
(
resampled
.
shape
)
==
(
5
,
5
,
5
,
10
)
# resample along the fourth dim
resampled
=
img
.
resample
((
15
,
15
,
15
,
15
),
None
)[
0
]
assert
tuple
(
resampled
.
shape
)
==
(
15
,
15
,
15
,
15
)
resampled
=
img
.
resample
((
5
,
5
,
5
,
15
),
None
)[
0
]
assert
tuple
(
resampled
.
shape
)
==
(
5
,
5
,
5
,
15
)
del
img
del
img
del
resampled
img
=
None
img
=
None
resampled
=
None
def
test_Image_init_xform_nifti1
():
_test_Image_init_xform
(
1
)
def
test_Image_init_xform_nifti1
():
_test_Image_init_xform
(
1
)
...
...
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