Exemple #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
Exemple #2
0
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
Exemple #3
0
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')
Exemple #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')
Exemple #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') 
Exemple #6
0
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')
Exemple #7
0
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')
Exemple #8
0
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')
Exemple #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') 
                            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:
    
Exemple #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)
Exemple #12
0
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)