|
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 |
|