a b/ants/ops/pad_image.py
1
2
__all__ = ['pad_image']
3
4
import math
5
6
import ants
7
from ants.decorators import image_method
8
from ants.internal import get_lib_fn
9
10
@image_method
11
def pad_image(image, shape=None, pad_width=None, value=0.0, return_padvals=False):
12
    """
13
    Pad an image to have the given shape or to be isotropic.
14
15
    Arguments
16
    ---------
17
    image : ANTsImage
18
        image to pad
19
20
    shape : tuple
21
        - if shape is given, the image will be padded in each dimension
22
          until it has this shape
23
        - if shape and pad_width are both None, the image will be padded along
24
          each dimension to match the largest existing dimension so that it has
25
          isotropic dimensions.
26
27
    pad_width : list of integers or list-of-list of integers
28
        How much to pad in each direction. If a single list is
29
        supplied (e.g., [4,4,4]), then the image will be padded by half
30
        that amount on both sides. If a list-of-list is supplied
31
        (e.g., [(0,4),(0,4),(0,4)]), then the image will be
32
        padded unevenly on the different sides
33
34
    pad_value : scalar
35
        value with which image will be padded
36
37
    Example
38
    -------
39
    >>> import ants
40
    >>> img = ants.image_read(ants.get_data('r16'))
41
    >>> img2 = ants.pad_image(img, shape=(300,300))
42
    >>> mni = ants.image_read(ants.get_data('mni'))
43
    >>> mni2 = ants.pad_image(mni)
44
    >>> mni3 = ants.pad_image(mni, pad_width=[(0,4),(0,4),(0,4)])
45
    >>> mni4 = ants.pad_image(mni, pad_width=(4,4,4))
46
    """
47
    inpixeltype = image.pixeltype
48
    ndim = image.dimension
49
    if image.pixeltype != 'float':
50
        image = image.clone('float')
51
52
    if pad_width is None:
53
        if shape is None:
54
            shape = [max(image.shape)] * image.dimension
55
        lower_pad_vals = [math.floor(max(ns-os,0)/2) for os,ns in zip(image.shape, shape)]
56
        upper_pad_vals = [math.ceil(max(ns-os,0)/2) for os,ns in zip(image.shape, shape)]
57
    else:
58
        if shape is not None:
59
            raise ValueError('Cannot give both `shape` and `pad_width`. Pick one!')
60
        if len(pad_width) != image.dimension:
61
            raise ValueError('Must give pad width for each image dimension')
62
63
        lower_pad_vals = []
64
        upper_pad_vals = []
65
        for p in pad_width:
66
            if isinstance(p, (list, tuple)):
67
                lower_pad_vals.append(p[0])
68
                upper_pad_vals.append(p[1])
69
            else:
70
                lower_pad_vals.append(math.floor(p/2))
71
                upper_pad_vals.append(math.ceil(p/2))
72
73
    libfn = get_lib_fn('padImage')
74
    itkimage = libfn(image.pointer, lower_pad_vals, upper_pad_vals, value)
75
76
    new_image = ants.from_pointer(itkimage).clone(inpixeltype)
77
    if return_padvals:
78
        return new_image, lower_pad_vals, upper_pad_vals
79
    else:
80
        return new_image
81
82