1

I have a set of 3D data (Volume of MRI) .nii images with the shape 98-by-240-by-342 (98:slices, 240:W and 342: H), for example. The sizes of volumes are varying from each other. I want to do center-cropping of the all volumes in a way that if width or height is less than 256, that dimension is padded with zeros. I know this can be done by applying on each slice separately, however, I am asking whether if there is a medical image analysis tool that can crop width and heights in a volume?

Thanks

sc241
  • 189
  • 17
  • Look at scikit-image, there should be functions for this in there. https://www.scipy-lectures.org/packages/scikit-image/ – Joe Jul 11 '18 at 06:20

3 Answers3

2

ITK, an n-dimensional library can fulfill your needs. It has pad and a crop filters. If it is not clear how to use it, you can take a look at documentation.

Dženan
  • 3,329
  • 3
  • 31
  • 44
1

I found an easy way of center cropping in SO, which is applicable in N-dimentional arrays. @Losses Don response, which is an smart way of center cropping. The padding part, I added my self.

def cropND(img, bounding):
    start = tuple(map(lambda a, da: a//2-da//2, img.shape, bounding))
    end = tuple(map(operator.add, start, bounding))
    slices = tuple(map(slice, start, end))
    return img[slices]
sc241
  • 189
  • 17
0

You might check this code:

def resize_image_with_crop_or_pad(image, img_size=(64, 64, 64), **kwargs):
"""Image resizing. Resizes image by cropping or padding dimension
 to fit specified size.
Args:
    image (np.ndarray): image to be resized
    img_size (list or tuple): new image size
    kwargs (): additional arguments to be passed to np.pad
Returns:
    np.ndarray: resized image
"""

assert isinstance(image, (np.ndarray, np.generic))
assert (image.ndim - 1 == len(img_size) or image.ndim == len(img_size)), \
    'Example size doesnt fit image size'

# Get the image dimensionality
rank = len(img_size)

# Create placeholders for the new shape
from_indices = [[0, image.shape[dim]] for dim in range(rank)]
to_padding = [[0, 0] for dim in range(rank)]

slicer = [slice(None)] * rank

# For each dimensions find whether it is supposed to be cropped or padded
for i in range(rank):
    if image.shape[i] < img_size[i]:
        to_padding[i][0] = (img_size[i] - image.shape[i]) // 2
        to_padding[i][1] = img_size[i] - image.shape[i] - to_padding[i][0]
    else:
        from_indices[i][0] = int(np.floor((image.shape[i] - img_size[i]) / 2.))
        from_indices[i][1] = from_indices[i][0] + img_size[i]

    # Create slicer object to crop or leave each dimension
    slicer[i] = slice(from_indices[i][0], from_indices[i][1])

# Pad the cropped image to extend the missing dimension
return np.pad(image[slicer], to_padding, **kwargs)

source: Usefull Python codes for MRI images