def s_hat_comp(self): if not hasattr(self, '_s_hat_comp') or \ self._s_hat_inf_loss != self.inf_loss: a_fields, psf_basis = self.get_variable_psf() var = self._bkg.globalrms nrm = self.normal_image dx, dy = center_of_mass(psf_basis[0]) if a_fields[0] is None: s_hat = self.interped_hat * \ _fftwn(psf_basis[0], s=self.pixeldata.shape, norm='ortho').conj() s_hat = fourier_shift(s_hat, (+dx, +dy)) else: s_hat = np.zeros_like(self.pixeldata.data, dtype=np.complex128) x, y = self.get_afield_domain() im_shape = self.pixeldata.shape for a, psf in zip(a_fields, psf_basis): conv = _fftwn(self.interped * a(x, y)/nrm, norm='ortho') *\ _fftwn(psf, s=im_shape, norm='ortho').conj() conv = fourier_shift(conv, (+dx, +dy)) np.add(conv, s_hat, out=s_hat) self._s_hat_comp = (self.zp / (var**2)) * s_hat self._s_hat_inf_loss = self.inf_loss return self._s_hat_comp
def p_sqnorm(self): phat = self.psf_hat_sqnorm() p = _ifftwn(phat, norm='ortho') print(np.sum(p)) return _ifftwn(fourier_shift( phat, (self.stamp_shape[0] / 2, self.stamp_shape[1] / 2)), norm='ortho')
def p_sqnorm(self): phat = self.psf_hat_sqnorm() return _ifftwn( fourier_shift(phat, (self.stamp_shape[0] / 2, self.stamp_shape[1] / 2)), norm="ortho", )
def cost(vec): dx, dy = vec b_n = _ifftwn(dhn, norm='ortho') - \ _ifftwn(fourier_shift(dhr, (dx, dy)), norm='ortho')*b - \ np.roll(gammap, (int(round(dx)), int(round(dy)))) cost = b_n.real[100:-100, 100:-100] cost = np.sum(np.abs(cost/(cost.shape[0]*cost.shape[1])))
def translate_img(img, t): ''' img: BxYxX real space image t: Bx2 shift in pixels ''' ff = np.fft.fft2(np.fft.fftshift(img)) ff = fourier_shift(ff, t) return np.fft.fftshift(np.fft.ifft2(ff)).real
def test_subpixel_precision(): reference_image = np.fft.fftn(camera()) subpixel_shift = (-2.4, 1.32) shifted_image = fourier_shift(reference_image, subpixel_shift) # subpixel precision result, error, diffphase = register_translation(reference_image, shifted_image, 100, space="fourier") assert_allclose(result[:2], -np.array(subpixel_shift), atol=0.05)
def fourier_shift(self, shx=0, shy=0, shz=0): ''' shift image in fourier space. Inplace ''' shft = [] if self.ndim == 1: shft = [shx] elif self.ndim == 2: shft = [shy, shx] elif self.ndim == 3: shft = [shz, shy, shx] else: raise Exception("Dimention %d not implemented for fourier_shift" % self.ndim) if self._isfft: self.data = fourier.fourier_shift(self.data, shft) else: self.data = EMImage(fourier.fourier_shift(self.fftdata, shft), isFFT=True).rdata return self
def test_correlation(): reference_image = np.fft.fftn(camera()) shift = (-7, 12) shifted_image = fourier_shift(reference_image, shift) # pixel precision result, error, diffphase = register_translation(reference_image, shifted_image, space="fourier") assert_allclose(result[:2], -np.array(shift))
def test_real_input(): reference_image = camera() subpixel_shift = (-2.4, 1.32) shifted_image = fourier_shift(np.fft.fftn(reference_image), subpixel_shift) shifted_image = np.fft.ifftn(shifted_image) # subpixel precision result, error, diffphase = register_translation(reference_image, shifted_image, 100) assert_allclose(result[:2], -np.array(subpixel_shift), atol=0.05)
def test_size_one_dimension_input(): # take a strip of the input image reference_image = np.fft.fftn(camera()[:, 15]).reshape((-1, 1)) subpixel_shift = (-2.4, 4) shifted_image = fourier_shift(reference_image, subpixel_shift) # subpixel precision result, error, diffphase = register_translation(reference_image, shifted_image, 100, space="fourier") assert_allclose(result[:2], -np.array((-2.4, 0)), atol=0.05)
def cshift(arr1, nx, ny): """ Shifts a complex array by nx and ny respectively. """ nx*=1. ny*=1. if ((nx % 1. == 0.) and (ny % 1. ==0)): return sp.roll(sp.roll(arr1, int(ny), axis=0), int(nx), axis=1 ) else: return spf.ifft2(spnf.fourier_shift(spf.fft2(arr1),(ny,nx)))
def cost(vec): b, dx, dy = vec gammap = gamma / np.sqrt(new.var**2 + b**2 * ref.var**2) norm = np.sqrt(norm_a + norm_b * b**2) dhn = D_hat_n / norm dhr = D_hat_r / norm b_n = _ifftwn(dhn, norm='ortho') - \ _ifftwn(fourier_shift(dhr, (dx, dy)), norm='ortho')*b - \ np.roll(gammap, (int(round(dx)), int(round(dy)))) cost = b_n.real[100:-100, 100:-100] cost = np.sum(np.abs(cost / (cost.shape[0] * cost.shape[1]))) return (cost)
def cost_beta(vec): beta, dx, dy = vec[:] norm = beta * beta * (r_var * r_var * np.absolute(psf_new_hat)**2) norm += n_var * n_var * np.absolute(psf_ref_hat)**2 #~ gamma_p = gamma/np.sqrt(n_var**2 + r_var**2 * beta**2) cost = _ifftwn(D_hat_n/np.sqrt(norm)) - \ _ifftwn(fourier_shift((D_hat_r/np.sqrt(norm))*beta, (dx,dy))) cost = np.sqrt(cost * cost.conjugate()).real #return np.sqrt(np.average(np.square(cost[50:-50, 50:-50]))) clipped = sigma_clip(cost.real[50:-50, 50:-50], 25) return clipped.filled(0).reshape(-1)
def diff(ref, new, align=False, inf_loss=0.25, smooth_psf=False, beta=True, shift=True, iterative=False, fitted_psf=True): """Function that takes a list of SingleImage instances and performs a stacking using properimage R estimator """ if fitted_psf: try: from .single_image_psfs import SingleImageGaussPSF as SI print('using single psf, gaussian modeled') except ImportError: from .single_image import SingleImage as SI else: from .single_image import SingleImage as SI if not isinstance(ref, SI): try: ref = SI(ref, smooth_psf=smooth_psf) except: # noqa try: ref = SI(ref.pixeldata, smooth_psf=smooth_psf) except: # noqa raise if not isinstance(new, SI): try: new = SI(new, smooth_psf=smooth_psf) except: # noqa try: new = SI(new.pixeldata, smooth_psf=smooth_psf) except: # noqa raise if align: registered = aa.register(new.pixeldata, ref.pixeldata) new._clean() registered = registered[:ref.pixeldata.shape[0], :ref.pixeldata. shape[1]] new = SI(registered.data, mask=registered.mask, borders=False, smooth_psf=smooth_psf) # new.pixeldata = registered # new.pixeldata.mask = registered.mask # make sure that the alignement has delivered arrays of size if new.pixeldata.data.shape != ref.pixeldata.data.shape: import ipdb ipdb.set_trace() t0 = time.time() mix_mask = np.ma.mask_or(new.pixeldata.mask, ref.pixeldata.mask) zps, meanmags = u.transparency([ref, new]) print(zps) ref.zp = zps[0] new.zp = zps[1] n_zp = new.zp r_zp = ref.zp # r_var = ref.var # n_var = new.var a_ref, psf_ref = ref.get_variable_psf(inf_loss) a_new, psf_new = new.get_variable_psf(inf_loss) if fitted_psf: # I already know that a_ref and a_new are None, both of them # And each psf is a list, first element a render, # second element a model p_r = psf_ref[1] p_n = psf_new[1] p_r.x_mean = ref.pixeldata.data.shape[0] / 2. p_r.y_mean = ref.pixeldata.data.shape[1] / 2. p_n.x_mean = new.pixeldata.data.shape[0] / 2. p_n.y_mean = new.pixeldata.data.shape[1] / 2. p_r.bounding_box = None p_n.bounding_box = None p_n = p_n.render(np.zeros(new.pixeldata.data.shape)) p_r = p_r.render(np.zeros(ref.pixeldata.data.shape)) # import ipdb; ipdb.set_trace() dx_ref, dy_ref = center_of_mass(p_r) # [0]) dx_new, dy_new = center_of_mass(p_n) # [0]) else: p_r = psf_ref[0] p_n = psf_new[0] dx_ref, dy_ref = center_of_mass(p_r) # [0]) dx_new, dy_new = center_of_mass(p_n) # [0]) # print(dx_new, dy_new) if dx_new < 0. or dy_new < 0.: import ipdb ipdb.set_trace() # rad_ref_sq = dx_ref*dx_ref + dy_ref*dy_ref # rad_new_sq = dx_new*dx_new + dy_new*dy_new psf_ref_hat = _fftwn(p_r, s=ref.pixeldata.shape, norm='ortho') psf_new_hat = _fftwn(p_n, s=new.pixeldata.shape, norm='ortho') psf_ref_hat[np.where(psf_ref_hat.real == 0)] = eps psf_new_hat[np.where(psf_new_hat.real == 0)] = eps psf_ref_hat_conj = psf_ref_hat.conj() psf_new_hat_conj = psf_new_hat.conj() D_hat_r = fourier_shift(psf_new_hat * ref.interped_hat, (-dx_new, -dy_new)) D_hat_n = fourier_shift(psf_ref_hat * new.interped_hat, (-dx_ref, -dy_ref)) # D_hat_r = psf_new_hat * ref.interped_hat # D_hat_n = psf_ref_hat * new.interped_hat norm_b = ref.var**2 * psf_new_hat * psf_new_hat_conj norm_a = new.var**2 * psf_ref_hat * psf_ref_hat_conj new_back = sep.Background(new.interped).back() ref_back = sep.Background(ref.interped).back() gamma = new_back - ref_back b = n_zp / r_zp norm = np.sqrt(norm_a + norm_b * b**2) if beta: # start with beta=1 if shift: def cost(vec): b, dx, dy = vec gammap = gamma / np.sqrt(new.var**2 + b**2 * ref.var**2) norm = np.sqrt(norm_a + norm_b * b**2) dhn = D_hat_n / norm dhr = D_hat_r / norm b_n = _ifftwn(dhn, norm='ortho') - \ _ifftwn(fourier_shift(dhr, (dx, dy)), norm='ortho')*b - \ np.roll(gammap, (int(round(dx)), int(round(dy)))) cost = b_n.real[100:-100, 100:-100] cost = np.sum(np.abs(cost / (cost.shape[0] * cost.shape[1]))) return (cost) ti = time.time() vec0 = [b, 0., 0.] bounds = ([0.1, -.9, -.9], [10., .9, .9]) solv_beta = optimize.least_squares(cost, vec0, xtol=1e-5, jac='3-point', method='trf', bounds=bounds) tf = time.time() if solv_beta.success: print(('Found that beta = {}'.format(solv_beta.x))) print(('Took only {} awesome seconds'.format(tf - ti))) print(('The solution was with cost {}'.format(solv_beta.cost))) b, dx, dy = solv_beta.x else: print('Least squares could not find our beta :(') print('Beta is overriden to be the zp ratio again') b = n_zp / r_zp dx = 0. dy = 0. elif iterative: bi = b def F(b): gammap = gamma / np.sqrt(new.var**2 + b**2 * ref.var**2) norm = np.sqrt(norm_a + norm_b * b**2) b_n = _ifftwn(D_hat_n/norm, norm='ortho') - gammap\ - b * _ifftwn(D_hat_r/norm, norm='ortho') # robust_stats = lambda b: sigma_clipped_stats( # b_n(b).real[100:-100, 100:-100]) return (np.sum(np.abs(b_n.real))) ti = time.time() solv_beta = optimize.minimize_scalar(F, method='bounded', bounds=[0.1, 10.], options={'maxiter': 1000}) tf = time.time() if solv_beta.success: print(('Found that beta = {}'.format(solv_beta.x))) print(('Took only {} awesome seconds'.format(tf - tf))) b = solv_beta.x else: print('Least squares could not find our beta :(') print('Beta is overriden to be the zp ratio again') dx = dy = 0. else: bi = b def F(b): gammap = gamma / np.sqrt(new.var**2 + b**2 * ref.var**2) norm = np.sqrt(norm_a + norm_b * b**2) b_n = _ifftwn(D_hat_n/norm, norm='ortho') - gammap \ - b * _ifftwn(D_hat_r/norm, norm='ortho') # robust_stats = lambda b: sigma_clipped_stats( # b_n(b).real[100:-100, 100:-100]) return (np.sum(np.abs(b_n.real))) ti = time.time() solv_beta = optimize.least_squares(F, bi, ftol=1e-8, bounds=[0.1, 10.], jac='2-point') tf = time.time() if solv_beta.success: print(('Found that beta = {}'.format(solv_beta.x))) print(('Took only {} awesome seconds'.format(tf - tf))) print(('The solution was with cost {}'.format(solv_beta.cost))) b = solv_beta.x else: print('Least squares could not find our beta :(') print('Beta is overriden to be the zp ratio again') dx = dy = 0. else: if shift: bi = n_zp / r_zp gammap = gamma / np.sqrt(new.var**2 + b**2 * ref.var**2) norm = np.sqrt(norm_a + norm_b * b**2) dhn = D_hat_n / norm dhr = D_hat_r / norm def cost(vec): dx, dy = vec b_n = _ifftwn(dhn, norm='ortho') - \ _ifftwn(fourier_shift(dhr, (dx, dy)), norm='ortho')*b - \ np.roll(gammap, (int(round(dx)), int(round(dy)))) cost = b_n.real[100:-100, 100:-100] cost = np.sum(np.abs(cost / (cost.shape[0] * cost.shape[1]))) return (cost) ti = time.time() vec0 = [0., 0.] bounds = ([-.9, -.9], [.9, .9]) solv_beta = optimize.least_squares(cost, vec0, xtol=1e-4, jac='2-point', method='trf', bounds=bounds) tf = time.time() if solv_beta.success: print(('Found that shift = {}'.format(solv_beta.x))) print(('Took only {} awesome seconds'.format(tf - ti))) print(('The solution was with cost {}'.format(solv_beta.cost))) dx, dy = solv_beta.x else: print('Least squares could not find our shift :(') dx = 0. dy = 0. else: b = new.zp / ref.zp dx = 0. dy = 0. norm = norm_a + norm_b * b**2 if dx == 0. and dy == 0.: D_hat = (D_hat_n - b * D_hat_r) / np.sqrt(norm) else: D_hat = (D_hat_n - fourier_shift(b * D_hat_r, (dx, dy))) / np.sqrt(norm) D = _ifftwn(D_hat, norm='ortho') if np.any(np.isnan(D.real)): pass d_zp = b / np.sqrt(ref.var**2 * b**2 + new.var**2) P_hat = (psf_ref_hat * psf_new_hat * b) / (np.sqrt(norm) * d_zp) P = _ifftwn(P_hat, norm='ortho').real dx_p, dy_p = center_of_mass(P) S_hat = fourier_shift(d_zp * D_hat * P_hat.conj(), (dx_p, dy_p)) kr = _ifftwn(new.zp * psf_ref_hat_conj * b * psf_new_hat * psf_new_hat_conj / norm, norm='ortho') kn = _ifftwn(new.zp * psf_new_hat_conj * psf_ref_hat * psf_ref_hat_conj / norm, norm='ortho') V_en = _ifftwn(_fftwn(new.pixeldata.filled(0) + 1., norm='ortho') * _fftwn(kn**2, s=new.pixeldata.shape), norm='ortho') V_er = _ifftwn(_fftwn(ref.pixeldata.filled(0) + 1., norm='ortho') * _fftwn(kr**2, s=ref.pixeldata.shape), norm='ortho') S_corr = _ifftwn(S_hat, norm='ortho') / np.sqrt(V_en + V_er) print('S_corr sigma_clipped_stats ') print(('mean = {}, median = {}, std = {}\n'.format( *sigma_clipped_stats(S_corr.real.flatten(), sigma=6.)))) print(('Subtraction performed in {} seconds\n\n'.format(time.time() - t0))) # import ipdb; ipdb.set_trace() return D, P, S_corr.real, mix_mask
def subtract(self): t0 = time.time() ref = self.ens.atoms[0] new = self.ens.atoms[1] shape = ref.imagedata.shape if self.psfshape is not None: _, psf_ref = ref.get_variable_psf(shape=self.psfshape) _, psf_new = new.get_variable_psf(shape=self.psfshape) else: _, psf_ref = ref.get_variable_psf(shape=self.psfshape) _, psf_new = new.get_variable_psf(shape=self.psfshape) psf_ref = psf_ref[0] / np.sum(psf_ref[0]) psf_new = psf_new[0] / np.sum(psf_new[0]) psf_ref_hat = _fftwn(psf_ref, s=shape) psf_new_hat = _fftwn(psf_new, s=shape) ref_shift = np.zeros_like(psf_ref) ref_shift[np.where(psf_ref == np.max(psf_ref))] = 1. ref_shift = _fftwn(ref_shift, s=shape) new_shift = np.zeros_like(psf_new) new_shift[np.where(psf_new == np.max(psf_new))] = 1. new_shift = _fftwn(new_shift, s=shape) if self.zp: zps = self.ens.transparencies r_zp = zps[0] n_zp = zps[1] print('Ref_zp = {}, New_zp = {}'.format(r_zp, n_zp)) else: r_zp = 1. n_zp = 1. r_var = ref.bkg.globalrms n_var = new.bkg.globalrms D_hat_r = psf_new_hat * _fftwn(ref.bkg_sub_img) * ref_shift.conjugate() D_hat_n = psf_ref_hat * _fftwn(new.bkg_sub_img) * new_shift.conjugate() if (self.sb or (r_zp == 1.0 and n_zp == 1.0)): from scipy.ndimage.fourier import fourier_shift #~ gamma = new.bkg.back()-ref.bkg.back() def cost_beta(vec): beta, dx, dy = vec[:] norm = beta * beta * (r_var * r_var * np.absolute(psf_new_hat)**2) norm += n_var * n_var * np.absolute(psf_ref_hat)**2 #~ gamma_p = gamma/np.sqrt(n_var**2 + r_var**2 * beta**2) cost = _ifftwn(D_hat_n/np.sqrt(norm)) - \ _ifftwn(fourier_shift((D_hat_r/np.sqrt(norm))*beta, (dx,dy))) cost = np.sqrt(cost * cost.conjugate()).real #return np.sqrt(np.average(np.square(cost[50:-50, 50:-50]))) clipped = sigma_clip(cost.real[50:-50, 50:-50], 25) return clipped.filled(0).reshape(-1) #return cost.real[50:-50, 50:-50].reshape(-1) def cost_beta_no_shift(vec): beta = vec[0] norm = beta * beta * (r_var * r_var * np.absolute(psf_new_hat)**2) norm += n_var * n_var * np.absolute(psf_ref_hat)**2 cost = _ifftwn(D_hat_n/np.sqrt(norm)) - \ _ifftwn((D_hat_r/np.sqrt(norm))*beta) cost = np.sqrt(cost * cost.conjugate()).real clipped = sigma_clip(cost[50:-50, 50:-50], 25) return clipped.filled(0).reshape(-1) if self.shift_beta: tbeta0 = time.time() vec0 = [n_zp / r_zp, 0., 0.] bounds = ([0.5, -2.9, -2.9], [2., 2.9, 2.9]) solv_beta = optimize.least_squares(cost_beta, vec0, ftol=1e-10, jac='3-point', bounds=bounds) tbeta1 = time.time() if solv_beta.success: print('Found that beta = {}'.format(solv_beta.x)) print('Took only {} awesome seconds'.format(tbeta1 - tbeta0)) print('The solution was with cost {}'.format( solv_beta.cost)) beta, dx, dy = solv_beta.x else: print('Least squares could not find our beta :(') print('Beta is overriden to be the zp ratio again') beta = n_zp / r_zp dx = 0. dy = 0. else: dx = 0 dy = 0 tbeta0 = time.time() vec0 = [n_zp / r_zp] bounds = ([0.01], [20.]) solv_beta = optimize.least_squares(cost_beta_no_shift, vec0, ftol=1e-9, jac='3-point', bounds=bounds) tbeta1 = time.time() if solv_beta.success: print('Found that beta = {}'.format(solv_beta.x)) print('Took only {} awesome seconds'.format(tbeta1 - tbeta0)) print('The solution was with cost {}'.format( solv_beta.cost)) beta = solv_beta.x else: print('Least squares could not find our beta :(') print('Beta is overriden to be the zp ratio again') beta = n_zp / r_zp else: beta = n_zp / r_zp dx = 0. dy = 0. norm = beta * beta * (r_var * r_var * np.absolute(psf_new_hat)**2) norm += n_var * n_var * np.absolute(psf_ref_hat)**2 if dx == 0. and dy == 0.: D_hat = (D_hat_n - beta * D_hat_r) / np.sqrt(norm) else: D_hat = (D_hat_n - fourier_shift(beta * D_hat_r, (dx, dy))) / np.sqrt(norm) D = _ifftwn(D_hat) d_zp = n_zp / np.sqrt(r_var * r_var * beta * beta + n_var * n_var) P_hat = (psf_ref_hat * psf_new_hat * beta) / (np.sqrt(norm) * d_zp) P = _ifftwn(P_hat).real shift = np.zeros_like(P) shift[np.where(P == np.max(P))] = 1. shift = _fftwn(shift, s=shape) S_hat = d_zp * D_hat * P_hat.conjugate() * shift kr = _ifftwn(beta * n_zp * psf_ref_hat.conjugate() * np.absolute(psf_new_hat)**2 / norm) kn = _ifftwn(beta * n_zp * psf_new_hat.conjugate() * np.absolute(psf_ref_hat)**2 / norm) V_en = _ifftwn(_fftwn(new.imagedata + 1.) * _fftwn(kn * kn, s=shape)) V_er = _ifftwn(_fftwn(ref.imagedata + 1.) * _fftwn(kr * kr, s=shape)) S_corr = _ifftwn(S_hat) / np.sqrt(V_en + V_er) print('S_corr sigma_clipped_stats ') print('mean = {}, median = {}, std = {}\n'.format( *sigma_clipped_stats(S_corr.real.flatten()))) print('Subtraction performed in {} seconds'.format(time.time() - t0)) #import ipdb; ipdb.set_trace() return D, P, S_corr.real
def fourier_shift_filter(grid,shift_size=(3,3,3),axis=-1,n=-1): filtered = grid.copy() scifourier.fourier_shift(grid,shift_size,n,axis,filtered) return filtered
dx, dy = solv_beta.x else: print('Least squares could not find our shift :(') dx = 0. dy = 0. else: b = new.zp/ref.zp dx = 0. dy = 0. norm = norm_a + norm_b * b**2 if dx == 0. and dy == 0.: D_hat = (D_hat_n - b * D_hat_r)/np.sqrt(norm) else: D_hat = (D_hat_n - fourier_shift(b*D_hat_r, (dx, dy)))/np.sqrt(norm) D = _ifftwn(D_hat, norm='ortho') if np.any(np.isnan(D.real)): pass d_zp = b/np.sqrt(ref.var**2 * b**2 + new.var**2) P_hat = (psf_ref_hat * psf_new_hat * b)/(np.sqrt(norm)*d_zp) P = _ifftwn(P_hat, norm='ortho').real dx_p, dy_p = center_of_mass(P) S_hat = fourier_shift(d_zp * D_hat * P_hat.conj(), (dx_p, dy_p)) kr = _ifftwn(new.zp * psf_ref_hat_conj * b * psf_new_hat * psf_new_hat_conj / norm, norm='ortho')
def apply_shift( X, shift ): """ Shift an image in the fourier domain """ return ifft2( fourier_shift( fft2(X), shift ) ).real
def stack_R(si_list, align=True, inf_loss=0.2, n_procs=2): """Function that takes a list of SingleImage instances and performs a stacking using properimage R estimator """ logger = logging.getLogger() for i_img, animg in enumerate(si_list): if not isinstance(animg, si): si_list[i_img] = si(animg) if align: img_list = utils._align_for_coadd(si_list) for an_img in img_list: an_img.update_sources() else: img_list = si_list shapex = np.min([an_img.data.shape[0] for an_img in img_list]) shapey = np.min([an_img.data.shape[1] for an_img in img_list]) global_shape = (shapex, shapey) zps, meanmags = utils.transparency(img_list) for j, an_img in enumerate(img_list): an_img.zp = zps[j] an_img._setup_kl_a_fields(inf_loss) psf_shapes = [an_img.stamp_shape[0] for an_img in img_list] psf_shape = np.max(psf_shapes) psf_shape = (psf_shape, psf_shape) if n_procs > 1: queues = [] procs = [] for chunk in utils.chunk_it(img_list, n_procs): queue = Queue() proc = StackCombinator( chunk, queue, shape=global_shape, stack=True, fourier=False ) logger.info("starting new process") proc.start() queues.append(queue) procs.append(proc) logger.info("all chunks started, and procs appended") S_hat = np.zeros(global_shape, dtype=np.complex128) P_hat = np.zeros(global_shape, dtype=np.complex128) mix_mask = np.zeros(global_shape, dtype=np.bool) for q in queues: serialized = q.get() logger.info("loading pickles") s_hat_comp, psf_hat_sum, mask = pickle.loads(serialized) np.add(s_hat_comp, S_hat, out=S_hat) # , casting='same_kind') np.add(psf_hat_sum, P_hat, out=P_hat) # , casting='same_kind') mix_mask = np.ma.mask_or(mix_mask, mask) P_r_hat = np.sqrt(P_hat) P_r = _ifftwn(fourier_shift(P_r_hat, psf_shape)) P_r = P_r / np.sum(P_r) R = _ifftwn(S_hat / np.sqrt(P_hat)) logger.info("S calculated, now starting to join processes") for proc in procs: logger.info("waiting for procs to finish") proc.join() logger.info("processes finished, now returning R") else: S_hat = np.zeros(global_shape, dtype=np.complex128) P_hat = np.zeros(global_shape, dtype=np.complex128) mix_mask = img_list[0].data.mask for an_img in img_list: np.add(an_img.s_hat_comp, S_hat, out=S_hat) np.add( ((an_img.zp / an_img.var) ** 2) * an_img.psf_hat_sqnorm(), P_hat, out=P_hat, ) mix_mask = np.ma.mask_or(mix_mask, an_img.data.mask) P_r_hat = np.sqrt(P_hat) P_r = _ifftwn(fourier_shift(P_r_hat, psf_shape)) P_r = P_r / np.sum(P_r) R = _ifftwn(S_hat / P_r_hat) return R, P_r, mix_mask
156-158 (2008). """ import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.feature import register_translation from skimage.feature.register_translation import _upsampled_dft from scipy.ndimage.fourier import fourier_shift image = data.camera() print('image size: {} w x {} h'.format(*image.shape)) # aprio_shift = (-2.4, 1.32) # pixel offset relative to reference coin aprio_shift = (-54.56, 38.2) # custom edit offset_image = fourier_shift(np.fft.fftn(image), aprio_shift) offset_image = np.fft.ifftn(offset_image) image_product = np.fft.fft2(image) * np.fft.fft2(offset_image).conj() print("Known offset (y, x):") print(aprio_shift) def precision_pixel(): shift, error, diffphase = register_translation(image, offset_image) fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 3)) ax1.imshow(image) ax1.set_axis_off() ax1.set_title('Reference image')
"Efficient subpixel image registration algorithms," Optics Letters 33, 156-158 (2008). """ import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.feature import register_translation from skimage.feature.register_translation import _upsampled_dft from scipy.ndimage.fourier import fourier_shift image = data.camera() shift = (-2.4, 1.32) # (-2.4, 1.32) pixel offset relative to reference coin offset_image = fourier_shift(np.fft.fftn(image), shift) offset_image = np.fft.ifftn(offset_image) print("Known offset (y, x):") print(shift) # pixel precision first shift, error, diffphase = register_translation(image, offset_image) fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 3)) ax1.imshow(image) ax1.set_axis_off() ax1.set_title('Reference image') ax2.imshow(offset_image.real) ax2.set_axis_off()