def crop_from_array(arr, bbox, arr_spacing=1., wanted_spacing=1., interpolation=CUBIC, dtype=None, blocksize=8000): """Crop bbox from arr and rescale to wanted_spacing. Assume arr has spacing arr_spacing. Respect bbox.spacing Args: arr (arry-like): image to crop from with spacing arr_spacing. bbox (BoundingBox): defines the crop area with spacing bbox.spacing. arr_spacing (float): spacing of arr. wanted_spacing (float): spacing of the returned crop. interpolation (int): interpolation used for eventual rescaling. From skimage.transform.rescale dtype (numpy dtype): integer dtype of the resulting crop. Returns: (np.ndarray): cropped image """ arr_spacing = float(arr_spacing) wanted_spacing = float(wanted_spacing) if bbox is None: bbox = BoundingBox.from_corners((0, 0), (arr.shape[1], arr.shape[0]), spacing=arr_spacing) else: bbox = BoundingBox.copy(bbox) bbox.set_to_spacing(arr_spacing) assert bbox.spacing == arr_spacing output_size = tuple([ int(math.floor(s * arr_spacing / wanted_spacing)) for s in bbox.get_hw(round_values=False) ]) if len(arr.shape) > 2: # Allow cropping from arrays with more than 2 dimensions output_size = output_size + arr.shape[2:] if dtype is None: result_crop = np.zeros(output_size, dtype=arr.dtype) else: result_crop = np.zeros(output_size, dtype=dtype) if not (blocksize * arr_spacing / wanted_spacing).is_integer(): log.warning( "blocksize * scale is not a natural number:{}. This may lead to problems in blockwise resizing." .format(blocksize * arr_spacing / wanted_spacing)) for box in blocks(bbox, (blocksize, blocksize)): # box is part of bbox, has to be moved by vector of upper left corner box.set_center( np.array(box.center) + np.array(bbox.get_corners(round_values=False)[0])) output_size = tuple([ int(math.floor(s * (arr_spacing / wanted_spacing))) for s in box.get_hw(round_values=False) ]) if min(output_size) == 0: continue #pyextrae.eventandcounters(5000, 20) crop = np.array(box.crop_from_array(arr)) #pyextrae.eventandcounters(5000, 0) if arr_spacing != wanted_spacing: # rescale the crop to fit to output_size #log.debug("crop_from_array is reshaping from {} to {}".format(crop.shape, output_size)) crop = resize(crop, output_size, interpolation=interpolation, antialias=True) assert crop.shape[:2] == output_size, "{} {}".format( crop.shape, output_size) if dtype is not None: crop = crop.astype(np.float64) / get_maxintensity( arr) * dtype_limits(dtype)[1] crop = crop.astype(dtype) # move box back to origin and insert crop into result_crop box.set_center( np.array(box.center) - np.array(bbox.get_corners(round_values=False)[0])) box.rescale(arr_spacing / wanted_spacing) box.set_hw(box.get_hw()[0], box.get_hw()[1]) box.write_to_array(result_crop, crop) return result_crop