Beispiel #1
0
def fpm_reconstruct_wrap(samples=None, hrshape=None, it=None, pupil_radius=None,
                    kdsc=None, cfg=None,  debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    from skimage.measure import compare_ssim as ssim

    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    # objectRecover = initialize(hrshape, cfg, 'zero')
    im_out = None
    objectRecover = np.ones(hrshape)
    lrsize = samples[(15, 15)].shape[0]
    xc, yc = fpmm.image_center(hrshape)

    def pupil_wrap(zfocus, radius):
        CTF = fpmm.generate_pupil(0, 0, [lrsize, lrsize], pupil_radius)
        # focus test
        # dky = 2*np.pi/(float(cfg.ps_req)*hrshape[0])
        kmax = np.pi/float(cfg.pixel_size)
        step = kmax/((lrsize-1)/2)
        kxm, kym = np.meshgrid(np.arange(-kmax,kmax+1,step), np.arange(-kmax,kmax+1, step));
        k0 = 2*np.pi/float(cfg.wavelength)
        kzm = np.sqrt(k0**2-kxm**2-kym**2);
        pupil = np.exp(1j*zfocus*np.real(kzm))*np.exp(-np.abs(zfocus)*np.abs(np.imag(kzm)));
        return CTF*pupil;

    objectRecoverFT = fftshift(fft2(objectRecover))  # shifted transform
    if debug:
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(25, 15))
        fig.show()
    # Steps 2-5
    factor = (lrsize/hrshape[0])**2

    im_cmp = Image.fromarray(samples[(15, 15)])
    im_cmp = im_cmp.resize(hrshape)
    im_cmp = np.array(im_cmp)
    im_cmp = im_cmp.astype('float64')
    for iteration in range(20):
        objectRecoverFT = fftshift(fft2(objectRecover))  # shifted transform

        zfocus = (-.4E-6)
        xoff = -0.45+0.1*iteration
        yoff = -.1.
        pupil = pupil_wrap(zfocus, pupil_radius)
        print(xoff, yoff, zfocus*1E6)
        if im_out is not None:
            im_out /= np.amax(im_out)
            im_cmp /= np.amax(im_cmp)
            print('ssim %.2f' % ssim(im_cmp, im_out))
        for iteration in range(5):
            iterator = ct.set_iterator(cfg)
            print('Iteration n. %d' % iteration)
            # Patching for testing
            for it in iterator:
                acqpars = it['acqpars']
                indexes, kx_rel, ky_rel = ct.n_to_krels(it, cfg, xoff, yoff)
                if indexes[0] > 19 or indexes[0] < 11 or indexes[1] > 19 or indexes[1] < 11:
                     continue
                lr_sample = samples[it['indexes']]/(acqpars[1])
                # From generate_il
                # Calculating coordinates
                [kx, ky] = kdsc*kx_rel, kdsc*ky_rel
                kyl = int(np.round(yc+ky-(lrsize+1)/2))
                kyh = kyl + lrsize
                kxl = int(np.round(xc+kx-(lrsize+1)/2))
                kxh = kxl + lrsize

                # Il = generate_il(im_array, f_ih, theta, phi, cfg)
                lowResFT = factor * objectRecoverFT[kyl:kyh, kxl:kxh]*pupil
                # Step 2: lr of the estimated image using the known pupil
                im_lowRes = ifft2(ifftshift(lowResFT))  # space pupil * fourier image
                im_lowRes = 1/factor * lr_sample * np.exp(1j*np.angle(im_lowRes))
                lowResFT = fftshift(fft2(im_lowRes))*pupil
                objectRecoverFT[kyl:kyh, kxl:kxh] = (1-pupil)*objectRecoverFT[kyl:kyh, kxl:kxh] + lowResFT
                # Step 3: spectral pupil area replacement
                ####################################################################
        im_out = np.abs(ifft2(ifftshift(objectRecoverFT)))
        if debug:
            fft_rec = np.log10(np.abs(objectRecoverFT))
            # fft_rec *= (255.0/fft_rec.max())
            # Il = Image.fromarray(np.uint8(Il), 'L')
            # im_rec *= (255.0/im_rec.max())
            def plot_image(ax, image, title):
                ax.cla()
                ax.imshow(image, cmap=plt.get_cmap('gray'))
                ax.set_title(title)
            axiter = iter([(ax1, 'Reconstructed FFT'), (ax2, 'Reconstructed magnitude'),
                        (ax3, 'Acquired image'), (ax4, 'Reconstructed phase')])
            for image in [np.abs(fft_rec), im_out, im_cmp, np.angle(ifft2(ifftshift(objectRecoverFT)))]:
                ax, title = next(axiter)
                plot_image(ax, image, title)
            fig.canvas.draw()
            # print("Testing quality metric", fpmm.quality_metric(samples, Il, cfg))
    return np.abs(im_out), np.angle(im_out)
Beispiel #2
0
import matplotlib.pyplot as plt
import numpy as np
import datetime

import pyfpm.local as local
import pyfpm.coordtrans as ct
import pyfpm.fpmmath as fpmm
import pyfpm.data as dt

# Simulation parameters
cfg = dt.load_config()
out_file = dt.generate_out_file(fname='simtest.npy')
iterator = ct.set_iterator(cfg)
simclient = local.SimClient(cfg=cfg)
imshape = simclient.im_array.shape
xc, yc = fpmm.image_center(imshape)

pupil_radius = simclient.pupil_radius
kdsc = simclient.kdsc
pup_list = list()

fig, ax1 = plt.subplots(1, 1, figsize=(5, 5))
fig.show()
image_dict = dict()
for it in iterator:
    print(it['indexes'])
    [kx, ky] = ct.angles_to_k(it['theta'], it['phi'], kdsc)
    # print('theta: %.1f phi: %.1f' % (it['theta'], it['phi']))
    pup_array = fpmm.pupil_image(yc + ky, yc + kx, pupil_radius, imshape)
    pup_list.append(pup_array)
    ax1.cla()
Beispiel #3
0
def fpm_reconstruct_classic(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).
    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation

    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    # k relative to absolute k factor
    npx = fpmm.get_image_size(cfg)
    ps_req = fpmm.get_pixel_size_required(cfg)
    wlen = fpmm.get_wavelength(cfg)
    led_gap = float(cfg.led_gap)
    height = float(cfg.sample_height)

    objectRecover_mag = (samples[(0, -1)]) / np.amax(samples[(0, -1)])
    objectRecover_phase = (samples[(0, -1)] - samples[(-1, 0)]) / (samples[
        (0, -1)] + samples[(-1, 0)])
    objectRecover_phase = np.pi * (
        objectRecover_phase) / np.amax(objectRecover_phase)
    objectRecover = objectRecover_mag * np.exp(1j * objectRecover_phase)
    objectRecover = np.ones(hrshape)
    # plt.imshow(objectRecover_phase)
    # plt.show()
    center = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(image_size=[lrsize, lrsize],
                            pupil_radius=pupil_radius) * .1
    # pupil = fpmm.aberrated_pupil(image_size=[lrsize, lrsize], pupil_radius=pupil_radius,
    #                             aberrations=[0,], pixel_size=ps, wavelength=wlen)
    objectRecoverFT = fftshift(fft2(objectRecover))  # shifted transform
    # Steps 2-5
    factor = (lrsize / hrshape[0])**2
    # For the convergence index
    # Steps 2-5
    for iteration in range(10):
        iterator = ct.set_iterator(cfg)
        # print('Iteration n. %d' % iteration)
        for it in iterator:
            # indexes, kx_rel, ky_rel = ct.n_to_krels(it=it, cfg=cfg, xoff=0, yoff=0)
            indexes = it['indexes']
            lr_sample = np.copy(samples[it['indexes']])
            led_number = np.array([it['ny'], it['nx']])
            # Convert indexes to pupil center coordinates kx, ky
            mc = np.array(cfg.mat_center)  #  Matrix center
            k_rel = np.sin(np.arctan((led_number - mc) * led_gap / height))
            k_abs = k_rel * ps_req * npx / wlen
            pup_center = k_abs + center
            # Pupil borders
            lp = np.round(pup_center - (lrsize + 1) / 2).astype(
                int)  # Extreme left low point
            hp = lp + lrsize  # Extreme right high point
            pupil_square = [slice(lp[0], hp[0]), slice(lp[1], hp[1])]

            lowResFT = factor * objectRecoverFT[pupil_square] * CTF
            im_lowRes = ifft2(ifftshift(lowResFT))
            im_lowRes = (1 / factor) * lr_sample * np.exp(
                1j * np.angle(im_lowRes))
            lowResFT = fftshift(fft2(im_lowRes)) * CTF

            objectRecoverFT[pupil_square] = (
                1 - CTF) * objectRecoverFT[pupil_square] + lowResFT
    im_out = ifft2(fftshift(objectRecoverFT))
    return im_out
Beispiel #4
0
def fpm_reconstruct_wrappable(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    kdsc = fpmm.get_k_discrete(cfg)

    objectRecover = np.ones(hrshape)
    xc, yc = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], pupil_radius)
    objectRecoverFT = fftshift(fft2(objectRecover))  # shifted transform
    # Steps 2-5
    factor = (lrsize / hrshape[0])**2
    # For the convergence index
    N = len(samples)

    for iteration in range(1):
        iterator = ct.set_iterator(cfg)
        # Patching for testing
        for it in iterator:
            # Coordinates manipulation
            acqpars = it['acqpars']
            indexes, kx_rel, ky_rel = ct.n_to_krels(it=it,
                                                    cfg=cfg,
                                                    xoff=0,
                                                    yoff=0)
            lr_sample = np.copy(samples[it['indexes']])
            [kx, ky] = kdsc * kx_rel, kdsc * ky_rel
            # Iteration step
            kyl = int(np.round(yc + ky - (lrsize + 1) / 2))
            kyh = kyl + lrsize
            kxl = int(np.round(xc + kx - (lrsize + 1) / 2))
            kxh = kxl + lrsize
            lowResFT = factor * objectRecoverFT[kyl:kyh, kxl:kxh] * CTF
            # Step 2: lr of the estimated image using the known pupil
            im_lowRes = ifft2(
                ifftshift(lowResFT))  # space pupil * fourier image
            im_lowRes = 1 / factor * lr_sample * np.exp(
                1j * np.angle(im_lowRes))
            ## pupil correction update
            lowResFT2 = fftshift(fft2(im_lowRes)) * CTF * 1. / pupil
            ORFT = objectRecoverFT[kyl:kyh, kxl:kxh].ravel()
            objectRecoverFT[kyl:kyh,
                            kxl:kxh] += (lowResFT2 - lowResFT) * np.conjugate(
                                pupil) / np.max(np.abs(pupil.ravel())**2)
            pupil += (lowResFT2 - lowResFT) * np.conjugate(
                objectRecoverFT[kyl:kyh, kxl:kxh]) / np.max(np.abs(ORFT)**2)
            ####################################################################
    im_out = ifft2(ifftshift(objectRecoverFT))
    return im_out
Beispiel #5
0
def fpm_reconstruct_epry(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    kdsc = fpmm.get_k_discrete(cfg)

    objectRecover = np.ones(hrshape)
    xc, yc = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], 1. * pupil_radius)
    # print(lrsize,hrshape)
    # plt.imshow(CTF)
    # plt.show()
    # pupil = np.ones_like(CTF, dtype='complex')
    pupil = 1
    # pupil = fpmm.aberrated_pupil(image_size=[lrsize, lrsize], pupil_radius=pupil_radius, aberrations=[-.1E-6,], pixel_size=ps, wavelength=wlen)*CTF
    # pupil = (rand(lrsize, lrsize)*(1+0*1j)+1)*0.5
    # gfk = exp(1j*rand(hrshape[0], hrshape[1])*pi)*fpmm.generate_CTF(0, 0, [hrshape[0], hrshape[1]], pupil_radius*.1)
    # gfk = np.zeros(hrshape, dtype='complex')
    gfk = fftshift(fft2(objectRecover))
    # gfk += rand(hrshape[0], hrshape[1])+1
    # gfk[yc-lrsize//2:yc+lrsize//2, xc-lrsize//2:xc+lrsize//2] = 1+rand(lrsize, lrsize)
    # gfk[yc, xc] = 1
    # Steps 2-5
    factor = (float(lrsize) / hrshape[0])**2
    # For convergence index
    e_gk = 0
    gk_prev = np.zeros_like(gfk)
    gk = np.ones_like(gfk) * (1 + 1j)
    gpk_prev = np.zeros_like(gfk)
    gpk = np.ones_like(gfk)
    ek = 1
    gm = 0
    a = 1
    b = 1
    sum_lr = 0
    for it in ct.set_iterator(cfg):
        indexes, kx_rel, ky_rel = ct.n_to_krels(it=it, cfg=cfg)
        sum_lr += np.sum(samples[it['indexes']])
    for iteration in range(15):

        iterator = ct.set_iterator(cfg)
        print('Iteration n. %d' % iteration)
        # Patching for testing
        e_gk = np.sum((abs(gk) - abs(gk_prev))**2) / (np.sum(abs(gk)**2))
        e_gpk = np.sum(
            (angle(gk) - angle(gk_prev))**2) / (np.sum(angle(gk)**2))
        gk_prev = gk
        print('Iteration %d | gk error %.2e | gpk error %.4f | ek %.2e |' %
              (iteration, e_gk, e_gpk, ek))
        # if (ek < 0.00001):
        #     break
        ek = 0
        gm = gm * e_gk
        for it in iterator:
            acqpars = it['acqpars']
            indexes, kx_rel, ky_rel = ct.n_to_krels(it=it,
                                                    cfg=cfg,
                                                    xoff=0.,
                                                    yoff=0.)
            lr_sample = np.copy(
                np.sqrt(samples[it['indexes']][:lrsize, :lrsize]))
            # From generate_il
            # Calculating coordinates
            [kx, ky] = kdsc * kx_rel, kdsc * ky_rel  # k_rel is sin(phi)
            # print(kdsc)
            kyl = int(np.round(yc + ky - (lrsize + 1) / 2))
            kyh = kyl + lrsize
            kxl = int(np.round(xc + kx - (lrsize + 1) / 2))
            kxh = kxl + lrsize
            delta_gfk1 = gfk[kyl:kyh, kxl:kxh] * pupil * CTF
            # print(kyl, kyh, kxl, kxh, yc+kx, yc+ky)
            # Step 2: lr of the estimated image using the known pupil
            delta_gk = ifft2(ifftshift(delta_gfk1))
            gk_prime = 1 / factor * lr_sample * delta_gk / abs(delta_gk)
            delta_gfk2 = fftshift(fft2(gk_prime))
            # update of the pupil and the fourier transform of the sample.
            delta_phi = delta_gfk2 - delta_gfk1
            sampled_gfk = gfk[kyl:kyh, kxl:kxh]
            sampled_gfk += a * delta_phi * conj(CTF * pupil) / amax(
                abs(CTF * pupil))**2
            if iteration > -1:
                pupil += b * delta_phi * conj(sampled_gfk) / amax(
                    abs(sampled_gfk))**2
            gfk[kyl:kyh, kxl:kxh] = sampled_gfk
            # test_img = delta_phi
            # plt.plot(abs(delta_phi[25,:]))
            # plt.show()
            ek += np.sum(abs(delta_gfk2 - delta_gfk1)**2) / sum_lr**2
        gk = ifft2(fftshift(gfk))
        # plt.imshow(np.log(abs(gfk)))
        # plt.show()
    return gk, pupil
Beispiel #6
0
def fpm_reconstruct(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    # objectRecover = initialize(hrshape, cfg, 'zero')
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    kdsc = fpmm.get_k_discrete(cfg)

    # Initialization
    xc, yc = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], pupil_radius)
    # gk_prime = np.ones(hrshape)*exp(1j*rand(hrshape)*pi)
    # gfk = np.ones(hrshape)*exp(1j*rand(hrshape[0], hrshape[1])*pi)
    objectRecover = np.ones(hrshape)
    gfk = fftshift(fft2(objectRecover))  # shifted transform

    factor = (lrsize / hrshape[0])**2
    # For the convergence index
    N = len(samples)
    beta = 0.
    gm = 0
    # lrarray = np.zeros((lrsize, lrsize, N))
    e_gk = 0
    gk_prev = np.zeros_like(gfk)
    gk = np.ones_like(gfk)
    gpk_prev = np.zeros_like(gfk)
    gpk = np.ones_like(gfk)
    for iteration in range(5):
        iterator = ct.set_iterator(cfg)
        # Patching for testing
        e_gk = np.sum((abs(gk) - abs(gk_prev))**2) / (np.sum(abs(gk)**2))
        e_gpk = np.sum(
            (angle(gk) - angle(gk_prev))**2) / (np.sum(angle(gk)**2))
        gk_prev = gk
        print('Iteration %d | gk error %.4f' % (iteration, e_gk))
        print(e_gpk)
        if (e_gk < 5E-5):
            break
        for it in iterator:
            gm = gm * e_gk
            CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], pupil_radius)
            acqpars = it['acqpars']
            # indexes, theta, phi = it['indexes'], it['theta'], it['phi']
            indexes, kx_rel, ky_rel = ct.n_to_krels(it, cfg=cfg)
            lr_sample = np.copy(samples[it['indexes']][:lrsize, :lrsize])
            # Calculating coordinates
            [ky, kx] = kdsc * ky_rel, kdsc * kx_rel
            kyl = int(np.round(yc + ky - (lrsize + 1) / 2))
            kyh = kyl + lrsize
            kxl = int(np.round(xc + kx - (lrsize + 1) / 2))
            kxh = kxl + lrsize
            # Fourier-space update
            delta_gfk = factor * gfk[kyl:kyh, kxl:kxh] * CTF
            # Step 2: lr of the estimated image using the known pupil
            delta_gk = ifft2(ifftshift(delta_gfk)) + gm * rand(lrsize, lrsize)
            # phase = arctan(real(delta_gk)/(imag(delta_gk)+0.))
            phase = angle(delta_gk)
            gk_prime = lr_sample * exp(1j * phase) / factor
            delta_gfk = fftshift(fft2(gk_prime)) * CTF
            gfk[kyl:kyh,
                kxl:kxh] = (1 - CTF) * gfk[kyl:kyh, kxl:kxh] + delta_gfk
        gk = ifft2(fftshift(gfk))
    return gk, gk