Skip to content

Commit bbd83d7

Browse files
committed
ENH: Permit cropping with negative indices, give more specific errors
1 parent 14ff162 commit bbd83d7

File tree

1 file changed

+30
-5
lines changed

1 file changed

+30
-5
lines changed

nibabel/funcs.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,41 @@ def crop_image(img, bounds, margin=0):
245245
Version of `img` with cropped data array and updated affine matrix
246246
'''
247247

248-
try:
249-
bounds = np.asanyarray(bounds) + np.array([-margin, margin])
250-
assert bounds.shape == (3, 2)
251-
except (ValueError, AssertionError):
248+
shape = np.reshape(img.shape[:3], (3, 1))
249+
bounds = np.asanyarray(bounds)
250+
if bounds.shape != (3, 2):
252251
raise ValueError("bounds must be interpretable as a 3x2 array")
252+
elif np.any(bounds > shape):
253+
raise ValueError("bounds must not exceed image dimensions")
254+
255+
# Permit negative bounds
256+
if np.any(bounds < 0):
257+
bounds = (bounds + shape) % shape
258+
259+
if np.any(bounds < 0):
260+
raise ValueError("negative bounds may not exceed image dimensions")
261+
elif np.any(bounds[:, 0] > bounds[:, 1]):
262+
raise ValueError("degenerate (0 width) crops are not permitted")
263+
264+
# Add margin in all directions
265+
bounds += np.array([-margin, margin])
266+
267+
# Set min/max
268+
bounds[bounds < 0] = 0
269+
over = bounds[:, 1] > shape.reshape(-1) - 1
270+
bounds[over, 1] = shape[over, 0] - 1
271+
272+
# Include upper bounds
273+
bounds[:, 1] += 1
274+
275+
# Return original image if no cropping required
276+
if np.array_equal(bounds, np.hstack(([[0], [0], [0]], shape))):
277+
return img
253278

254279
x, y, z = bounds
255280
new_origin = np.vstack((bounds[:, [0]], 1))
256281

257-
bounded_data = img.get_data()[x[0]:x[1] + 1, y[0]:y[1] + 1, z[0]:z[1] + 1]
282+
bounded_data = img.get_data()[x[0]:x[1], y[0]:y[1], z[0]:z[1]]
258283

259284
new_aff = img.affine.copy()
260285
new_aff[:, [3]] = img.affine.dot(new_origin)

0 commit comments

Comments
 (0)