Esempio n. 1
0
def blocks(data, size):
    """A generator yielding sliding bounding boxes with a given size over given data.

    Args:
        data : provides a shape attribute. E.g. a hdf5 dataset or a (py)tiff image
        size : sets the size of the generated bounding boxes.

    Returns:
        BoundingBox : A bounding box from the given data.
    """
    size = np.array(size)
    shape = np.array(data.shape)
    n_rows, n_cols = np.ceil(shape[:2] / size).astype(int)
    for r in range(n_rows):
        for c in range(n_cols):
            # swap row and column, x = column, y = row
            upper_left = (c * size[1], r * size[0])
            lower_right = (min((c + 1) * size[1],
                               shape[1]), min((r + 1) * size[0], shape[0]))
            yield BoundingBox.from_corners(upper_left, lower_right)
Esempio n. 2
0
    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