def test_ifft2(self): x = random((30, 20)) + 1j * random((30, 20)) expect = fft.ifft(fft.ifft(x, axis=1), axis=0) assert_array_almost_equal(expect, fft.ifft2(x)) assert_array_almost_equal(expect, fft.ifft2(x, norm="backward")) assert_array_almost_equal(expect * np.sqrt(30 * 20), fft.ifft2(x, norm="ortho")) assert_array_almost_equal(expect * (30 * 20), fft.ifft2(x, norm="forward"))
def invert(data, vel_locs, inv_w, inv_beta, eps_w, eps_beta): # invert for w, beta, or m given the observed elevation change h_obs # and possibly horizontal surface velocity (u_obs,v_obs) defined at locations vel_locs # # data = [h_obs,u_obs,v_obs] dim = inv_w + inv_beta vel_data = np.max(vel_locs) print('Solving normal equations with CG....\n') if inv_w == 1 and dim == 1: if vel_data == 0: b = adjoint_w(fft2(data[0])) elif vel_data == 1: b = h_wt * adjoint_w(fft2(data[0])) + u_wt * vel_locs * ( adjoint_Uw(fft2(data[1])) + adjoint_Vw(fft2(data[2]))) sol = cg_solve(b, inv_w, inv_beta, eps_w, eps_beta, vel_locs) fwd = ifft2(forward_w(sol)).real elif inv_beta == 1 and dim == 1: if vel_data == 0: b = h_wt * adjoint_beta(fft2(data[0])) elif vel_data == 1: b = h_wt * adjoint_beta(fft2(data[0])) + u_wt * vel_locs * ( adjoint_Ub(fft2(data[1])) + adjoint_Vb(fft2(data[2]))) sol = cg_solve(b, inv_w, inv_beta, eps_w, eps_beta, vel_locs) fwd = ifft2(forward_beta(sol)).real elif dim == 2: if vel_data == 1: b1 = h_wt * adjoint_w(fft2(data[0])) + u_wt * vel_locs * ( adjoint_Uw(fft2(data[1])) + adjoint_Vw(fft2(data[2]))) b2 = h_wt * adjoint_beta(fft2(data[0])) + u_wt * vel_locs * ( adjoint_Ub(fft2(data[1])) + adjoint_Vb(fft2(data[2]))) elif vel_data == 0: b1 = adjoint_w(fft2(data[0])) b2 = adjoint_beta(fft2(data[0])) b = np.array([b1, b2]) sol = cg_solve(b, inv_w, inv_beta, eps_w, eps_beta, vel_locs) h = ifft2(Hc(sol)).real u = ifft2(forward_U(sol[0], sol[1])).real v = ifft2(forward_V(sol[0], sol[1])).real fwd = np.array([h, u, v]) return sol, fwd
def test_resample(self): """ Compare resampling in Fourier space vs. real space i.e. compare resample() with resample_fourier_sp() :return: """ expand_x = 3 expand_y = 2 img = np.random.rand(30, 30) img_ft = fft.fft2(img) img_resampled_rs = tools.duplicate_pix(img, nx=expand_x, ny=expand_y) img_resampled_rs_ft = fft.fft2(img_resampled_rs) img_resampled_fs = tools.duplicate_pix_ft(img_ft, mx=expand_x, my=expand_y, centered=False) img_resampled_fs_rs = fft.ifft2(img_resampled_fs) err_fs = np.abs(img_resampled_fs - img_resampled_rs_ft).max() err_rs = np.abs(img_resampled_rs - img_resampled_fs_rs).max() self.assertTrue(err_fs < 1e-12) self.assertTrue(err_rs < 1e-12)
def Uzk(u0=None, z=50, lam=lam): A = fft2(U0) dx = np.diff(g)[0] kg = 2 * np.pi * fftfreq(n=len(g), d=dx) kx, ky = np.meshgrid(kg, kg) k = 1e6 * 2 * np.pi / lam return np.abs(ifft2(A * np.exp(-1j * z * np.sqrt(k**2 - kx**2 - ky**2))))
def filter(): file = Image.open('fourierPeriodic.JPEG') image = np.asarray(file) per = Image.open('periodic.JPEG') imagep = np.asarray(per) selectedFilter = request.json['filter'] nx = int(request.json['nx']) ny = int(request.json['ny']) newImage = [] inv = [] f = fft.fftshift(fft.fft2(imagep)) imager, imagei = getMagAndPhase(f) if selectedFilter == 'band': newImage = saveArrayImage('band', np.asarray(bandReject(image, nx, ny))) inv = inverse(np.asarray(bandReject(imager, nx, ny)), imagei) elif selectedFilter == 'notch': newImage = saveArrayImage('notch', np.asarray(notchFilter(image, nx, ny))) inv = inverse(np.asarray(notchFilter(imager, nx, ny)), imagei) else: newImage = saveArrayImage('fourierPeriodic', image) inv = inverse(imager, imagei) invF = fft.ifft2(inv) newImageInv = saveArrayImage('inverse', np.abs(invF)) return jsonify({'img': newImage, 'inv': newImageInv})
def mask(): click = request.json['click'] if click == 0: file = Image.open('fourierPeriodic.JPEG') fileOrg = Image.open('periodic.JPEG') elif click == 1: file = Image.open('mask.JPEG') fileOrg = Image.open('maskOrg.JPEG') width, height = file.size x = request.json['x'] y = request.json['y'] h = request.json['height'] w = request.json['width'] fx = math.floor(x / (w / width)) fy = math.floor(y / (h / height)) image = np.asarray(file) imageOrg = np.asarray(fileOrg) f = fft.fftshift(fft.fft2(imageOrg)) imager, imagei = getMagAndPhase(f) editedImage = image.copy() editedImage[fy, fx] = 0 editedImageOrg = imager.copy() editedImageOrg[fy, fx] = 0 editedImageFinal = saveArrayImage('mask', editedImage) inv = inverse(np.asarray(editedImageOrg), imagei) invF = fft.ifft2(inv) newImageInv = saveArrayImage('maskOrg', np.abs(invF)) return jsonify({'img': editedImageFinal, 'inv': newImageInv})
def step(self): """Advance the algorithm one iteration.""" G = fft.fft2(self.g) mse = _mean_square_error(abs(G), self.absF, self.mse_denom) phs_G = np.angle(G) Gprime = self.absF * np.exp(1j * phs_G) gprime = fft.ifft2(Gprime) # steepest descent is the same as GS until the time to form # g'' ... # g'' - g = -1/4 partial_g B = 1/2 (g' - g) # move g out of the LHS # -> g'' = 1/2 (g' - g) + g # if doublestep g'' = (g' - g) + g => g'' = g' if self.doublestep: gprimeprime = gprime else: gprimeprime = 0.5 * (gprime - self.g) + self.g # finally, apply the object domain constraint phs_gprime = np.angle(gprime) gprimeprime = self.absg * np.exp(1j * phs_gprime) self.costF.append(mse) self.iter += 1 self.g = gprimeprime return gprimeprime
def step(self): """Advance the algorithm one iteration.""" G = fft.fft2(self.g) mse = _mean_square_error(abs(G), self.absF, self.mse_denom) Bk = mse phs_G = np.angle(G) Gprime = self.absF * np.exp(1j * phs_G) gprime = fft.ifft2(Gprime) # this is the update described in Fienup1982 Eq. 36 # if self.iter == 0: # D = gprime - self.g # else: # D = (gprime - self.g) + (Bk/self.Bkm1) * self.Dkm1 # gprimeprime = self.g + self.hk * D gprimeprime = gprime + self.hk * (gprime - self.gprimekm1) # finally, apply the object domain constraint phs_gprime = np.angle(gprimeprime) gprimeprime = self.absg * np.exp(1j * phs_gprime) self.costF.append(mse) self.iter += 1 self.Bkm1 = Bk # bkm1 = "B_{k-1}"; B for iter k-1 # self.Dkm1 = D self.gprimekm1 = gprime self.g = gprimeprime return gprimeprime
def mifft2(a, overwrite_x = False): """Computes matrix ifft2 on a matrix of shape (..., n,n,4,4). This is identical to np.ifft2(a, axes = (-4,-3)) Parameters ---------- a : array_like Input array (must be complex). overwrite_x : bool Specifies whether original array can be destroyed (for inplace transform) Returns ------- out : complex ndarray Result of the transformation along the (-4,-3) axes. """ a = np.asarray(a, dtype = CDTYPE) libname = DTMMConfig["fftlib"] if libname == "mkl_fft": return mkl_fft.ifft2(a, axes = (-4,-3), overwrite_x = overwrite_x) elif libname == "scipy": return spfft.ifft2(a, axes = (-4,-3), overwrite_x = overwrite_x) elif libname == "numpy": return npfft.ifft2(a, axes = (-4,-3)) elif libname == "pyfftw": return pyfftw.interfaces.scipy_fft.ifft2(a, axes = (-4,-3), overwrite_x = overwrite_x) else: #default implementation is numpy return npfft.ifft2(a, axes = (-4,-3))
def step(self): """Advance the algorithm one iteration.""" G = fft.fft2(self.g) mseF = np.sum((abs(G) - self.absF)**2) / G.size phs_G = np.angle(G) Gprime = self.absF * np.exp(1j * phs_G) gprime = fft.ifft2(Gprime) msef = np.sum((abs(gprime) - self.absg)**2) / G.size gprimeprime = gprime # update g'' where the constraints are violated mask = abs(gprime) < 0 mask |= self.supportmask gprimeprime[~mask] = self.g[~mask] gprimeprime[mask] = self.g[mask] - self.beta * gprime[mask] # finally, apply the object domain constraint # phs_gprime = np.angle(gprimeprime) # gprimeprime = self.absg * np.exp(1j*phs_gprime) self.costF.append(mseF) self.costf.append(msef) self.iter += 1 self.g = gprimeprime return gprimeprime
def test_masked_registration_random_masks_non_equal_sizes(): """masked_register_translation should be able to register translations between images that are not the same size even with random masks.""" # See random number generator for reproducible results np.random.seed(23) reference_image = camera() shift = (-7, 12) shifted = np.real(fft.ifft2(fourier_shift( fft.fft2(reference_image), shift))) # Crop the shifted image shifted = shifted[64:-64, 64:-64] # Random masks with 75% of pixels being valid ref_mask = np.random.choice( [True, False], reference_image.shape, p=[3 / 4, 1 / 4]) shifted_mask = np.random.choice( [True, False], shifted.shape, p=[3 / 4, 1 / 4]) measured_shift = masked_register_translation( reference_image, shifted, reference_mask=np.ones_like(ref_mask), moving_mask=np.ones_like(shifted_mask)) assert_equal(measured_shift, -np.array(shift))
def fft_backward(pk, nx, ny): nkx = (nx-2)//3 nky = (ny-2)//3 pk_lx = 2*nkx+1 pk_ly = nky+1 pk_full = np.zeros((pk_lx, pk_ly+nky), dtype='c16') ph = np.zeros((nx, ny), dtype='c16') # in HMEq_FFTW, normalization coeff is applied at forward transformation # (caution!! ↑that treatment is different from ordinal FFT procedure!!# ) # realistic condition enforcing pattern coeff_norm = nx*ny for i in range(pk_lx): for j in range(pk_ly): pk_full[i, j+nky] = coeff_norm*pk[i, j] for i in range(pk_lx): for j in range(1, nky+1): ikx = i-nkx iky = j pk_full[i, j] = coeff_norm*pk[nkx-ikx, nky-iky].conjugate() # copy from pk_full to ph for i in range(pk_lx): for j in range(pk_ly+nky): ist = nx//2-nkx jst = ny//2-nky ph[i+ist, j+jst] = pk_full[i, j] phr = fftshift(ph) return np.real(ifft2(phr))
def xy_autocorr(im): ft = fft.fft2(im) ft_conj = np.conj(ft) m, n = ft.shape acf = np.real(fft.ifft2(ft * ft_conj)) acf = np.roll(acf, -m // 2 + 1, axis=0) acf = np.roll(acf, -n // 2 + 1, axis=1) return acf
def kinematicsim(crystal, kx, ky, energy=90): """ Propagate a plane wave through a crystal and compute the resulting diffraction pattern, in the kinematic approximation (thin specimen). .. versionadded:: 2.0.5 Parameters ---------- crystal : crystals.Crystal Crystal from which to scatter. kx, ky : `~numpy.ndarray`, shape (N,M) Momenta mesh where to calculate the diffraction pattern [:math:`Å^{-1}`] energy : float, optional Electron energy [keV] Returns ------- diff_pattern : `~numpy.ndarray` Scattered intensity. """ shape = tuple(map(fft.next_fast_len, kx.shape)) period_x, period_y, period_z = crystal.periodicity # We create the grid ourselves so that we minimize Fourier artifacts as much as possible. # It is much easier to interpolate to the requested grid than to prevent artifact formation. extent = 8 * period_x * period_y extent_x = np.linspace(0, extent, num=shape[0]) extent_y = np.linspace(0, extent, num=shape[1]) xx, yy = np.meshgrid( extent_x, extent_y, indexing="xy", ) kx_, ky_ = fft2freq(xx, yy, indexing="xy") k = np.hypot(kx_, ky_) potential = pelectrostatic(crystal, xx, yy) transmission_function = np.exp(1j * interaction_parameter(energy) * potential) exit_wave = fft.ifft2( fft.fft2(np.ones_like(xx, dtype=complex) * transmission_function) ) intensity = fft.fftshift(np.abs(fft.fft2(exit_wave)) ** 2) kx_ = fft.fftshift(kx_) ky_ = fft.fftshift(ky_) # Note that the definition of 'frequency' in fftfreq & friends necessitates dividing by 2pi twopi = 2 * np.pi return RegularGridInterpolator( points=(kx_[0, :], ky_[:, 0]), values=intensity, bounds_error=False, fill_value=0, ).__call__(xi=(kx / twopi, ky / twopi))
def test_ihfft2(self): x = random((30, 20)) expect = fft.ifft2(x)[:, :11] assert_array_almost_equal(expect, fft.ihfft2(x)) assert_array_almost_equal(expect, fft.ihfft2(x, norm="backward")) assert_array_almost_equal(expect * np.sqrt(30 * 20), fft.ihfft2(x, norm="ortho")) assert_array_almost_equal(expect * (30 * 20), fft.ihfft2(x, norm="forward"))
def power_spec(temp, source): """ Compute power spectrum via fft. Much fast than a convolution """ data_fft = fft2(temp) data_fft2 = np.conj(fft2(source)) x = np.multiply(data_fft, data_fft2) x /= np.abs(x) return ifft2(x).real
def gaugeField(self): """ Calculates the gauge field for the given color charge distribution by solving the (modified) Poisson equation involving the color charge field using Fourier method. If the field already exists, it is simply returned and no calculation is done. """ if self._gaugeFieldExists: return self._gaugeField # Make sure the charge field has already been generated (if not, this will generate it) self.colorChargeField() # Compute the fourier transform of the charge field chargeDensityFFTArr = fft2(self._colorChargeField, axes=(-2, -1), norm=self.fftNormalization) # This function calculates the individual elements of the gauge field in fourier space, # which we can then ifft back to get the actual gauge field # This expression was acquired by def AHat_mn(m, n, chargeFieldFFT_mn): numerator = -self.delta**2 * self.g * chargeFieldFFT_mn denominator = 2 * ( np.cos(2 * np.pi * m * self.delta / self.length) + np.cos(2 * np.pi * n * self.delta / self.length) - 2 - (self.M * self.delta)**2 / 2) if denominator == 0: return 0 return numerator / denominator vec_AHat_mn = np.vectorize(AHat_mn) # For indexing along the lattice iArr = np.arange(0, self.N) jArr = np.arange(0, self.N) # Calculate the individual elements of the gauge field in fourier space gaugeFieldFFTArr = np.zeros_like(self._colorChargeField, dtype='complex') for k in range(self.gluonDOF): gaugeFieldFFTArr[k] = [ vec_AHat_mn(i, jArr, chargeDensityFFTArr[k, i, jArr]) for i in iArr ] # Take the inverse fourier transform to get the actual gauge field self._gaugeField = np.real( ifft2(gaugeFieldFFTArr, axes=(-2, -1), norm=self.fftNormalization)) # Make sure this process isn't repeated unnecessarily by denoting that it has been done self._gaugeFieldExists = True return self._gaugeField
def focus_reconstruction(self, a): """ Propagate reconstruction to be in focus a: constant used to propagate field """ x00 = np.linspace(-self.shape[0]//2,self.shape[0]//2-1, self.shape[0]) x01 = np.linspace(-self.shape[1]//2,self.shape[1]//2-1, self.shape[1]) x0, x1 = np.meshgrid(x00,x01) r = np.sqrt(np.square(x0) + np.square(x1)) H = fftshift(np.exp(1j * a * r**2)) self.u_fft = ifft2(fft2(self.u_fft0)*H)
def test_expand_fourier_sp_even2d(self): """ test function with even input size """ arr = np.random.rand(100, 100) arr_ft = fft.fftshift(fft.fft2(fft.ifftshift(arr))) arr_ex_ft = tools.resample_bandlimited_ft(arr_ft, (2, 2)) arr_exp = fft.fftshift(fft.ifft2(fft.ifftshift(arr_ex_ft))).real max_err = np.max(np.abs(arr_exp[::2, ::2] - arr)) self.assertTrue(max_err < 1e-14)
def fitness(self, x): observed = _get_observed(self.number_points, self.im_fft, x) im_reconstruct = fft.ifft2(observed).real val = (mean_squared_error(self.im_numpy, im_reconstruct), ) with monitor: count.value += 1 if val[0] < best.value: best.value = val[0] print( str(count.value) + ' fval = ' + str(val[0]) + " t = " + str(round(1000 * (time() - t0))) + " ms" + " x = " + ", ".join(str(xi) for xi in x)) return val
def ourconv(image, filt): # pad padded_size = np.array(image.shape) + np.array(filt.shape) pad_img = pad_RHS(image, padded_size, padval=0.5) pad_filt = pad_RHS(filt, padded_size, padval=0) # Paul's slightly corrected version temp = np.real(fft.ifft2(fft.fft2(pad_img) * fft.fft2(pad_filt))) # extract the appropriate portion of the filtered image filtered = unpad_RHS(temp, image.shape) return filtered
def PhaseKai2opt(k_vector, noisy_original_image_fft, system_otf): w = np.shape(noisy_original_image_fft)[0] wo = np.int(w / 2) noisy_original_image_fft = noisy_original_image_fft * ( 1 - 1 * system_otf**10) #Increase the contrast by denoising noisy_original_image_fft = noisy_original_image_fft * np.conj( system_otf ) #Build term for minimisation (highlights places where i term is similar) otf_cutoff = otf_smooth(system_otf) DoubleMatSize = 0 if ( 2 * otf_cutoff > wo ): #Contingency for the situtation where the size of the FFT is not large enough to fit in extra frequency info from SIM reconstruction DoubleMatSize = 1 if (DoubleMatSize > 0): t = 2 * w noisy_original_image_fft_temp = np.zeros((t, t)) noisy_original_image_fft_temp[wo:w + wo, wo:w + wo] = noisy_original_image_fft noisy_original_image_fft = noisy_original_image_fft_temp else: t = w to = np.int(t / 2) u = np.linspace(0, t - 1, t) v = np.linspace(0, t - 1, t) [U, V] = np.meshgrid(u, v) # Build term for comparison in cross-correlation (image with frequency added to it) noisy_image_freqadd = np.exp( -1j * 2 * np.pi * (k_vector[1] / t * (U - to)) + (k_vector[0] / t * (V - to))) * fft.ifft2(noisy_original_image_fft) noisy_image_freqadd_fft = fft.fft2(noisy_image_freqadd) mA = np.longlong( np.sum(noisy_original_image_fft * np.conj(noisy_image_freqadd_fft)) ) # Sum across pixels of product of image with complex conjugate with frequency introduced. mA = mA / np.longlong( (np.sum(noisy_image_freqadd_fft * np.conj(noisy_image_freqadd_fft)) )) # Normalising cross-correlation term #print(type(mA)) #print(-np.abs(mA)) correlation_FOM = -abs( mA ) # Negative absolute value allows for minimisation; FOM = figure of merit return (correlation_FOM)
def poisson(zeta, psi): Z = fft2(-zeta) # Taking FFT of zeta # Constructing the vector of wave numbers K = np.zeros(L, dtype=complex) K[:int(L / 2)] = np.arange(int(L / 2)) K[int(L / 2):] = np.arange(-int(L / 2), 0) KX, KY = np.meshgrid(K, K) # Finding solution and enforcing the well-posedness of the system by setting 0,0 to be zero delsq = -(KX ** 2 + KY ** 2) delsq[0, 0] = 1 psi1 = Z / delsq psi1[0, 0] = 0 f = ifft2(psi1) # Inverting FFT return np.real(f)
def fft_backward_xyz(phikxkyz, nxw=None, nyw=None): # 3次元配列用逆FFT(最後の2軸に対して計算) """ Backward Fourier transform phi[z,ky,kx]->phi[z,y,x] Arbitrary length of z is applicable. Parameters ---------- phikxkyz[:,global_ny+1,2*nx+1] : Numpy array, dtype=np.complex128 phi[z,ky,kx] in wavenumber space [ky,kx] and z nxw : int, optional (grid number in xx) = 2*nxw # Default: nxw = int(nx*1.5)+1 nyw : int, optional (grid number in yy) = 2*nyw # Default: nyw = int(gny*1.5)+1 Returns ------- phixy[:,2*nyw,2*nxw] : Numpy array, dtype=np.float64 phi[z,y,x] in real space """ import numpy as np from scipy import fft from diag_geom import nxw as nxw_geom from diag_geom import nyw as nyw_geom # GKVパラメータを換算する nx = int((phikxkyz.shape[2] - 1) / 2) gny = int(phikxkyz.shape[1] - 1) len_z = phikxkyz.shape[0] if (nxw == None): nxw = nxw_geom if (nyw == None): nyw = nyw_geom # 2次元逆フーリエ変換 phi[z,ky,kx] -> phi[z,y,x] phixyz = np.zeros([len_z, 2 * nyw, 2 * nxw], dtype=np.complex128) # fft.ifft2用Numpy配列 phixyz[:, 0:gny + 1, 0:nx + 1] = phikxkyz[:, 0:gny + 1, nx:2 * nx + 1] # 波数空間配列の並び替え phixyz[:, 0:gny + 1, 2 * nxw - nx:2 * nxw] = phikxkyz[:, 0:gny + 1, 0:nx] phixyz[:, 2 * nyw - gny:2 * nyw, 2 * nxw - nx:2 * nxw] = np.conj(phikxkyz[:, gny:0:-1, 2 * nx:nx:-1]) phixyz[:, 2 * nyw - gny:2 * nyw, 0:nx + 1] = np.conj(phikxkyz[:, gny:0:-1, nx::-1]) phixyz = fft.ifft2(phixyz, axes=(-2, -1)) * (2 * nxw) * ( 2 * nyw) # phi[y,x] = Sum_kx Sum_ky phi[ky,kx]*exp[i(kx*x+ky*y)] phixyz = phixyz.real # phi[z,y,x]は実数配列 return phixyz
def step( self, D ): # Propagate input Wave object over distance, D; return Wave object. Fourier algorithm. Pin = fft2( self.U ) # 2D FFT of amplitude distribution, U, gives spatial frequency distribution, Pin at initial position, z. Pout = Pin * np.exp( 1j * self.kz * D ) # Multiply Spatial frequency distribution by phase-factor corresponding to propagation through distance, D, to give new spatial frequency distribution, Pout. Uout = ifft2( Pout ) # 2D IFFT of spatial frequency distribution gives amplitude distribution, Uout, at plane z = z + D self.U = Uout return self
def sch(image, sch_angle): """Schlieren microscopy.""" x = (_fft.fftshift((_numpy.arange(image.shape[0])-image.shape[0]/2.+0.5) / float(image.shape[0]))[_numpy.newaxis, :]) y = (_fft.fftshift((_numpy.arange(image.shape[1])-image.shape[1]/2.+0.5) / float(image.shape[1]))[:, _numpy.newaxis]) T = y < x*_numpy.tan(sch_angle) image_ft = _fft.fft2(image) image_ft *= T image_transformed = _fft.ifft2(image_ft) intensity = abs(image_transformed)**2 return intensity
def _fresnel_old_dfft(cmode_to_propagate, wavelength, nx, ny, xstart, ystart, xend, yend, rx, ry, distance): # Warning! The fft2 of impulse function and ic should be done together with # numpy fft fft2. Or some speckle will apear. """ Double FFT Fresnel propagation of coherent mode. Args: cmode_to_propagate - the coherent mode to propagate. cmode_mask - the mask of coherent mode. wavelength - the wavelength of light field. nx - the dim of aixs x. ny - the dim of axis y. xstart - location of start along axis x. ystart - location of start along axis y. xend - location of end along axis x. yend - lcoation of end along axis y. rx - the range of x. ry - the range of y. distance - the distance of the propagation. Return: propagated coherent mode. """ # cmode_to_propagate = cmode_to_propagate # wave number k wave_num = 2 * np.pi / wavelength # the axis in frequency space x0 = np.linspace(xstart, xend, nx) y0 = np.linspace(ystart, yend, ny) mesh_x, mesh_y = np.meshgrid(x0, y0) # propagation function impulse = (np.exp(1j * wave_num * distance) * np.exp(-1j * wave_num * (mesh_x**2 + mesh_y**2) / (2 * distance)) / (1j * wavelength * distance)) # the multiply of coherent mode and propagation function propagated_cmode = fft.ifftshift( fft.ifft2(fft.fft2(cmode_to_propagate) * fft.fft2(impulse))) return propagated_cmode
def step(self): """Advance the algorithm one iteration.""" G = fft.fft2(self.g) mse = _mean_square_error(abs(G), self.absF, self.mse_denom) phs_G = np.angle(G) Gprime = self.absF * np.exp(1j * phs_G) gprime = fft.ifft2(Gprime) phs_gprime = np.angle(gprime) gprimeprime = self.absg * np.exp(1j * phs_gprime) self.costF.append(mse) self.iter += 1 self.g = gprimeprime return gprimeprime
def reconvolve_gaussian_kernel(img, old_maj, old_min, old_pa, new_maj, new_min, new_pa): """ convolve image with a gaussian kernel without FFTing it bmaj, bmin -- in pixels, bpa -- in degrees from top clockwise (like in Beam) inverse -- use True to deconvolve. NOTE: yet works for square image without NaNs """ size = len(img) imean = img.mean() img -= imean fimg = np.fft.fft2(img) krel = fft_psf(new_maj, new_min, new_pa, size) / fft_psf(old_maj, old_min, old_pa, size) fconv = fimg * ifftshift(krel) return ifft2(fconv).real + imean
def hybrid(low, high, factor=.8, cutoff_low=25, cutoff_high=20): low_pass_input_image, low_std = low high_pass_input_image, high_std = high # get low fft low_fft = low_pass_filter(low_pass_input_image, low_std, cutoff_low) # save low image frequency domain # low_fft_image = 8 * np.log(np.abs(low_fft)) # cv.imwrite('q4_12_lowpassed.jpg', low_fft_image, ) # calculate low image in spatial domain low = np.abs(fft.ifft2(fft.ifftshift(low_fft))) ############## # get high fft high_fft = high_pass_filter(high_pass_input_image, high_std, cutoff_high) # save high image frequency domain # high_fft_image = 8 * np.log(np.abs(high_fft)) # cv.imwrite('q4_11_highpassed.jpg', high_fft_image) # calculate low image in spatial domain high = np.abs(fft.ifft2(fft.ifftshift(high_fft))) # calculate hybrid fft hybrid_fft = factor * low_fft + (1 - factor) * high_fft # save hybrid image frequency domain # hybrid_fft_image = 8 * np.log(np.abs(hybrid_fft)) # cv.imwrite('q4_13_hybrid_frequency.jpg', hybrid_fft_image) hybrid_result = np.abs(fft.ifft2(hybrid_fft)) return hybrid_result, low, high