@@ -88,19 +88,6 @@ def squeeze_image(img):
88
88
img .extra )
89
89
90
90
91
- def _shape_equal_excluding (shape1 , shape2 , exclude_axes ):
92
- """ Helper function to compare two array shapes, excluding any
93
- axis specified."""
94
-
95
- if len (shape1 ) != len (shape2 ):
96
- return False
97
-
98
- idx_mask = np .ones ((len (shape1 ),), dtype = bool )
99
- idx_mask [exclude_axes ] = False
100
- return np .array_equal (np .asarray (shape1 )[idx_mask ],
101
- np .asarray (shape2 )[idx_mask ])
102
-
103
-
104
91
def concat_images (images , check_affines = True , axis = None ):
105
92
''' Concatenate images in list to single image, along specified dimension
106
93
@@ -112,50 +99,53 @@ def concat_images(images, check_affines=True, axis=None):
112
99
If True, then check that all the affines for `images` are nearly
113
100
the same, raising a ``ValueError`` otherwise. Default is True
114
101
axis : None or int, optional
115
- If None, concatenates on a new dimension. This requires all images
116
- to be the same shape).
117
- If not None, concatenates on the specified dimension. This requires
118
- all images to be the same shape, except on the specified dimension.
102
+ If None, concatenates on a new dimension. This requires all images to
103
+ be the same shape. If not None, concatenates on the specified
104
+ dimension. This requires all images to be the same shape, except on
105
+ the specified dimension.
119
106
Returns
120
107
-------
121
108
concat_img : ``SpatialImage``
122
109
New image resulting from concatenating `images` across last
123
110
dimension
124
111
'''
125
-
112
+ images = [load (img ) if not hasattr (img , 'get_data' )
113
+ else img for img in images ]
126
114
n_imgs = len (images )
127
115
if n_imgs == 0 :
128
116
raise ValueError ("Cannot concatenate an empty list of images." )
129
-
117
+ img0 = images [0 ]
118
+ affine = img0 .affine
119
+ header = img0 .header
120
+ klass = img0 .__class__
121
+ shape0 = img0 .shape
122
+ n_dim = len (shape0 )
123
+ if axis is None :
124
+ # collect images in output array for efficiency
125
+ out_shape = (n_imgs , ) + shape0
126
+ out_data = np .empty (out_shape )
127
+ else :
128
+ # collect images in list for use with np.concatenate
129
+ out_data = [None ] * n_imgs
130
+ # Get part of shape we need to check inside loop
131
+ idx_mask = np .ones ((n_dim ,), dtype = bool )
132
+ if axis is not None :
133
+ idx_mask [axis ] = False
134
+ masked_shape = np .array (shape0 )[idx_mask ]
130
135
for i , img in enumerate (images ):
131
- if not hasattr (img , 'get_data' ):
132
- img = load (img )
133
-
134
- if i == 0 : # first image, initialize data from loaded image
135
- affine = img .affine
136
- header = img .header
137
- shape = img .shape
138
- klass = img .__class__
139
-
140
- if axis is None : # collect images in output array for efficiency
141
- out_shape = (n_imgs , ) + shape
142
- out_data = np .empty (out_shape )
143
- else : # collect images in list for use with np.concatenate
144
- out_data = [None ] * n_imgs
145
-
146
- elif check_affines and not np .all (img .affine == affine ):
147
- raise ValueError ('Affines do not match' )
148
-
149
- elif ((axis is None and not np .array_equal (shape , img .shape )) or
150
- (axis is not None and not _shape_equal_excluding (shape , img .shape ,
151
- exclude_axes = [axis ]))):
152
- # shape mismatch; numpy broadcast / concatenate can hide these.
153
- raise ValueError ("Image #%d (shape=%s) does not match the first "
154
- "image shape (%s)." % (i , shape , img .shape ))
155
-
156
- out_data [i ] = img .get_data ()
157
-
158
- del img
136
+ if len (img .shape ) != n_dim :
137
+ raise ValueError (
138
+ 'Image {0} has {1} dimensions, image 0 has {2}' .format (
139
+ i , len (img .shape ), n_dim ))
140
+ if not np .all (np .array (img .shape )[idx_mask ] == masked_shape ):
141
+ raise ValueError ('shape {0} for image {1} not compatible with '
142
+ 'first image shape {2} with axis == {0}' .format (
143
+ img .shape , i , shape0 , axis ))
144
+ if check_affines and not np .all (img .affine == affine ):
145
+ raise ValueError ('Affine for image {0} does not match affine '
146
+ 'for first image' .format (i ))
147
+ # Do not fill cache in image if it is empty
148
+ out_data [i ] = img .get_data (caching = 'unchanged' )
159
149
160
150
if axis is None :
161
151
out_data = np .rollaxis (out_data , 0 , out_data .ndim )
0 commit comments