# simply does not have any way of storing the information (Zeiss Xradia
# does not store anything but the projecions)

# if this is the case, the general way of tackling the problem is:

# Step 1: define your geometry and angles
geo=tigre.geometry()
angles=

# Step 2: Load projections:
#store in NP array. Use whichever python lirbary will help you get the data loaded. 


# Step 3: validate

tigre.plotproj(proj,angles)
# you need to make sure that:
#     1) white=metal/bone/high density and black=air.
#         If this is not the case
proj=-np.log(proj/(np.max(proj+1)); # Beer-Lanbert law
#     2) rotation happens left-right instead of top-bottom.
#        If its top bottom permute your data as required

# Step 4: test
imgfdk=algs.fdk(proj,geo,angles)
tigre.plotimg(imgFDK,dim='z')
# If this does not look good, possible things to check:
# - Are the angles in the right direction? maybe they need to be inverted. 
# - Is your geometry properly defined? mistake on geometry will be
#   detrimental to image quality
# - if microCT: halos around the features? COR correction needed. 
Exemple #2
0
# sample the voxels at a given sample rate.

#%% Main difference

head = sample_loader.load_head_phantom(geo.nVoxel)
start_time = time.time()
projInterp = tigre.Ax(head, geo, angles, "interpolated")
interptime = time.time() - start_time

start_time = time.time()
projray = tigre.Ax(head, geo, angles, "Siddon")
raytime = time.time() - start_time
# It is relatively clear that discretization artefacts appear with the
# ray-voxel approach (middle one)
tigre.plotproj(
    np.concatenate([np.abs(projInterp - projray), projray, projInterp],
                   axis=1), angles)
# But also the ray voxel approach is faster (more obvious at bigger sizes)
print("Time interpolated: " + str(interptime))
print("Time Siddon      : " + str(raytime))

#%% With small voxel the errors are more obvious
geo.nVoxel = np.array([32, 32, 32])  # number of voxels              (vx)
geo.sVoxel = np.array([256, 256, 256])  # total size of the image       (mm)
geo.dVoxel = geo.sVoxel / geo.nVoxel  # size of each voxel            (mm)
head = sample_loader.load_head_phantom(geo.nVoxel)

geo.accuracy = 3
projInterp3 = tigre.Ax(head, geo, angles, "interpolated")
geo.accuracy = 1
projInterp1 = tigre.Ax(head, geo, angles, "interpolated")
roll = angles
pitch = 0.7 * np.linspace(0, 1, len(angles))
yaw = 0.7 * np.linspace(0, 1, len(angles))

geo.rotDetector = np.array(np.vstack([roll, pitch, yaw])).T

#%%
# Load thorax phatom data
head = sample_loader.load_head_phantom(geo.nVoxel)
# generate projections
projections = tigre.Ax(head, geo, angles)
# add noise
noise_projections = CTnoise.add(projections,
                                Poisson=1e5,
                                Gaussian=np.array([0, 10]))

tigre.plotproj(projections, angles)

#%% recon
imgRotDet = algs.ossart(projections, geo, angles, 50)

#% No rotation
geo.rotDetector = np.array([0, 0, 0])
projections2 = tigre.Ax(head, geo, angles)

imgnoRot = algs.ossart(projections2, geo, angles, 50)
# %% Plot to show that indeed the reconstruction is right

tigre.plotimg(np.concatenate([imgRotDet, imgnoRot], axis=1), dim="z")
Exemple #4
0
geo = tigre.geometry_default(high_resolution=False)

#%% Define angles of projection and load phatom image

# define projection angles (in radians)
angles = np.linspace(0, 2 * np.pi, 50)
# load phatnom image
head = sample_loader.load_head_phantom(geo.nVoxel)

# Simulate forward projection.
# To match with mathematical notation, the projection operation is called Ax
projections = tigre.Ax(head, geo, angles)

# Add realistic noise. Adds photon scattering noise ('Poisson') and
# electronic noise of the detector ('Gaussian').
#
# 'Poisson' is related to the maximum photon count in the detector. 1e5 is
# a standard clinical nuber, reduce it for more noise
# 'Gaussian' is related to possible electronic noise in the detector. mean
# of 0 and std of 10 is common in clinical scenario. Increase std for more
# noise.
noise_projections = CTnoise.add(projections,
                                Poisson=1e5,
                                Gaussian=np.array([0, 10]))

#%% Plot Projections
tigre.plotproj(projections)
# plot noise
tigre.plotproj(projections - noise_projections)
clims = [0, 200]

# 'Savegif': allows to save the plotted figure as an animated gif,
# specified by the given filename.

giffilename = "demo5projections.gif"

# 'Slice': allows to plot a single projection .Will overwrite the behaviour
# of 'Step'
slice = 5

# Lets try out.
tigre.plotproj(noise_projections,
               angles,
               step=step,
               colormap=colormap,
               clims=clims,
               savegif=giffilename)  # not using 'Step'

# Remember you can also plot errors, for example the added noise by:

noise = np.abs(noise_projections -
               projections)  # abs is what we are interested in plotting
tigre.plotproj(noise, angles, clims=[0, 2])

#%% PlotImg

# plotImg plots the image slice by slice.
#
# List of optional parameters:
#%% Load data and generate projections
# define angles
angles = np.linspace(0, 2 * np.pi, 100)
## Define angles
numProjs = 100

anglesY = np.linspace(0, 2 * np.pi, numProjs)
anglesZ2 = anglesY
anglesZ1 = np.pi * np.sin(np.linspace(0, 2 * np.pi, numProjs))
angles = np.vstack([anglesZ1, anglesY, anglesZ2]).T

## Get Image

head = sample_loader.load_head_phantom(geo.nVoxel)

## Project

projections = tigre.Ax(head, geo, angles)

tigre.plotproj(projections,
               anglesY)  # angle information not right in the title
## Reconstruct:

# Note, FDK will not work.

imgSIRT = algs.sirt(projections, geo, angles, 50)
imgCGLS = algs.cgls(projections, geo, angles, 10)

tigre.plotimg(np.concatenate([head, imgSIRT, imgCGLS], axis=1), dim="z")