fslsplit
, fslmerge
and fslroi
(for breaking apart images, putting them back
together and extracting ROIs). cd ~/fsl_course_data/intro
These tools enable various properties of an image to be viewed.
Type fslinfo sub-002_T1w_brain
and fslinfo thresh_zstat1
and note their different
image matrix dimensions (dim1-3) and voxel sizes, in mm (pixdim1-3).
Note that some images (sub-002_T1w_brain
) are of integer
datatype, while others (thresh_zstat1
) are of floating
point datatype. Integer means that the intensity values can only take on
whole numbers - no fractions - raw image data is normally of this
type. Floating point means that intensity values can be fractional - the
result of applying most statistical processing algorithms to image data
results in images of floating point type.
Also try running fslhd
on these files. This
provides much more detailed information about the images. Don't worry if you
don't know what every field means.
fslstats
is a general tool for calculating various
values/statistics from the image intensities. It is quite flexible but we
will just illustrate some basic uses here. Type
fslstats
to see the full list of possible
options and brief description of the output. Any combination and order of
options is possible.
Run
fslstats sub-002_T1w_brain -R -r
The first pair of numbers (specified by -R
) is the absolute
range of the data - i.e., the min and max intensities. The second pair
(-r
) is the "robust range" - i.e. the min and max if
the outer tails of the intensity distribution are ignored (this is useful if
the data contains outliers). View the image histogram in FSLeyes to see how
all these numbers relate to the histogram.
Slightly confusingly, the robust range doesn't seem to be doing the same
thing for the left and right tails. This is because there are lots of empty
voxels in the image (because the data has been brain-extracted) that are
affecting the calculation. Click on the spanner button
() on the histogram toolbar, expand
the Histogram settings for selected overlay section, un-check the
Ignore zeros setting, and enter
-1
for the minimum
Data range bound. See how the histogram is affected.
Run:
fslstats sub-002_T1w_brain -m -M
The first number is the mean intensity of all voxels in image, whilst the second is the mean of only the non-zero voxels. The first is much lower because of all the zero background voxels dragging down the mean. The second number is a more meaningful mean of the actual within-brain intensities - view the image and click around inside the brain to see this.
fslmaths
is a very general image calculator and can be used to
perform a great variety of manipulations of images. See the (long) usage by
just typing fslmaths
. Don't worry about
understanding it all at this point, we will illustrate some basic uses here,
but be aware that it is a very general and powerful tool that is worth getting
to know.
As a very simple example, we will find the difference between two consecutive timepoint images (the images are extracted from a functional dataset, and this difference calculation might be used as part of a quality assessment). Do this by running:
fslmaths image0 -sub image1 imdiff
and view the output (the final argument in that command) in FSLeyes. Now calculate this as a percent difference image by running:
fslmaths imdiff -div image0 -mul 100 imdiffpercent
This means: "take the difference image, divide by the first of the
original images (voxelwise), multiply by 100, and output". View the
output in FSLeyes, and then use fslstats
to calculate its
absolute and robust range - see that the robust range is quite small, with
most change showing up as motion effects round the edge of the brain.
Make sure that you understand the fslmaths
commands above;
and note that in general an "input" can be a number instead of an
image (the "100
" could have been an image name
instead). This does not apply to the first input in the command!
Now let's consider another example where we need both
fslmaths
and fslstats
. In this example we will take
a probabilistic ROI of the left Thalamus (already transformed from a
standard-space atlas) and quantify some characteristics of the thresholded
fMRI activations that we viewed earlier. This will involve making an
appropriate binary mask and then using this with fslstats
.
If you view the image LThal_mask_func
in FSLeyes (best if
loaded on top of the example_func
image) you will see that it
contains values between 0 and 1, representing the probability that each voxel
is part of the thalamus. To use this as a mask it is necessary to turn it
into a binary image (where each voxel contains either 0 or 1 but no numbers in
between). This requires choosing a threshold value and then applying this in
fslmaths
to make a binary image. Let us choose 0.5 (i.e. 50%
probability) as the threshold, and apply it with this command:
fslmaths LThal_mask_func -thr 0.5 -bin LThal_mask_func_bin
We can now use this mask with fslstats
to extract the size of
the ROI, the size of the overlap with the thresholded statistic map and the
average value of the statistics within this ROI. These can be calculated with
the following commands:
fslstats LThal_mask_func_bin -V fslstats thresh_zstat1 -k LThal_mask_func_bin -V fslstats thresh_zstat1 -k LThal_mask_func_bin -M
See if you understand what each command does and what the output means. If
not, look at the usage for fslstats
, by typing it on
its own at the command line and pressing return. If it still isn't clear then
ask one of the tutors.
Note that in the last command the -M
option was used (as
opposed to -m
) to ensure that the average is only within the area
where the thresholded stats are non-zero inside the ROI.
Becoming familiar with fslmaths
and fslstats
can
save you a huge amount of time when you want to carry out simple image
manipulations quickly. Also, if you want to carry out simple things many
times, you can easily put these commands into small scripts (text files that
contain the same commands that you might type in the terminal). We cannot
emphasise strongly enough how useful it can be to learn these basic
command-line programs, and also basic scripting. (Unfortunately you will
probably not have time during the course to go through the scripting practical
- there's just too much stuff to fit in! - but we do recommend that you have a
look at it after the course, at least the first few basic sections).
The following exercises are intending to teach you how to use the
tools fslsplit
, fslmerge
and fslroi
.
The examples represent some situations that can be encountered in practice,
but the scope of these tools goes way beyond these specific examples.
Familiarity with these basic tools can help in getting data into the right
format for analysis, in case it is not that way to begin with (which is more
common than you might think) or give you ways of looking at original or
processed data in different ways.
In this example we will look at a way of separating a diffusion sequence
into diffusion-weighted and non-diffusion-weighted parts. To start with,
check how many timepoints there are in the diffusion-weighted
acquisition sub-003_dwi
using fslinfo
and then run:
fslsplit sub-003_dwi
to split up the 4D input image into its individual 3D images, or volumes,
(vol0000, vol0001, vol0002,
etc.). To list these new files
do:
ls vol*
(note that the *
is expanded by the terminal to fit any
characters in all possible filenames present, and so can be used in any
commands, not just ls
, as we will see below). You'll see that the
counting of the images starts with 0, and that the number of images should
match the number of timepoints in the original 4D image.
In this diffusion sequence, as in most, there are several
non-diffusion-weighted scans (the "b=0" scans) which show up as very
bright in the diffusion sequence (try viewing diffdata
in the
movie mode of FSLeyes). So we will separate this data into two 4D images: one
containing just non-diffusion-weighted scans and one containing the
diffusion-weighted scans. This is not always necessary for analysis of
diffusion data, but can be helpful for visualisation of input and processed
data.
In this sequence there are 4 non-diffusion scans: numbers 0, 16, 32 and 48,
with the counting starting at zero, just like in FSLeyes and consistent with
how fslsplit
numbers things. These numbers could be found from
the bvals
file, or by looking at the data in FSLeyes, but here we
are giving them to you.
The easiest way to separate the two sets is just to rename the
non-diffusion volumes, using the UNIX mv
command like this:
mv vol0000.nii.gz b0vol0000.nii.gz
and doing the equivalent for vol0016.nii.gz, vol0032.nii.gz
and vol0048.nii.gz
. Note that because mv
is not a
specific FSL command it is absolutely essential to include
the .nii.gz
part of the filenames (whereas for FSL commands it
doesn't matter if these are included or left out).
Check that these files have been renamed correctly by looking at the
directory contents using ls
. Now remerge the remaining
diffusion-weighted 3D images into a new 4D image with:
fslmerge -t sub-003_dwi_diff vol*
The -t
tells fslmerge
to merge the images
in time (fslmerge
is also capable of doing other merges,
such as stacking them on top of each other in space). After
"sub-003_dwi_diff
" (the name of the output
image), fslmerge
expects a list of images to be merged.
As mentioned above, for all FSL commands the image names can be used
with or without including the filetype extension (extensions
are .nii.gz .hdr .img
etc.).
View the resulting image in FSLeyes using the movie loop and check that the non-diffusion-weighted scans not part of this new 4D image. See how much easier it is to visualise the data this way.
The non-diffusion scans can also be merged into a single 4D image using:
fslmerge -t sub-003_dwi_b0 b0vol*
We will now fix an image that is "wrapped", with the nose sitting behind the back of the head, as you sometimes see in poorly planned acquisitions ...
fsleyes sub-004_T1w_wrapped &
You will use fslroi
to split this image into two (front and
back parts) and fslmerge
to remerge them back together in the
right order. In FSLeyes, look at an inferior (bottom) axial slice so that you
can work out the y coordinate (in the anterior-posterior direction) where you
want to make the split. Record the y-coordinate (in voxels, not mm).
Now use fslinfo
to find out what the image matrix dimensions
are (dim1,dim2,dim3)
. You're now ready to extract the back part
of the head into a temporary file. If your y-coordinate was 76 you would do:
fslroi sub-004_T1w_wrapped sub-004_T1w_back 0 256 76 180 0 128
Now just type fslroi
to see the usage. There are
several ways to run fslroi
: you can specify just a 3D ROI, as we
have done here - this is the first of the usage possibilities. The second
option is to extract a temporal ROI from a 4D dataset (one or more full 3D
volumes). The final option extracts a 4D ROI from a 4D dataset, controlling
the region to be extracted in space and time. The program knows which
option you want from the number of "arguments" that you type. Note
that if you use the first option (3D ROI) on a 4D input file, the output will
still be 4D, with the number of timepoints unchanged, and each volume cut down
in 3D in the same way, as specified by the arguments.
Make sure that you understand the exact numbers used in the above command,
that created the sub-004_T1w_back
image; note in particular that the second
number in each pair is the length of the ROI in the relevant
dimension, not the end point - the <ysize>
was 180
(256-76) not 256.
Now work out how to run a similar command to create
"sub-004_T1w_front
", from the back part of sub-004_T1w_wrapped
.
Use fslmerge
to merge front
and
back
together correctly, and verify with FSLeyes. You
could also do a similar thing with the slight wraparound at the top of
the image.
As a last example, we will use fslstats
to determine an ROI to
use with fslroi
. To do this run:
fslstats sub-002_T1w_brain -w
which will generate a set of numbers suitable for fslroi
.
This ROI is the smallest ROI possible that fully contains all non-zero voxels.
We could now run fslroi
using these numbers, but instead we'll
combine the two commands into one, using the unix trick of putting a command
within `
quote marks (this is the backquote, not the usual
forward quote!). When you put a command within these quote marks then this
part of a larger command will get replaced by the text output of the command
within quotes. We will cut down sub-002_T1w_brain
so that the image just
about contains the brain, and the end slices that only contain zeros are
thrown away. Run the following, and then try to understand how it works:.
fslroi sub-002_T1w_brain sub-002_T1w_brain_roi `fslstats sub-002_T1w_brain -w`
\
") in the fsleyes
command here
allows you to split a long command across multiple lines to make it easier
to read.
You can see what fslroi has done by overlaying the two images in FSLeyes:
fsleyes sub-002_T1w_brain -cm red-yellow -dr -1 16000 \ sub-002_T1w_brain_roi -cm blue-lightblue -dr -1 16000
The End.