Ejemplo n.º 1
0
def julia_set_cp(zs, phase):
    ns = cp.zeros_like(Z, dtype=cp.float32)
    for i in range(n_iteration):
        # cupy doesn't support complex in where, we need to decompose it to real and img parts
        zs_real = cp.where(
            cp.abs(zs) < R, cp.real(zs**2 + 0.7885 * cp.exp(phase)),
            cp.real(zs))
        zs_imag = cp.where(
            cp.abs(zs) < R, cp.imag(zs**2 + 0.7885 * cp.exp(phase)),
            cp.imag(zs))
        zs = zs_real + 1j * zs_imag
        not_diverged = cp.abs(zs) < R
        ns = ns + not_diverged.astype(cp.float32)

    return ns, zs
Ejemplo n.º 2
0
    def quantize(self, voltages, custom_stds=None):
        """
        Quantize input complex voltages. Cache voltage means and standard deviations, per 
        polarization and per antenna.
        
        Parameters
        ----------
        voltages : array
            Array of complex voltages
        custom_stds : float, list, or array
            Custom standard deviation to use for scaling, instead of automatic calculation. Each quantizer will go
            from custom_stds values to self.target_std. Can either be a single value or an array-like object of length
            2, to set the custom standard deviation for real and imaginary parts.
            
        Returns
        -------
        q_voltages : array
            Array of complex quantized voltages
        """
        try:
            assert len(custom_stds) == 2
        except TypeError:
            custom_stds = [custom_stds] * 2

        q_r = self.quantizer_r.quantize(xp.real(voltages),
                                        custom_std=custom_stds[0])
        q_i = self.quantizer_i.quantize(xp.imag(voltages),
                                        custom_std=custom_stds[1])

        self.stats_cache_r = self.quantizer_r.stats_cache
        self.stats_cache_i = self.quantizer_i.stats_cache

        return q_r + q_i * 1j
def cupy_signal(signal):
    amp = cp.sqrt(cp.real(signal * cp.conj(signal)))
    phase = cp.angle(signal)
    real = cp.real(signal)
    imag = cp.imag(signal)

    return amp, phase, real, imag
Ejemplo n.º 4
0
    def positive_constrain(self,dn_3D,dF_3D_2):
        n_med = 1.334
        wavelength = 532
        k2 = (2*np.pi*n_med/wavelength)**2
        n_med2 = n_med**2
        # dF_3D = cupy.multiply(cupy.subtract(cupy.divide(cupy.multiply(dn_3D,dn_3D),n_med2),1),-k2)
        # dF_3D = cupy.fft.fftn(dF_3D)
        # dF_3D[cupy.not_equal(dF_3D_2,0)] = dF_3D_2[cupy.not_equal(dF_3D_2,0)]
        # dF_3D   = cupy.fft.ifftn(dF_3D)    
        # dn_3D   = cupy.multiply(cupy.sqrt(cupy.add(cupy.divide(dF_3D,-k2), 1)), n_med)
        
        # dn_3D =  cupy.fft.fftshift(dn_3D);
        dn_3D[cupy.less(cupy.real(dn_3D),n_med)] = n_med+1j*cupy.imag(dn_3D[cupy.less(cupy.real(dn_3D),n_med)])
        dn_3D[cupy.less(cupy.imag(dn_3D),0)]     = cupy.real(dn_3D[cupy.less(cupy.imag(dn_3D), 0)])


        return dn_3D
def phase_optimization(filename_psf_target,scale=1,step=1.0,iterations=100,filename_phi="phases/foo.npy"):
    psf_target = np.load(filename_psf_target)
    print("Performing phase optimization...")
    if scale==1:
        Y = psf_target
        Y= cp.asarray(Y)
    else:
        dim_0 = scale*psf_target.shape[0]
        dim_1 = scale*psf_target.shape[1]
        dim = (dim_0,dim_1)
        Y= cv.resize(psf_target, dim, interpolation=cv.INTER_NEAREST)
        Y= cp.asarray(Y)
    if len(Y.shape)==2:
        Y = Y/cp.sum(Y)
    else:
        Y = Y/cp.reshape(cp.sum(Y,axis=(0,1)),(1,1)+Y.shape[2:])
    
    phi = cp.random.random_sample(Y.shape)*2.0*np.pi
    #phi = cp.fft.fftshift(cp.angle(cp.fft.fft2(cp.sqrt(Y),axes=(0, 1))),axes=(0,1))+2.0*np.pi
    losses = []
    #grads = []
    mempool.free_all_blocks()
    for i in range(iterations):
        
        h = cp.fft.ifft2(cp.fft.ifftshift(cp.exp(1.0j*phi),axes=(0, 1)),axes=(0, 1))
        psf_new = cp.square(cp.abs(h))
        if len(psf_new.shape)==2:
            norm = cp.sum(psf_new)
        else:
            norm = cp.reshape(cp.sum(psf_new,axis=(0,1)),(1,1)+psf_new.shape[2:])
        psf_new = psf_new/norm
        h = h/cp.sqrt(norm)
        
        D = (Y-psf_new)
        loss = cp.sum(cp.square(D))
        losses.append(loss)
        if i%100==0:
            print("Iteration {} of {}, Loss: {}".format(i,iterations,loss))
        
        gradient = -4.0*cp.imag(cp.exp(-1.0j*phi)*cp.fft.fftshift(cp.fft.fft2((D*h),axes=(0, 1)),axes=(0,1)))
        phi = phi - step*gradient
        #grads.append(cp.sum(gradient**2))
        mempool.free_all_blocks()
        
    print("Phase Optimization process completed!")
    phi_np = cp.asnumpy(phi)
    np.save(filename_phi,phi_np)
Ejemplo n.º 6
0
def rf_c2r(rf: ndarrayA) -> ndarrayA:
    r"""Convert complex RF to real RF

    Usage:
        ``rf = rf_c2r(rf)``
    Inputs:
        - ``rf``: `(N, 1, nT, (nCoils))`, RF pulse, complex
    Outputs:
        - ``rf``: `(N, xy, nT, (nCoils))`, RF pulse, x for real, y for imag.

    See Also:
        :func:`~mrphy.utils.rf_r2c`
    """
    if isinstance(rf, ndarray_c):
        return np.concatenate((np.real(rf), np.imag(rf)), axis=1)
    else:  # ndarray_g, i.e., cupy.ndarray
        return cp.concatenate((cp.real(rf), cp.imag(rf)), axis=1)
Ejemplo n.º 7
0
def quantize_complex(x,
                     target_mean=0,
                     target_std=32 / (2 * xp.sqrt(2 * xp.log(2))),
                     num_bits=8,
                     stats_calc_num_samples=10000):
    """
    Quantize complex voltage data to integers with specified number of bits
    and target FWHM range. 

    Parameters
    ----------
    x : array
        Array of complex voltages
    target_mean : float, optional
        Target mean for voltages
    target_std : float, optional
        Target standard deviation for voltages
    num_bits : int, optional
        Number of bits to quantize to. Quantized voltages will span -2**(num_bits - 1) 
        to 2**(num_bits - 1) - 1, inclusive.
    stats_calc_num_samples : int, optional
        Maximum number of samples for use in estimating noise statistics
        
    Returns
    -------
    q_c : array
        Array of complex quantized voltages
    """
    r, i = xp.real(x), xp.imag(x)

    q_r = quantize_real(r,
                        target_mean=target_mean,
                        target_std=target_std,
                        num_bits=num_bits,
                        stats_calc_num_samples=stats_calc_num_samples)

    q_i = quantize_real(i,
                        target_mean=target_mean,
                        target_std=target_std,
                        num_bits=num_bits,
                        stats_calc_num_samples=stats_calc_num_samples)

    q_c = q_r + q_i * 1j

    return q_c
Ejemplo n.º 8
0
    def backward(self, grad_out):
        """
        In the backward pass we receive a Tensor containing the gradient of the loss
        with respect to the output, and we need to compute the gradient of the loss
        with respect to the input. Thus, we need the gradient of the output with respect to the input,
        i.e. we need the gradient of the kernel tensor with respect to the phase profile.
        """
        # grad_out: gradient of loss function (scalar) wrt kernels, thus, has same shape as kernel tensor
        grad_out = grad_out.numpy()
        #grad_out = cp.asarray(grad_out)
        phi = cp.asarray(self.phi) 
        
        #First, we calculate the gradient of the loss function wrt the PSF
        #This will be in terms of the gradient of the loss function wrt the kernel tensor, grad_out
        def gradient_L_wrt_B(grad_out):
            
            grads_pos_pad = [np.pad(grad_out[:,:,:,i], ((pad,pad), (pad,pad),(0,0)), 'constant') for i in range(depth)]
            grads_pos = np.concatenate(
                [np.concatenate((grads_pos_pad[i*cols:(i+1)*cols]), axis=1) for i in range(rows)], axis=0)
            grads_neg_pad = [np.pad(-1.0*grad_out[:,:,:,i], ((pad,pad), (pad,pad),(0,0)), 'constant') for i in range(depth)]
            grads_neg = np.concatenate(
                [np.concatenate((grads_neg_pad[i*cols:(i+1)*cols]), axis=1) for i in range(rows)], axis=0)
            
            D = np.concatenate((grads_pos, grads_neg), axis=0)
            extra_pad_1 = (final_dim - np.shape(D)[0])//2
            extra_pad_2 = (final_dim - np.shape(D)[1])//2
            
            D = np.pad(D, ((extra_pad_1,extra_pad_1), (extra_pad_2,extra_pad_2),(0,0)), 'constant')
            dim = (final_dim*scale,final_dim*scale)
            D = cv.resize(D, dim, interpolation=cv.INTER_NEAREST)
        
            return D
        
                

        D = gradient_L_wrt_B(grad_out)        
        A = np.load(filename_crosstalk)
        H = np.matmul(A.reshape((1,1)+A.shape),D.reshape(D.shape+(1,))).reshape(D.shape)
        
        H = cp.asarray(H)
        #Now, we can use this gradient to efficiently calculate the gradient of the loss wrt the phases
        h = cp.fft.ifft2(cp.fft.ifftshift(cp.exp(1.0j*phi),axes=(0, 1)),axes=(0, 1))
        gradient_loss = 2.0*cp.imag(cp.exp(-1.0j*phi)*cp.fft.fftshift(cp.fft.fft2((H*h),axes=(0, 1)),axes=(0,1)))
        mempool.free_all_blocks()
        return gradient_loss*norm_factor
    def mul_phase(magnitudes, phase):
        """
        Parameters
        ------------
        magnitudes: pytorch tensor
        phase: cupy ndarray
        """
        phase_real = c2t(cp.real(phase))
        phase_imag = c2t(cp.imag(phase))

        input_real = magnitudes * phase_real
        input_imag = magnitudes * phase_imag

        # a virtual complex solution, since pytorch doesn't support complex type
        complex_spec = torch.cat(
            [input_real.unsqueeze(dim=-1),
             input_imag.unsqueeze(dim=-1)],
            dim=-1)
        return complex_spec
Ejemplo n.º 10
0
 def normalize(fft_image):
     re, im = cp.real(fft_image), cp.imag(fft_image)
     length = cp.sqrt(re * re + im * im)
     return fft_image / length
Ejemplo n.º 11
0
def ampli_cupy(complex_arr):
    return((((cp.imag(complex_arr) ** 2) + (cp.real(complex_arr) ** 2)) ** 0.5))
Ejemplo n.º 12
0
def phase_cupy(complex_arr):
    return(cp.arctan(cp.imag(complex_arr)/cp.real(complex_arr)))
Ejemplo n.º 13
0
    def calculate_correlations(record: OrderedDict,
                               averaging_method: str) -> tuple:
        """
        Calculates the auto- and cross-correlations for main and interferometer arrays given the bfiq data in record.

        Parameters
        ----------
        record: OrderedDict
            hdf5 record containing bfiq data and metadata
        averaging_method: str
            Averaging method. Supported types are 'mean' and 'median'

        Returns
        -------
        main_acfs: np.array
            Autocorrelation of the main array data
        intf_acfs: np.array
            Autocorrelation of the interferometer array data
        xcfs: np.array
            Cross-correlation of the main and interferometer arrays
        """
        # TODO: Figure out how to remove pulse offsets
        pulse_phase_offset = record['pulse_phase_offset']

        # bfiq data shape  = [num_arrays, num_sequences, num_beams, num_samps]
        bfiq_data = record['data']

        # Get the data and reshape
        num_arrays, num_sequences, num_beams, num_samps = record[
            'data_dimensions']
        bfiq_data = bfiq_data.reshape(record['data_dimensions'])

        num_lags = len(record['lags'])
        main_corrs_unavg = xp.zeros(
            (num_sequences, num_beams, record['num_ranges'], num_lags),
            dtype=xp.complex64)
        intf_corrs_unavg = xp.zeros(
            (num_sequences, num_beams, record['num_ranges'], num_lags),
            dtype=xp.complex64)
        cross_corrs_unavg = xp.zeros(
            (num_sequences, num_beams, record['num_ranges'], num_lags),
            dtype=xp.complex64)

        # Loop through every sequence and compute correlations.
        # Output shape after loop is [num_sequences, num_beams, num_range_gates, num_lags]
        for sequence in range(num_sequences):
            # data input shape  = [num_antenna_arrays, num_beams, num_samps]
            # data return shape = [num_beams, num_range_gates, num_lags]
            main_corrs_unavg[sequence, ...] = \
                ProcessBfiq2Rawacf.correlations_from_samples(bfiq_data[0, sequence, :, :],
                                                             bfiq_data[0, sequence, :, :],
                                                             record)
            intf_corrs_unavg[sequence, ...] = \
                ProcessBfiq2Rawacf.correlations_from_samples(bfiq_data[1, sequence, :, :],
                                                             bfiq_data[1, sequence, :, :],
                                                             record)
            cross_corrs_unavg[sequence, ...] = \
                ProcessBfiq2Rawacf.correlations_from_samples(bfiq_data[1, sequence, :, :],
                                                             bfiq_data[0, sequence, :, :],
                                                             record)

        if averaging_method == 'median':
            main_corrs = xp.median(
                xp.real(main_corrs_unavg),
                axis=0) + 1j * xp.median(xp.imag(main_corrs_unavg), axis=0)
            intf_corrs = xp.median(
                xp.real(intf_corrs_unavg),
                axis=0) + 1j * xp.median(xp.imag(intf_corrs_unavg), axis=0)
            cross_corrs = xp.median(
                xp.real(cross_corrs_unavg),
                axis=0) + 1j * xp.median(xp.imag(cross_corrs_unavg), axis=0)
        else:
            # Using mean averaging
            main_corrs = xp.einsum('ijkl->jkl',
                                   main_corrs_unavg) / num_sequences
            intf_corrs = xp.einsum('ijkl->jkl',
                                   intf_corrs_unavg) / num_sequences
            cross_corrs = xp.einsum('ijkl->jkl',
                                    cross_corrs_unavg) / num_sequences

        main_acfs = main_corrs.flatten()
        intf_acfs = intf_corrs.flatten()
        xcfs = cross_corrs.flatten()

        return main_acfs, intf_acfs, xcfs
Ejemplo n.º 14
0
    #	cp_structure_factor.real[cp_amp%2==0]=cp_diff_amp[cp_amp%2==0] / cp.sqrt(2.0)
    #	cp_structure_factor.imag[cp_amp%2==0]=cp_diff_amp[cp_amp%2==0] / cp.sqrt(2.0)

    #	np_amp=cp.asnumpy(cp_amp)
    #	tifffile.imsave(header + "_" + str(i+1) + '_np_amp.tif' ,np_amp)

    #	cp_structure_factor_abs=cp.absolute(cp_structure_factor)
    #	np_structure_factor=cp.asnumpy(cp_structure_factor_abs)
    #	tifffile.imsave(header + "_" + str(i+1) + '_np_structure_factor_abs.tif' ,np_structure_factor)

    #

    cp_structure_factor = cp.fft.ifftshift(cp_structure_factor)
    cp_dens_pre = cp.fft.ifft2(cp_structure_factor, norm="ortho")
    cp_dens_pre_real = cp.real(cp_dens_pre)
    cp_dens_pre_imag = cp.imag(cp_dens_pre)
    cp_dens_pre_abs = cp.absolute(cp_dens_pre)

    #R-factorの計算

    R_dens = cp_dens_pre * cp_sup
    R_structure_factor = cp.fft.fft2(R_dens, norm="ortho")
    R_structure_factor = cp.fft.fftshift(R_structure_factor)
    R_amp = cp.absolute(R_structure_factor)

    if (i + 1 == int(fft_iteration)):
        np_R_amp = cp.asnumpy(cp.square(R_amp))  #cupy配列 ⇒ numpy配列に変換
        tifffile.imsave(header + "_" + str(i + 1).zfill(6) + '_diff.tif',
                        np_R_amp)

    amp2_sum = cp.sum(cp.square(R_amp))
                          str(scale_factor[n]) + " " + str(R_factor[n]) + " " +
                          str(OS_ratio[n]) + " " + str(gamma[n]))

    #実空間拘束

    cp_dens_bk = cp.real(cp_dens)

    cp_dens.real[cp_sup % 2 == 1] = cp_dens_pre.real[cp_sup % 2 == 1]
    cp_dens.real[(cp_dens_pre.real % 2 < 0.0) |
                 (cp_sup % 2 == 0)] = cp_dens_bk[
                     (cp_dens_pre.real % 2 < 0.0) |
                     (cp_sup % 2 == 0)] - 0.9 * cp_dens_pre.real[
                         (cp_dens_pre.real % 2 < 0.0) | (cp_sup % 2 == 0)]

    if (complex_constraint_flag == 1):
        cp_dens_imag_bk = cp.imag(cp_dens)
        cp_dens.imag[cp_sup % 2 == 1] = cp_dens_pre.imag[cp_sup % 2 == 1]
        cp_dens.imag[(cp_dens_pre.imag % 2 < 0.0) |
                     (cp_sup % 2 == 0)] = cp_dens_imag_bk[
                         (cp_dens_pre.imag % 2 < 0.0) |
                         (cp_sup % 2 == 0)] - 0.9 * cp_dens_pre.imag[
                             (cp_dens_pre.imag % 2 < 0.0) | (cp_sup % 2 == 0)]
    else:
        cp_dens.imag[:, :, :] = 0.0

    #OSS mask convolution

    if ((OSS_flag == 1) & ((i + 1) <= int(iteration))):
        cp_structure_factor = cp.fft.fftn(cp_dens, axes=(1, 2),
                                          norm="ortho")  #【フーリエ変換】
Ejemplo n.º 16
0
 def imag(arr):
     return cp.imag(arr)
Ejemplo n.º 17
0
    def collect_data_block(self, digitize=True, requantize=True, verbose=True):
        """
        General function to actually collect data from the antenna source and return coarsely channelized 
        complex voltages. Collects one block of data.
        
        Parameters
        ----------
        digitize : bool, optional
            Whether to quantize input voltages before the PFB
        requantize : bool, optional
            Whether to quantize output complex voltages after the PFB
        verbose : bool, optional
            Control whether tqdm prints progress messages 
            
        Returns
        -------
        final_voltages : array
            Complex voltages formatted according to GUPPI RAW specifications; array of shape 
            (num_chans * num_antennas, block_size / (num_chans * num_antennas))
        """
        obsnchan = self.num_chans * self.num_antennas
        final_voltages = np.empty((obsnchan, int(self.block_size / obsnchan)))

        if self.input_file_stem is not None:
            if not requantize:
                raise ValueError(
                    "Must set 'requantize=True' when using input RAW data!")
            input_voltages = self._read_next_block()

        # Make sure that block_size is appropriate
        assert self.block_size % int(
            obsnchan * self.num_taps * self.bytes_per_sample) == 0
        T = int(self.block_size / (obsnchan * self.bytes_per_sample))

        W = int(xp.ceil(T / self.num_taps / self.num_subblocks)) + 1
        subblock_T = self.num_taps * (W - 1)

        # Change self.num_subblocks if necessary
        self.num_subblocks = int(xp.ceil(T / subblock_T))
        subblock_t_len = int(subblock_T * self.bytes_per_sample)

        with tqdm(total=self.num_antennas * self.num_pols * self.num_subblocks,
                  leave=False) as pbar:
            pbar.set_description('Subblocks')

            for subblock in range(self.num_subblocks):
                if verbose:
                    tqdm.write(f'Creating subblock {subblock}...')

                # Change num windows at the end if self.num_subblocks doesn't go in evenly
                if T % subblock_T != 0 and subblock == self.num_subblocks - 1:
                    W = int((T % subblock_T) / self.num_taps) + 1

                if self.antenna_source.start_obs:
                    num_samples = self.num_branches * self.num_taps * W
                else:
                    num_samples = self.num_branches * self.num_taps * (W - 1)

                # Calculate the real voltage samples from each antenna
                t = time.time()
                antennas_v = self.antenna_source.get_samples(num_samples)
                self.sample_stage_t += time.time() - t

                for antenna in range(self.num_antennas):
                    if verbose and self.is_antenna_array:
                        tqdm.write(f'Creating antenna #{antenna}...')

                    c_idx = antenna * self.num_chans + np.arange(
                        0, self.num_chans)
                    for pol in range(self.num_pols):
                        # Store indices used for numpy data i/o per polarization
                        if T % subblock_T != 0 and subblock == self.num_subblocks - 1:
                            # Uses smaller num windows W
                            subblock_t_range = self.num_taps * (
                                W - 1) * self.bytes_per_sample
                        else:
                            subblock_t_range = subblock_t_len
                        t_idx = subblock * subblock_t_len + self.num_bits // 4 * pol + np.arange(
                            0, subblock_t_range,
                            self.num_bits // 4 * self.num_pols)

                        # Send voltage data through the backend
                        v = antennas_v[antenna][pol]

                        if digitize:
                            t = time.time()
                            v = self.digitizer[antenna][pol].quantize(v)
                            self.digitizer_stage_t += time.time() - t

                        t = time.time()
                        v = self.filterbank[antenna][pol].channelize(v)
                        v = v[:,
                              self.start_chan:self.start_chan + self.num_chans]
                        self.filterbank_stage_t += time.time() - t

                        if requantize:
                            t = time.time()

                            if self.input_file_stem is not None:
                                temp_mean_r = self.requantizer[antenna][
                                    pol].quantizer_r.target_mean
                                self.requantizer[antenna][
                                    pol].quantizer_r.target_mean = 0
                                temp_mean_i = self.requantizer[antenna][
                                    pol].quantizer_i.target_mean
                                self.requantizer[antenna][
                                    pol].quantizer_i.target_mean = 0

                                # Start off assuming signals are embedded in Gaussian noise with std 1
                                custom_stds = self.filterbank[antenna][
                                    pol].channelized_stds
                                # If digitizing real voltages, scale up by the appropriate factor
                                if digitize:
                                    custom_stds *= self.digitizer[antenna][
                                        pol].target_std
                                v = self.requantizer[antenna][pol].quantize(
                                    v, custom_stds=custom_stds)

                                self.requantizer[antenna][
                                    pol].quantizer_r.target_mean = temp_mean_r
                                self.requantizer[antenna][
                                    pol].quantizer_i.target_mean = temp_mean_i

                                if self.num_bits == 8:
                                    input_v = input_voltages[c_idx[:,
                                                                   np.newaxis],
                                                             (t_idx // 2
                                                              )[np.newaxis, :]]
                                elif self.num_bits == 4:
                                    input_v = input_voltages[
                                        c_idx[:, np.newaxis],
                                        t_idx[np.newaxis, :]]
                                input_v = xp.array(input_v)
                                v += input_v.T

                            v = self.requantizer[antenna][pol].quantize(v)
                            self.requantizer_stage_t += time.time() - t

                        # Convert to numpy array if using cupy
                        try:
                            R = xp.asnumpy(xp.real(v).T)
                            I = xp.asnumpy(xp.imag(v).T)
                        except AttributeError:
                            R = xp.real(v).T
                            I = xp.imag(v).T

                        if self.num_bits == 8 or not requantize:
                            final_voltages[c_idx[:, np.newaxis],
                                           t_idx[np.newaxis, :]] = R
                            final_voltages[c_idx[:, np.newaxis],
                                           (t_idx + 1)[np.newaxis, :]] = I
                        elif self.num_bits == 4:
                            # Translate 4 bit complex voltages to an 8 bit equivalent representation
                            I[I < 0] += 16
                            final_voltages[c_idx[:, np.newaxis],
                                           t_idx[np.newaxis, :]] = R * 16 + I
                        else:
                            raise ValueError(
                                f'{self.num_bits} bits not supported...')

                        pbar.update(1)

        return final_voltages
Ejemplo n.º 18
0
#%% ORIGIN constrain and reconstuct
 
# disp_3Dx = np.fft.fftshift(C_3D)
# print(np.sum(np.isnan(F_3Dx)))
plot_F_domain(np.fft.fftshift(F_3Dx), ffsize, df)
plot_F_domain(np.fft.fftshift(C_3D/C_3D), ffsize, df)

# dF_3Dx = cupy.fft.fftshift(dF_dst)
dF_3Dx = cupy.array(F_3Dx.copy())
dF_3D   = cupy.fft.ifftn(cupy.divide(dF_3Dx,dx))
dF_3D_2 = cupy.divide(dF_3Dx,dx)
dn_3D   = cupy.multiply(cupy.sqrt(cupy.add(cupy.divide(dF_3Dx,-k2), 1)), n_med)


# Positive constraint
dn_3D[cupy.less(cupy.real(dn_3D),n_med)] = cupy.real(n_med)+cupy.imag(dn_3D[cupy.less(cupy.real(dn_3D),n_med)])
dn_3D[cupy.less(cupy.imag(dn_3D),0)]     = cupy.real(dn_3D[cupy.less(cupy.imag(dn_3D), 0)])

n_3D_bi = np.zeros(dn_3D.shape,dtype=int)

# for iter in tqdm(range(0,100)): 
    
#     dF_3D = cupy.multiply(cupy.subtract(cupy.divide(cupy.multiply(dn_3D,dn_3D),n_med2),1),-k2)
#     dF_3D = cupy.fft.fftn(dF_3D)
#     dF_3D[cupy.not_equal(dF_3D_2,0)] = dF_3D_2[cupy.not_equal(dF_3D_2,0)]
#     dF_3D   = cupy.fft.ifftn(dF_3D)    
#     dn_3D   = cupy.multiply(cupy.sqrt(cupy.add(cupy.divide(dF_3D,-k2), 1)), n_med)
#     #Positive constraint
#     dn_3D[cupy.less(cupy.real(dn_3D),n_med)] = cupy.real(n_med)+cupy.imag(dn_3D[cupy.less(cupy.real(dn_3D),n_med)])
#     dn_3D[cupy.less(cupy.imag(dn_3D),0)]     = cupy.real(dn_3D[cupy.less(cupy.imag(dn_3D), 0)])
Ejemplo n.º 19
0
def phasecong100(im,
                 nscale=2,
                 norient=2,
                 minWavelength=7,
                 mult=2,
                 sigmaOnf=0.65):

    rows, cols = im.shape
    imagefft = fft2(im)
    zero = cp.zeros(shape=(rows, cols))

    EO = dict()
    EnergyV = cp.zeros((rows, cols, 3))

    x_range = cp.linspace(-0.5, 0.5, num=cols, endpoint=True)
    y_range = cp.linspace(-0.5, 0.5, num=rows, endpoint=True)

    x, y = cp.meshgrid(x_range, y_range)
    radius = cp.sqrt(x**2 + y**2)

    theta = cp.arctan2(-y, x)

    radius = ifftshift(radius)

    theta = ifftshift(theta)

    radius[0, 0] = 1.

    sintheta = cp.sin(theta)
    costheta = cp.cos(theta)

    lp = lowpass_filter((rows, cols), 0.45, 15)

    logGabor = []
    for s in range(1, nscale + 1):
        wavelength = minWavelength * mult**(s - 1.)
        fo = 1.0 / wavelength
        logGabor.append(
            cp.exp((-(cp.log(radius / fo))**2) / (2 * cp.log(sigmaOnf)**2)))
        logGabor[-1] *= lp
        logGabor[-1][0, 0] = 0

    # The main loop...
    for o in range(1, norient + 1):
        angl = (o - 1.) * cp.pi / norient
        ds = sintheta * cp.cos(angl) - costheta * cp.sin(angl)
        dc = costheta * cp.cos(angl) + sintheta * cp.sin(angl)
        dtheta = cp.abs(cp.arctan2(ds, dc))
        dtheta = cp.minimum(dtheta * norient / 2., cp.pi)
        spread = (cp.cos(dtheta) + 1.) / 2.
        sumE_ThisOrient = zero.copy()
        sumO_ThisOrient = zero.copy()
        for s in range(0, nscale):
            filter_ = logGabor[s] * spread
            EO[(s, o)] = ifft2(imagefft * filter_)
            sumE_ThisOrient = sumE_ThisOrient + cp.real(EO[(s, o)])
            sumO_ThisOrient = sumO_ThisOrient + cp.imag(EO[(s, o)])
        EnergyV[:, :, 0] = EnergyV[:, :, 0] + sumE_ThisOrient
        EnergyV[:, :, 1] = EnergyV[:, :, 1] + cp.cos(angl) * sumO_ThisOrient
        EnergyV[:, :, 2] = EnergyV[:, :, 2] + cp.sin(angl) * sumO_ThisOrient
    OddV = cp.sqrt(EnergyV[:, :, 0]**2 + EnergyV[:, :, 1]**2)
    featType = cp.arctan2(EnergyV[:, :, 0], OddV)
    return featType