def __init__(self, A, S, lmbda, opt=None, axes=(0, 1), caxis=None): """ Initialise a TVL2Deconv object with problem parameters. Parameters ---------- A : array_like Filter kernel corresponding to operator :math:`H` above S : array_like Signal vector or matrix lmbda : float Regularisation parameter opt : TVL2Deconv.Options object Algorithm options axes : tuple or list Axes on which TV regularisation is to be applied caxis : int or None, optional (default None) Axis on which channels of a multi-channel image are stacked. If None, TV regularisation is applied indepdendently to each channel, otherwise Vector TV :cite:`blomgren-1998-color` regularisation is applied jointly to all channels. """ if opt is None: opt = TVL2Deconv.Options() # Set dtype attribute based on S.dtype and opt['DataType'] self.set_dtype(opt, S.dtype) self.S = np.asarray(S, dtype=self.dtype) self.axes = axes if caxis is None: self.saxes = (-1,) else: self.saxes = (caxis, -1) self.lmbda = self.dtype.type(lmbda) # Set penalty parameter self.set_attr('rho', opt['rho'], dval=(2.0*self.lmbda + 0.1), dtype=self.dtype) yshape = S.shape + (len(axes),) super(TVL2Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt) self.axshp = [S.shape[k] for k in axes] self.A = sl.atleast_nd(S.ndim, A.astype(self.dtype)) self.Af = sl.rfftn(self.A, self.axshp, axes=axes) self.Sf = sl.rfftn(self.S, axes=axes) self.AHAf = np.conj(self.Af)*self.Af self.AHSf = np.conj(self.Af)*self.Sf self.Wtv = np.asarray(self.opt['TVWeight'], dtype=self.dtype) if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim: self.Wtvna = self.Wtv[..., np.newaxis] else: self.Wtvna = self.Wtv # Construct gradient operators in frequency domain self.Gf, self.GHGf = sl.GradientFilters(S.ndim, axes, self.axshp, dtype=self.dtype)
def rgb2gray(rgb): """Convert RGB image to grayscale. Parameters ---------- rgb : ndarray RGB image as Nr x Nc x 3 or Nr x Nc x 3 x K array Returns ------- gry : ndarray Grayscale image as Nr x Nc or Nr x Nc x K array """ w = sla.atleast_nd( rgb.ndim, np.array([0.299, 0.587, 0.144], dtype=rgb.dtype, ndmin=3)) return np.sum(w * rgb, axis=2)
def rgb2gray(rgb): """Convert an RGB image (or images) to grayscale. Parameters ---------- rgb : ndarray RGB image as Nr x Nc x 3 or Nr x Nc x 3 x K array Returns ------- gry : ndarray Grayscale image as Nr x Nc or Nr x Nc x K array """ w = sla.atleast_nd(rgb.ndim, np.array([0.299, 0.587, 0.144], dtype=rgb.dtype, ndmin=3)) return np.sum(w * rgb, axis=2)
def __init__(self, A, S, lmbda, opt=None, axes=(0, 1), caxis=None): """ | **Call graph** .. image:: ../_static/jonga/tvl1dcn_init.svg :width: 20% :target: ../_static/jonga/tvl1dcn_init.svg | Parameters ---------- A : array_like Filter kernel corresponding to operator :math:`H` above S : array_like Signal vector or matrix lmbda : float Regularisation parameter opt : TVL1Deconv.Options object Algorithm options axes : tuple, optional (default (0,1)) Axes on which TV regularisation is to be applied caxis : int or None, optional (default None) Axis on which channels of a multi-channel image are stacked. If None, TV regularisation is applied indepdendently to each channel, otherwise Vector TV :cite:`blomgren-1998-color` regularisation is applied jointly to all channels. """ if opt is None: opt = TVL1Deconv.Options() # Set dtype attribute based on S.dtype and opt['DataType'] self.set_dtype(opt, S.dtype) self.axes = axes self.axsz = tuple(np.asarray(S.shape)[list(axes)]) if caxis is None: self.saxes = (-1, ) else: self.saxes = (caxis, -1) self.lmbda = self.dtype.type(lmbda) # Set penalty parameter self.set_attr('rho', opt['rho'], dval=(2.0 * self.lmbda + 0.1), dtype=self.dtype) yshape = S.shape + (len(axes) + 1, ) self.S = np.asarray(S, dtype=self.dtype) super(TVL1Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt) self.axshp = tuple([S.shape[k] for k in axes]) self.A = sl.atleast_nd(S.ndim, A.astype(self.dtype)) self.Af = sl.rfftn(self.A, self.axshp, axes=axes) self.Sf = sl.rfftn(self.S, axes=axes) self.AHAf = np.conj(self.Af) * self.Af self.AHSf = np.conj(self.Af) * self.Sf self.Wdf = np.asarray(self.opt['DFidWeight'], dtype=self.dtype) self.Wtv = np.asarray(self.opt['TVWeight'], dtype=self.dtype) if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim: self.Wtvna = self.Wtv[..., np.newaxis] else: self.Wtvna = self.Wtv self.Gf, self.GHGf = sl.GradientFilters(S.ndim, axes, self.axshp, dtype=self.dtype) self.GAf = np.concatenate((self.Gf, self.Af[..., np.newaxis]), axis=self.Gf.ndim - 1)
def __init__(self, A, S, lmbda, opt=None, axes=(0,1), caxis=None): """ Initialise a TVL1Deconv object with problem parameters. Parameters ---------- A : array_like Filter kernel corresponding to operator :math:`H` above S : array_like Signal vector or matrix lmbda : float Regularisation parameter opt : TVL1Deconv.Options object Algorithm options axes : tuple, optional (default (0,1)) Axes on which TV regularisation is to be applied caxis : int or None, optional (default None) Axis on which channels of a multi-channel image are stacked. If None, TV regularisation is applied indepdendently to each channel, otherwise Vector TV :cite:`blomgren-1998-color` regularisation is applied jointly to all channels. """ if opt is None: opt = TVL1Deconv.Options() # Set dtype attribute based on S.dtype and opt['DataType'] self.set_dtype(opt, S.dtype) self.axes = axes if caxis is None: self.saxes = (-1,) else: self.saxes = (caxis,-1) self.lmbda = self.dtype.type(lmbda) # Set penalty parameter self.set_attr('rho', opt['rho'], dval=(2.0*self.lmbda + 0.1), dtype=self.dtype) yshape = S.shape + (len(axes)+1,) self.S = np.asarray(S, dtype=self.dtype) super(TVL1Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt) self.axshp = [S.shape[k] for k in axes] self.A = sl.atleast_nd(S.ndim, A.astype(self.dtype)) self.Af = sl.rfftn(self.A, self.axshp, axes=axes) self.Sf = sl.rfftn(self.S, axes=axes) self.AHAf = np.conj(self.Af)*self.Af self.AHSf = np.conj(self.Af)*self.Sf self.Wdf = np.asarray(self.opt['DFidWeight'], dtype=self.dtype) self.Wtv = np.asarray(self.opt['TVWeight'], dtype=self.dtype) if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim: self.Wtvna = self.Wtv[...,np.newaxis] else: self.Wtvna = self.Wtv self.Gf, self.GHGf = sl.GradientFilters(S.ndim, axes, self.axshp, dtype=self.dtype) self.GAf = np.concatenate((self.Gf, self.Af[...,np.newaxis]), axis=self.Gf.ndim-1) # Increment `runtime` to reflect object initialisation # time. The timer object is reset to avoid double-counting of # elapsed time if a similar increment is applied in a derived # class __init__. self.runtime += self.timer.elapsed(reset=True)
def __init__(self, A, S, lmbda, opt=None, axes=(0, 1)): """ Initialise a TVL2Deconv object with problem parameters. Parameters ---------- A : array_like Filter kernel (see :math:`\mathbf{h}` above) S : array_like Signal vector or matrix lmbda : float Regularisation parameter opt : TVL2Deconv.Options object Algorithm options axes : tuple or list Axes on which TV regularisation is to be applied """ if opt is None: opt = TVL2Deconv.Options() # Set dtype attribute based on S.dtype and opt['DataType'] self.set_dtype(opt, S.dtype) self.S = np.asarray(S, dtype=self.dtype) self.axes = axes self.lmbda = self.dtype.type(lmbda) # Set penalty parameter self.set_attr('rho', opt['rho'], dval=(2.0 * self.lmbda + 0.1), dtype=self.dtype) yshape = S.shape + (len(axes), ) super(TVL2Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt) self.axshp = [S.shape[k] for k in axes] self.A = sl.atleast_nd(S.ndim, A.astype(self.dtype)) self.Af = sl.rfftn(self.A, self.axshp, axes=axes) self.Sf = sl.rfftn(self.S, axes=axes) self.AHAf = np.conj(self.Af) * self.Af self.AHSf = np.conj(self.Af) * self.Sf self.Wtv = np.asarray(self.opt['TVWeight'], dtype=self.dtype) if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim: self.Wtvna = self.Wtv[..., np.newaxis] else: self.Wtvna = self.Wtv # Construct gradient operators in frequency domain self.Gf, self.GHGf = sl.GradientFilters(S.ndim, axes, self.axshp, dtype=self.dtype) # Increment `runtime` to reflect object initialisation # time. The timer object is reset to avoid double-counting of # elapsed time if a similar increment is applied in a derived # class __init__. self.runtime += self.timer.elapsed(reset=True)
def __init__(self, Z, S, W, dsz, opt=None, dimK=None, dimN=2): """ | **Call graph** .. image:: ../_static/jonga/ccmodmdfista_init.svg :width: 20% :target: ../_static/jonga/ccmodmdfista_init.svg | Parameters ---------- Z : array_like Coefficient map array S : array_like Signal array W : array_like Mask array. The array shape must be such that the array is compatible for multiplication with the *internal* shape of input array S (see :class:`.cnvrep.CDU_ConvRepIndexing` for a discussion of the distinction between *external* and *internal* data layouts). dsz : tuple Filter support size(s) opt : :class:`ConvCnstrMODMasked.Options` object Algorithm options dimK : 0, 1, or None, optional (default None) Number of dimensions in input signal corresponding to multiple independent signals dimN : int, optional (default 2) Number of spatial dimensions """ # Set default options if none specified if opt is None: opt = ConvCnstrMODMask.Options() # Infer problem dimensions and set relevant attributes of self self.cri = cr.CDU_ConvRepIndexing(dsz, S, dimK=dimK, dimN=dimN) # Append singleton dimensions to W if necessary if hasattr(W, 'ndim'): W = sl.atleast_nd(self.cri.dimN + 3, W) # Reshape W if necessary (see discussion of reshape of S in # ccmod base class) if self.cri.Cd == 1 and self.cri.C > 1 and hasattr(W, 'ndim'): # In most cases broadcasting rules make it possible for W # to have a singleton dimension corresponding to a # non-singleton dimension in S. However, when S is # reshaped to interleave axisC and axisK on the same axis, # broadcasting is no longer sufficient unless axisC and # axisK of W are either both singleton or both of the same # size as the corresponding axes of S. If neither of these # cases holds, it is necessary to replicate the axis of W # (axisC or axisK) that does not have the same size as the # corresponding axis of S. shpw = list(W.shape) swck = shpw[self.cri.axisC] * shpw[self.cri.axisK] if swck > 1 and swck < self.cri.C * self.cri.K: if W.shape[self.cri.axisK] == 1 and self.cri.K > 1: shpw[self.cri.axisK] = self.cri.K else: shpw[self.cri.axisC] = self.cri.C W = np.broadcast_to(W, shpw) self.W = W.reshape( W.shape[0:self.cri.dimN] + (1, W.shape[self.cri.axisC] * W.shape[self.cri.axisK], 1)) else: self.W = W super(ConvCnstrMODMask, self).__init__(Z, S, dsz, opt, dimK, dimN) # Create byte aligned arrays for FFT calls self.WRy = sl.pyfftw_empty_aligned(self.S.shape, dtype=self.dtype) self.Ryf = sl.pyfftw_rfftn_empty_aligned(self.S.shape, self.cri.axisN, self.dtype)
def __init__(self, Z, S, W, dsz, opt=None, dimK=None, dimN=2): """ | **Call graph** .. image:: ../_static/jonga/ccmodmdfista_init.svg :width: 20% :target: ../_static/jonga/ccmodmdfista_init.svg | Parameters ---------- Z : array_like Coefficient map array S : array_like Signal array W : array_like Mask array. The array shape must be such that the array is compatible for multiplication with the *internal* shape of input array S (see :class:`.cnvrep.CDU_ConvRepIndexing` for a discussion of the distinction between *external* and *internal* data layouts). dsz : tuple Filter support size(s) opt : :class:`ConvCnstrMODMasked.Options` object Algorithm options dimK : 0, 1, or None, optional (default None) Number of dimensions in input signal corresponding to multiple independent signals dimN : int, optional (default 2) Number of spatial dimensions """ # Set default options if none specified if opt is None: opt = ConvCnstrMODMask.Options() # Infer problem dimensions and set relevant attributes of self self.cri = cr.CDU_ConvRepIndexing(dsz, S, dimK=dimK, dimN=dimN) # Append singleton dimensions to W if necessary if hasattr(W, 'ndim'): W = sl.atleast_nd(self.cri.dimN + 3, W) # Reshape W if necessary (see discussion of reshape of S in # ccmod base class) if self.cri.Cd == 1 and self.cri.C > 1 and hasattr(W, 'ndim'): # In most cases broadcasting rules make it possible for W # to have a singleton dimension corresponding to a # non-singleton dimension in S. However, when S is # reshaped to interleave axisC and axisK on the same axis, # broadcasting is no longer sufficient unless axisC and # axisK of W are either both singleton or both of the same # size as the corresponding axes of S. If neither of these # cases holds, it is necessary to replicate the axis of W # (axisC or axisK) that does not have the same size as the # corresponding axis of S. shpw = list(W.shape) swck = shpw[self.cri.axisC] * shpw[self.cri.axisK] if swck > 1 and swck < self.cri.C * self.cri.K: if W.shape[self.cri.axisK] == 1 and self.cri.K > 1: shpw[self.cri.axisK] = self.cri.K else: shpw[self.cri.axisC] = self.cri.C W = np.broadcast_to(W, shpw) self.W = W.reshape(W.shape[0:self.cri.dimN] + (1, W.shape[self.cri.axisC] * W.shape[self.cri.axisK], 1)) else: self.W = W super(ConvCnstrMODMask, self).__init__(Z, S, dsz, opt, dimK, dimN) # Create byte aligned arrays for FFT calls self.WRy = sl.pyfftw_empty_aligned(self.S.shape, dtype=self.dtype) self.Ryf = sl.pyfftw_rfftn_empty_aligned(self.S.shape, self.cri.axisN, self.dtype)
def __init__(self, A, S, lmbda, opt=None, axes=(0, 1), caxis=None): """ | **Call graph** .. image:: ../_static/jonga/tvl2dcn_init.svg :width: 20% :target: ../_static/jonga/tvl2dcn_init.svg | Parameters ---------- A : array_like Filter kernel corresponding to operator :math:`H` above S : array_like Signal vector or matrix lmbda : float Regularisation parameter opt : TVL2Deconv.Options object Algorithm options axes : tuple or list Axes on which TV regularisation is to be applied caxis : int or None, optional (default None) Axis on which channels of a multi-channel image are stacked. If None, TV regularisation is applied indepdendently to each channel, otherwise Vector TV :cite:`blomgren-1998-color` regularisation is applied jointly to all channels. """ if opt is None: opt = TVL2Deconv.Options() # Set dtype attribute based on S.dtype and opt['DataType'] self.set_dtype(opt, S.dtype) self.S = np.asarray(S, dtype=self.dtype) self.axes = axes self.axsz = np.asarray(S.shape)[list(axes)] if caxis is None: self.saxes = (-1,) else: self.saxes = (caxis, -1) self.lmbda = self.dtype.type(lmbda) # Set penalty parameter self.set_attr('rho', opt['rho'], dval=(2.0*self.lmbda + 0.1), dtype=self.dtype) yshape = S.shape + (len(axes),) super(TVL2Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt) self.axshp = [S.shape[k] for k in axes] self.A = sl.atleast_nd(S.ndim, A.astype(self.dtype)) self.Af = sl.rfftn(self.A, self.axshp, axes=axes) self.Sf = sl.rfftn(self.S, axes=axes) self.AHAf = np.conj(self.Af)*self.Af self.AHSf = np.conj(self.Af)*self.Sf self.Wtv = np.asarray(self.opt['TVWeight'], dtype=self.dtype) if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim: self.Wtvna = self.Wtv[..., np.newaxis] else: self.Wtvna = self.Wtv # Construct gradient operators in frequency domain self.Gf, self.GHGf = sl.GradientFilters(S.ndim, axes, self.axshp, dtype=self.dtype)