Exemple #1
0
def super_lhsf(x0, tracer, factor=2):
    ##  Extend sinogram to [0,2pi)
    m0, n0 = x0.shape
    n0_h = np.int(0.5 * n0)
    s_2pi = extend_full_period(x0)
    ig = np.unique(np.argwhere(s_2pi != tracer)[:, 1])
    ib = np.unique(np.argwhere(s_2pi == tracer)[:, 1])
    print(ig.shape)
    print(s_2pi.shape)
    print(s_2pi[:, ig].shape)
    print(n0_h)

    ##  Resample each projection at cosinusoidal nodes
    s_2pi = s_2pi[:, ig].reshape(2 * m0, n0_h)
    sc_a = resampling_cosine_nodes(s_2pi)
    dis.plot(sc_a, 'SC')
    sc = np.zeros((2 * m0, 2 * sc_a.shape[1]), dtype=myfloat)
    print(sc.shape)
    print(sc_a.shape)
    sc[:, ::2] = sc_a
    sc[:, 1::2] = 0.0
    dis.plot(sc, 'SC')

    m1, n1 = sc.shape
    mh1 = int(m1 * 0.5)
    nh1 = int(n1 * 0.5)

    ##  Indexes for Fourier-Chebyshev filtering
    ic = get_ind_zerout(n1, m0)

    ##  Get traced and non-traced elements
    sx = sc.copy()
    #sx[:,ib] = 0.0
    nc = n1
    norm = np.sqrt(1.0 / (2.0 * (nc + 1)))

    ##  Decomposition and filter
    c = norm * fp.dst(sx, type=1, axis=1)
    b = np.fft.fftshift(np.fft.fft(c, axis=0), axes=0)
    b[ic[:, 0], ic[:, 1]] = 0.0

    ##  Reconstruction
    c[:] = np.real(np.fft.ifft(np.fft.ifftshift(b, axes=0), axis=0))
    ci = np.imag(np.fft.ifft(np.fft.ifftshift(b, axes=0), axis=0))
    sx_r = norm * fp.dst(c, type=1, axis=1)
    sx_i = norm * fp.dst(ci, type=1, axis=1)
    sx[:] = np.sqrt(sx_r**2 + sx_i**2)

    ##  Renormalize
    sx[:] = factor * sx

    ##  Crop original sinogram interval [0,pi) and first channel half (transl. of 1)
    sx = sx[:mh1, :]

    ##  Interpolate back on equispaced nodes
    x = resampling_equisp_nodes(sx, n0)

    print('\n')

    return x
def main():
    print('\n')
    print('#########################################################')
    print('#########################################################')
    print('###                                                   ###')
    print('###             ANALYTICAL RADON TRANSFORM OF         ###')
    print('###             RADIALLY SYMMETRIC FUNCTIONS          ###')
    print('###                                                   ###')
    print('#########################################################')
    print('#########################################################')
    print('\n')

    ##  Get arguments
    args = getArgs()

    ##  Get input parameters
    npix = args.npix
    nang = args.nang
    deg = args.degree
    dpc = args.dpc

    print('\nNumber of pixels: ', npix)
    print('Number of views: ', nang)
    print('Function degree: ', deg)
    print('Option DPC: ', dpc)

    ##  Create LUT for the radially symmetric functions
    lut = create_lut(npix)

    ##  Create Shepp-Logan phantom
    phantom = create_phantom(npix, deg, lut)

    ##  Write phantom
    write_output_file(phantom, 'image', args)

    ##  Plot phantom
    if args.plot is True:
        dis.plot(
            phantom,
            'Radon phantom  with ' + str(npix) + ' X ' + str(npix) + ' pixels')

    ##  Compute analitically radon transform of the phantom
    if args.nang is not None:
        print('\nCalculating analytical radon transform of the phantom ....')

        sinogram = radon_transform_analytical(lut, npix, nang, deg, dpc)
        if args.dpc is False:
            sinogram[:, :] = sinogram[:, ::-1]
        sinogram[:, :] = np.roll(sinogram, 1, axis=1)

        ##  Write sinogram
        write_output_file(sinogram, 'sinogram', args)

        ##  Plot Shepp-Logan phantom
        if args.plot is True:
            dis.plot(
                sinogram,
                'Sinogram  ' + str(nang) + ' views X ' + str(npix) + ' pixels')

    print('\n\n')
Exemple #3
0
def lhsf_analysis(s):
    ##  Get dimensions of the sinogram
    na, n = s.shape

    ##  Decompose sinogram into Fourier-Chebyshev basis
    b = decomposition(s)
    nc = b.shape[1]
    dis.plot(np.real(b), 'Fourier-Chebyshev decomposition')

    ##  Zero-out coefficients at ( m , k ) s.t ( |m| > k ) or ( |m| + k even )
    ii = get_ind_zerout(nc, na)

    ##  Compute number and power percentage of wrong coefficients
    n_wro = len(ii)
    bb = b[ii[:, 0], ii[:, 1]]
    iii = np.argwhere(np.abs(bb) > 0.5)
    value = len(iii) / myfloat(n_wro) * 100.0
    print('\nFourier-Chebyshev analysis of the forward projection:')
    print('Wrong Fourier-Chebyshev coefficients: ', value, ' %')

    pb_tot = np.linalg.norm(b)
    pb_wro = np.linalg.norm(bb)
    value = pb_wro / myfloat(pb_tot) * 100.0
    print('Wrong Fourier-Chebyshev power: ', value, ' %\n')

    b[ii[:, 0], ii[:, 1]] = 0.0

    ##  Reverse FFT and sine transform
    sf = reconstruction(b, n)
    return sf
def main():
    print('\nADD BLURRING TO IMAGES\n')

    ##  Get input arguments
    args = getArgs()

    ##  Get input and output path
    pathin = args.pathin
    if pathin[len(pathin) - 1] != '/':
        pathin += '/'

    if args.pathout is None:
        pathout = pathin
    else:
        pathout = args.pathout
    if pathout[len(pathout) - 1] != '/':
        pathout += '/'

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get single image
    filein = args.filein
    imagein = io.readImage(pathin + filein)
    nrows, ncols = imagein.shape

    print('\nReading image:\n', filein, '\n')
    print('Image size: ', nrows, ' X ', ncols)

    ##  Check plot
    if args.plot is True:
        dis.plot(imagein, 'Input image')

    ##  Allocate memory for the noisy temporary image
    image_blur = np.zeros((nrows, ncols), dtype=myfloat)

    ##  Get blurring radii
    if args.sigma_range is None:
        sigma_list = args.sigma_list
        sigma_arr = np.array(sigma_list.split(':'), dtype=myfloat)
        nimg = len(sigma_arr)
    else:
        sigma_list = args.sigma_range
        sigma_list = np.array(sigma_list.split('-'), dtype=myfloat)
        sigma_arr = np.linspace(sigma_list[0], sigma_list[1], sigma_list[2])
        nimg = len(sigma_arr)

    ##  Loop on each gaussian sigma
    for im in range(nimg):
        ##  Add gaussian noise
        image_blur[:, :] = add_gaussian_blurring(imagein, sigma_arr[im])

        ##  Check noisy image
        if args.plot is True:
            dis.plot(image_blur,
                     'Blurred image -- sigma: ' + str(sigma_arr[im]))

        ##  Write noisy image to file
        write_output_file(pathout, filein, image_blur, sigma_arr[im])
Exemple #5
0
def super_filt(sino, factor=2):
    nang, npix = sino.shape

    tracer = np.min(sino) - 100
    factor = np.int(factor)
    if factor <= 1:
        factor = 2
    npix_new = npix * factor

    ig = np.arange(0, npix_new, factor)
    ib = np.setdiff1d(np.arange(npix_new), ig)

    sino_new = np.zeros((nang, npix_new), dtype=myfloat)
    sino_new[:, ig] = sino
    sino_new[:, ib] = tracer
    dis.plot(sino_new, 'Starting')
    sino_new[:] = super_lhsf(sino_new, tracer)
    dis.plot(sino_new, 'Ending')

    sino_new[:, ig] = sino

    return sino_new
Exemple #6
0
def main():

    print('')
    print('######################################') 
    print('######################################')
    print('####                              ####')
    print('####  CALCULATE IMAGE COMPLEXITY  ####')
    print('####                              ####')   
    print('######################################')
    print('######################################') 


    ##  Get input arguments
    args = getArgs()


    ##  Read input image
    filein  = args.pathin + args.filein 
    image   = io.readImage( filein )
    nx , ny = image.shape
    
    print('\nReading input image:\n', filein)     
    print('Image size: ', nx, '  X  ', ny)
    
    if args.jpeg_compr <= 0 and args.jpeg_compr >= 100:
        args.jpeg_compr = 75    

    if args.plot is True:
        dis.plot( image , 'Input image' )


    ##  Calculate image complexity index based on JPEG compression
    complexity_jpeg( image , args )


    ##  Calculate image complexity index based on spatial information (SI)
    complexity_struct_info( image )
def admm(b, a, param):
    ##  Get number of pixels and angles
    m, n, nz = param.nang, param.npix_op, param.nz
    b = np.array(b).astype(myfloat)
    rd = param.radon_degree

    ##  Init forward and back-projector
    if param.projector == 'grid-pswf':
        tp = cpj1.projectors(n,
                             a,
                             kernel='pswf',
                             oversampl=2.0,
                             radon_degree=rd)
    elif param.projector == 'grid-kb':
        tp = cpj1.projectors(n,
                             a,
                             kernel='kb',
                             oversampl=1.5,
                             W=6.6,
                             errs=6.0e-6,
                             interp='lin',
                             radon_degree=rd)
    elif param.projector == 'bspline':
        tp = cpj2.projectors(n,
                             a,
                             param,
                             bspline_degree=3,
                             proj_support_y=4,
                             radon_degree=rd)
    elif param.projector == 'radon':
        tp = cpj2.projectors(n,
                             a,
                             param,
                             bspline_degree=1,
                             proj_support_y=2,
                             radon_degree=rd)
    elif param.projector == 'pix-driv':
        tp = cpj3.projectors(n, a, oper='pd')
    elif param.projector == 'ray-driv':
        tp = cpj3.projectors(n, a, oper='rd')
    elif param.projector == 'dist-driv':
        tp = cpj3.projectors(n, a, oper='dd')
    elif param.projector == 'slant':
        tp = cpj3.projectors(n, a, oper='ss')

    ##  Initialize x
    x = np.ones((nz, n, n), dtype=myfloat)

    if param.init_object is True:
        i1 = param.index_start
        i2 = param.index_end
        x_new = []
        b_new = []

        for i in range(nz):
            x[i, :, :] = tp.fbp(b[i, :, :])
            if param.plot is True:
                dis.plot(x[i, :, :], 'Initialization')

    ##  Reconstruction with CG
    if param.reg == 'cg':
        x[:], info = conj_grad(x, b, tp, param)

    ##  Reconstruction with Lasso-L1
    elif param.reg == 'lasso':
        x[:], info = lasso_l1(x, b, tp, param)

    ##  Reconstruction with Lasso-TV
    elif param.reg == 'lasso-tv':
        x[:], info = lasso_tv(x, b, tp, param)

    ##  Reconstruction with Plug-and-Play
    else:
        x[:], info = plug_and_play(x, b, tp, param)

    ##  Conversion for bspline reconstruction and rotate
    if param.projector == 'bspline':
        for i in range(nz):
            x[i, :, :] = bfun.convert_from_bspline_to_pixel_basis(
                x[i, :, :], 3)
        x[:, :, :] = x[:, ::-1, ::-1]

    return x, info
def main():
    ##  Initial print
    print('\n')
    print('##########################################################')
    print('##########################################################')
    print('#####                                                #####')
    print('#####          ADMM Iterative Reconstruction         #####')
    print('#####                                                #####')
    print('##########################################################')
    print('##########################################################')
    print('\n')

    ##  Get input arguments
    args = getArgs()

    ##  Get input and output paths
    pathin, pathout = utils.get_io_path(args)

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get input sinogram
    sino_list = []
    filein = []

    if args.filein is not None:
        sinoname = pathin + args.filein
        sino = io.readImage(sinoname).astype(myfloat)
        if args.angle_pi is True:
            sino = sino[:sino.shape[0] - 1, :]
        nang, npix = sino.shape
        nz = 1
        sino_list.append(sino)
        filein.append(args.filein)
        print('\nSinogram to reconstruct:\n', sinoname)

    else:
        print('\nReading stack of images\n')
        curr_dir = os.getcwd()
        os.chdir(pathin)

        for f in os.listdir('./'):
            if f.endswith('.DMP') is True:
                ext = '.DMP'
                break
            elif f.endswith('.tif') is True:
                ext = '.tif'
                break
            else:
                sys.exit('\nERROR: no .DMP or .tif file found in:\n' + pathin)

        filein.append(sorted(glob.glob('*' + ext)))
        nz = len(filein[0])
        os.chdir(curr_dir)

        print('Stack extension: ', ext)
        print('Number of slices: ', nz)

        print('\nLoading images .... ')
        for i in range(nz):
            if i == 0:
                sino = io.readImage(pathin + filein[0][i]).astype(myfloat)
                nang, npix = sino.shape
                sino_list.append(sino)
            else:
                sino_list.append(
                    io.readImage(pathin + filein[0][i]).astype(myfloat))
        print(' done! ')

    print('\nNumber of projection angles: ', nang)
    print('Number of pixels: ', npix)

    ##  Check plot
    if args.plot is True:
        if nz == 1:
            dis.plot(sino_list[0], 'Input sinogram')
        else:
            nzz = np.int(nz * 0.5)
            dis.plot(sino_list[nzz], 'Input sinogram')

    ##  Center of rotation axis
    if args.ctr == -1:
        ctr = npix * 0.5

    elif args.ctr != -1:
        ctr = args.ctr

    ##  Enable edge padding
    if args.lt is True:
        edf = 0.87
    elif args.lt is False and args.edge_padding != 0:
        edf = args.edge_padding
    else:
        edf = 0.0

    if edf:
        npix_old = npix
        for i in range(nz):
            sino_list[i] = proc.sino_edge_padding(sino_list[i], edf)
        npix = sino_list[0].shape[1]
        i1 = myint((npix - npix_old) * 0.5)
        i2 = i1 + npix_old
        ctr += i1

        print('\nEdge padding: ', edf)
        print('Number of edge-padded pixels: ', npix)
        print('Index start: ', i1, '   Index end: ', i2)
        print('Center of rotation axis new position: ', ctr)

        if args.plot is True:
            if nz == 1:
                dis.plot(sino_list[0], 'Sinogram with edge-padding')
            else:
                nzz = np.int(nz * 0.5)
                dis.plot(sino_list[nzz], 'Input sinogram')

    else:
        npix_old = npix
        i1 = 0
        i2 = npix

    ##  Compute differential sinogram if DBP option enabled
    if args.dbp is True:
        print('\nComputing differential sinogram ....')
        for i in range(nz):
            sino_list[i] = proc.diff_sino_savitzky_golay(sino_list[i],
                                                         window_size=args.sg)

        if args.plot is True:
            dis.plot(sino_list[0], 'Differential sinogram')

    ##  Correct for the center of rotation axis
    if args.ctr != -1:
        for i in range(nz):
            sino_list[i] = proc.sino_correct_rot_axis(sino_list[i], ctr)

    print('\nCenter of rotation axis position: ', ctr)
    print('Center of rotation corrected')

    ##  Get geometry
    if args.geometry == '0':
        angles = utils.create_projection_angles(nang)
    else:
        angles = utils.create_projection_angles(textfile=pathin +
                                                args.geometry)

    ##  Getting stopping criterion
    print('\nSetup of the iterative procedure:')

    if nz == 0:
        labelout = pathout + filein[0][:len(filein[0]) - 4]
    else:
        labelout = pathout + filein[0][0][:len(filein[0]) - 4]

    param = cap.admm_param(npix_old, nang, nz, ctr, labelout, args)

    print('Projectors enabled: ', args.projector)

    if args.dbp is True:
        print('DBP reconstruction enabled')

    if args.dpc is True:
        print('DPC reconstruction enabled')

    if args.n_iter is not None:
        print('Number of iterations: ', param.n_iter)

    if args.eps is not None:
        print('Stopping epsilon: ', param.eps)

    if args.n_iter_pcg is not None:
        print('Number of PCG iterations: ', param.n_iter_pcg)

    if args.plot is True:
        print('Interactive plot:', param.plot)

    if args.logfile is True:
        print('Interactive plot:', param.logfile)

    if param.reg is not None:
        if param.reg == 'cg':
            print('Conjugate gradient')
        if param.reg == 'lasso':
            print('Regularization type: Lasso L1')
        elif param.reg == 'lasso-tv':
            print('Regularization type: Lasso TV')
        elif param.reg == 'pp-breg':
            print('Regularization type: Plug and Play -- TV Bregman')
        elif param.reg == 'pp-chamb':
            print('Regularization type: Plug and Play -- TV Chambolle')
        elif param.reg == 'pp-nlmeans':
            print('Regularization type: Plug and Play -- Non Local Means')
        elif param.reg == 'pp-tgv':
            print(
                'Regularization type: Plug and Play -- Total generalized variation'
            )
        elif param.reg == 'pp-nltv':
            print(
                'Regularization type: Plug and Play -- Non-local total variation'
            )

        if param.reg != 'cg':
            print('\nLambda 1: ', param.lambd1)
            print('Lambda 2: ', param.lambd2)
            print('Mu:       ', param.mu)

    if args.init_object is True:
        print('\nInitialization with FBP reconstruction:', param.init_object)

    if param.mask is not None:
        print('\nObject support enabled')
        if param.plot is True:
            dis.plot(param.mask, 'Object support')

    if param.mask_add is not None:
        print('\nAdditional supports provided')
        if param.plot is True:
            if param.mask_add_n == 1:
                dis.plot(param.mask_add[0])
            else:
                dis.plot_multi(param.mask_add)

    if param.lt is True:
        print('\nLocal tomography mode enabled')

    ##  Iterative reconstruction
    print('\n\nReconstructing with ADMM ....')
    time1 = time.time()
    reco_list, info = admm(sino_list, angles, param)
    time2 = time.time()
    print('.... reconstruction done!')

    for i in range(nz):
        ##  Crop reconstruction if edge-padding enabled
        if edf != 0.0:
            reco = reco_list[i, i1:i2, i1:i2]
        else:
            reco = reco_list[i, :, :]

        ##  Show reconstruction
        if args.plot is True and nz == 1 and args.reg != 'cg':
            dis.plot(reco, 'Reconstruction')
            plot_convergence_curves(info)
        elif args.plot is True and i == nzz and args.reg != 'cg':
            nzz = np.int(nz * 0.5)
            dis.plot(reco_list[nzz, :, :],
                     'Reconstruction of slice ' + str(nzz))

        ##  Save reconstruction
        if nz == 1:
            save_reco(pathout, filein[0], args, param, reco)
        else:
            save_reco(pathout, filein[0][i], args, param, reco)

    ##  Time elapsed for the reconstruction
    time_tot = (time2 - time1) / 60.0
    print('\nTime elapsed for the reconstruction: ', time_tot)

    ##  Write log file
    if args.logfile is True:
        write_logfile(pathin, pathout, args, angles, ctr, param, time_tot,
                      info)

        write_info(pathout, filein[0], info, param, args)

    ##  Final print
    print('\n')
    print('\n')
    print('##########################################################')
    print('##########################################################')
    print('#####                                                #####')
    print('#####             ADMM Reconstruction done!          #####')
    print('#####                                                #####')
    print('##########################################################')
    print('##########################################################')
    print('\n')
Exemple #9
0
def main():
    ##  Initial print
    print('\n')
    print('##########################################################')
    print('##########################################################')
    print('#####                                                #####')
    print('#####       STATISTICAL ITERATIVE RECONSTRUCTION     #####')
    print('#####                                                #####')
    print('##########################################################')
    print('##########################################################')
    print('\n')

    ##  Getting arguments
    args = getArgs()

    ##  Get input & output paths
    pathin, pathout = utils.get_io_path(args)

    print('\nInput path: \n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get input sinogram
    sino_list = []
    filein = []

    if args.filein is not None:
        sinoname = pathin + args.filein
        sino = io.readImage(sinoname).astype(myfloat)
        nang, npix = sino.shape
        nz = 1
        sino_list.append(sino)
        filein.append(args.filein)
        print('\nSinogram to reconstruct:\n', sinoname)

    else:
        print('\nReading stack of images\n')
        curr_dir = os.getcwd()
        os.chdir(pathin)

        for f in os.listdir('./'):
            if f.endswith('.DMP') is True:
                ext = '.DMP'
                break
            elif f.endswith('.tif') is True:
                ext = '.tif'
                break
            else:
                sys.exit('\nERROR: no .DMP or .tif file found in:\n' + pathin)

        filein.append(sorted(glob.glob('*' + ext)))
        nz = len(filein[0])
        os.chdir(curr_dir)

        print('Stack extension: ', ext)
        print('Number of slices: ', nz)

        print('\nLoading images .... ')
        for i in range(nz):
            if i == 0:
                sino = io.readImage(pathin + filein[0][i]).astype(myfloat)
                nang, npix = sino.shape
                sino_list.append(sino)
            else:
                sino_list.append(
                    io.readImage(pathin + filein[0][i]).astype(myfloat))
        print(' done! ')

    print('\nNumber of projection angles: ', nang)
    print('Number of pixels: ', npix)

    ##  Check plot
    if args.plot is True:
        if nz == 1:
            dis.plot(sino_list[0], 'Input sinogram')
        else:
            nzz = np.int(0.5 * nz)
            dis.plot(sino_list[nzz], 'Input sinogram')

    ##  Center of rotation axis
    if args.ctr == -1:
        ctr = npix * 0.5

    elif args.ctr != -1:
        ctr = args.ctr

    ##  Enable edge padding
    if args.lt is True:
        edf = 0.87
    elif args.lt is False and args.edge_padding != 0:
        edf = args.edge_padding
    else:
        edf = 0.0

    if edf:
        npix_old = npix
        for i in range(nz):
            sino_list[i] = proc.sino_edge_padding(sino_list[i], edf)
        npix = sino_list[0].shape[1]
        i1 = myint((npix - npix_old) * 0.5)
        i2 = i1 + npix_old
        ctr += i1

        print('\nEdge padding: ', edf)
        print('Number of edge-padded pixels: ', npix)
        print('Index start: ', i1, '   Index end: ', i2)
        print('Center of rotation axis new position: ', ctr)

        if args.plot is True:
            dis.plot(sino_list[0], 'Sinogram with edge-padding')

    else:
        npix_old = npix
        i1 = 0
        i2 = npix

    ##  Correct for the center of rotation axis
    if args.ctr != -1:
        for i in range(nz):
            sino_list[i] = proc.sino_correct_rot_axis(sino_list[i], ctr)

    print('\nCenter of rotation axis position: ', ctr)
    print('Center of rotation corrected')

    ##  Get geometry
    if args.geometry == '0':
        angles = utils.create_projection_angles(nang)
    else:
        angles = utils.create_projection_angles(textfile=pathin +
                                                args.geometry)

    ##  Setup iterative procedure
    print('\nSetup of the iterative procedure:')

    if nz == 0:
        labelout = pathout + filein[0][:len(filein[0]) - 4]
    else:
        labelout = pathout + filein[0][0][:len(filein[0]) - 4]

    param = csp.sir_param(nang, npix_old, nz, ctr, labelout, args)

    print('Selected projector: ', args.projector)

    if args.eps is not None:
        print('Stopping threshold: ', param.eps)

    if args.n_iter is not None:
        print('Number of iterations: ', param.n_iter)

    if args.plot is True:
        print('Interactive plot:', param.plot)

    if args.logfile is True:
        print('Interactive plot:', param.logfile)

    if param.reg is not None:
        if param.reg == 'huber':
            print('Regularization type: Huber penalty')
            print('Huber constant ---> delta: ')
        elif param.reg == 'tikhonov':
            print('Regularization type: l2 penalty')
        elif param.reg == 'haar':
            print('Regularization type: l1 penalty')

        print('Regularization constant (beta): ', param.reg_cost)

    if args.init_object is True:
        print('Initialization with FBP reconstruction:', param.init_object)

    ##  Reconstruction
    print('\n\nPerforming STASTICAL ITERATIVE RECONSTRUCTION ....')
    time1 = time.time()
    reco_list, info = sir(sino_list, angles, param)
    time2 = time.time()
    print('.... reconstruction done!')

    for i in range(nz):
        ##  Crop reconstruction if edge-padding enabled
        if edf != 0.0:
            reco = reco_list[i, i1:i2, i1:i2]
        else:
            reco = reco_list[i, :, :]

        ##  Show reconstruction
        if args.plot is True and nz == 1:
            dis.plot(reco, 'Reconstruction')
        elif args.plot is True and i == nzz:
            dis.plot(reco, 'Reconstruction')

        ##  Save reconstruction
        if nz == 1:
            save_reco(pathout, filein[0], args, param, reco)
        else:
            save_reco(pathout, filein[0][i], args, param, reco)

    ##  Time elapsed for the reconstruction
    time_tot = (time2 - time1) / 60.0
    print('\nTime elapsed for the reconstruction: ', time_tot)

    ##  Write log file
    if args.logfile is True:
        write_logfile(pathin, pathout, args, angles, ctr, param, time_tot,
                      info)

        write_info(pathout, filein[0], info, param, args)

    ##  Final print
    print('\n')
    print('\n')
    print('##########################################################')
    print('##########################################################')
    print('#####                                                #####')
    print('#####   STATISTICAL ITERATIVE RECONSTRUCTION DONE!   #####')
    print('#####                                                #####')
    print('##########################################################')
    print('##########################################################')
    print('\n')
Exemple #10
0
def sir(b, a, param):
    ##  Get number of pixels and angles
    m, n, nz = param.nang, param.npix_op, param.nz
    b = np.array(b).astype(myfloat)

    ##  Init forward and back-projector
    if param.projector == 'grid-pswf':
        tp = cpj1.projectors(n, a, kernel='pswf', oversampl=2.0)
    elif param.projector == 'grid-kb':
        tp = cpj1.projectors(n,
                             a,
                             kernel='kb',
                             oversampl=1.5,
                             W=6.6,
                             errs=6.0e-6,
                             interp='lin')
    elif param.projector == 'bspline':
        tp = cpj2.projectors(n, a, param, bspline_degree=3, proj_support_y=4)
    elif param.projector == 'radon':
        tp = cpj2.projectors(n, a, param, bspline_degree=1, proj_support_y=2)
    elif param.projector == 'pix-driv':
        tp = cpj3.projectors(n, a, oper='pd')
    elif param.projector == 'ray-driv':
        tp = cpj3.projectors(n, a, oper='rd')
    elif param.projector == 'dist-driv':
        tp = cpj3.projectors(n, a, oper='dd')
    elif param.projector == 'slant':
        tp = cpj3.projectors(n, a, oper='ss')

    ##  Initialize x
    x = np.ones((nz, n, n), dtype=myfloat)

    if param.init_object is True:
        i1 = param.index_start
        i2 = param.index_end
        x_new = []
        b_new = []

        for i in range(nz):
            x[i, :, :] = tp.fbp(b[i, :, :])
            if param.plot is True:
                dis.plot(x[i, :, :], 'Initialization')

    ##  Reconstruction with CG
    if param.algorithm == 'em':
        print('\n\nUsing Maximum-Likelihood Expectation-Maximization')
        x[:], info = em(x, b, tp, param)

    ##  Reconstruction with Lasso-L1
    elif param.algorithm == 'sps':
        print('\n\nUsing Separable Paraboloidal Surrogate')
        x[:], info = sps(x, b, tp, param)

    ##  Conversion for bspline reconstruction and rotate
    if param.projector == 'bspline':
        for i in range(nz):
            x[i, :, :] = bfun.convert_from_bspline_to_pixel_basis(
                x[i, :, :], 3)
        x[:, :, :] = x[:, ::-1, ::-1]

    return x, info
def main():
    ##  Initial print
    print(
        """\nThe program will execute in order 4 tests for the gridding implementation of the forward and backprojector"""
    )

    print(
        """\nEvery time an image is displayed the code is temporarily halted. To the successive tests close the image"""
    )

    #############################################################
    ##  Test n.1
    #############################################################
    inp = raw_input("\n\nProceed with test n.1? (y/n) ")
    if inp == "n":
        exit()

    print("###################################################")
    print("###                                             ###")
    print("###        TEST 1: Test adjoint operator        ###")
    print("###                                             ###")
    print("###################################################")

    test1()

    #############################################################
    ##  Test n.2
    #############################################################
    inp = raw_input("\n\nProceed with test n.2? (y/n) ")
    if inp == "n":
        exit()

    print("###################################################")
    print("###                                             ###")
    print("###        TEST 2: Test forward operator        ###")
    print("###                                             ###")
    print("###################################################")

    sino = test2()

    dis.plot(sino, "Forward projection 402 views X 256 pixels")

    #############################################################
    ##  Test n.3
    #############################################################
    inp = raw_input("\n\nProceed with test n.3? (y/n) ")
    if inp == "n":
        exit()

    print("###################################################")
    print("###                                             ###")
    print("###          TEST 3: Test Backprojector         ###")
    print("###                                             ###")
    print("###################################################")

    reco = test3(sino)

    dis.plot(reco, "Non-filtered backprojection")

    #############################################################
    ##  Test n.4
    #############################################################
    inp = raw_input("\n\nProceed with test n.4? (y/n) ")
    if inp == "n":
        exit()

    print("###################################################")
    print("###                                             ###")
    print("###              TEST 4: Test FBP               ###")
    print("###                                             ###")
    print("###################################################")

    reco = test4(sino)

    dis.plot(reco, "Reconstruction with Hanning filter")
def main():
    ##  Initial print
    print('\n')
    print('###########################################################')
    print('#############   FORWARD REGRIDDING PROJECTOR  #############')
    print('###########################################################')
    print('\n')

    ##  Get the startimg time of the reconstruction
    time1 = time.time()

    ##  Get input arguments
    args = getArgs()

    ##  Get input/output directory
    pathin, pathout = utils.get_io_path(args)

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get input files
    file_list, file1, nimg, ext = utils.get_input(args, pathin)

    print('\nNumber of input files: ', nimg)
    print('Extension of the files: ', ext)

    ##  Read first image
    image = io.readImage(pathin + file1).astype(myfloat)
    npix = image.shape[0]

    print('\nFirst image to forward project: ', file1)
    print('Number of pixels: ', npix)

    if args.plot is True:
        dis.plot(image, 'Input image')

    ##  Get projection angles
    if args.geometry == '0' or args.geometry == '1':
        nang = args.nang
        angle_type = myint(args.geometry)

        if args.angle_range.find(':') == -1 or args.geometry == -1:
            angle_start = myfloat(args.angle_range)
            angle_end = angle_start + 180.0

        else:
            angle_aux = args.angle_range.find(':')
            angle_start = myfloat(angle_aux[0])
            angle_end = myfloat(angle_aux[1])

        angles = utils.create_projection_angles(nang, angle_start, angle_end)

    else:
        angles = utils.create_projection_angles(pathin + args.geometry)

    nang = len(angles)

    print('\nNumber of views: ', nang)
    print('Selected angle range: [ ', angle_start, ' , ', angle_end, ' )')
    print('Angles:\n', angles)

    ##  Initialize projectior class
    tp = cpj.projectors(npix, angles, args=args)

    ##  Apply forward projection operator
    time_rec1 = time.time()
    sino = tp.A(image)
    time_rec2 = time.time()

    ##  Display sinogram
    if args.plot is True:
        dis.plot(sino, 'Sinogram')

    ##  Save sinogram
    save_sinogram(pathout, file1, angles, args, sino)

    ##  Create sinograms from all the other images in the stack
    if args.filein is None:
        pool = mproc.Pool()
        for i in range(1, nimg):
            pool.apply_async(multi_thread,
                             (pathin, pathout, file_list[0][i], angles, args))
        pool.close()
        pool.join()
    time2 = time.time()

    print('\nTime elapsed to run the 1st forward gridrec: ',
          time_rec2 - time_rec1)
    print('Total time elapsed for the run of the program: ', time2 - time1)

    print('\n')
    print('#######################################')
    print('####    FORWARD PROJECTION DONE !  ####')
    print('#######################################')
    print('\n')
def main():
    print('\nRESCALE IMAGE\n')

    ##  Get input arguments
    args = getArgs()

    ##  Get input and output path
    pathin = args.pathin
    if pathin[len(pathin) - 1] != '/':
        pathin += '/'

    if args.pathout is None:
        pathout = pathin
    else:
        pathout = args.pathout
    if pathout[len(pathout) - 1] != '/':
        pathout += '/'

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get single image
    if args.image is not None:
        ##  Reading image
        filein = args.image
        imagein = io.readImage(pathin + filein)
        nrows, ncols = imagein.shape[0], imagein.shape[1]

        print('\nReading image:', filein)
        print('Image size: ', nrows, ' X ', ncols)

        ##  Check plot
        if args.plot is True:
            dis.plot(imagein, 'Input image')

        ##  Make image square
        if args.square is True:
            if nrows < ncols:
                imagein = imagein[:, :nrows]
            else:
                imagein = imagein[:ncols, :]

        ##  Rescaled image
        if args.rescale is not None:
            rescale = args.rescale
            nrows_new = int(nrows * rescale)
            ncols_new = int(ncols * rescale)

        else:
            nrows_new = ncols_new = args.npix
            rescale = nrows_new / myfloat(nrows)

        image_rescale = rescale_image(imagein, rescale)

        print('\nRescaled factor: ', rescale)
        print('Rescaled-image size: ', image_rescale.shape)

        ##  Check plot
        if args.plot is True:
            dis.plot(image_rescale,
                     'Rescaled image -- factor = ' + str(rescale))

        ##  Write noisy image to file
        fileout = filein[:len(filein) - 4] + '_pix'
        if nrows_new < 100:
            fileout += '00' + str(nrows_new) + '.DMP'
        elif nrows_new < 1000:
            fileout += '0' + str(nrows_new) + '.DMP'
        else:
            fileout += str(nrows_new) + '.DMP'

        io.writeImage(pathout + fileout, image_rescale)
        print('\nWriting rescaled image:', fileout)

    ##  Get bunch of input images
    elif args.label is not None:
        curr_dir = os.getcwd()

        ##  Reading images
        os.chdir(pathin)
        files = sorted(glob.glob('*' + args.label + '*'))
        os.chdir(curr_dir)

        num_im_input = len(files)

        for i in range(num_im_input):
            imagein = io.readImage(pathin + files[i])
            nrows, ncols = imagein.shape[0], imagein.shape[1]

            print('\nReading image:\n', files[i])
            print('\nImage size: ', nrows, ' X ', ncols)

            ##  Make image square
            if args.square is True:
                if nrows < ncols:
                    imagein = imagein[:, :nrows]
                else:
                    imagein = imagein[:ncols, :]

            ##  Rescaled image
            if args.rescale is not None:
                rescale = args.rescale
                nrows_new = int(nrows * rescale)
                ncols_new = int(ncols * rescale)

            else:
                nrows_new = ncols_new = args.npix
                rescale = nrows_new / myfloat(nrows)

            image_rescale = rescale_image(imagein, rescale)

            print('\nRescaled factor: ', rescale)
            print('Rescaled-image size: ', image_rescale.shape)

            ##  Write noisy image to file
            fileout = files[i][:len(files[i]) - 4] + '_pix'
            if nrows_new < 100:
                fileout += '00' + str(nrows_new) + '.DMP'
            elif nrows_new < 1000:
                fileout += '0' + str(nrows_new) + '.DMP'
            else:
                fileout += str(nrows_new) + '.DMP'

            io.writeImage(pathout + fileout, image_rescale)
            print('\nWriting rescaled image:', fileout)

    print('\n\n')
def anti_alias_filt(sino,
                    op='cubic',
                    factor=2,
                    bd=0.7,
                    radius=2,
                    reassign=True,
                    plot=False):
    nang, npix = sino.shape

    tracer = np.min(sino) - 100
    factor = np.int(factor)
    if factor <= 1:
        factor = 2
    nang_new = nang * factor

    ig = np.arange(0, nang_new, factor)
    ib = np.setdiff1d(np.arange(nang_new), ig)

    sino_new = np.zeros((nang_new, npix), dtype=myfloat)
    sino_new[ig, :] = sino
    sino_new[ib, :] = tracer

    if plot is True:
        dis.plot(sino_new, 'Sinogram to inpaint')

    if op == 'pg1d':
        for i in range(npix):
            proj = sino_new[:, i]
            sino_new[:, i] = papoulis_gerchberg_1d(proj,
                                                   tracer,
                                                   bd=bd,
                                                   niter=50,
                                                   eps=1e-10)

    elif op == 'pg2d':
        sino_new[:] = papoulis_gerchberg_2d(sino_new,
                                            tracer,
                                            bd=bd,
                                            niter=50,
                                            eps=1e-10)

    elif op == 'zp1d':
        for i in range(npix):
            proj = sino[:, i]
            sino_new[:, i] = zero_padding(proj, mode='c')

    elif op == 'zp2d':
        sino_new[:] = zero_padding(sino, mode='a')[:, ::2]

    elif op == 'cubic':
        for i in range(npix):
            proj = sino_new[:, i]
            sino_new[:, i] = interp(proj, tracer, side=0, itype='cubic')

    elif op == 'navier':
        sino_new[:] = inpainting_navier_stokes(sino_new, tracer, radius=radius)

    elif op == 'telea':
        sino_new[:] = inpainting_telea(sino_new, tracer, radius=radius)

    if reassign is True:
        sino_new[ig, :] = sino

    return sino_new
Exemple #15
0
def main():
    print('\n')
    print('#######################################')
    print('#######################################')
    print('###                                 ###')
    print('###   STRUCTURAL SIMILARITY INDEX   ###')
    print('###                                 ###')
    print('#######################################')
    print('#######################################')
    print('\n')

    ##  Get input arguments
    args = getArgs()

    ## Get oracle image
    currDir = os.getcwd()
    image1 = io.readImage(args.image1)
    image1 = image1.astype(myfloat)

    print('\nReading reference image:\n', args.image1)
    print('Image shape: ', image1.shape)

    image_list = []
    results = []

    ##  CASE OF SINGLE IMAGE TO ANALYZE
    if args.image2 is not None:
        if args.image2.find(':') == -1:
            image_list.append(args.image2)
            image2 = io.readImage(args.image2)  # image2 --> image to analyze
            image2 = image2.astype(myfloat)
            num_img = 1

            print('\nReading image to analyze:\n', args.image2)
            print('Image shape: ', image2.shape)

            ## Get time in which the prgram starts to run
            time1 = time.time()

            ##  Scale image to analyze with respect to the reference one
            if args.scaling is True:
                print('\nPerforming linear regression ....')
                image2 = proc.linear_regression(image1, image2)

            ##  Register images
            if args.register is True:
                print('\nPerforming registration of the image to analize ....')
                image2 = proc.image_registration(image2, image1, 'ssd')

            ##  Crop resolution circle of the images
            if args.resol_circle is True:
                print('\nSelecting the resolution circle')
                image1 = proc.select_resol_square(image1)
                image2 = proc.select_resol_square(image2)

            ##  Crop images if enabled
            if args.roi is not None:
                roi = args.roi

                if roi.find(':') != -1:
                    roi = roi.split(',')
                    p0 = [int(roi[0].split(':')[1]), int(roi[0].split(':')[0])]
                    p1 = [int(roi[1].split(':')[1]), int(roi[1].split(':')[0])]

                    print('Cropping rectangular ROI with vertices:  ( ', \
                            p0[0],' , ', p0[1], ')   ( ', p1[0],' , ',p1[1], ')')

                    image1 = proc.crop_image(image1, p0, p1)
                    image2 = proc.crop_image(image2, p0, p1)

                else:
                    print('\nUsing pixels specified in file:\n', roi)
                    pixels = np.loadtxt(roi)
                    pixels = pixels.astype(int)
                    p0 = np.array([pixels[0, 0], pixels[0, 1]])
                    p1 = np.array([
                        pixels[len(pixels) - 1, 0], pixels[len(pixels) - 1, 1]
                    ])

                    print('Cropping rectangular ROI with vertices:  ( ', \
                            p0[0],' , ', p0[1], ')   ( ', p1[0],' , ',p1[1], ')')

                    image1 = proc.crop_image(image1, p0, p1)
                    image2 = proc.crop_image(image2, p0, p1)

            ##  Compute the gradient of the images, if enabled
            if args.gradient is True:
                image1 = compute_gradient_image(image1)
                image2 = compute_gradient_image(image2)

            ##  Check whether the 2 images have the same shape
            if image1.shape != image2.shape:
                sys.error('\nERROR: The input images have different shapes!\n')

            ##  Plot to check whether the images have the same orientation
            if args.plot is True:
                print('\nPlotting images to check orientation ....')
                img_list = [image1, image2]
                title_list = ['Oracle image', 'Image to analyze']
                dis.plot_multi(img_list, title_list, 'Check plot')

            ##  Get window size
            window_size = args.window
            print('\nSize of the computation window: ', window_size)

            if window_size % 2 != 0:
                window_size += 1
                print('Window size is even: window size changed to ',
                      window_size)

            ##  Get sigma of the gaussian kernel
            sigma = SIGMA
            print('Sigma of the gaussian kernel: ', sigma)

            ## Calculate map of SSIM values
            map_ssim, MSSIM = compute_map_ssim(image1, image2, window_size,
                                               sigma)
            results.append(MSSIM)

            if args.plot is True:
                print('\nPlotting images + map of ssim ....')
                img_list = [image1, image2, map_ssim]
                title_list = [
                    'Oracle image', 'Image to analyze', 'Map of SSIM'
                ]
                dis.plot_multi(img_list, title_list, 'Images and map of SSIM')

            ##  Save SSIM map
            filename = args.image2[:len(args.image2) - 4] + '_ssim_map.png'
            io.writeImage(filename, map_ssim)

        ##  CASE OF MULTIPLE SPECIFIC IMAGES
        else:
            image_list = args.image2.split(':')
            img_list = []
            title_list = []
            num_img = len(image_list)

            for im in range(num_img):
                img_file = image_list[im]
                image1 = io.readImage(args.image1)
                image2 = io.readImage(img_file)  # image2 --> image to analyze
                image2 = image2.astype(myfloat)
                print('\nReading image to analyze:\n', args.image2)
                print('Image shape: ', image2.shape)

                ##  Get time in which the prgram starts to run
                time1 = time.time()

                ##  Scale image to analyze with respect to the reference one
                if args.scaling is True:
                    print('\nPerforming linear regression ....')
                    image2 = proc.linearRegression(image1, image2)

                ##  Register images
                if args.register is True:
                    print(
                        '\nPerforming registration of the image to analize ....'
                    )
                    image2 = proc.image_registration(image2, image1, 'ssd')

                ##  Crop resolution circle of the images
                if args.resol_circle is True:
                    print('\nSelecting the resolution circle')
                    image1 = proc.selectResolutionSquare(image1)
                    image2 = proc.selectResolutionSquare(image2)

                ##  Crop images if enabled
                if args.roi is not None:
                    roi = args.roi

                    if args.roi.find(',') != -1:
                        roi = roi.split(',')
                        p0 = [
                            int(roi[0].split(':')[1]),
                            int(roi[0].split(':')[0])
                        ]
                        p1 = [
                            int(roi[1].split(':')[1]),
                            int(roi[1].split(':')[0])
                        ]

                        print('Cropping rectangular ROI with vertices:  ( ', \
                                p0[0],' , ', p0[1], ')   ( ', p1[0],' , ',p1[1], ')')

                        image1 = proc.crop_image(image1, p0, p1)
                        image2 = proc.crop_image(image2, p0, p1)

                    else:
                        print('\nUsing pixels specified in file:\n', roi)
                        pixels = np.loadtxt(roi)
                        pixels = pixels.astype(int)
                        p0 = np.array([pixels[0, 0], pixels[0, 1]])
                        p1 = np.array([
                            pixels[len(pixels) - 1, 0], pixels[len(pixels) - 1,
                                                               1]
                        ])

                        print('Cropping rectangular ROI with vertices:  ( ', \
                                p0[0],' , ', p0[1], ')   ( ', p1[0],' , ',p1[1], ')')

                        image1 = proc.crop_image(image1, p0, p1)
                        image2 = proc.crop_image(image2, p0, p1)

                ##  Compute the gradient of the images, if enabled
                if args.gradient is True:
                    image1 = compute_gradient_image(image1)
                    image2 = compute_gradient_image(image2)

                ##  Check whether the 2 images have the same shape
                if image1.shape != image2.shape:
                    sys.exit(
                        '\nERROR: The input images have different shapes!\n')

                ##  Plot to check whether the images have the same orientation
                if args.plot is True:
                    print('\nPlotting images to check orientation ....')
                    img_list2 = [image1, image2]
                    title_list2 = ['Oracle image', 'Image to analyze']
                    dis.plot_multi(img_list2, title_list2, 'Check plot')

                ##  Get window size
                window_size = args.window
                print('\nSize of the computation window: ', window_size)

                if window_size % 2 != 0:
                    window_size += 1
                    print('Window size is even: window size changed to ',
                          window_size)

                ##  Get sigma of the gaussian kernel
                sigma = SIGMA
                print('Sigma of the gaussian kernel: ', sigma)

                ##  Calculate map of SSIM values
                map_ssim, MSSIM = compute_map_ssim(image1, image2, window_size,
                                                   sigma)
                results.append(MSSIM)

                map_ssim[map_ssim < 0] = 0.0

                if args.plot is True:
                    img_list.append(map_ssim)
                    title_list.append('SSIM map n.' + str(im + 1))

                ##  Save SSIM map
                filename = img_file[:len(img_file) - 4] + '_ssim_map.png'
                io.writeImage(filename, map_ssim)

            if args.plot is True:
                print('\nPlotting images + map of ssim ....')
                dis.plot(img_list[0])
                dis.plot(img_list[1])
                dis.plot_multi_colorbar(img_list, title_list, 'Maps of SSIM')

    ##  CASE OF BUNCH OF IMAGES TO ANALYZE
    else:
        os.chdir(args.path)
        image_list = sorted(glob.glob('*'))
        num_images = len(image_list)
        img_list.append(image1)
        title_list.append('Oracle image')

        ##  Get time in which the prgram starts to run
        time1 = time.time()

        ##  Loop on all the images to analyze
        for i in range(num_img):
            image1 = io.readImage(args.image1)
            image2 = io.readImage(image_list[i])
            image2 = image2.astype(myfloat)

            print('\n\n\nIMAGE TO ANALYZE NUMBER: ', i)
            print('\nReading image to analyze:\n', fileIn[i])
            print('Image shape: ', image2.shape)

            ##  Scale image to analyze with respect to the reference one
            if args.scaling is True:
                print('\nPerforming linear regression ....')
                image2 = proc.linearRegression(image1, image2)

            ##  Register images
            if args.register is True:
                print('\nPerforming registration of the image to analize ....')
                image2 = proc.image_registration(image2, image1, 'ssd')

            ##  Crop resolution circle of the images
            if args.resol_circle is True:
                print('\nSelecting the resolution circle')
                image1 = proc.selectResolutionSquare(image1)
                image2 = proc.selectResolutionSquare(image2)

            ##  Crop images if enabled
            if args.roi is not None:
                roi = args.roi

                if args.roi.find(',') != -1:
                    roi = roi.split(',')
                    p0 = [int(roi[0].split(':')[1]), int(roi[0].split(':')[0])]
                    p1 = [int(roi[1].split(':')[1]), int(roi[1].split(':')[0])]

                    print('Cropping rectangular ROI with vertices:  ( ', \
                            p0[0],' , ', p0[1], ')   ( ', p1[0],' , ',p1[1], ')')

                    image1 = proc.crop_image(image1, p0, p1)
                    image2 = proc.crop_image(image2, p0, p1)

                else:
                    print('\nUsing pixels specified in file:\n', roi)
                    pixels = np.loadtxt(roi)
                    pixels = pixels.astype(int)
                    p0 = np.array([pixels[0, 0], pixels[0, 1]])
                    p1 = np.array([
                        pixels[len(pixels) - 1, 0], pixels[len(pixels) - 1, 1]
                    ])

                    print('Cropping rectangular ROI with vertices:  ( ', \
                            p0[0],' , ', p0[1], ')   ( ', p1[0],' , ',p1[1], ')')

                    image1 = proc.crop_image(image1, p0, p1)
                    image2 = proc.crop_image(image2, p0, p1)

            ##  Compute the gradient of the images, if enabled
            if args.gradient is True:
                image1 = compute_gradient_image(image1)
                image2 = compute_gradient_image(image2)

            ##  Check whether the 2 images have the same shape
            if image1.shape != image2.shape and args.roi is None:
                sys.error('\nERROR: The input images have different shapes!\n')

            ##  Plot to check whether the images have the same orientation
            if args.plot is True:
                print('\nPlotting images to check orientation ....')
                img_list = [image1, image2]
                title_list = ['Oracle image', 'Image to analyze']
                dis.plot_multi(img_list, title_list, 'Check plot')

            ##  Get window size
            window_size = args.window
            print('\nSize of the computation window: ', window_size)

            if window_size % 2 != 0:
                window_size += 1
                print('Window size is even: window size changed to ',
                      window_size)

            ##  Get sigma of the gaussian kernel
            sigma = SIGMA
            print('Sigma of the gaussian kernel: ', sigma)

            ##  Calculate map of SSIM values
            map_ssim, MSSIM = compute_map_ssim(image1, image2, window_size,
                                               sigma)
            results.append(MSSIM)

            ##  Diplay map of SSIM
            if args.plot is True:
                fig = plt.figure()
                plt.title('Map of SSIM indeces')
                plt.imshow(map_ssim, cmap=cm.Greys_r)
                #plt.colorbar()
                plt.show()

            ##  Save SSIM map
            filename = image_list[i][:len(image_list[i]) - 4] + '_ssim_map.png'
            io.writeImage(filename, map_ssim)
        os.chdir(currDir)

    ##  Summary print of the results
    print('\n\nSUMMARY OF THE RESULTS:\n')
    print('\nReference image:\n', args.image1)

    for i in range(num_img):
        print('\n\nTest image number ', i, '\n', image_list[i], '\n')
        print('SSIM = ', results[i])

    ##  Get time elapsed for the run of the program
    time2 = time.time() - time1
    print('\n\nTime elapsed for the calculation: ', time2)

    ##  Write log file
    write_log_file(args, image_list, results)

    print('\n\n')
Exemple #16
0
def lhem(x0, tracer):
    ##  Extend sinogram to [0,2pi)
    m0, n0 = x0.shape
    s_2pi = extend_full_period(x0)
    ig = np.argwhere(s_2pi != tracer)[:, 0]
    ib = np.argwhere(s_2pi == tracer)[:, 0]

    ##  Resample each projection at cosinusoidal nodes
    sc = resampling_cosine_nodes(s_2pi)
    sc[ib, :] = tracer
    m1, n1 = sc.shape
    mh1 = int(m1 * 0.5)
    nh1 = int(n1 * 0.5)

    ##  Get matrix representation of each operator
    print('Creating Fy and Fya ....')
    Fy = ftmy(m1, n1)
    Fya = Fy.getH()
    print('Creating Sx ....')
    Sx = fsmx(m1, n1)
    print('Creating M ....')
    M = fbmask(m1, n1)
    #I  = ss.eye( m1 * n1 , m1 * n1 )
    I = np.eye(m1 * n1, m1 * n1)

    ##  Matrix representation of D, that keeps only the
    ##  extrapolated values
    print('Creating D ....')
    sx = np.mat(sc.copy().reshape(m1 * n1, 1))
    ib2 = np.argwhere(sx == tracer)
    sx[ib2] = 0.0
    D = np.zeros((m1 * n1, m1 * n1), dtype=myint)
    D[ib2, ib2] = 1.0
    D = ss.coo_matrix(D)

    aux = D.dot(sx)
    dis.plot(aux.reshape(m1, n1), 'Aux')

    ##  Complete operator
    print('Creating H ....')
    H = D.dot(Fya.dot(Sx.dot(M.dot(Sx.dot(Fy)))))

    ##  Compute limit operator
    print('Creating Hl ....')
    eps = 1e-5
    H = H.todense()
    Hl = np.linalg.pinv(I - H)

    #Hl = np.eye( m1 * n1 , dtype=mycomplex )
    #for i in range( 1 , 50 ):
    #    print( 'i = ' , i )
    #    Hl += np.linalg.matrix_power( H , i )

    #for i in range( 1 , 30 ):
    #    print( 'i = ' , i )
    #    sx[:] = np.mat( np.dot( H , sx ) )
    #    sx[ig] = sc[ig]
    #sx = sx.reshape( m1 , n1 )

    eva, eve = np.linalg.eig(H)
    print('Max-eigen: ', np.max(np.abs(eva)))

    H2 = np.dot(np.transpose(np.conjugate(H)), H)
    eva, eve = np.linalg.eig(H2)
    print('Max-eigen: ', np.max(np.abs(eva)))

    ##  Filtered sinogram
    print('Creating filt. sinogram ....')
    #sx = np.real( Hl.dot( sx ) ).reshape( m1 , n1 )
    sx = np.real(np.dot(Hl, sx)).reshape(m1, n1)

    ##  Resample on equispaced nodes
    print('Resample on equispaced nodes ....')
    x = resampling_equisp_nodes(sx, n0)

    ##  Halve the nuber of projections
    x = x[:m0, :]

    return x
Exemple #17
0
def debug_lhem(x0, tracer):
    ##  Extend sinogram to [0,2pi)
    m0, n0 = x0.shape
    s_2pi = extend_full_period(x0)
    ig = np.argwhere(s_2pi != tracer)[:, 0]
    ib = np.argwhere(s_2pi == tracer)[:, 0]
    #dis.plot( s_2pi , 'S-2pi' )

    ##  Resample each projection at cosinusoidal nodes
    sc = resampling_cosine_nodes(s_2pi)
    sc[ib, :] = tracer
    m1, n1 = sc.shape
    mh1 = int(m1 * 0.5)
    nh1 = int(n1 * 0.5)
    dis.plot(sc, 'SC')

    ##  Get matrix representation of each operator
    print('Creating Fy and Fya ....')
    Fy = ftmy(m1, n1)
    Fya = Fy.getH()
    print('Creating Sx ....')
    Sx = fsmx(m1, n1)
    print('Creating M ....')
    M = fbmask(m1, n1)
    I = ss.eye(m1 * n1, m1 * n1)

    ##  Matrix representation of D, that keeps only the
    ##  extrapolated values
    print('Creating D ....')
    sx = np.mat(sc.copy().reshape(m1 * n1, 1))
    ib2 = np.argwhere(sx == tracer)
    D = np.zeros((m1 * n1, m1 * n1), dtype=myint)
    D[ib2, ib2] = 1.0
    D = ss.coo_matrix(D)

    ##  Get traced and non-traced elements
    sx = sc.copy()
    sx[ib, :] = 0.0

    ##  Loop
    it = 0
    err = 1000
    nc = n1
    niter = 50
    eps = 1e-10

    while it < niter and err > eps:
        sx = sx.reshape(m1 * n1, 1)

        ##  Fourier-Chebyshev decomposition
        if it == 0:
            c = Sx.dot(sx)  #fp.dst( sx , type=1 , axis=1 )
            b = Fy.dot(
                c)  #np.fft.fftshift( np.fft.fft( c , axis=0 ) , axes=0 )
            sp = sx.copy().reshape(m1, n1)
        else:
            c[:] = Sx.dot(sx)  #fp.dst( sx , type=1 , axis=1 )
            b[:] = Fy.dot(
                c)  #np.fft.fftshift( np.fft.fft( c , axis=0 ) , axes=0 )
            sp[:] = sx.reshape(m1, n1)

        ##  Zero-out inconsistent coefficients
        #dis.plot( np.real( b ).reshape( m1 , n1 ) , 'B before' )
        b[:] = M.dot(b)  #b[ic[:,0],ic[:,1]] = 0.0
        #dis.plot( np.real( b ).reshape( m1 , n1 ) , 'B after' )

        ##  Reproject to real space
        c = Fya.dot(
            b
        )  #c[:]  = np.real( np.fft.ifft( np.fft.ifftshift( b , axes=0 ) , axis=0 ) )
        #dis.plot( np.real( c ).reshape( m1 , n1 ) , 'C' )
        # sx_r[:] = 1.0 / ( 2.0 * ( nc + 1 ) ) * fp.dst( c , type=1 , axis=1 )
        # sx_i[:] = 1.0 / ( 2.0 * ( nc + 1 ) ) * fp.dst( ci , type=1 , axis=1 )
        sx[:] = Sx.dot(c)  # sx[:] = np.sqrt( sx_r**2 + sx_i**2 )

        #dis.plot( np.real( sx ).reshape( m1 , n1 ) , 'Sx before reassign' )
        ##  Re-assign original values
        sx = sx.reshape(m1, n1)
        sx[ig, :] = sc[ig, :]
        #dis.plot( sx , 'Sx after reassign' )

        ##  Compute error & PSNR
        err = np.linalg.norm(sx - sp)
        it += 1

        print('\n    Iteration n. ',
              it,
              ' ---> || x_{k+1} - x{k}|| = ',
              err,
              end='')

    ##  Crop original sinogram interval [0,pi) and first channel half (transl. of 1)
    sx = sx[:mh1, :]

    ##  Interpolate back on equispaced nodes
    x = resampling_equisp_nodes(sx, n0)

    print('\n')

    return x
def main():
    ##  Initial print
    print('\n')
    print('##################################################################')
    print('#############   TOMOGRAPHIC GRIDDING RECONSTRUCTION  #############')
    print('##################################################################')
    print('\n')

    ##  Get the startimg time of the reconstruction
    time1 = time.time()

    ##  Get input arguments
    args = getArgs()

    ##  Get input/output directory
    pathin, pathout = utils.get_io_path(args)

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get input files
    file_list, file1, nimg, ext = utils.get_input(args, pathin)

    print('\nNumber of input files: ', nimg)
    print('Extension of the files: ', ext)

    ##  Read first sinogram
    sino = io.readImage(pathin + file1).astype(myfloat)
    nang, npix = sino.shape

    print('\nSinogram to reconstruct:\n', file1)
    print('Number of projection angles: ', nang)
    print('Number of pixels: ', npix)

    if args.plot is True:
        dis.plot(sino, 'Input sinogram')

    ##  Enable edge padding
    if args.edge_pad is True:
        sino = proc.sino_edge_padding(sino, 0.5).astype(myfloat)
        i1 = int((sino.shape[1] - npix) * 0.5)
        i2 = i1 + npix
        npix = sino.shape[1]
        ctr = args.ctr

        if ctr != 0.0:
            ctr += i1

        if args.plot is True:
            dis.plot(sino, 'Edge padded sinogram')
    else:
        i1 = 0
        i2 = npix
        ctr = args.ctr

    ##  Getting projection geometry
    if args.geometry == '0':
        print(
            '\nDealing with equiangular projections distributed between 0 and'
            + ' 180 degrees ---> [0,180)')
        angles = utils.create_projection_angles(nang)

    else:
        print('\nReading list of projection angles:\n', pathin + args.geometry)
        angles = utils.create_projection_angles(textfile=pathin +
                                                args.geometry)

    if args.plot is True:
        print('\nProjection angles:')
        pp.printArray(angles)

    ##  Enable object support calculation
    if args.object_support is True:
        print('\nObject support calculation enabled')
        mask = ob.object_support(sino)
        if args.plot is True:
            dis.plot(mask, 'Object support mask')

    ##  Differential sinogram fo DBP
    if args.dbp is True:
        print('\nDifferential backprojection enabled')
        print(
            'Computing differential sinogram by means of Savitzky-Golay method'
        )
        sino[:, :] = proc.diff_sino_savitzky_golay(sino, window_size=11)

        if args.plot is True:
            dis.plot(sino, 'Differential sinogram')

    ##  Initialize projectior class
    tp = cpj.projectors(npix, angles, ctr=ctr, args=args)

    ##  Apply forward projection operator
    time_rec1 = time.time()
    reco = tp.fbp(sino)
    time_rec2 = time.time()

    ##  Crop reconstruction
    if args.edge_pad:
        reco = reco[i1:i2, i1:i2]

    ##  Apply object support mask
    if args.object_support is True:
        reco[mask == 0] = 0.0

    ##  Display reconstruction
    if args.plot is True:
        dis.plot(reco, 'Reconstruction')

    ##  Save reconstruction
    save_reconstruction(pathout, file1, args, reco)

    ##  Reconstruct sinograms from all the other images in the stack
    if args.filein is None:
        pool = mproc.Pool()
        for i in range(1, nimg):
            pool.apply_async(
                multi_thread,
                (pathin, pathout, file_list[0][i], args, [i1, i2]))
        pool.close()
        pool.join()
    time2 = time.time()

    print('\nTime elapsed to run the 1st backward gridrec: ',
          time_rec2 - time_rec1)
    print('Total time elapsed for the run of the program: ', time2 - time1)

    print('\n')
    print('##############################################')
    print('####    GRIDDING RECONSTRUCTION DONE !    ####')
    print('##############################################')
    print('\n')
Exemple #19
0
def main():
    print('\n')
    print('#########################################################')
    print('#########################################################')
    print('###                                                   ###')
    print('###  CREATE SHEPP-LOGAN AND ITS ANALYTICAL SINOGRAM   ###')        
    print('###                                                   ###')     
    print('#########################################################')
    print('#########################################################') 
    print('\n')


    
    ##  Get arguments
    args = getArgs()


    
    ##  Get number of pixels
    npix = args.npix
    nang = args.nang
    
    print('\nNumber of pixels: ', npix)
    print('Number of views: ', nang)   

    
    
    ##  Create look-up-table of Shepp-Logan ellipses or read specifics from file
    if args.filein is None:
        LUT = lut_shepp_logan( npix , nang ) 
        print('\nCreated LUT for Shepp-Logan phantom')

    else:
        lut_file = np.loadtxt( args.filein )
        LUT = lut_generic_phantom( lut_file , npix , nang )
        
        if args.filein.find( '/' ) == -1:
            name = args.filein.split( '.' )[0]
        else:
            tokens = args.filein.split( '/' )
            name = tokens[len(tokens)-1].split('.')[0]  

        print('\nReading LUT for phantom from file:\n', args.filein)
        print('Label selected for the putput files: ', name)
        


    ##  Create Shepp-Logan phantom
    phantom = create_phantom( LUT , npix )

    

    ##  Write phantom
    path = args.path
    if path[len(path)-1] != '/':
        path += '/'

    if args.filein is None:
        filename = path + 'shepp_logan_pix'
    else:
        filename = path + name + '_pix'

    if npix < 10:
        common = '000' + str( npix )    
    elif npix < 100:
        common = '00' + str( npix )
    elif npix < 1000:
        common = '0' + str( npix )
    else:
        common = str( npix )

    filename += common + args.file_format

    io.writeImage( filename , phantom )   
    
    print('\nWriting sinogram in:\n', filename)     


    
    ##  Plot phantom
    if args.plot is True:
        dis.plot( phantom , 'Shepp-Logan ' + str( npix ) + ' X ' + str( npix ) + ' pixels' )

    

    ##  Compute analitically radon transform of the phantom
    if args.nang is not None:
        print('\nCalculating analytical radon transform of the phantom ....')
        
        sinogram = radon_transform_analytical( phantom , LUT , npix , nang )
        sinogram[:,:] = sinogram[:,::-1]
        sinogram[:,:] = np.roll( sinogram , 1 , axis=1 )


        ##  Plot Shepp-Logan phantom
        if args.plot is True:
            dis.plot( sinogram , 'Sinogram  ' + str( nang ) + ' views X ' + str( npix ) + ' pixels' )


        ##  Write sinogram
        if args.filein is None:
            filename = path + 'shepp_logan_pix' + common + '_ang'
        else:
            filename = path + name + '_pix' + common + '_ang'

        if nang < 10:
            filename += '000' + str( nang ) + '_rt_anal_sino' + args.file_format
        elif nang < 100:
            filename += '00' + str( nang ) + '_rt_anal_sino' + args.file_format
        elif nang < 1000:
            filename += '0' + str( nang ) + '_rt_anal_sino' + args.file_format
        else:
            filename += str( nang ) + '_rt_anal_sino' + args.file_format  
        
        io.writeImage( filename , sinogram )
   
        print('\nWriting sinogram in:\n', filename)      
    
    
    print('\n\n')
def main():
    ##  Initial print
    print('\n')
    print('########################################################')
    print('####              CREATE VIRTUAL SINOGRAM           ####')
    print('########################################################')
    print('\n')  



    ##  Get arguments
    args = getArgs()



    ##  Get input/output directory
    pathin , pathout = utils.get_io_path( args )
    
    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)



    ##  Get input files
    file_list , file1 , nimg , ext = utils.get_input( args , pathin )
    
    print('\nNumber of input files: ' , nimg)
    print('Extension of the files: ', ext)



    ##  Read first sinogram
    sino = io.readImage( pathin + file1 ).astype( myfloat )
    nang , npix = sino.shape

    print('\nSinogram to reconstruct:\n', file1)
    print('Number of projection angles: ', nang)
    print('Number of pixels: ', npix)     

    if args.plot is True:
        dis.plot( sino , 'Input sinogram' )



    ##  Set center of rotation axis
    if args.ctr == None:
        ctr = 0.0
        print('Center of rotation axis placed at pixel: ', npix * 0.5)  
    else:
        ctr = args.ctr
        print('Center of rotation axis placed at pixel: ', ctr)



    ##  Enable edge-padding
    if args.edge_pad is True:
        sino = proc.sino_edge_padding( sino , 0.5 ).astype( myfloat )
        i1 = int( ( sino.shape[1] - npix ) * 0.5 )
        i2 = i1 + npix            
        npix = sino.shape[1]

        if ctr != 0.0:
            ctr += i1
        
        if args.plot is True:
            dis.plot( sino , 'Edge padded sinogram' )
    else:
        i1 = 0
        i2 = npix 



    ##  Prepare projectors
    ang = np.arange( nang ) * 180.0 / myfloat( nang )  
    tp = cpj.projectors( npix , ang , kernel='kb' , oversampl=2.32 , 
                         W=6.6 , errs=6.0e-6 , interp='lin' , 
                         radon_degree=0 , filt=args.filt , ctr=ctr ) 



    ##  Reconstruct
    reco = tp.fbp( sino )
    if args.plot is True:
        dis.plot( reco , 'Reconstruction' ) 
    #reco = reco[i1:i2,i1:i2]



    ##  Zero-out pixels outside resolution circle
    reco_new = reco.copy();  reco_new[:] = 0.0
    io.writeImage( 'reco.DMP' , reco[i1:i2,i1:i2] ) 
    reco_new[i1:i2,i1:i2] = utils.resol_circle_constr( reco[i1:i2,i1:i2] )
    reco[:] = reco_new[:]

    if args.plot is True:
        dis.plot( reco , 'Constrained reconstruction' )
    io.writeImage( 'reco_circle.DMP' , reco )



    ##  Background equalization
    reco[:] = background_equalization( reco )

    if args.plot is True:
        dis.plot( reco , 'Equalized reconstruction' )
    io.writeImage( 'reco_equaliz.DMP' , reco )



    ##  Forward projection
    nang_new = np.int( npix * np.pi / 2.0 )
    ang_new  = np.arange( nang_new ) * 180.0 / np.float32( nang_new )
    tp       = cpj.projectors( npix , ang_new , kernel='kb' , oversampl=2.32 , 
                               W=6.6 , errs=6.0e-6 , interp='lin' , 
                               radon_degree=0 ) 
    sino = tp.A( reco )
    #sino = sino[:,i1:i2]

    if args.plot is True:
        dis.plot( sino , 'Forward projection' )
    io.writeImage( 'sino_circle.DMP' , sino )



    ##  Save output file
    if args.fileout is None:
        filein    = args.filein
        extension = filein[len(filein)-4:]
        fileout   = filein[:len(filein)-4] + '_virt.tif'
    else:
        fileout = args.fileout
    io.writeImage( pathout + fileout , sino )
    print( '\nWritten output file:\n' , pathout + fileout )
def main():
    ##  Initial print
    print('\n')
    print('########################################################')
    print('#############   REGRIDDING BACKPROJECTION  #############')
    print('########################################################')
    print('\n')

    ##  Get the startimg time of the reconstruction
    time1 = time.time()

    ##  Get input arguments
    args = getArgs()

    ##  Get input/output directory
    pathin, pathout = utils.get_io_path(args)

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get input files
    file_list, file1, nimg, ext = utils.get_input(args, pathin)

    print('\nNumber of input files: ', nimg)
    print('Extension of the files: ', ext)

    ##  Read first sinogram
    sino = io.readImage(pathin + file1).astype(myfloat)
    nang, npix = sino.shape

    print('\nSinogram to reconstruct:\n', file1)
    print('Number of projection angles: ', nang)
    print('Number of pixels: ', npix)

    if args.plot is True:
        dis.plot(sino, 'Input sinogram')

    ##  Getting projection geometry
    if args.geometry == '0':
        print(
            '\nDealing with equiangular projections distributed between 0 and'
            + ' 180 degrees ---> [0,180)')
        angles = utils.create_projection_angles(nang)

    else:
        print('\nReading list of projection angles:\n', pathin + args.geometry)
        angles = utils.create_projection_angles(textfile=pathin +
                                                args.geometry)

    ##  Set center of rotation axis
    if args.ctr == None:
        ctr = 0.0
        print('Center of rotation axis placed at pixel: ', npix * 0.5)
    else:
        if args.ctr == -1:
            ctr = proc.search_rot_ctr(sino, None, 'a')
            print('Center of rotation axis placed at pixel: ', ctr)
        else:
            ctr = args.ctr
            print('Center of rotation axis placed at pixel: ', ctr)
            if args.dbp is True:
                sino[:, :] = proc.sino_correct_rot_axis(sino, ctr)
                print('Center of rotation corrected')
                ctr = 0.0

    ##  Enable edge padding
    if args.edge_pad is True:
        sino = proc.sino_edge_padding(sino, 0.5).astype(myfloat)
        i1 = int((sino.shape[1] - npix) * 0.5)
        i2 = i1 + npix
        npix = sino.shape[1]

        if ctr != 0.0:
            ctr += i1

        if args.plot is True:
            dis.plot(sino, 'Edge padded sinogram')
    else:
        i1 = 0
        i2 = npix

    ##  External sinogram filtering
    if args.filt == 'ramp-ext' or args.filt == 'conv-ext':
        if filt == 'ramp-ext':
            sino = fil.filter_fft(sino, 'ramp')

        elif filt == 'conv-ext':
            sino = fil.filter_convolve(sino)

        sino *= 4.0 / myfloat(npix)
        args.filt = 0

    ##  Differential sinogram fo DBP
    if args.dbp is True:
        print('\nDifferential backprojection enabled')
        print(
            'Computing differential sinogram by means of Savitzky-Golay method'
        )
        print('Savizky-Golay window length: ', args.sg)
        sino[:, :] = proc.diff_sino_savitzky_golay(sino, window_size=args.sg)

        if args.plot is True:
            dis.plot(sino, 'Differential sinogram')

    ##  Initialize projectior class
    tp = cpj.projectors(npix, angles, ctr=ctr, args=args)

    ##  Apply forward projection operator
    time_rec1 = time.time()
    reco = tp.fbp(sino)
    time_rec2 = time.time()

    ##  Crop reconstruction
    if args.edge_pad:
        reco = reco[i1:i2, i1:i2]

    ##  Display reconstruction
    if args.plot is True:
        dis.plot(reco, 'Reconstruction')

    ##  Save reconstruction
    save_reconstruction(pathout, file1, args, reco)

    ##  Reconstruct sinograms from all the other images in the stack
    if args.filein is None:
        pool = mproc.Pool()
        for i in range(1, nimg):
            pool.apply_async(
                multi_thread,
                (pathin, pathout, file_list[0][i], args, [i1, i2]))
        pool.close()
        pool.join()
    time2 = time.time()

    print('\nTime elapsed to run the 1st backward gridrec: ',
          time_rec2 - time_rec1)
    print('Total time elapsed for the run of the program: ', time2 - time1)

    print('\n')
    print('##############################################')
    print('####   REGRIDDING BACKPROJECTION DONE !   ####')
    print('##############################################')
    print('\n')
Exemple #22
0
def main():
    ##  Initial print
    print('\n')
    print('########################################################')
    print('#############   REGRIDDING BACKPROJECTION  #############')
    print('########################################################')
    print('\n')


    ##  Get the startimg time of the reconstruction
    time1 = time.time()



    ##  Get input arguments
    args = getArgs()


    
    ##  Get input and output directory
    pathin = args.pathin
    
    if pathin[len(pathin)-1] != '/':
        pathin += '/'

    if os.path.exists( pathin ) is False:
        sys.exit('\nERROR: input directory ', pathin,' does not exist!')

    if args.pathout is None:
        pathout = pathin
    else:
        pathout = args.pathout
        if pathout[len(pathout)-1] != '/':
            pathout += '/'

    if os.path.exists( pathin ) is False:
        sys.exit('\nERROR: input directory ', pathin,' does not exist!')  

    print('\nInput directory:\n', pathin)



    ##  Get input sinogram
    sinofile = pathin + args.sino
    sino = io.readImage( sinofile )
    nang, npix = sino.shape

    print('\nSinogram to reconstruct:\n', sinofile)
    print('Number of projection angles: ', nang)
    print('Number of pixels: ', npix)



    ##  Display sinogram
    if args.plot is True:
        dis.plot( sino , 'Input sinogram' )



    ##  Getting projection geometry  
    ##  Case of equiangular projections distributed in [0,180)
    if args.geometry == '0':
        print('\nDealing with equiangular projections distributed between 0 and'
                +' 180 degrees ---> [0,180)')
        angles = np.arange( nang ).astype( myfloat )
        angles[:] = ( angles * 180.0 )/myfloat( nang )

    ##  Case of list of projection angles in degrees
    else:
        geometryfile = pathin + args.geometry
        print('\nReading list of projection angles: ', geometryfile)
        angles = np.fromfile( geometryfile , sep="\t" )

    if args.plot is True:
        print('\nProjection angles:\n', angles)


    
    ##  Choose filtering function
    filt_list = [ 'none' , 'ramp' , 'shlo' , 'hann' , 'hamm' , 'parz' , 'lanc' ]
    filt = args.filt

    if filt not in filt_list:
        sys.exit("\nERROR: filter named: ', filt,' does not exist!\n \
                  Use one of the following available filters:\n \
                  'none' , 'ramp' , 'shlo' , 'hann' , 'hamm' , 'parz' , 'lancz'")

    print('\nSelected filter: ', filt)

    param = np.zeros( 3 )

    if filt == 'none':
        param[1] = 0
    elif filt == 'ramp':
        param[1] = 1 
    elif filt == 'shlo':
        param[1] = 2 
    elif filt == 'hann':
        param[1] = 3 
    elif filt == 'hamm':
        param[1] = 4 
    elif filt == 'lanc':
        param[1] = 5 
    elif filt == 'parz':
        param[1] = 6


    
    ##  Set center of rotation axis
    if args.ctr == None:
        ctr = npix * 0.5
    elif args.ctr == -1:
        ctr = proc.searchCtrRot( sino , None , 'a' )
    else:
        ctr = args.ctr


    
    ##  Enable edge padding
    if args.edge_pad is True:
        sino = proc.edgePadding( sino , 0.5 )
        i1 = int( ( sino.shape[1] - npix ) * 0.5 )
        i2 = i1 + npix            
        npix = sino.shape[1]
        ctr += i1
        
        if args.plot is True:
            dis.plot( sino , 'Edge padded sinogram' )

    param[0] = ctr
    print('Center of rotation axis placed at pixel: ', ctr) 



    ##  Reconstruction with regridding method
    time_rec1 = time.time()
    
    reco = grid.backproj( sino.astype( myfloat ) ,
                          angles.astype( myfloat ) ,
                          param.astype( myfloat ) )

    time_rec2 = time.time()


    
    ##  Crop reconstruction
    if args.edge_pad:
        reco = reco[i1:i2,i1:i2]  


    
    ##  Display reconstruction
    if args.plot is True:
        dis.plot( reco , 'Reconstruction' )


    
    ##  Save reconstruction
    saveReco( reco , pathin , pathout , args )

    
    
    ##  Time elapsed for the reconstruction
    time2 = time.time()
    print('\nTime elapsed for the back-projection: ', time_rec2-time_rec1 )
    print('Total time elapsed: ', time2-time1 )


    
    print('\n')
    print('##############################################')
    print('####   REGRIDDING BACKPROJECTION DONE !   ####')
    print('##############################################')
    print('\n')
def main():
    ##  Initial print
    print('\n')
    print('########################################################')
    print('#############   EQUALLY SLOPED TOMOGRAPHY  #############')
    print('########################################################')
    print('\n')


    ##  Get the startimg time of the reconstruction
    time1 = time.time()



    ##  Get input arguments
    args = getArgs()


    
    ##  Get input directory
    pathin = args.pathin
    
    if pathin[len(pathin)-1] != '/':
        pathin += '/'

    if os.path.exists( pathin ) is False:
        sys.exit('\nERROR: input directory ', pathin,' does not exist!')

    print('\nInput directory:\n', pathin)



    ##  Get input sinogram
    sinofile = pathin + args.sino
    sino = io.readImage( sinofile )
    nang, npix = sino.shape

    print('\nSinogram to reconstruct:\n', sinofile)
    print('Number of projection angles: ', nang)
    print('Number of pixels: ', npix)



    ##  Display sinogram
    if args.plot is True:
        dis.plot( sino , 'Input sinogram' )



    ##  Getting projection geometry  
    ##  Case of equiangular projections distributed in [0,180)
    if args.geometry == '0':
        print('\nDealing with equiangular views distributed in [0,180)')
        angles = np.arange( nang ).astype( myfloat )
        angles[:] = ( angles * 180.0 )/myfloat( nang )

    ##  Case of pseudo polar views
    elif args.geometry == '1':
        print('\nDealing with equally sloped views in [0,180)')
        angles , dump1 , dum2 = pyest.create_est_views( nang )
        angles *= 180.0 / np.pi

    ##  Case of list of projection angles in degrees
    else:
        geometryfile = pathin + args.geometry
        print('\nReading list of projection angles: ', geometryfile)
        angles = np.fromfile( geometryfile , sep="\t" )

    print('\nProjection angles:\n', angles)



    ##  Set center of rotation axis
    if args.ctr == None:
        ctr = 0.0
        print('\nCenter of rotation axis placed at pixel: ', npix * 0.5)  
    elif args.ctr == -1:
        ctr = proc.searchCtrRot( sino , None , 'a' )
        print('\nCenter of rotation axis placed at pixel: ', ctr)
        sino = proc.sinoRotAxisCorrect( sino , ctr )
    else:
        ctr = args.ctr
        print('\nCenter of rotation axis placed at pixel: ', ctr)
        sino = proc.sinoRotAxisCorrect( sino , ctr ) 



    ##  Get inverse procedure
    if args.reco_proc == 1:
        proc = args.reco_proc
        print('\nSelected inverse procedure: PCG-IPPFT')

    elif args.reco_proc == 2:
        proc = args.reco_proc
        print('\nSelected inverse procedure: iterative procedure with constraints')   



    ##  Reconstruction with EQUALLY SLOPED TOMOGRAPHY
    print('\nPerforming EST reconstruction ....')
    time_rec1 = time.time()
    reco = pyest.est_tomo( sino , angles , proc )
    time_rec2 = time.time()
    print('\n.... reconstruction done!')



    ##  Display reconstruction    
    dis.plot( reco , 'Reconstruction' )


    
    ##  Save reconstruction
    saveReco( reco , pathin , args )

    
    
    ##  Time elapsed for the reconstruction
    time2 = time.time()
    print('\nTime elapsed for the back-projection: ', time_rec2-time_rec1 )
    print('Total time elapsed: ', time2-time1 )


    
    print('\n')
    print('##############################################')
    print('####   EQUALLY SLOPED TOMOGRAPHY DONE !   ####')
    print('##############################################')
    print('\n')
def main():
    print('\nADD NOISE TO IMAGES\n')

    ##  Get input arguments
    args = getArgs()

    ##  Get input and output path
    pathin = args.pathin
    if pathin[len(pathin) - 1] != '/':
        pathin += '/'

    if args.pathout is None:
        pathout = pathin
    else:
        pathout = args.pathout
    if pathout[len(pathout) - 1] != '/':
        pathout += '/'

    print('\nInput path:\n', pathin)
    print('\nOutput path:\n', pathout)

    ##  Get single image
    if args.image is not None:
        ##  Reading image
        filein = args.image
        imagein = io.readImage(pathin + filein).astype(myfloat)
        shape = np.array(imagein.shape)
        print('\nReading image:\n', filein, '\n')

        if len(shape) == 2:
            dim = 2
            nrows, ncols = shape
            print('Image size: ', nrows, ' X ', ncols)
            if args.plot is True:
                dis.plot(imagein, 'Input image')
        else:
            dim = 3
            nz, nrows, ncols = shape
            print('Image size: ', nz, ' X ', nrows, ' X ', ncols)
            if args.plot is True:
                dis.plot(imagein[0, :, :], 'Input image')

        ##  Compute standard deviation of the image
        ##  and, subsequently, the gaussian sigmas
        if args.noise == 'gaussian':
            sigma = 0.5 * np.max(imagein)

            sigma_list = args.sigma_list
            sigma_list = np.array(sigma_list.split(':'), dtype=myfloat)
            nimg = len(sigma_list)

            sigma_arr = sigma * sigma_list / 100.0

            print('\nSigma of the input image: ', sigma)
            print('Sigma percentages: ', sigma_list)

        elif args.noise == 'poisson':
            nimg = 1

        else:
            sys.exit('\nERROR: Noise type "' + args.noise +
                     '" is not an option available with this routine!\n')

        ##  Loop on each gaussian sigma
        for im in range(nimg):
            ##  Add noise
            if args.noise == 'gaussian':
                image_noisy = add_gaussian_noise(imagein, sigma_arr[im])
                label = 'gauss'
                write_output_image(pathout,
                                   filein,
                                   image_noisy,
                                   label,
                                   sigma=sigma_list[im])

            elif args.noise == 'poisson':
                image_noisy = add_poisson_noise(imagein)
                label = 'poiss'
                write_output_image(pathout, filein, image_noisy, label)

            ##  Check noisy image
            if args.plot is True:
                if dim == 2:
                    if args.noise == 'gaussian':
                        dis.plot(
                            image_noisy, 'Gaussian noisy image -- sigma: ' +
                            str(sigma_list[im]))
                    elif args.noise == 'poisson':
                        dis.plot(image_noisy, 'Poisson noisy image')
                else:
                    if args.noise == 'gaussian':
                        dis.plot(
                            image_noisy[0, :, :],
                            'Gaussian noisy image -- sigma: ' +
                            str(sigma_list[im]))
                    elif args.noise == 'poisson':
                        dis.plot(image_noisy[0, :, :], 'Poisson noisy image')

    ##  Get bunch of input images
    elif args.label is not None:
        curr_dir = os.getcwd()

        ##  Reading images
        os.chdir(pathin)
        files = sorted(glob.glob('*' + args.label + '*'))
        os.chdir(curr_dir)

        num_im_input = len(files)

        for i in range(num_im_input):
            imagein = io.readImage(pathin + files[i]).astype(myfloat)
            nrows, ncols = imagein.shape

            print('\nReading image:\n', files[i])
            print('Image size: ', nrows, ' X ', ncols)

            ##  Compute standard deviation of the image
            ##  and, subsequently, the gaussian sigmas
            sigma = np.mean(imagein)
            if sigma == 0:
                sigma = 1.0

            sigma_list = args.sigma_list
            sigma_list = np.array(sigma_list.split(':'), dtype=myfloat)
            nimg = len(sigma_list)

            sigma_arr = sigma * sigma_list / 100.0

            print('\nSigma of the input image: ', sigma)
            print('Sigma percentages: ', sigma_list)
            print('Gaussian sigma values: ', sigma_arr)

            ##  Add noise ##  Loop on each gaussian sigma
            if args.noise == 'gaussian':
                for im in range(nimg):
                    ##  Loop on each gaussian sigma
                    image_noisy = add_gaussian_noise(imagein, sigma_arr[im])
                    label = 'gauss'
                    write_output_file(pathout,
                                      files[i],
                                      image_noisy,
                                      label,
                                      sigma=sigma_arr[im])

            elif args.noise == 'poisson':
                image_noisy = add_poisson_noise(imagein)
                label = 'poiss'
                write_output_file(pathout, files[i], image_noisy, label)

    print('\n\n')