@@ -221,37 +221,42 @@ def _aff_is_diag(aff):
221221 return np .allclose (rzs_aff , np .diag (np .diag (rzs_aff )))
222222
223223
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
226226
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.
229229 The affine matrix is updated with the new intercept, so that all values are
230230 found at the same RAS locations.
231231
232232 Parameters
233233 ----------
234234 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
237241
238242 Returns
239243 -------
240244 cropped_img : ``spatialimage``
241245 Version of `img` with cropped data array and updated affine matrix
242246 '''
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' )
247247
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+
249254 x , y , z = bounds
250- new_origin = np .vstack ((bounds [:, [0 ]], [ 1 ] ))
255+ new_origin = np .vstack ((bounds [:, [0 ]], 1 ))
251256
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 ]
253258
254259 new_aff = img .affine .copy ()
255260 new_aff [:, [3 ]] = img .affine .dot (new_origin )
256261
257- return img .__class__ (new_data , new_aff , img .header )
262+ return img .__class__ (bounded_data , new_aff , img .header )
0 commit comments