/
saving_images.Rmd
101 lines (79 loc) · 2.25 KB
/
saving_images.Rmd
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
100
101
---
jupyter:
jupytext:
text_representation:
extension: .Rmd
format_name: rmarkdown
format_version: '1.2'
jupytext_version: 1.11.5
---
# Making and saving new images in nibabel
We often want to do some processing on an image, then save the processed image
back to an image file on disk.
When we load an image from disk, we get back an image object. When we load a
NIfTI `.nii` image, we get an image object of type `Nifti1Image`.
```{python}
import numpy as np
import nibabel as nib
```
```{python}
# Load the function to fetch the data file we need.
import nipraxis
# Fetch the data file.
data_fname = nipraxis.fetch_file('ds114_sub009_highres.nii')
# Show the file name of the fetched data.
data_fname
```
```{python}
img = nib.load(data_fname)
type(img)
```
Maybe we were worried about some very high values in the image, and we wanted
to clip them down to a more reasonable number:
```{python}
data = img.get_fdata()
data.max()
```
We might consider clipping the top 5 percent of voxel values:
```{python}
data = img.get_fdata()
top_95_thresh = np.percentile(data, 95)
top_95_thresh
```
```{python}
new_data = data.copy()
new_data[new_data > top_95_thresh] = top_95_thresh
new_data.max()
```
We can make a new `Nifti1Image` by constructing it directly. We pass the
new data, the image affine, and (optionally) a template header for the image:
```{python}
clipped_img = nib.Nifti1Image(new_data, img.affine, img.header)
type(clipped_img)
```
The `nib.Nifti1Image` call copies and adapts the passed header to the new
image data shape, and affine.
```{python}
# Show the original data array shape from the original header
img.header.get_data_shape()
```
```{python}
# Here we construct a new empty header
empty_header = nib.Nifti1Header()
empty_header.get_data_shape()
```
If we make a new image with this header, the constructor routine fixes the
header to have the correct shape for the data array:
```{python}
another_img = nib.Nifti1Image(new_data, img.affine, empty_header)
another_img.header.get_data_shape()
```
We can save the new image with `nib.save`:
```{python}
nib.save(clipped_img, 'clipped_image.nii')
```
This image has the clipped data:
```{python}
clipped_back = nib.load('clipped_image.nii')
clipped_back.get_fdata().max()
```