def fft(array, interpolation=1.0, window='tukey', *kwargs): """ A n-dimensional Forward Discrete Fourier transform with some extra bells and whistles added on top of the standard Numpy method. :param array: the image to be transformed :type array: np.ndarray :param interpolation: Add "interpolation" to the FFT by zero-padding prior to transform. This is expressed as a multiple of the image size. :type interpolation: float :param window: a window function to apply. 'tukey' or 'hamming' :type window: str or None :return: the complex Fourier transform of the input array """ # Apply a Window if requested if window is None: pass elif window == 'tukey': array = windowing.apply_tukey_window(array, *kwargs) elif window == 'hamming': array = windowing.apply_hamming_window(array) # Add extra padding if interpolation > 1.0: new_shape = tuple(int(interpolation * i) for i in array.shape) array = ndarray.expand_to_shape(array, new_shape) # Transform forward array = np.fft.fftshift(np.fft.fftn(array)) return array
def __get_fourier_psfs(self): """ Pre-calculates the PSFs during image fusion process. """ psf = self.psf[:] if self.imdims == 3: adj_psf = psf[::-1, ::-1, ::-1] else: adj_psf = psf[::-1, ::-1] padded_block_size = tuple(self.block_size + 2*self.options.block_pad) psf_fft = ops_array.expand_to_shape(psf, padded_block_size).astype(np.complex64) adj_psf_fft = ops_array.expand_to_shape(adj_psf, padded_block_size).astype(np.complex64) psf_fft = np.fft.fftshift(psf_fft) adj_psf_fft = np.fft.fftshift(adj_psf_fft) self.psf_fft = np.fft.fftn(psf_fft) self.adj_psf_fft = np.fft.fftn(adj_psf_fft)
def __get_fourier_psfs(self): """ Pre-calculates the PSFs during image fusion process. """ print("Pre-calculating PSFs") padded_block_size = tuple(self.block_size + 2 * self.options.block_pad) memmap_shape = (self.n_views, ) + padded_block_size if self.options.disable_fft_psf_memmap: self.psfs_fft = numpy.zeros(memmap_shape, dtype=numpy.complex64) self.adj_psfs_fft = numpy.zeros(memmap_shape, dtype=numpy.complex64) else: psfs_fft_f = os.path.join(self.memmap_directory, "psf_fft_f.dat") self.psfs_fft = numpy.memmap(psfs_fft_f, dtype='complex64', mode='w+', shape=memmap_shape) adj_psfs_fft_f = os.path.join(self.memmap_directory, "adj_psf_fft_f.dat") self.adj_psfs_fft = numpy.memmap(adj_psfs_fft_f, dtype='complex64', mode='w+', shape=memmap_shape) for idx in range(self.n_views): self.psfs_fft[idx] = ops_array.expand_to_shape( self.psfs[idx], padded_block_size).astype(numpy.complex64) self.adj_psfs_fft[idx] = ops_array.expand_to_shape( self.adj_psfs[idx], padded_block_size).astype(numpy.complex64) self.psfs_fft[idx] = numpy.fft.fftshift(self.psfs_fft[idx]) self.adj_psfs_fft[idx] = numpy.fft.fftshift(self.adj_psfs_fft[idx]) self.psfs_fft[idx] = cp.asnumpy( fftpack.fftn(cp.asarray(self.psfs_fft[idx]), plan=self._fft_plan)) self.adj_psfs_fft[idx] = cp.asnumpy( fftpack.fftn(cp.asarray(self.adj_psfs_fft[idx]), plan=self._fft_plan))
def __get_fourier_psfs(self): """ Pre-calculates the PSFs during image fusion process. """ print("Pre-calculating PSFs") padded_block_size = tuple(self.block_size + 2 * self.options.block_pad) memmap_shape = numpy.insert(numpy.array(padded_block_size), 0, len(self.views)) if self.options.disable_fft_psf_memmap: self.psfs_fft = numpy.zeros(tuple(memmap_shape), dtype=numpy.complex64) self.adj_psfs_fft = numpy.zeros(tuple(memmap_shape), dtype=numpy.complex64) else: psfs_fft_f = os.path.join(self.memmap_directory, 'psf_fft_f.dat') self.psfs_fft = numpy.memmap(psfs_fft_f, dtype='complex64', mode='w+', shape=tuple(memmap_shape)) adj_psfs_fft_f = os.path.join(self.memmap_directory, 'adj_psf_fft_f.dat') self.adj_psfs_fft = numpy.memmap(adj_psfs_fft_f, dtype='complex64', mode='w+', shape=tuple(memmap_shape)) for idx in range(self.n_views): self.psfs_fft[idx] = ops_array.expand_to_shape( self.psfs[idx], padded_block_size).astype(numpy.complex64) self.adj_psfs_fft[idx] = ops_array.expand_to_shape( self.adj_psfs[idx], padded_block_size).astype(numpy.complex64) self.psfs_fft[idx] = numpy.fft.fftshift(self.psfs_fft[idx]) self.adj_psfs_fft[idx] = numpy.fft.fftshift(self.adj_psfs_fft[idx]) fft_inplace(self.psfs_fft[idx]) fft_inplace(self.adj_psfs_fft[idx])
def ifft(array_f, interpolation=1.0): """ A n-dimensional Inverse Discrete Fourier transform with some extra bells and whistles added on top of the standard Numpy method. Assumes a FFT shifted Fourier domain image. :param array_f: the image to be transformed :type array_f: np.ndarray :param interpolation: add interpolation, by defining a value > 1.0. Corresponds to enlargement of the result image. :type interpolation: float :return: returns the iFFTd array """ # Add padding if interpolation > 1.0: new_shape = tuple(int(interpolation * i) for i in array_f.shape) array_f = ndarray.expand_to_shape(array_f, new_shape) # Transform back iarray_f = np.fft.ifftn(np.fft.fftshift(array_f)) return iarray_f
def __init__(self, shape, d_bin, d_angle): """ :param shape: Shape of the data :param d_bin: The radius increment size (pixels) :param d_angle: The angle increment size (degrees) """ assert len(shape) == 3, "This iterator assumes a 3D shape" FourierShellIterator.__init__(self, shape, d_bin) plane = nputils.expand_to_shape(np.ones((1, shape[1], shape[2])), shape) self.plane = itkutils.convert_from_numpy(plane, (1, 1, 1)) self.rotated_plane = plane > 0 self.rotation_start = 0 self.rotation_stop = 360 / d_angle - 1 self.current_rotation = self.rotation_start self.angles = np.arange(0, 360, d_angle, dtype=int)