Esempio n. 1
0
    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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
    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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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)