Exemplo n.º 1
0
def subdivide(im, divs=2):
    r"""
    Returns slices into an image describing the specified number of sub-arrays.

    This function is useful for performing operations on smaller images for
    memory or speed.  Note that for most typical operations this will NOT work,
    since the image borders would cause artifacts (e.g. ``distance_transform``)

    Parameters
    ----------
    im : ND-array
        The image of the porous media

    divs : scalar or array_like
        The number of sub-divisions to create in each axis of the image.  If a
        scalar is given it is assumed this value applies in all dimensions.

    Returns
    -------
    slices : 1D-array
        A 1-D array containing slice objects for indexing into ``im`` that
        extract the sub-divided arrays.

    Notes
    -----
    This method uses the
    `array_split package <https://github.com/array-split/array_split>`_ which
    offers the same functionality as the ``split`` method of Numpy's ND-array,
    but supports the splitting multidimensional arrays in all dimensions.

    Examples
    --------
    >>> import porespy as ps
    >>> import matplotlib.pyplot as plt
    >>> im = ps.generators.blobs(shape=[200, 200])
    >>> s = ps.tools.subdivide(im, divs=[2, 2])

    ``s`` contains an array with the shape given by ``divs``.  To access the
    first and last quadrants of ``im`` use:
    >>> print(im[tuple(s[0, 0])].shape)
    (100, 100)
    >>> print(im[tuple(s[1, 1])].shape)
    (100, 100)

    It can be easier to index the array with the slices by applying ``flatten``
    first:
    >>> s_flat = s.flatten()
    >>> for i in s_flat:
    ...     print(im[i].shape)
    (100, 100)
    (100, 100)
    (100, 100)
    (100, 100)
    """
    # Expand scalar divs
    if isinstance(divs, int):
        divs = [divs for i in range(im.ndim)]
    s = shape_split(im.shape, axis=divs)
    return s
Exemplo n.º 2
0
    def create_mpi_map(self):
        self.map_mpi = np.empty(self.size, dtype=object)
        target_sample = (self.target_global_y_size, self.target_global_x_size)

        # Découpage des axes
        target_slices = shape_split(target_sample, self.size, axis=[0, 0])

        slice_index = 0
        for slyce in target_slices.flatten():
            slice = tuple(slyce)

            map = {}
            # Grille source
            map["dst_global_x"] = slice[1]
            map["dst_global_y"] = slice[0]

            map["dst_local_x_size"] = map["dst_global_x"].stop - map["dst_global_x"].start
            map["dst_local_y_size"] = map["dst_global_y"].stop - map["dst_global_y"].start

            dst_global_x_min_overlap = max(0, map["dst_global_x"].start - Coverage.HORIZONTAL_OVERLAPING_SIZE)
            dst_global_x_max_overlap = min(self.target_global_x_size,
                                           map["dst_global_x"].stop + Coverage.HORIZONTAL_OVERLAPING_SIZE)
            map["dst_global_x_overlap"] = np.s_[dst_global_x_min_overlap:dst_global_x_max_overlap]

            dst_global_y_min_overlap = max(0, map["dst_global_y"].start - Coverage.HORIZONTAL_OVERLAPING_SIZE)
            dst_global_y_max_overlap = min(self.target_global_y_size,
                                           map["dst_global_y"].stop + Coverage.HORIZONTAL_OVERLAPING_SIZE)
            map["dst_global_y_overlap"] = np.s_[dst_global_y_min_overlap:dst_global_y_max_overlap]

            map["dst_global_x_size_overlap"] = map["dst_global_x_overlap"].stop - map["dst_global_x_overlap"].start
            map["dst_global_y_size_overlap"] = map["dst_global_y_overlap"].stop - map["dst_global_y_overlap"].start

            dst_x_min = Coverage.HORIZONTAL_OVERLAPING_SIZE
            dst_x_max = map["dst_global_x_size_overlap"] - Coverage.HORIZONTAL_OVERLAPING_SIZE
            dst_y_min = Coverage.HORIZONTAL_OVERLAPING_SIZE
            dst_y_max = map["dst_global_y_size_overlap"] - Coverage.HORIZONTAL_OVERLAPING_SIZE

            if map["dst_global_x"].start == 0:
                dst_x_min = 0

            if map["dst_global_x"].stop == self.target_global_x_size:
                dst_x_max = map["dst_global_x_size_overlap"]

            if map["dst_global_y"].start == 0:
                dst_y_min = 0

            if map["dst_global_y"].stop == self.target_global_y_size:
                dst_y_max = map["dst_global_y_size_overlap"]

            map["dst_local_x"] = np.s_[dst_x_min:dst_x_max]
            map["dst_local_y"] = np.s_[dst_y_min:dst_y_max]

            # Source grille
            map["src_global_x"] = map["dst_global_x"]
            map["src_global_y"] = map["dst_global_y"]

            map["src_global_x_overlap"] = map["dst_global_x_overlap"]
            map["src_global_y_overlap"] = map["dst_global_y_overlap"]

            map["src_local_x"] = map["dst_local_x"]
            map["src_local_y"] = map["dst_local_y"]

            map["src_local_x_size"] = map["dst_local_x_size"]
            map["src_local_y_size"] = map["dst_local_y_size"]

            map["src_local_x_size_overlap"] = map["dst_global_x_size_overlap"]
            map["src_local_y_size_overlap"] = map["dst_global_y_size_overlap"]

            self.map_mpi[slice_index] = map

            slice_index = slice_index + 1
Exemplo n.º 3
0
def subdivide(im, divs=2, overlap=0, flatten=False):
    r"""
    Returns slices into an image describing the specified number of sub-arrays.

    This function is useful for performing operations on smaller images for
    memory or speed.  Note that for most typical operations this will NOT work,
    since the image borders would cause artifacts (e.g. ``distance_transform``)

    Parameters
    ----------
    im : ND-array
        The image of the porous media

    divs : scalar or array_like
        The number of sub-divisions to create in each axis of the image.  If a
        scalar is given it is assumed this value applies in all dimensions.

    overlap : scalar or array_like
        The amount of overlap to use when dividing along each axis.  If a
        scalar is given it is assumed this value applies in all dimensions.

    flatten : boolean
        If set to ``True`` then the slice objects are returned as a flat
        list, while if ``False`` they are returned in a ND-array where each
        subdivision is accessed using row-col or row-col-layer indexing.

    Returns
    -------
    slices : ND-array
        An ND-array containing sets of slice objects for indexing into ``im``
        that extract subdivisions of an image.  If ``flatten`` was ``True``,
        then this array is flat, suitable  for iterating.  If ``flatten`` was
        ``False`` then the slice objects must be accessed by row, col, layer
        indices.  An ND-array is the preferred container since it's shape can
        be easily queried.

    Notes
    -----
    This method uses the
    `array_split package <https://github.com/array-split/array_split>`_ which
    offers the same functionality as the ``split`` method of Numpy's ND-array,
    but supports the splitting of multidimensional arrays in all dimensions.

    See Also
    --------
    chunked_func

    Examples
    --------
    >>> import porespy as ps
    >>> import matplotlib.pyplot as plt
    >>> im = ps.generators.blobs(shape=[200, 200])
    >>> s = ps.tools.subdivide(im, divs=[2, 2], flatten=True)
    >>> print(len(s))
    4

    """
    divs = np.ones((im.ndim, ), dtype=int) * np.array(divs)
    halo = overlap * (divs > 1)
    slices = shape_split(im.shape,
                         axis=divs,
                         halo=halo.tolist(),
                         tile_bounds_policy=ARRAY_BOUNDS).astype(object)
    if flatten is True:
        slices = np.ravel(slices)
    return slices