tests.data.test_image.TestImage.test_load_uint()   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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