|
1
|
|
|
import numpy as np |
|
2
|
|
|
import nibabel as nib |
|
3
|
|
|
from ....torchio import TypeTripletInt, DATA |
|
4
|
|
|
from .bounds_transform import BoundsTransform |
|
5
|
|
|
|
|
6
|
|
|
|
|
7
|
|
|
class Crop(BoundsTransform): |
|
8
|
|
|
r"""Crop an image. |
|
9
|
|
|
|
|
10
|
|
|
Args: |
|
11
|
|
|
cropping: Tuple |
|
12
|
|
|
:math:`(w_{ini}, w_{fin}, h_{ini}, h_{fin}, d_{ini}, d_{fin})` |
|
13
|
|
|
defining the number of values cropped from the edges of each axis. |
|
14
|
|
|
If the initial shape of the image is |
|
15
|
|
|
:math:`H \times W \times D`, the final shape will be |
|
16
|
|
|
:math:`(- w_{ini} + W - w_{fin}) \times (- h_{ini} + H - h_{fin}) |
|
17
|
|
|
\times (- d_{ini} + D - d_{fin})`. |
|
18
|
|
|
If only three values :math:`(w, h, d)` are provided, then |
|
19
|
|
|
:math:`w_{ini} = w_{fin} = w`, |
|
20
|
|
|
:math:`h_{ini} = h_{fin} = h` and |
|
21
|
|
|
:math:`d_{ini} = d_{fin} = d`. |
|
22
|
|
|
If only one value :math:`n` is provided, then |
|
23
|
|
|
:math:`w_{ini} = w_{fin} = h_{ini} = h_{fin} |
|
24
|
|
|
= d_{ini} = d_{fin} = n`. |
|
25
|
|
|
""" |
|
26
|
|
|
def apply_transform(self, sample) -> dict: |
|
27
|
|
|
low = self.bounds_parameters[::2] |
|
28
|
|
|
high = self.bounds_parameters[1::2] |
|
29
|
|
|
index_ini = low |
|
30
|
|
|
index_fin = np.array(sample.spatial_shape) - high |
|
31
|
|
|
for image in self.get_images(sample): |
|
32
|
|
|
new_origin = nib.affines.apply_affine(image.affine, index_ini) |
|
33
|
|
|
new_affine = image.affine.copy() |
|
34
|
|
|
new_affine[:3, 3] = new_origin |
|
35
|
|
|
i0, j0, k0 = index_ini |
|
36
|
|
|
i1, j1, k1 = index_fin |
|
37
|
|
|
image[DATA] = image[DATA][:, i0:i1, j0:j1, k0:k1].clone() |
|
|
|
|
|
|
38
|
|
|
return sample |
|
39
|
|
|
|