fsleyes_render.md 13.5 KB
Newer Older
Saad Jbabdi's avatar
Saad Jbabdi committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Creating figures and movies with FSLeyes

You may be familiar with using FSLeyes for looking at your data. Perhaps you have taken screenshots and pasted those into a talk or a paper. Here we will learn how to script such things and ask FSLeyes to create complex figures directly from the command line. 

This has several advantages. For example, you can re-create the same or similar figures simply by editing the script, instead of re-doing all the FSLeyes tinkering. It is also useful if you need to create complex figures for many datasets/subjects.


## Content

* [Using FSLeyes render to create a PNG](#create-png)
* [Creating a movie for a talk with FSLeyes and ImageMagick](#create-movie)
* [Creating a figure for a paper](#create-for-paper)


<a class="anchor" id="create-png"></a>
## Using fsleyes render

The first thing we will learn is how to generate a complex command line for FSLeyes. 

Everything you can set manually by clicking on the FSLeyes graphical interface can be reproduced through the command line. You can learn all about the command line arguments by reading the [documentation](https://open.win.ox.ac.uk/pages/fsl/fsleyes/fsleyes/userdoc/command_line.html) or looking at the FSLeyes full help (`fsleyes -fh`). 

Here we will instead cheat and use the lazy approach. We will first use the graphical interface to produce a nice looking image. Then we will generate a full command line in FSLeyes and use that as the basis for creating more similar figures.

### Creating an examplar
Start by opening FSLeyes. The command below also loads a MNI brain (copy this onto a Terminal shell):

Saad Jbabdi's avatar
Saad Jbabdi committed
27
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
28
29
30
31
32
33
34
35
fsleyes -std1mm &
```


Let's make this brain look funkier. Start by toggling off the sagittal and coronal views. We only want to see the axial view. 

Next, toggle off the location cursor. You should now see this:

Saad Jbabdi's avatar
Saad Jbabdi committed
36
37
<img src="data/snapshot1.png" alt="snapshot1" style="width:400px;"/>

Saad Jbabdi's avatar
Saad Jbabdi committed
38
39
40
41
42
43
44
45
46
47
48

Now change the colormap to "Cool" (of course), and open the Overlay display panel (cogwheel at the top left). Then follow these steps (or do your own prittification):

- Change interpolation to "Spline interpolation"
- Change the colourmap resolution from 256 to 7
- Change the Display range to min=1000 and max=8000

Close the display panel and open the View settings (spanner below cogwheel), then change the background color to be white. 

If you did the above you should now see:

Saad Jbabdi's avatar
Saad Jbabdi committed
49
<img src="data/snapshot2.png" alt="snapshot2" style="width:400px;"/>
Saad Jbabdi's avatar
Saad Jbabdi committed
50
51
52
53


Now wouldn't it be nice if one could generate the same thing from scratch without going through the above steps by hand? Here is how you do it:  

Saad Jbabdi's avatar
Saad Jbabdi committed
54
**Settings -> Ortho View 1 -> Show command line for scene**
Saad Jbabdi's avatar
Saad Jbabdi committed
55
56
57

You can even click on copy to clipboard. Do that, then open a new text file (e.g. with emacs) and paste the result into the text file. The command you get looks very long so I am highlighting in <span style="color:blue">blue</span> the bit about the scene and in <span style="color:red">red</span> the bit about the overlay. 

Saad Jbabdi's avatar
Saad Jbabdi committed
58

Saad Jbabdi's avatar
Saad Jbabdi committed
59
----
60
<img src="data/snapshot7.png" alt="snapshot7" style="width:800px;"/>
Saad Jbabdi's avatar
Saad Jbabdi committed
61

62
<!--- <code>fsleyes <span style="color:blue">--scene ortho --worldLoc -0.49994659423828125 -17.50005340576172 18.49994659423828 --displaySpace /usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz --xcentre  0.00000  0.00000 --ycentre  0.00000  0.00000 --zcentre  0.00000  0.00000 --xzoom 100.0 --yzoom 100.0 --zzoom 100.0 --hideLabels --layout horizontal --hidex --hidey --hideCursor --bgColour 1.0 1.0 1.0 --fgColour 0.0 0.0 0.0 --cursorColour 0.0 1.0 0.0 --colourBarLocation top --colourBarLabelSide top-left --colourBarSize 100.0 --labelSize 12 --performance 3 --movieSync </span> /usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz <span style="color:red">--name "MNI152_T1_1mm" --overlayType volume --alpha 100.0 --brightness 52.4977497749775 --contrast 64.99649964996499 --cmap cool --negativeCmap greyscale --displayRange 1000.0 8000.0 --clippingRange 1000.0 10098.99 --modulateRange 0.0 9999.0 --gamma 0.0 --cmapResolution 7 --interpolation spline --numSteps 100 --blendFactor 0.1 --smoothing 0 --resolution 100 --numInnerSteps 10 --clipMode intersection --volume 0</code> --->
Saad Jbabdi's avatar
Saad Jbabdi committed
63

Saad Jbabdi's avatar
Saad Jbabdi committed
64
----
Saad Jbabdi's avatar
Saad Jbabdi committed
65
66
67
68
69

If you run it all in a Terminal it will open FSLeyes and set it up to look like the above screenshot. Try that!

Now as I said the command line is long and contains many things that are default behaviour anyway. So let's strip it down a little bit as it will make this document shorter. In the below, I am only keeping a subset of the options, but I did not add new ones:

Saad Jbabdi's avatar
Saad Jbabdi committed
70
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
fsleyes --scene ortho --hideLabels --layout horizontal --hidex --hidey --hideCursor --bgColour 1.0 1.0 1.0 --fgColour 0.0 0.0 0.0 /usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz --overlayType volume --cmap cool --displayRange 1000.0 8000.0 --cmapResolution 7 --interpolation spline 

```

> Check that the above command generates the same view by running it in a terminal!

### Rendering

Instead of opening FSLeyes, wee want to create an image (a PNG for example) to use in a presentation. This can be done very simply by using the above command and adding a render flag to fsleyes:

```
fsleyes render -outputfile my_image.png <rest of the command>
```

Run the above code (make sure you replace `<rest of the command>` with the rest of the FSLeyes command we created earlier). This should now output a PNG file. Have a look at it!

> Exercise: Do the same as above but instead of rendering an axial view of the MNI brain, try to render a 3D view. Make it look nice before you render.

<a class="anchor" id="create-movie"></a>
## Creating a movie

Here we will create a movie of the MNI brain scrolling through z-slices. We'll also add a bit of text showing the slice number for good measure. The result will look like this:

<img src="data/snapshot3.gif" alt="snapshot3" style="width:400px;"/>

First, make sure that you have ImageMagick installed. To do that, go to your terminal and run thee command `convert`. If you get a long help for the convert command you are good to go. Otherwise install ImageMagick from [here](https://imagemagick.org/script/download.php).

We will re-use the previous render command. Start by copying that into a text editor. You can use the code below:

Saad Jbabdi's avatar
Saad Jbabdi committed
100
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
101
102
103
104
105
fsleyes render --outfile my_image.png --scene ortho --hideLabels --layout horizontal --hidex --hidey --hideCursor --bgColour 1.0 1.0 1.0 --fgColour 0.0 0.0 0.0 /usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz --overlayType volume --cmap cool --displayRange 1000.0 8000.0 --cmapResolution 7 --interpolation spline 
```

Now to change the z-location, we will use the `-voxelLoc` flag. We will also use a FOR loop to change the location, and store a different PNG at each step. Here is what the code will look like (copy it onto your text editor):

Saad Jbabdi's avatar
Saad Jbabdi committed
106
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
107
108
109
110
111
112
rest_of_command="--scene ortho --hideLabels --layout horizontal --hidex --hidey --hideCursor --bgColour 1.0 1.0 1.0 --fgColour 0.0 0.0 0.0 /usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz --overlayType volume --cmap cool --displayRange 1000.0 8000.0 --cmapResolution 7 --interpolation spline"


mkdir -p my_folder
for ((z=0;z<=181;z+=4));do
    zzz=`$FSLDIR/bin/zeropad $z 3`
Saad Jbabdi's avatar
Saad Jbabdi committed
113
    echo "Slice $zzz"
Saad Jbabdi's avatar
Saad Jbabdi committed
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    
    out=my_folder/image_${zzz}.png
    fsleyes render --outfile $out  --voxelLoc 91 109 $z $rest_of_command
done
```

Examine the above script line by line. We first create a variable called `rest_of_command` containing all the extra stuff for display that does not change in the FOR loop.

We then use a FOR loop, where we go through every fourth z-slice (can you see that?). We create a variable called `zzz` inside the loop. This is to use for naming the output PNG files so that they are listed in the same order as the z-slices (e.g. instead of image_1.png we have image_001.png). 

Run this script and you should see that many PNGs will get created, one per slice.

Now to combine all these PNGs into a single GIF, run the below ImageMagick command:

Saad Jbabdi's avatar
Saad Jbabdi committed
128
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
129
130
131
132
133
134
135
convert -delay 1 my_folder/image_???.png -loop 0 my_movie.gif
```

Have a look at the GIF. On a mac you can simply use the space bar on your keyboard to preview the GIF. 

It is still missing the changing text. We will also use ImageMagick for this. Below is the same script as before but with the addition of a call to `convert` that adds the text:

Saad Jbabdi's avatar
Saad Jbabdi committed
136
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
137
138
139
140
141
142
rest_of_command="--scene ortho --hideLabels --layout horizontal --hidex --hidey --hideCursor --bgColour 1.0 1.0 1.0 --fgColour 0.0 0.0 0.0 /usr/local/fsl/data/standard/MNI152_T1_1mm.nii.gz --overlayType volume --cmap cool --displayRange 1000.0 8000.0 --cmapResolution 7 --interpolation spline"


mkdir -p my_folder
for ((z=0;z<=181;z+=4));do
    zzz=`$FSLDIR/bin/zeropad $z 3`
Saad Jbabdi's avatar
Saad Jbabdi committed
143
    echo "Slice $zzz"
Saad Jbabdi's avatar
Saad Jbabdi committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    
    out=my_folder/image_${zzz}.png
    fsleyes render --outfile $out  --voxelLoc 91 109 $z $rest_of_command
    
    # Bit that adds annotation to the image
    out_annot=my_folder/image_annot_${zzz}.png
    convert $out \
            -gravity NorthWest  -pointsize 50 \
            -fill black -annotate 1 "`echo Z = $z`" $out_annot

done
```

Now run the above, then run the below to make the final GIF:

Saad Jbabdi's avatar
Saad Jbabdi committed
159
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
160
161
162
163
164
165
166
167
168
169
170
171
convert -delay 1 my_folder/image_annot_???.png -loop 0 my_annotated_movie.gif
```

> Exercise: Create a similar movie which scrolls through every 6th Sagittal slice


### Scalped pacman

The video that we have just created is nice. But wouldn't it be even better if we could create a scalped pacman?

Open a new session of FSLeyes with a 2mm standard brain, this time directly in 3D mode:

Saad Jbabdi's avatar
Saad Jbabdi committed
172
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
173
174
175
176
177
178
179
180
181
182
183
184
185
186
fsleyes -std --scene 3d &
```

Ok I now that looks a little scary. Let's make the following changes. Open the overlay display panel (Settings->3D View 1->Overlay display panel) and:

- Change the colourmap to Yellow
- Change the display range to min=1000, max=5000
- Turn the brain upside down 
- Add two clipping planes

Copy the command line that creates this scene as we have done before (Settings->3D View 1->Show command line for scence).

Now we are going to create a FOR loop where we will change the angles of the clipping planes and save each angle in a separate PNG files. We will then combine them into a single GIF. In the code below, you can find the FOR loop, all that is missing is the command line fsleyes that you have copied to the clipboard:

Saad Jbabdi's avatar
Saad Jbabdi committed
187
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
188
189
190
191
192
193
194
195
196
197
198
199
200
outputfolder=my_pacman
mkdir -p $outputfolder

for ((angle1=0,angle2=180;angle1<=16;angle1++,angle2--));do
    echo $z $i

    fsleyes render --outfile $outputfolder/grot_`zeropad $z 3`.png [INSERT THE COMMAND HERE AND PUT IN $angle1 AND $angle2 WHERE YOU THINK THEY SHOULD GO ]
    
done
```

Run the command above (after suitable changes - or you can copy my [version](data/cmd.txt)) and then run the below to produce the GIF:

Saad Jbabdi's avatar
Saad Jbabdi committed
201
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
202
convert -delay 1x30 `ls $outputfolder/grot_???.png` `ls -r $outputfolder/grot_???.png` -loop 0 $outputfolder/pacman.gif
Saad Jbabdi's avatar
Saad Jbabdi committed
203
204
205
206
207
208
209
210
211
212
213
```

Notice we are using the PNGs twice, once for opening the mouth, and once for closing it, where the files are read in reverse order (`ls -r`).

You should be able to see this GIF:

<img src="data/snapshot4.gif" alt="snapshot4" style="width:400px;"/>

<a class="anchor" id="create-for-paper"></a>
## Figure for a paper

Saad Jbabdi's avatar
Saad Jbabdi committed
214
By now hopefully you have seen how you can combine the power of intuitively interacting with the FSLeyes graphical interface and the power of bash scripting. We'll do one more example of creating a nice graphic and then rendering it in a bash script. This one will look very nice.
Saad Jbabdi's avatar
Saad Jbabdi committed
215
216
217

Run the code below. It will open FSLeyes, with a 2mm MNI brain, and will also load the XTRACT tracts atlas. 

Saad Jbabdi's avatar
Saad Jbabdi committed
218
```bash
Saad Jbabdi's avatar
Saad Jbabdi committed
219
220
221
    fsleyes -std $FSLDIR/data/atlases/XTRACT/xtract-tract-atlases-prob-1mm &
```

Saad Jbabdi's avatar
Saad Jbabdi committed
222
223
224
225
226
227
228
229
230
231
We will try to make this nice by displaying the two images using maximum intensity projections.

Do the following:

- Change the colourmap of the MNI brain to "Bone"
- Change its min/max display range to 5000-10000
- Change the colourmap of the tracts to "Red-Yellow"
- Change the display type of both from "3d/4D volume" to "Maximum intensity projection"
- Change the MNI brain to have "Spline interpolation"
- Select volume number 14 for the tracts
Saad Jbabdi's avatar
Saad Jbabdi committed
232
- Use the spanner to add a colourbar on the left with size 30
Saad Jbabdi's avatar
Saad Jbabdi committed
233
234
235
236
237
238
239
240
241
242
243
- Untoggle the axial view
- Copy the command line onto the clipboard as before

[This](data/tracts.txt) is what I got after doing the above (feel free to use that).

Now use FSleyes render to create a nice looking figure. We will also control the DPI (digits per inch) of this figure, as some journal publishers insist that you have good quality images. 

```
fsleyes render --outfile my_tract.png --size 800 600 <COPY REST OF THE COMMAND HERE>
```

Saad Jbabdi's avatar
Saad Jbabdi committed
244
245
If you want to compare what you produced to what I made, have a look at [this](data/snapshot5.png)

Saad Jbabdi's avatar
Saad Jbabdi committed
246
247
248
> Exercise : create a FOR loop that produces a snapshot like the one above for all the XTRACT tracts.


Saad Jbabdi's avatar
Saad Jbabdi committed
249
250
251
252
----

Ok one last thing. Let's imagine that you want to check that your registration has worked properly and also wanted to make a PNG to show others that it does. 

Saad Jbabdi's avatar
Saad Jbabdi committed
253
For this, we will need two images that have been aligned with each other. These two are included with the practical material:
Saad Jbabdi's avatar
Saad Jbabdi committed
254
255
256
257
258
259
260

```
fsleyes data/example_func2highres.nii.gz data/highres.nii.gz & 
```

Then follow this recipe:

Saad Jbabdi's avatar
Saad Jbabdi committed
261
- Change the display mode of the highres to "3D/4D mask image"
Saad Jbabdi's avatar
Saad Jbabdi committed
262
263
264
265
266
267
268
269
- Change the color to Red
- Click on the cogwheel
- Change the threshold to 600-1400
- Click on "Show outline only"
- Change outline width to 3

Copy the command line to the clipboard and use the command line to render an image. The result should look like this:

Saad Jbabdi's avatar
snap6    
Saad Jbabdi committed
270
<img src="data/snapshot6.png" alt="snapshot5" style="width:400px;"/>
Saad Jbabdi's avatar
Saad Jbabdi committed
271

Saad Jbabdi's avatar
Saad Jbabdi committed
272
Now you should be able to use FSLeyes for this kind of thing and hopefully you will never ever need to use `slicesdir` ever again.
Saad Jbabdi's avatar
Saad Jbabdi committed
273

Saad Jbabdi's avatar
snap6    
Saad Jbabdi committed
274
275
----

Saad Jbabdi's avatar
Saad Jbabdi committed
276
The End.