def _deformation_grid(self):
        """
        Get a new random deformation grid
        :return: deformation tensor
        """
        sigma = np.random.rand() * self.sigma
        displacement = np.random.randn(*self.points, 2) * sigma

        # filter the displacement
        displacement_f = np.zeros_like(displacement)
        for d in range(0, displacement.ndim - 1):
            spline_filter1d(displacement, axis=d, order=3, output=displacement_f, mode='nearest')
            displacement = displacement_f

        # resample to proper size
        displacement_f = np.zeros((self.shape[0], self.shape[1], self.shape[2], 2))
        for d in range(0, displacement.ndim - 1):
            displacement_f[:, :, :, d] = cv2.resize(displacement[:, :, :, d], dsize=self.shape,
                                                    interpolation=cv2.INTER_CUBIC)

        displacement = torch.Tensor(displacement_f).unsqueeze(0)
        if self.cuda:
            displacement = displacement.cuda()
        grid = self.grid + displacement

        return grid
示例#2
0
def test_spline_filter_vs_matrix_solution(order):
    n = 100
    eye = np.eye(n, dtype=float)
    spline_filter_axis_0 = ndimage.spline_filter1d(eye, axis=0, order=order)
    spline_filter_axis_1 = ndimage.spline_filter1d(eye, axis=1, order=order)
    matrix = make_spline_knot_matrix(n, order)
    assert_almost_equal(eye, np.dot(spline_filter_axis_0, matrix))
    assert_almost_equal(eye, np.dot(spline_filter_axis_1, matrix.T))
def test_spline_filter_vs_matrix_solution(order):
    n = 100
    eye = np.eye(n, dtype=float)
    spline_filter_axis_0 = ndimage.spline_filter1d(eye, axis=0, order=order)
    spline_filter_axis_1 = ndimage.spline_filter1d(eye, axis=1, order=order)
    matrix = make_spline_knot_matrix(n, order)
    assert_almost_equal(eye, np.dot(spline_filter_axis_0, matrix))
    assert_almost_equal(eye, np.dot(spline_filter_axis_1, matrix.T))
示例#4
0
def image_process(data,
                  mode="gaussian",
                  sigma=2.5,
                  order=0,
                  weight=None,
                  weightMtxSize=7,
                  convMode="constant",
                  cval=0.0,
                  splineOrder=1.0):
    if mode == "convolve":
        # if weight is None, create a weight matrix
        if weight is None:
            weight = np.ones((weightMtxSize, weightMtxSize))
            center = (weightMtxSize - 1) / 2
            for i in range(-(center), center + 1, 1):
                for j in range(-(center), center + 1, 1):
                    weight[i][j] /= math.pow(2.0, max(abs(i), abs(j)))
        return ndimage.convolve(data, weight, mode=convMode, cval=cval)
    elif mode == "fourier_gaussian":
        return ndimage.fourier_gaussian(data, sigma=sigma)
    elif mode == "spline":
        return ndimage.spline_filter1d(data, order=splineOrder)
    else:
        if mode != "gaussian":
            print "apply Gaussian filter in image_process()"
        return ndimage.gaussian_filter(data, sigma=sigma, order=order)
示例#5
0
    def smooth(self, idata, mode, **kwargs):
        """Smooth data for contour() and contourf()

        idata is smoothed by convolve, fourier_gaussian, spline or
        gaussian (default). If contour_mode is 'convolve' and weight is None,
        the weight matrix is created automatically.

        Parameters
        -----------
        idata : numpy 2D array
            Input data
        mode : string
            'convolve','fourier','spline' or 'gaussian'

        Returns
        ---------
        odata : numpy 2D array

        See also
        ----------
        http://docs.scipy.org/doc/scipy/reference/ndimage.html

        """
        # modify default parameter
        self._set_defaults(kwargs)

        if mode == 'convolve':
            # if weight is None, create a weight matrix
            if self.convolve_weights is None:
                weights = np.ones(
                    (self.convolve_weightSize, self.convolve_weightSize))
                center = int((self.convolve_weightSize - 1) / 2)
                for i in range(-(center), center + 1, 1):
                    for j in range(-(center), center + 1, 1):
                        weights[i][j] /= pow(2.0, max(abs(i), abs(j)))
                self.convolve_weights = weights
            odata = ndimage.convolve(idata,
                                     weights=self.convolve_weights,
                                     mode=self.convolve_mode,
                                     cval=self.convolve_cval,
                                     origin=self.convolve_origin)
        elif mode == 'fourier':
            odata = ndimage.fourier_gaussian(idata,
                                             sigma=self.fourier_sigma,
                                             n=self.fourier_n,
                                             axis=self.fourier_axis)
        elif mode == 'spline':
            odata = ndimage.spline_filter1d(idata,
                                            order=self.spline_order,
                                            axis=self.spline_axis)
        else:
            if mode != 'gaussian':
                print('apply Gaussian filter in image_process()')
            odata = ndimage.gaussian_filter(idata,
                                            sigma=self.gaussian_sigma,
                                            order=self.gaussian_order,
                                            mode=self.gaussian_mode,
                                            cval=self.gaussian_cval)
        return odata
示例#6
0
    def smooth(self, idata, mode, **kwargs):
        '''Smooth data for contour() and contourf()

        idata is smoothed by convolve, fourier_gaussian, spline or
        gaussian (default). If contour_mode is 'convolve' and weight is None,
        the weight matrix is created automatically.

        Parameters
        -----------
        idata : numpy 2D array
            Input data
        mode : string
            'convolve','fourier','spline' or 'gaussian'

        Returns
        ---------
        odata : numpy 2D array

        See also
        ----------
        http://docs.scipy.org/doc/scipy/reference/ndimage.html

        '''
        # modify default parameter
        self._set_defaults(kwargs)

        if mode == 'convolve':
            # if weight is None, create a weight matrix
            if self.convolve_weights is None:
                weights = np.ones((self.convolve_weightSize,
                                   self.convolve_weightSize))
                center = (self.convolve_weightSize - 1) / 2
                for i in range(- (center), center + 1, 1):
                    for j in range(- (center), center + 1, 1):
                        weights[i][j] /= pow(2.0, max(abs(i), abs(j)))
                self.convolve_weights = weights
            odata = ndimage.convolve(idata,
                                     weights=self.convolve_weights,
                                     mode=self.convolve_mode,
                                     cval=self.convolve_cval,
                                     origin=self.convolve_origin)
        elif mode == 'fourier':
            odata = ndimage.fourier_gaussian(idata,
                                             sigma=self.fourier_sigma,
                                             n=self.fourier_n,
                                             axis=self.fourier_axis)
        elif mode == 'spline':
            odata = ndimage.spline_filter1d(idata,
                                            order=self.spline_order,
                                            axis=self.spline_axis)
        else:
            if mode != 'gaussian':
                print 'apply Gaussian filter in image_process()'
            odata = ndimage.gaussian_filter(idata,
                                            sigma=self.gaussian_sigma,
                                            order=self.gaussian_order,
                                            mode=self.gaussian_mode,
                                            cval=self.gaussian_cval)
        return odata
示例#7
0
def image_process(data, mode="gaussian", sigma=2.5, order=0, weight=None,
                  weightMtxSize=7, convMode="constant", cval=0.0,
                  splineOrder=1.0):
    if mode=="convolve":
        # if weight is None, create a weight matrix
        if weight is None:
            weight = np.ones((weightMtxSize, weightMtxSize))
            center = (weightMtxSize - 1) / 2
            for i in range(-(center), center+1, 1):
                for j in range(-(center), center+1, 1):
                    weight[i][j] /= math.pow(2.0, max(abs(i),abs(j)))
        return ndimage.convolve(data, weight, mode=convMode, cval=cval)
    elif mode=="fourier_gaussian":
        return ndimage.fourier_gaussian(data, sigma=sigma)
    elif mode=="spline":
        return ndimage.spline_filter1d(data, order=splineOrder)
    else:
        if mode!="gaussian":
            print "apply Gaussian filter in image_process()"
        return ndimage.gaussian_filter(data, sigma=sigma, order=order)
示例#8
0
def opt(obj, psf, theta=None, pad=False):
    """
    Simulate the OPT imaging of an object

    Parameters
    ----------
    obj : array [ZXY]
        the object to be imaged, ZX must be square
    psf : array [ZXY]
        the PSF of the imaging system, Z dimension must match object ZX
    theta : array, optional
        array of rotation angles (in degrees), by default None
        If None, uses numpy.arange(180).
    pad : bool, optional
        extend the field of view to see all contributions
        (needed if the object is not contained in the inner cylinder to the array), by default False

    Returns
    -------
    array [TPY]
        the imaged sinogram

    Raises
    ------
    ValueError
        if the PSF dimension does not match the object
    """

    if not obj.shape[0] == obj.shape[1]:
        raise NotImplementedError(
            'Please provide a square object in ZX dimensions')

    if psf.shape[0] % 2 != obj.shape[0] % 2:
        raise ValueError(
            'In order to correctly center the PSF,'
            ' please profide a PSF with the same Z axis parity as the object Z axis'
        )

    if theta is None:
        theta = np.arange(180)

    full_size = obj.shape[0]

    if pad:
        full_size = int(full_size * np.sqrt(2)) + 1
        pad_size = (full_size - obj.shape[0]) // 2
        full_size = obj.shape[0] + 2 * pad_size

    if psf.shape[0] < full_size:
        raise ValueError(
            'PSF Z size must be greater than padded object Z size: {} >= {}'.
            format(psf.shape[0], full_size))

    if pad and pad_size:
        obj = np.pad(obj, ((pad_size, ), (pad_size, ), (0, )))

    if pad:
        mode = 'full'
        sinogram = np.empty((theta.size, obj.shape[0] + psf.shape[1] - 1,
                             obj.shape[-1] + psf.shape[-1] - 1))
    else:
        mode = 'same'
        sinogram = np.empty((theta.size, obj.shape[0], obj.shape[-1]))

    splimage = ndimage.spline_filter1d(obj, axis=0)
    splimage = ndimage.spline_filter1d(obj, axis=1, output=splimage)

    crop_size = (psf.shape[0] - obj.shape[0]) // 2
    if crop_size:
        psf = psf[crop_size:-crop_size, ...]

    psf = np.flip(psf, 0)

    for idx, angle in enumerate(theta):
        rotated = ndimage.rotate(splimage,
                                 angle,
                                 prefilter=False,
                                 reshape=False)

        rotated = sig.fftconvolve(rotated, psf, axes=(1, 2), mode=mode)

        sinogram[idx, ...] = rotated.sum(0)

    return sinogram
 def to_spline(start, width):
     in_array = c[:, ..., start:start+width]
     out_array = output[:, ..., start:start+width]
     ndimage.spline_filter1d(
         in_array, degree, axis=0, mode=mode, output=out_array)
def convert_to_interpolation_coefficients(c, degree, tolerance=1e-9,
                                          boundary_condition='Mirror',
                                          in_place=False):
    """
    Computes the b-spline interpolation coefficients of a signal
    In the input array, the signals are considered along the first
    dimension (1D computations).
    """

    if degree == 0 or degree == 1 or c.shape[0] == 1:
        if not in_place:
            return c.copy()
        return c

    elif 2 <= degree <= 5:
        if boundary_condition.upper() == 'MIRROR':
            mode = 'mirror'
        elif boundary_condition.upper() == 'PERIODIC':
            mode = 'grid-wrap'
        else:
            raise ValueError(
                'Invalid boundary condition: {}'.format(boundary_condition))

        output = None
        if in_place:
            output = c

        if c.ndim < 2:
            output = ndimage.spline_filter1d(
                c, degree, axis=0, mode=mode, output=output)

        else:
            if output is None:
                output = np.empty_like(c)

            split_size = c.shape[-1]

            def to_spline(start, width):
                in_array = c[:, ..., start:start+width]
                out_array = output[:, ..., start:start+width]
                ndimage.spline_filter1d(
                    in_array, degree, axis=0, mode=mode, output=out_array)

            parallel.parallelize(to_spline, split_size)

        return output

    if not in_place:
        c = c.copy()

    if degree == 6:
        z = [-0.488294589303044755130118038883789062112279161239377608394,
             -0.081679271076237512597937765737059080653379610398148178525368,
             -0.00141415180832581775108724397655859252786416905534669851652709]
    elif degree == 7:
        z = [-0.5352804307964381655424037816816460718339231523426924148812,
             -0.122554615192326690515272264359357343605486549427295558490763,
             -0.0091486948096082769285930216516478534156925639545994482648003]
    elif degree == 8:
        z = [-0.57468690924876543053013930412874542429066157804125211200188,
             -0.163035269297280935240551896860737052234768145508298548489731,
             -0.0236322946948448500234039192963613206126659208546294370651457,
             -0.000153821310641690911739352530184021607629640540700430019629940]
    elif degree == 9:
        z = [-0.60799738916862577900772082395428976943963471853990829550220,
             -0.201750520193153238796064685055970434680898865757470649318867,
             -0.043222608540481752133321142979429688265852380231497069381435,
             -0.00212130690318081842030489655784862342205485609886239466341517]
    elif degree == 10:
        z = [-0.63655066396942385875799205491349773313787959010128860432339,
             -0.238182798377573284887456162200161978666543494059728787251924,
             -0.065727033228308551538201803949684252205121694392255863103034,
             -0.0075281946755486906437698340318148831650567567441314086093636,
             -0.0000169827628232746642307274679399688786114400132341362095006930]
    elif degree == 11:
        z = [-0.66126606890073470691013126292248166961816286716800880802421,
             -0.272180349294785885686295280258287768151235259565335176244192,
             -0.089759599793713309944142676556141542547561966017018544406214,
             -0.0166696273662346560965858360898150837154727205519335156053610]
    else:
        raise ValueError("Invalid spline degree {0}".format(degree))

    # compute overall gain
    z = np.atleast_1d(z)
    # apply gain to coeffs
    c *= np.prod((1 - z) * (1 - 1 / z))

    # loop over all poles
    for pole in z:
        # causal initialization
        c[0, ...] = initial_causal_coefficient(
            c, pole, tolerance, boundary_condition)
        # causal filter
        zinit = pole * c[0, ...]
        zinit = zinit[np.newaxis, ...]

        if c.ndim < 2:
            c[1:, ...], _ = signal.lfilter(
                [1], [1, -pole], c[1:, ...], axis=0, zi=zinit)

        else:
            split_size = c.shape[-1]

            def lfilt(start, width):
                c[1:, ..., start:start+width], _ = signal.lfilter(
                    [1], [1, -pole], c[1:, ..., start:start+width], axis=0, zi=zinit[:, ..., start:start+width])

            parallel.parallelize(lfilt, split_size)

        # anticausal initialization
        c[-1, ...] = initial_anticausal_coefficient(
            c, pole, boundary_condition=boundary_condition)
        # anticausal filter
        zinit = pole * c[-1, ...]
        zinit = zinit[np.newaxis, ...]

        if c.ndim < 2:
            c[:-1], _ = signal.lfilter([-pole], [1, -pole],
                                       np.flipud(c[0:-1, ...]), axis=0, zi=zinit)

        else:
            split_size = c.shape[-1]
            fc = np.flipud(c[0:-1, ...])

            def lfilt2(start, width):
                c[:-1, ...,  start:start+width], _ = signal.lfilter([-pole], [1, -pole],
                                                                    fc[:, ...,  start:start+width], axis=0, zi=zinit[:, ..., start:start+width])

            parallel.parallelize(lfilt2, split_size)

        c[:-1] = np.flipud(c[:-1])

    return c