Passed
Push — master ( 6deb01...ca4890 )
by Fernando
01:56 queued 40s
created

tests.data.test_image.TestImage.test_gif_rgb()   A

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
#!/usr/bin/env python
2
3
"""Tests for Image."""
4
5
import copy
6
import tempfile
7
8
import torch
9
import numpy as np
10
import nibabel as nib
11
12
import torchio as tio
13
from ..utils import TorchioTestCase
14
15
16
class TestImage(TorchioTestCase):
17
    """Tests for `Image`."""
18
19
    def test_image_not_found(self):
20
        with self.assertRaises(FileNotFoundError):
21
            tio.ScalarImage('nopath')
22
23
    def test_wrong_path_value(self):
24
        with self.assertRaises(RuntimeError):
25
            tio.ScalarImage('~&./@#"!?X7=+')
26
27
    def test_wrong_path_type(self):
28
        with self.assertRaises(TypeError):
29
            tio.ScalarImage(5)
30
31
    def test_wrong_affine(self):
32
        with self.assertRaises(TypeError):
33
            tio.ScalarImage(5, affine=1)
34
35
    def test_tensor_flip(self):
36
        sample_input = torch.ones((4, 30, 30, 30))
37
        tio.RandomFlip()(sample_input)
38
39
    def test_tensor_affine(self):
40
        sample_input = torch.ones((4, 10, 10, 10))
41
        tio.RandomAffine()(sample_input)
42
43
    def test_wrong_scalar_image_type(self):
44
        data = torch.ones((1, 10, 10, 10))
45
        with self.assertRaises(ValueError):
46
            tio.ScalarImage(tensor=data, type=tio.LABEL)
47
48
    def test_wrong_label_map_type(self):
49
        data = torch.ones((1, 10, 10, 10))
50
        with self.assertRaises(ValueError):
51
            tio.LabelMap(tensor=data, type=tio.INTENSITY)
52
53
    def test_no_input(self):
54
        with self.assertRaises(ValueError):
55
            tio.ScalarImage()
56
57
    def test_bad_key(self):
58
        with self.assertRaises(ValueError):
59
            tio.ScalarImage(path='', data=5)
60
61
    def test_repr(self):
62
        subject = tio.Subject(
63
            t1=tio.ScalarImage(self.get_image_path('repr_test')),
64
        )
65
        assert 'memory' not in repr(subject['t1'])
66
        subject.load()
67
        assert 'memory' in repr(subject['t1'])
68
69
    def test_data_tensor(self):
70
        subject = copy.deepcopy(self.sample_subject)
71
        subject.load()
72
        self.assertIs(subject.t1.data, subject.t1.tensor)
73
74
    def test_bad_affine(self):
75
        with self.assertRaises(ValueError):
76
            tio.ScalarImage(tensor=torch.rand(1, 2, 3, 4), affine=np.eye(3))
77
78
    def test_nans_tensor(self):
79
        tensor = np.random.rand(1, 2, 3, 4)
80
        tensor[0, 0, 0, 0] = np.nan
81
        with self.assertWarns(RuntimeWarning):
82
            image = tio.ScalarImage(tensor=tensor, check_nans=True)
83
        image.set_check_nans(False)
84
85
    def test_get_center(self):
86
        tensor = torch.rand(1, 3, 3, 3)
87
        image = tio.ScalarImage(tensor=tensor)
88
        ras = image.get_center()
89
        lps = image.get_center(lps=True)
90
        self.assertEqual(ras, (1, 1, 1))
91
        self.assertEqual(lps, (-1, -1, 1))
92
93
    def test_with_list_of_missing_files(self):
94
        with self.assertRaises(FileNotFoundError):
95
            tio.ScalarImage(path=['nopath', 'error'])
96
97
    def test_with_a_list_of_paths(self):
98
        shape = (5, 5, 5)
99
        path1 = self.get_image_path('path1', shape=shape)
100
        path2 = self.get_image_path('path2', shape=shape)
101
        image = tio.ScalarImage(path=[path1, path2])
102
        self.assertEqual(image.shape, (2, 5, 5, 5))
103
        self.assertEqual(image[tio.STEM], ['path1', 'path2'])
104
105
    def test_with_a_list_of_images_with_different_shapes(self):
106
        path1 = self.get_image_path('path1', shape=(5, 5, 5))
107
        path2 = self.get_image_path('path2', shape=(7, 5, 5))
108
        image = tio.ScalarImage(path=[path1, path2])
109
        with self.assertRaises(RuntimeError):
110
            image.load()
111
112
    def test_with_a_list_of_images_with_different_affines(self):
113
        path1 = self.get_image_path('path1', spacing=(1, 1, 1))
114
        path2 = self.get_image_path('path2', spacing=(1, 2, 1))
115
        image = tio.ScalarImage(path=[path1, path2])
116
        with self.assertWarns(RuntimeWarning):
117
            image.load()
118
119
    def test_with_a_list_of_2d_paths(self):
120
        shape = (5, 6)
121
        path1 = self.get_image_path('path1', shape=shape, suffix='.nii')
122
        path2 = self.get_image_path('path2', shape=shape, suffix='.img')
123
        path3 = self.get_image_path('path3', shape=shape, suffix='.hdr')
124
        image = tio.ScalarImage(path=[path1, path2, path3])
125
        self.assertEqual(image.shape, (3, 5, 6, 1))
126
        self.assertEqual(image[tio.STEM], ['path1', 'path2', 'path3'])
127
128
    def test_axis_name_2d(self):
129
        path = self.get_image_path('im2d', shape=(5, 6))
130
        image = tio.ScalarImage(path)
131
        height_idx = image.axis_name_to_index('t')
132
        width_idx = image.axis_name_to_index('l')
133
        self.assertEqual(image.height, image.shape[height_idx])
134
        self.assertEqual(image.width, image.shape[width_idx])
135
136
    def test_plot(self):
137
        image = self.sample_subject.t1
138
        image.plot(show=False, output_path=self.dir / 'image.png')
139
140
    def test_data_type_uint16_array(self):
141
        tensor = np.random.rand(1, 3, 3, 3).astype(np.uint16)
142
        image = tio.ScalarImage(tensor=tensor)
143
        self.assertEqual(image.data.dtype, torch.int32)
144
145
    def test_data_type_uint32_array(self):
146
        tensor = np.random.rand(1, 3, 3, 3).astype(np.uint32)
147
        image = tio.ScalarImage(tensor=tensor)
148
        self.assertEqual(image.data.dtype, torch.int64)
149
150
    def test_save_image_with_data_type_boolean(self):
151
        tensor = np.random.rand(1, 3, 3, 3).astype(bool)
152
        image = tio.ScalarImage(tensor=tensor)
153
        image.save(self.dir / 'image.nii')
154
155
    def test_load_uint(self):
156
        affine = np.eye(4)
157
        for dtype in np.uint16, np.uint32:
158
            data = np.ones((3, 3, 3), dtype=dtype)
159
            img = nib.Nifti1Image(data, affine)
160
            with tempfile.NamedTemporaryFile(suffix='.nii') as f:
161
                nib.save(img, f.name)
162
                tio.ScalarImage(f.name).load()
163
164
    def test_pil_3d(self):
165
        with self.assertRaises(RuntimeError):
166
            tio.ScalarImage(tensor=torch.rand(1, 2, 3, 4)).as_pil()
167
168
    def test_pil_1(self):
169
        tio.ScalarImage(tensor=torch.rand(1, 2, 3, 1)).as_pil()
170
171
    def test_pil_2(self):
172
        with self.assertRaises(RuntimeError):
173
            tio.ScalarImage(tensor=torch.rand(2, 2, 3, 1)).as_pil()
174
175
    def test_pil_3(self):
176
        tio.ScalarImage(tensor=torch.rand(3, 2, 3, 1)).as_pil()
177
178
    def test_set_data(self):
179
        with self.assertWarns(DeprecationWarning):
180
            im = self.sample_subject.t1
181
            im.data = im.data
182
183
    def test_no_type(self):
184
        with self.assertWarns(UserWarning):
185
            tio.Image(tensor=torch.rand(1, 2, 3, 4))
186
187
    def test_custom_reader(self):
188
        path = self.dir / 'im.npy'
189
190
        def numpy_reader(path):
191
            return np.load(path), np.eye(4)
192
193
        def assert_shape(shape_in, shape_out):
194
            np.save(path, np.random.rand(*shape_in))
195
            image = tio.ScalarImage(path, reader=numpy_reader)
196
            assert image.shape == shape_out
197
198
        assert_shape((5, 5), (1, 5, 5, 1))
199
        assert_shape((5, 5, 3), (3, 5, 5, 1))
200
        assert_shape((3, 5, 5), (3, 5, 5, 1))
201
        assert_shape((5, 5, 5), (1, 5, 5, 5))
202
        assert_shape((1, 5, 5, 5), (1, 5, 5, 5))
203
        assert_shape((4, 5, 5, 5), (4, 5, 5, 5))
204
205
    def test_fast_gif(self):
206
        with self.assertWarns(UserWarning):
207
            with tempfile.NamedTemporaryFile(suffix='.gif') as f:
208
                self.sample_subject.t1.to_gif(0, 0.0001, f.name)
209
210
    def test_gif_rgb(self):
211
        with tempfile.NamedTemporaryFile(suffix='.gif') as f:
212
            tio.ScalarImage(tensor=torch.rand(3, 4, 5, 6)).to_gif(0, 1, f.name)
213