1
|
|
|
import torch |
2
|
|
|
|
3
|
|
|
from ...transform import TypeMaskingMethod |
4
|
|
|
from .remap_labels import RemapLabels |
5
|
|
|
from .label_transform import LabelTransform |
6
|
|
|
|
7
|
|
|
|
8
|
|
|
class SequentialLabels(LabelTransform): |
9
|
|
|
r"""Remap the integer IDs of labels in a LabelMap to be sequential. |
10
|
|
|
|
11
|
|
|
For example, if a label map has 6 labels with IDs (3, 5, 9, 15, 16, 23), |
12
|
|
|
then this will apply a :class:`~torchio.RemapLabels` transform with |
13
|
|
|
``remapping={3: 1, 5: 2, 9: 3, 15: 4, 16: 5, 23: 6}``. |
14
|
|
|
This transformation is always `fully invertible <invertibility>`_. |
15
|
|
|
|
16
|
|
|
Args: |
17
|
|
|
masking_method: See :class:`~torchio.transforms.RemapLabels`. |
18
|
|
|
**kwargs: See :class:`~torchio.transforms.Transform` for additional |
19
|
|
|
keyword arguments. |
20
|
|
|
""" |
21
|
|
|
def __init__( |
22
|
|
|
self, |
23
|
|
|
masking_method: TypeMaskingMethod = None, |
24
|
|
|
**kwargs |
25
|
|
|
): |
26
|
|
|
super().__init__(**kwargs) |
27
|
|
|
self.masking_method = masking_method |
28
|
|
|
|
29
|
|
|
def apply_transform(self, subject): |
30
|
|
|
for name, image in self.get_images_dict(subject).items(): |
31
|
|
|
unique_labels = torch.unique(image.data) |
32
|
|
|
remapping = { |
33
|
|
|
unique_labels[i].item(): i |
34
|
|
|
for i in range(1, len(unique_labels)) |
35
|
|
|
} |
36
|
|
|
transform = RemapLabels( |
37
|
|
|
remapping=remapping, |
38
|
|
|
masking_method=self.masking_method, |
39
|
|
|
include=name, |
40
|
|
|
) |
41
|
|
|
subject = transform(subject) |
42
|
|
|
|
43
|
|
|
return subject |
44
|
|
|
|