@@ -221,37 +221,42 @@ def _aff_is_diag(aff):
221
221
return np .allclose (rzs_aff , np .diag (np .diag (rzs_aff )))
222
222
223
223
224
- def crop_image (img , mask = None ):
225
- ''' Crop ``img`` to smallest region that contains all non-zero data
224
+ def crop_image (img , bounds , margin = 0 ):
225
+ ''' Crop ``img`` to specified bounds
226
226
227
- The image is cropped in the current orientation; no rotations or resampling
228
- are performed.
227
+ The image is cropped in the current orientation; no rotation or resampling
228
+ is performed.
229
229
The affine matrix is updated with the new intercept, so that all values are
230
230
found at the same RAS locations.
231
231
232
232
Parameters
233
233
----------
234
234
img : ``spatialimage``
235
- mask : ``spatialimage``, optional
236
- If supplied, use the bounding box of ``mask``, rather than ``img``
235
+ Image to be cropped
236
+ bounds : (3, 2) array-like
237
+ Minimum and maximum (inclusive) voxel indices, in each dimension, to be
238
+ included in cropped image
239
+ margin : int, optional
240
+ Margin, in voxels, to include on each side of cropped image
237
241
238
242
Returns
239
243
-------
240
244
cropped_img : ``spatialimage``
241
245
Version of `img` with cropped data array and updated affine matrix
242
246
'''
243
- if mask is None :
244
- mask = img
245
- elif not np .allclose (img .affine == mask .affine ):
246
- raise ValueError ('Affine for image does not match affine for mask' )
247
247
248
- bounds = np .sort (np .vstack (np .nonzero (mask .get_data ())))[:, [0 , - 1 ]]
248
+ try :
249
+ bounds = np .asanyarray (bounds ) + np .array ([- margin , margin ])
250
+ assert bounds .shape == (3 , 2 )
251
+ except (ValueError , AssertionError ) as err :
252
+ raise ValueError ("bounds must be interpretable as a 3x2 array" )
253
+
249
254
x , y , z = bounds
250
- new_origin = np .vstack ((bounds [:, [0 ]], [ 1 ] ))
255
+ new_origin = np .vstack ((bounds [:, [0 ]], 1 ))
251
256
252
- new_data = img .get_data ()[x [0 ]:x [1 ] + 1 , y [0 ]:y [1 ] + 1 , z [0 ]:z [1 ] + 1 ]
257
+ bounded_data = img .get_data ()[x [0 ]:x [1 ] + 1 , y [0 ]:y [1 ] + 1 , z [0 ]:z [1 ] + 1 ]
253
258
254
259
new_aff = img .affine .copy ()
255
260
new_aff [:, [3 ]] = img .affine .dot (new_origin )
256
261
257
- return img .__class__ (new_data , new_aff , img .header )
262
+ return img .__class__ (bounded_data , new_aff , img .header )
0 commit comments