def crop(self, crop_width): """ Crop sky image at the edges with given crop width. Analogous method to :meth:`SkyImage.pad()` to crop the sky image at the edges. Adapts the WCS specification accordingly. Parameters ---------- crop_width : {sequence, array_like, int} Number of values cropped from the edges of each axis. Defined analogously to `pad_with` from `~numpy.pad`. Returns ------- image : `~gammapy.image.SkyImage` Cropped image """ crop_width = _validate_lengths(self.data, crop_width) xlo, xhi = crop_width[self._ax_idx.x] ylo, yhi = crop_width[self._ax_idx.y] data = self.data[ylo:-yhi, xlo:-xhi] if self.wcs: wcs = self.wcs.deepcopy() wcs.wcs.crpix -= np.array([xlo, ylo]) else: wcs = None return self.__class__(name=self.name, data=data, wcs=wcs, unit=self.unit)
def crop(ar, crop_width, copy=False, order='K'): """Crop array `ar` by `crop_width` along each dimension. Parameters ---------- ar : array-like of rank N Input array. crop_width : {sequence, int} Number of values to remove from the edges of each axis. ``((before_1, after_1),`` ... ``(before_N, after_N))`` specifies unique crop widths at the start and end of each axis. ``((before, after),)`` specifies a fixed start and end crop for every axis. ``(n,)`` or ``n`` for integer ``n`` is a shortcut for before = after = ``n`` for all axes. copy : bool, optional If `True`, ensure the returned array is a contiguous copy. Normally, a crop operation will return a discontiguous view of the underlying input array. order : {'C', 'F', 'A', 'K'}, optional If ``copy==True``, control the memory layout of the copy. See ``np.copy``. Returns ------- cropped : array The cropped array. If ``copy=False`` (default), this is a sliced view of the input array. """ ar = np.array(ar, copy=False) crops = _validate_lengths(ar, crop_width) slices = [slice(a, ar.shape[i] - b) for i, (a, b) in enumerate(crops)] if copy: cropped = np.array(ar[tuple(slices)], order=order, copy=True) else: cropped = ar[tuple(slices)] return cropped
def crop(ar, crop_width, copy=False, order='K'): ar = np.array(ar, copy=False) crops = _validate_lengths(ar, crop_width) slices = [slice(a, ar.shape[i] - b) for i, (a, b) in enumerate(crops)] if copy: cropped = np.array(ar[slices], order=order, copy=True) else: cropped = ar[slices] return cropped
def crop(ar, crop_width, copy=False, order='K'): """Crop array `ar` by `crop_width` along each dimension. Parameters ---------- ar : array-like of rank N Input array. crop_width : {sequence, int} Number of values to remove from the edges of each axis. ``((before_1, after_1),`` ... ``(before_N, after_N))`` specifies unique crop widths at the start and end of each axis. ``((before, after),)`` specifies a fixed start and end crop for every axis. ``(n,)`` or ``n`` for integer ``n`` is a shortcut for before = after = ``n`` for all axes. copy : bool, optional If `True`, ensure the returned array is a contiguous copy. Normally, a crop operation will return a discontiguous view of the underlying input array. order : {'C', 'F', 'A', 'K'}, optional If ``copy==True``, control the memory layout of the copy. See ``np.copy``. Returns ------- cropped : array The cropped array. If ``copy=False`` (default), this is a sliced view of the input array. """ # Since arraycrop is in the critical import path, we lazy import distutils # to check the version of numpy # After numpy 1.15, a new backward compatible function have been # implemented. # See https://github.com/numpy/numpy/pull/11966 from distutils.version import LooseVersion as Version old_numpy = Version(np.__version__) < Version('1.16') if old_numpy: from numpy.lib.arraypad import _validate_lengths else: from numpy.lib.arraypad import _as_pairs ar = np.array(ar, copy=False) if old_numpy: crops = _validate_lengths(ar, crop_width) else: crops = _as_pairs(crop_width, ar.ndim, as_index=True) slices = tuple(slice(a, ar.shape[i] - b) for i, (a, b) in enumerate(crops)) if copy: cropped = np.array(ar[slices], order=order, copy=True) else: cropped = ar[slices] return cropped
def crop(ar, crop_width, copy=False, order='K'): '''Crop numpy array at the borders by crop_width. Source: www.github.com/scikit-image.''' ar = np.array(ar, copy=False) crops = _validate_lengths(ar, crop_width) slices = [slice(a, ar.shape[i] - b) for i, (a, b) in enumerate(crops)] if copy: cropped = np.array(ar[slices], order=order, copy=True) else: cropped = ar[slices] return cropped
def pad(self, pad_width, mode='reflect', **kwargs): """ Pad sky image at the edges. Calls `numpy.pad`, passing ``mode`` and ``kwargs`` to it and adapts the wcs specifcation. Parameters ---------- pad_width : {sequence, array_like, int} Number of values padded to the edges of each axis, passed to `numpy.pad` mode : str ('reflect') Padding mode, passed to `numpy.pad`. Returns ------- image : `~gammapy.image.SkyImage` Padded image Examples -------- >>> from gammapy.image import SkyImage >>> image = SkyImage.empty(nxpix=10, nypix=13) >>> print(image.data.shape) (13, 10) >>> image2 = image.pad(pad_width=4, mode='reflect') >>> image2.data.shape (18, 21) """ # converting from unicode to ascii string as a workaround # for https://github.com/numpy/numpy/issues/7112 mode = str(mode) pad_width = _validate_lengths(self.data, pad_width) xlo, xhi = pad_width[self._ax_idx.x] ylo, yhi = pad_width[self._ax_idx.y] data = np.pad(self.data, pad_width=pad_width, mode=mode, **kwargs) wcs = self.wcs.deepcopy() wcs.wcs.crpix += np.array([xlo, ylo]) return self.__class__(name=self.name, data=data, wcs=wcs, unit=self.unit)
def crop(ar, crop_width, copy=False, order='K'): """Crop array `ar` by `crop_width` along each dimension. Parameters ---------- ar : array-like of rank N Input array. crop_width : {sequence, int} Number of values to remove from the edges of each axis. ``((before_1, after_1),`` ... ``(before_N, after_N))`` specifies unique crop widths at the start and end of each axis. ``((before, after),)`` specifies a fixed start and end crop for every axis. ``(n,)`` or ``n`` for integer ``n`` is a shortcut for before = after = ``n`` for all axes. copy : bool, optional If `True`, ensure the returned array is a contiguous copy. Normally, a crop operation will return a discontiguous view of the underlying input array. order : {'C', 'F', 'A', 'K'}, optional If ``copy==True``, control the memory layout of the copy. See ``np.copy``. Returns ------- cropped : array The cropped array. If ``copy=False`` (default), this is a sliced view of the input array. """ ar = np.array(ar, copy=False) if old_numpy: crops = _validate_lengths(ar, crop_width) else: crops = _as_pairs(crop_width, ar.ndim, as_index=True) slices = tuple(slice(a, ar.shape[i] - b) for i, (a, b) in enumerate(crops)) if copy: cropped = np.array(ar[slices], order=order, copy=True) else: cropped = ar[slices] return cropped
def tf_pad_wrap(array, pad_width): """ Modified from numpy.lib.arraypad.wrap """ if not np.asarray(pad_width).dtype.kind == 'i': raise TypeError('`pad_width` must be of integral type.') pad_width = _validate_lengths(_DummyArray(array.get_shape().ndims), pad_width) for axis, (pad_before, pad_after) in enumerate(pad_width): if array.get_shape().as_list()[axis] is None and (pad_before > 0 or pad_after > 0): raise TypeError( '`pad_width` must be zero for dimensions that are None.') # If we get here, use new padding method newmat = tf.identity(array) for axis, (pad_before, pad_after) in enumerate(pad_width): # Recursive padding along any axis where `pad_amt` is too large # for indexing tricks. We can only safely pad the original axis # length, to keep the period of the reflections consistent. safe_pad = newmat.get_shape().as_list()[axis] if safe_pad is None: continue while ((pad_before > safe_pad) or (pad_after > safe_pad)): pad_iter_b = min(safe_pad, safe_pad * (pad_before // safe_pad)) pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad)) newmat = _pad_wrap(newmat, (pad_iter_b, pad_iter_a), axis) pad_before -= pad_iter_b pad_after -= pad_iter_a safe_pad += pad_iter_b + pad_iter_a newmat = _pad_wrap(newmat, (pad_before, pad_after), axis) return newmat