Passed
Push — main ( 61f0e5...8543db )
by Fernando
01:52
created

Crop.inverse()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
import numpy as np
2
from nibabel.affines import apply_affine
3
4
from ....data.subject import Subject
5
from .bounds_transform import BoundsTransform
6
from .bounds_transform import TypeBounds
7
8
9
class Crop(BoundsTransform):
10
    r"""Crop an image.
11
12
    Args:
13
        cropping: Tuple
14
            :math:`(w_{ini}, w_{fin}, h_{ini}, h_{fin}, d_{ini}, d_{fin})`
15
            defining the number of values cropped from the edges of each axis.
16
            If the initial shape of the image is
17
            :math:`W \times H \times D`, the final shape will be
18
            :math:`(- w_{ini} + W - w_{fin}) \times (- h_{ini} + H - h_{fin})
19
            \times (- d_{ini} + D - d_{fin})`.
20
            If only three values :math:`(w, h, d)` are provided, then
21
            :math:`w_{ini} = w_{fin} = w`,
22
            :math:`h_{ini} = h_{fin} = h` and
23
            :math:`d_{ini} = d_{fin} = d`.
24
            If only one value :math:`n` is provided, then
25
            :math:`w_{ini} = w_{fin} = h_{ini} = h_{fin}
26
            = d_{ini} = d_{fin} = n`.
27
        **kwargs: See :class:`~torchio.transforms.Transform` for additional
28
            keyword arguments.
29
30
    .. seealso:: If you want to pass the output shape instead, please use
31
        :class:`~torchio.transforms.CropOrPad` instead.
32
    """
33
34
    def __init__(self, cropping: TypeBounds, **kwargs):
35
        super().__init__(cropping, **kwargs)
36
        self.cropping = cropping
37
        self.args_names = ['cropping']
38
39
    def apply_transform(self, subject: Subject) -> Subject:
40
        assert self.bounds_parameters is not None
41
        low = self.bounds_parameters[::2]
42
        high = self.bounds_parameters[1::2]
43
        index_ini = low
44
        index_fin = np.array(subject.spatial_shape) - high
45
        for image in self.get_images(subject):
46
            new_origin = apply_affine(image.affine, index_ini)
47
            new_affine = image.affine.copy()
48
            new_affine[:3, 3] = new_origin
49
            i0, j0, k0 = index_ini
50
            i1, j1, k1 = index_fin
51
            image.set_data(image.data[:, i0:i1, j0:j1, k0:k1].clone())
52
            image.affine = new_affine
53
        return subject
54
55
    def inverse(self):
56
        from .pad import Pad
57
58
        return Pad(self.cropping)
59