def generate_il(im_array, f_ih, theta, phi, cfg): """ Returns the low resolution sampled image with added reconstructed phase in the according spectral position. More detailed explanation: Takes the high resolution spectrum, calculates a low resolution sample in the spectral area occupied by the sampled image (im_array) by cuting it with the pupil at the (theta, phi), takes just the phase information in this area and replaces its modulus with the acquired im_array. Why this is outside the main function? Because it is also used in the quality metric (to be reimpemented here). """ ps = fpmm.ps_required(cfg.phi[1], cfg.wavelength, cfg.na) image_size = np.shape(im_array) pupil = fpmm.generate_pupil(theta=theta, phi=phi, image_size=image_size, wavelength=cfg.wavelength, pixel_size=ps, na=cfg.na) pupil_shift = fftshift(pupil) # Step 2: lr of the estimated image using the known pupil f_il = ifft2(f_ih*pupil_shift) # space pupil * fourier image Phl = np.angle(f_il) # Step 3: spectral pupil area replacement Il = np.sqrt(im_array) * np.exp(1j*Phl) # Spacial update Iupdate = Il # Iupdate /= np.max(Iupdate) # Iupdate *= 150 return Iupdate
def dpc_init(samples=None, backgrounds=None, it=None, init_point=None, cfg=None, debug=False): """ Absolutely experimental reconstruction function. Virtually analog to fpm_reconstruct() to be used as a test sandbox. """ # pc = PlatformCoordinates(theta=0, phi=0, height=cfg.sample_height, cfg=cfg) xoff, yoff = init_point # Selection of the image patch ps_required = fpmm.ps_required(cfg.phi[1], cfg.wavelength, cfg.na) # mask = get_mask(samples, backgrounds, xoff, yoff, cfg) # Getting the maximum angle by the given configuration # Step 1: initial estimation Et = initialize(samples, backgrounds, xoff, yoff, cfg, 'zero') f_ih = fft2(Et) # unshifted transform, shift is later applied to the pupil if debug: fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(25, 15)) fig.show() # fig, axes = implot.init_plot(4) # Steps 2-5 for iteration in range(cfg.n_iter): iterator = ct.set_iterator(cfg) print('Iteration n. %d' % iteration) # Patching for testing for index, theta, shift in iterator: theta, phi = ct.corrected_coordinates(theta=theta, shift=shift, cfg=cfg) print(theta, phi) # Final step: squared inverse fft for visualization im_array = fpmm.crop_image(samples[(theta, shift)], cfg.patch_size, xoff, yoff) background = fpmm.crop_image(backgrounds[(theta, shift)], cfg.patch_size, xoff, yoff) im_array = image_correction(im_array, background, mode='background') im_array, resc_size = image_rescaling(im_array, cfg) Il = generate_il(im_array, f_ih, theta, phi, cfg) # print("Testing quality metric", quality_metric(image_dict, Il, cfg), phi) pupil = fpmm.generate_pupil(theta=theta, phi=phi, image_size=resc_size, wavelength=cfg.wavelength, pixel_size=ps_required, na=cfg.objective_na) pupil_shift = fftshift(pupil) f_il = fft2(Il) f_ih = f_il*pupil_shift + f_ih*(1 - pupil_shift) if debug and index % 1 == 0: fft_rec = np.log10(np.abs(f_ih)+1) fft_rec *= (255.0/fft_rec.max()) fft_rec = fftshift(fft_rec) # fft_rec = Image.fromarray(np.uint8(fft_rec*255), 'L') im_rec = ifft2(f_ih) # im_rec *= (255.0/im_rec.max()) im_rec_abs = np.abs(im_rec*np.conj(im_rec)) def plot_image(ax, image): ax.cla() ax.imshow(image, cmap=plt.get_cmap('hot')) ax = iter([ax1, ax2, ax3, ax4]) for image in [np.abs(fft_rec), im_rec, im_array, np.angle(im_rec)]: plot_image(ax.next(), image) fig.canvas.draw() # print("Testing quality metric", quality_metric(image_dict, Il, cfg, max_phi)) return np.abs(np.power(ifft2(f_ih), 2)), np.angle(ifft2(f_ih+1))
def image_rescaling(lr_image, cfg): """ Image rescaling acording to sampling requirements. The numerical aperture, wavelength, pixel size and maximum sampling are used to calculate the upsampled image size to contain all the new information. Args: ----- image: the (xpy, npx) image to be rescaled cfg: configuration (named tuple) Returns: -------- (ndarray) upsampled image and final high resolution shape """ phi_max = float(cfg.phi[1]) wavelength = float(cfg.wavelength) na = float(cfg.objective_na) ps_required = fpmm.ps_required(phi_max, wavelength, na) scale_factor = cfg.pixel_size/ps_required Ih = ndimage.zoom(lr_image, scale_factor, order=0) # HR image hr_shape = np.shape(Ih) return Ih, hr_shape