|
1
|
|
|
from .sampler import ImageSampler, crop |
|
2
|
|
|
from ... import DATA, LABEL, TYPE |
|
3
|
|
|
from ..subject import Subject |
|
4
|
|
|
|
|
5
|
|
|
|
|
6
|
|
|
class LabelSampler(ImageSampler): |
|
7
|
|
|
r"""Extract random patches containing labeled voxels. |
|
8
|
|
|
|
|
9
|
|
|
This iterable dataset yields patches that contain at least one voxel |
|
10
|
|
|
without background. |
|
11
|
|
|
|
|
12
|
|
|
It extracts the label data from the first image in the sample with type |
|
13
|
|
|
:py:attr:`torchio.LABEL`. |
|
14
|
|
|
|
|
15
|
|
|
Args: |
|
16
|
|
|
sample: Sample generated by a |
|
17
|
|
|
:py:class:`~torchio.data.dataset.ImagesDataset`, from which image |
|
18
|
|
|
patches will be extracted. |
|
19
|
|
|
patch_size: Tuple of integers :math:`(d, h, w)` to generate patches |
|
20
|
|
|
of size :math:`d \times h \times w`. |
|
21
|
|
|
If a single number :math:`n` is provided, |
|
22
|
|
|
:math:`d = h = w = n`. |
|
23
|
|
|
|
|
24
|
|
|
.. warning:: For now, this implementation is not efficient because it uses |
|
25
|
|
|
brute force to look for foreground voxels. It the number of |
|
26
|
|
|
non-background voxels is very small, this sampler will be slow. |
|
27
|
|
|
""" |
|
28
|
|
|
@staticmethod |
|
29
|
|
|
def get_first_label_image_dict(sample: Subject): |
|
30
|
|
|
for image_dict in sample.get_images(intensity_only=False): |
|
31
|
|
|
if image_dict[TYPE] == LABEL: |
|
32
|
|
|
label_image_dict = image_dict |
|
33
|
|
|
break |
|
34
|
|
|
else: |
|
35
|
|
|
raise ValueError('No images of type torchio.LABEL found in sample') |
|
36
|
|
|
return label_image_dict |
|
37
|
|
|
|
|
38
|
|
|
def extract_patch(self): |
|
39
|
|
|
has_label = False |
|
40
|
|
|
label_image_data = self.get_first_label_image_dict(self.sample)[DATA] |
|
41
|
|
|
while not has_label: |
|
42
|
|
|
index_ini, index_fin = self.get_random_indices( |
|
43
|
|
|
self.sample, self.patch_size) |
|
44
|
|
|
patch_label = crop(label_image_data, index_ini, index_fin) |
|
45
|
|
|
has_label = patch_label.sum() > 0 |
|
46
|
|
|
cropped_sample = self.copy_and_crop( |
|
47
|
|
|
self.sample, |
|
48
|
|
|
index_ini, |
|
|
|
|
|
|
49
|
|
|
index_fin, |
|
|
|
|
|
|
50
|
|
|
) |
|
51
|
|
|
return cropped_sample |
|
52
|
|
|
|