コード例 #1
0
def histogram(data, nbin=256, rng=[], plot=True, log=False):
    """
    Compute histogram of the data.
    """

    #print('Calculating histogram...')
    data2 = data[::2, ::2, ::2]

    if rng == []:
        mi = min(data2.min(), 0)

        ma = numpy.percentile(data2, 99.99)
    else:
        mi = rng[0]
        ma = rng[1]

    y, x = numpy.histogram(data2, bins=nbin, range=[mi, ma])

    # Set bin values to the middle of the bin:
    x = (x[0:-1] + x[1:]) / 2

    if plot:
        display.plot(x, y, semilogy=log, title='Histogram')

    return x, y
コード例 #2
0
ファイル: spectrum.py プロジェクト: teascavenger/flexcalc
def spectralize(proj, kv = 90, n_phot = 1e8, specimen = {'material':'Al', 'density': 2.7}, filtr = {'material':'Cu', 'density':8, 'thickness':0.1}, detector = {'material':'Si', 'density':5, 'thickness':1}):
    """
    Simulate spectral data.
    """
    
    # Generate spectrum:
    energy, spectrum = effective_spectrum(kv, filtr, detector)
    
    # Get the material refraction index:
    mu = linear_attenuation(energy, specimen['material'], specimen['density'])
     
    # Display:
    display.plot(energy, spectrum, title = 'Spectrum') 
    display.plot(energy, mu, title = 'Linear attenuation') 
        
    # Simulate intensity images:
    counts = numpy.zeros_like(proj)
        
    for ii in range(len(energy)):
        
        # Monochromatic component:
        monochrome = spectrum[ii] * numpy.exp(-proj * mu[ii])
        monochrome = resolution.apply_noise(monochrome, 'poisson', n_phot) / n_phot    
        
        # Detector response is assumed to be proportional to E
        counts += energy[ii] * monochrome
    
    return counts
コード例 #3
0
ファイル: project.py プロジェクト: teascavenger/flextomo
def FISTA(projections, volume, geometry, iterations):
    '''
    FISTA reconstruction. Right now there is no TV minimization substep here!
    '''
    global settings
    preview = settings['preview']
    norm_update = settings['norm_update']

    # Sampling:
    samp = geometry['proj_sample']
    anisotropy = geometry['vol_sample']

    shp = numpy.array(projections.shape)
    shp //= samp

    prj_weight = 1 / (shp[1] * numpy.prod(anisotropy) * max(volume.shape))

    # Initialize L2:
    settings['norm'] = []
    t = 1

    volume_t = volume.copy()
    volume_old = volume.copy()

    print('FISTING in progress...')
    sleep(0.5)

    # Switch off progress bar if preview is on...
    if preview:
        ncols = 0
    else:
        ncols = 50

    for ii in tqdm(range(iterations), ncols=ncols):

        # Update volume:
        if sum(samp) > 3:
            proj = projections[::samp[0], ::samp[1], ::samp[2]]
            FISTA_step(proj, prj_weight, volume, volume_old, volume_t, t,
                       geometry)

        else:
            FISTA_step(projections, volume, volume_old, volume_t, t, geometry)

        # Preview
        if preview:
            display.display_slice(volume, dim=1)

    if norm_update:
        display.plot(settings['norm'], semilogy=True, title='Resudual norm')
コード例 #4
0
def FISTA( projections, volume, geometry, iterations, lmbda = 0):
    '''
    FISTA reconstruction. Right now there is no TV minimization substep here!
    '''
    ss = settings
    preview = ss.preview    
    bounds = ss.bounds
        
    # Residual norms:    
    rnorms = []
    
    # Various variables:
    t = 1
    volume_t = volume.copy()
    volume_old = volume.copy()
    
    # TV residual:
    sz = list(volume.shape)
    sz.insert(0, 3)
    volume_tv = numpy.zeros(sz, dtype = 'float32')
    
    logger.print('FISTING started...')
    
    # Progress bar:
    pbar = _pbar_start_(iterations, 'iterations')
    
    for ii in range(iterations):
        
        # L2 update:
        norm = fista_update(projections, volume, volume_old, volume_t, volume_tv, t, geometry, lmbda = lmbda)
        
        if norm:
            rnorms.append(norm)
        
        # Apply bounds:
        if bounds:
            numpy.clip(volume, a_min = bounds[0], a_max = bounds[1], out = volume)    
         
        # Show preview or progress:    
        if preview:
            display.slice(volume, dim = 1, title = 'Preview')
        else:
            _pbar_update_(pbar)

    # Stop progress bar    
    _pbar_close_(pbar)
            
    if rnorms:   
         display.plot(rnorms, semilogy = True, title = 'Resudual norm')
コード例 #5
0
def EM( projections, volume, geometry, iterations):
    """
    Expectation Maximization
    """ 
    ss = settings
    preview = ss.preview    
    bounds = ss.bounds
    
    # Make sure that the volume is positive:
    if (volume.max() == 0)|(volume.min()<0): 
        logger.error('Wrong initial guess. Make sure that initial guess for EM is positive.')
    
    if (projections.min() < 0):    
        logger.error('Wrong projection data. Make sure that projections have no negative values.')
    
    logger.print('Em Emm Emmmm...')
    
    # Residual norms:    
    rnorms = []
    
    # Progress bar:
    pbar = _pbar_start_(iterations, 'iterations')
        
    for ii in range(iterations):
        
        # Update volume:
        norm = em_update(projections, volume, geometry)
        
        # Apply bounds
        if bounds:
            numpy.clip(volume, a_min = bounds[0], a_max = bounds[1], out = volume) 
                               
        if norm:
            rnorms.append(norm)
            
        if preview:
            display.slice(volume, dim = 1, title = 'Preview')
        else:
            _pbar_update_(pbar)

    # Stop progress bar    
    _pbar_close_(pbar)
            
    if rnorms:   
         display.plot(rnorms, semilogy = True, title = 'Resudual norm') 
コード例 #6
0
ファイル: project.py プロジェクト: teascavenger/flextomo
def SIRT(projections, volume, geometry, iterations):
    """
    Simultaneous Iterative Reconstruction Technique.
    """
    global settings
    preview = settings['preview']
    norm_update = settings['norm_update']

    # Sampling:
    samp = geometry['proj_sample']

    shp = numpy.array(projections.shape)
    shp //= samp

    # Initialize L2:
    settings['norm'] = []

    print('Feeling SIRTy...')
    sleep(0.5)

    # Switch off progress bar if preview is on...
    if preview:
        ncols = 0
    else:
        ncols = 50

    # Iterate:
    for ii in tqdm(range(iterations), ncols=ncols):

        # Update volume:
        if sum(samp) > 3:

            L2_step(projections[::samp[0], ::samp[1], ::samp[2]], volume,
                    geometry)

        else:
            L2_step(projections, volume, geometry)

        # Preview
        if preview:
            display.display_slice(volume, dim=1)

    if norm_update:
        display.plot(settings['norm'], semilogy=True, title='Resudual L2')
コード例 #7
0
ファイル: project.py プロジェクト: teascavenger/flextomo
def MULTI_SIRT(projections, volume, geometries, iterations):
    """
    A multi-dataset version of SIRT. Here prjections and geometries are lists.
    """
    global settings
    preview = settings['preview']
    norm_update = settings['norm_update']
    norm = settings['norm']

    # Make sure array is contiguous (if not memmap):
    # if not isinstance(projections, numpy.memmap):
    #    projections = numpy.ascontiguousarray(projections)

    # Initialize L2:
    norm = []

    print('Doing SIRT`y things...')
    sleep(0.5)

    # Switch off progress bar if preview is on...
    if preview:
        ncols = 0
    else:
        ncols = 50

    for ii in tqdm(range(iterations), ncols=ncols):

        norm = 0
        for ii, proj in enumerate(projections):

            # This weight is half of the normal weight to make sure convergence is ok:
            #prj_weight = 1 / (proj.shape[1] * max(volume.shape))

            # Update volume:
            L2_step(proj, volume, geometries[ii])

        # Preview
        if preview:
            display.display_slice(volume, dim=1)

    if norm_update:
        display.plot(norm, semilogy=True, title='Resudual norm')
コード例 #8
0
ファイル: project.py プロジェクト: teascavenger/flextomo
def EM(projections, volume, geometry, iterations):
    """
    Expectation Maximization
    """
    global settings
    preview = settings['preview']
    norm_update = settings['norm_update']

    # Make sure that the volume is positive:
    if volume.max() <= 0:
        volume *= 0
        volume += 1
    elif volume.min() < 0:
        volume[volume < 0] = 0

    projections[projections < 0] = 0

    # Initialize L2:
    settings['norm'] = []

    print('Em Emm Emmmm...')
    sleep(0.5)

    # Switch off progress bar if preview is on...
    if preview:
        ncols = 0
    else:
        ncols = 50

    # Go!
    for ii in tqdm(range(iterations), ncols=ncols):

        # Update volume:
        EM_step(projections, volume, geometry)

        # Preview
        if preview:
            display.display_slice(volume, dim=1)

    if norm_update:
        display.plot(settings['norm'], semilogy=True, title='Resudual norm')
コード例 #9
0
def PWLS(projections, volume, geometry, iterations):
    """
    Simple implementation of the Penalized Weighted Least Squeares. 
    Gives better results when photon starvation and metal artifacts are present in small parts of the volume.
    Needs more memory than SIRT!
    """ 
    ss = settings
    preview = ss.preview    
    bounds = ss.bounds
    
    logger.print('PWLS-PWLS-PWLS-PWLS...')
    
    # Residual norms:    
    rnorms = []
    
    # Progress bar:
    pbar = _pbar_start_(iterations, 'iterations')
        
    for ii in range(iterations):
        
        # L2 update:
        norm = pwls_update(projections, volume, geometry)
        
        if norm:
            rnorms.append(norm)
        
        # Apply bounds
        if bounds:
            numpy.clip(volume, a_min = bounds[0], a_max = bounds[1], out = volume)    
       
        if preview:
            display.slice(volume, dim = 1, title = 'Preview')
        else:
            _pbar_update_(pbar)

    # Stop progress bar    
    _pbar_close_(pbar)
                     
    if rnorms:   
         display.plot(rnorms, semilogy = True, title = 'Resudual L2') 
コード例 #10
0
                            theta_range = [0, 360], geom_type = 'simple')

#%% Short version of the spectral modeling:

# This is our phantom:
vol = phantom.cuboid([1,128,128], geometry, 8,8,8)  
display.display_slice(vol , title = 'Phantom') 

# Spectrum of the scanner:   
kv = 90
filtr = {'material':'Cu', 'density':8, 'thickness':0.1}
detector = {'material':'Si', 'density':5, 'thickness':1} 
E, S = spectrum.effective_spectrum(kv = 90, filtr = filtr, detector = detector)  

# Display:
display.plot(E,S, title ='Spectrum')   

# Materials list that corresponds to the number of labels in our phantom:  
mats = [{'material':'Al', 'density':2.7},]
        
# Sinogram that will be simultated:
counts = numpy.zeros([1, 128, 128], dtype = 'float32')

# Simulate:
spectrum.forward_spectral(vol, counts, geometry, mats, E, S, n_phot = 1e6)

# Display:
display.display_slice(counts, title = 'Modelled sinogram')  

#%% Reconstruct:
    
コード例 #11
0
                         det2obj=100,
                         det_pixel=0.2,
                         ang_range=[0, 360])

# This is our phantom:
vol = phantom.cuboid([1, 128, 128], geom, 8, 8, 8)
display.slice(vol, title='Phantom')

# Spectrum of the scanner:
kv = 90
filtr = {'material': 'Cu', 'density': 8, 'thickness': 0.1}
detector = {'material': 'Si', 'density': 5, 'thickness': 1}
E, S = model.effective_spectrum(kv=kv, filtr=filtr, detector=detector)

# Display:
display.plot(E, S, title='Effective spectrum')

# Materials list that corresponds to the number of labels in our phantom:
mats = [
    {
        'material': 'Al',
        'density': 2.7
    },
]

# Sinogram that will be simultated:
counts = numpy.zeros([1, 128, 128], dtype='float32')

# Simulate:
model.forward_spectral(vol, counts, geom, mats, E, S, n_phot=1e6)
proj = -numpy.log(counts)
コード例 #12
0
ファイル: project.py プロジェクト: teascavenger/flextomo
def MULTI_PWLS(projections,
               volume,
               geometries,
               iterations=10,
               student=False,
               weight_power=1):
    '''
    Penalized Weighted Least Squares based on multiple inputs.
    '''
    #error log:
    global settings
    norm = settings['norm']
    block_number = settings['block_number']
    mode = settings['mode']

    norm = []

    fac = volume.shape[2] * geometries[0]['img_pixel'] * numpy.sqrt(2)

    print('PWLS-ing in progress...')
    sleep(0.5)

    # Iterations:
    for ii in tqdm(range(iterations)):

        # Error:
        L_mean = 0

        #Blocks:
        for jj in range(block_number):

            # Volume update:
            vol_tmp = numpy.zeros_like(volume)
            bwp_w = numpy.zeros_like(volume)

            for kk, projs in enumerate(projections):

                index = _block_index_(jj, block_number, projs.shape[1], mode)

                proj = numpy.ascontiguousarray(projs[:, index, :])
                geom = geometries[kk]

                proj_geom = io.astra_proj_geom(geom, projs.shape, index=index)
                vol_geom = io.astra_vol_geom(geom, volume.shape)

                prj_tmp = numpy.zeros_like(proj)

                # Compute weights:
                if student:
                    fwp_w = numpy.ones_like(proj)

                else:
                    me = proj.max() * weight_power / 5
                    fwp_w = numpy.exp(-proj * weight_power / me)

                #fwp_w = scipy.ndimage.morphology.grey_erosion(fwp_w, size=(3,1,3))

                _backproject_block_add_(fwp_w, bwp_w, proj_geom, vol_geom,
                                        'BP3D_CUDA')
                _forwardproject_block_add_(prj_tmp, volume, proj_geom,
                                           vol_geom)

                prj_tmp = (proj - prj_tmp) * fwp_w / fac

                if student:
                    prj_tmp = _studentst_(prj_tmp, 5)

                _backproject_block_add_(prj_tmp, vol_tmp, proj_geom, vol_geom,
                                        'BP3D_CUDA')

                # Mean L for projection
                L_mean += (prj_tmp**2).mean()

            eps = bwp_w.max() / 1000
            bwp_w[bwp_w < eps] = eps

            volume += vol_tmp / bwp_w
            volume[volume < 0] = 0

            #print((volume<0).sum())

        norm.append(L_mean / block_number / len(projections))

    display.plot(numpy.array(norm), semilogy=True)