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
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
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