def process(self, out=None): if self.tigre_geom.is2D: data_temp = np.expand_dims(self.get_input().as_array(), axis=1) arr_out = fdk(data_temp, self.tigre_geom, self.tigre_angles) arr_out = np.squeeze(arr_out, axis=0) else: arr_out = fdk(self.get_input().as_array(), self.tigre_geom, self.tigre_angles) if out is None: out = ImageData(arr_out, deep_copy=False, geometry=self.volume_geometry.copy(), suppress_warning=True) return out else: out.fill(arr_out)
proj,geo, angles = tigreio.NikonDataLoader(datafolder) # as micro-CT datasets are large, optional arguments for loading partial # amount of data is available: # load equidistant angles, but only few: proj, geo, angles = tigreio.NikonDataLoader(datafolder,sampling='equidistant',num_angles=150) # load every X angles (10) proj, geo, angles = tigreio.NikonDataLoader(datafolder,sampling='step',sampling_step=10) # load first X angles (1000) proj, geo, angles = tigreio.NikonDataLoader(datafolder,sampling='continuous',num_angles=1000) # You can directly call reconstruction code now: img=algs.ossart(proj,geo,angles,100) img=algs.fdk(proj,geo,angles) #%% Brucker Skyscan datafolder='~/your_data_path/Bruker/Sample_name/' proj,geo, angles = tigreio.BrukerDataLoader(datafolder) # the same options for sampling and number of angles that exist for Nikon (avobe) exist for Bruker data loaders. # Sometimes a folder will contain more than one dataset. proj,geo, angles = tigreio.BrukerDataLoader(datafolder,dataset_num='all') # load all of them proj,geo, angles = tigreio.BrukerDataLoader(datafolder,dataset_num=0) # load the first #%% DICOM data (only tested on Philips Allura)
default=True) geo.dDetector = np.array([0.8, 0.8]) * 2 # size of each pixel (mm) geo.sDetector = geo.dDetector * geo.nDetector # print(geo) nangles = 100 angles = np.linspace(0, 2 * np.pi, nangles, endpoint=False, dtype=np.float32) # Prepare projection data #head = np.load('src_img_cubic_256.npy') head = data_loader.load_head_phantom(geo.nVoxel) proj = tigre.Ax(head, geo, angles, gpuids=gpuids) # Reconstruct niter = 20 fdkout = algs.fdk(proj, geo, angles, gpuids=gpuids) sirtout = algs.ossart(proj, geo, angles, niter, blocksize=20, gpuids=gpuids) # Measure Quality # 'RMSE', 'MSSIM', 'SSD', 'UQI' print('RMSE fdk:') print(Measure_Quality(fdkout, head, ['nRMSE'])) print('RMSE ossart') print(Measure_Quality(sirtout, head, ['nRMSE'])) # Plot fig, axes = plt.subplots(3, 2) axes[0, 0].set_title('FDK') axes[0, 0].imshow(fdkout[geo.nVoxel[0] // 2]) axes[1, 0].imshow(fdkout[:, geo.nVoxel[1] // 2, :]) axes[2, 0].imshow(fdkout[:, :, geo.nVoxel[2] // 2])
import sys from tigre.demos.Test_data import data_loader from matplotlib import pyplot as plt from tigre.utilities.Measure_Quality import Measure_Quality #geo1 = tigre.geometry(mode='cone', high_quality=False, default=True) geo = tigre.geometry(mode='cone', nVoxel=np.array([256,256,256]),default=True) geo.dDetector = np.array([0.8, 0.8])*2 # size of each pixel (mm) geo.sDetector = geo.dDetector * geo.nDetector niter = 10 nangles = 100 angles = np.linspace(0, 2 * np.pi, nangles, dtype=np.float32) #head = np.load('src_img_cubic_256.npy') #data_loader.load_head_phantom(geo.nVoxel) head = data_loader.load_head_phantom(geo.nVoxel) proj = tigre.Ax(head,geo,angles) fdkout = algs.fdk(proj,geo,angles) sirtout = algs.ossart(proj,geo,angles,20,blocksize=20) # 'RMSE' # 'MSSIM' # 'SSD' # 'UQI' print('RMSE fdk:') print(Measure_Quality(fdkout,head,['nRMSE'])) print('RMSE ossart') print(Measure_Quality(sirtout,head,['nRMSE'])) plt.subplot(211) plt.imshow(fdkout[geo.nVoxel[0]//2]) plt.subplot(212) plt.imshow(sirtout[geo.nVoxel[0]//2]) plt.colorbar()
import tigre import tigre.algorithms as algs import numpy as np geo = tigre.geometry(mode='cone', nVoxel=np.array([32, 64, 128]), default_geo=True) from tigre.demos.Test_data import data_loader img = data_loader.load_head_phantom(geo.nVoxel) angles = np.linspace(0, np.pi * 2, 100, dtype=np.float32) proj = tigre.Ax(img, geo, angles) algs.fdk(proj, geo, angles)
# # ASD-POCS has a veriety of optional arguments, and some of them are crucial # to determine the behaviour of the algorithm. The advantage of ASD-POCS is # the power to create good images from bad data, but it needs a lot of # tunning. # # Optional parameters that are very relevant: # ---------------------------------------------- # 'maxL2err' Maximum L2 error to accept an image as valid. This # parameter is crucial for the algorithm, determines at # what point an image should not be updated further. # Default is 20% of the FDK L2 norm. # # its called epsilon in the paper epsilon = ( im3DNORM(tigre.Ax(algs.fdk(noise_projections, geo, angles), geo, angles) - noise_projections, 2) * 0.15 ) # 'alpha': Defines the TV hyperparameter. default is 0.002. # However the paper mentions 0.2 as good choice alpha = 0.002 # 'tviter': Defines the amount of TV iterations performed per SART # iteration. Default is 20 ng = 25 # Other optional parameters # ---------------------------------------------- # 'lambda': Sets the value of the hyperparameter for the SART iterations. # Default is 1
def fdk(self, x): data_temp = np.expand_dims(x.as_array(),axis=1) arr_out = fdk(data_temp, self.tigre_geom, self.angles) arr_out = np.squeeze(arr_out, axis=0) return arr_out
# Coded by: Manasavee Lohvithee # -------------------------------------------------------------------------- #%%Initialize import tigre import numpy as np from tigre.utilities import sample_loader from tigre.utilities import CTnoise import tigre.algorithms as algs from matplotlib import pyplot as plt #%% Geometry geo = tigre.geometry_default(high_resolution=False) #%% Load data and generate projections # define angles angles = np.linspace(0, 2 * np.pi, 100) # 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])) #%% Some recon, FDK for example imgFDK = algs.fdk(projections, geo, angles) # TODO, these are not implemented/accesible in python TIGRE # Issues #270 #271
# the FDK algorithm has been taken and modified from # 3D Cone beam CT (CBCT) projection backprojection FDK, iterative reconstruction Matlab examples # https://www.mathworks.com/matlabcentral/fileexchange/35548-3d-cone-beam-ct--cbct--projection-backprojection-fdk--iterative-reconstruction-matlab-examples # The algorithm takes, as eny of them, 3 mandatory inputs: # PROJECTIONS: Projection data # GEOMETRY : Geometry describing the system # ANGLES : Propjection angles # And has a single optional argument: # FILTER: filter type applied to the projections. Possible options are # 'ram_lak' (default) # 'shepp_logan' # 'cosine' # 'hamming' # 'hann' # The choice of filter will modify the noise and sopme discreatization # errors, depending on which is chosen. # imgFDK1 = algs.fdk(noise_projections, geo, angles, filter="hann") imgFDK2 = algs.fdk(noise_projections, geo, angles, filter="ram_lak") # They look quite the same tigre.plotimg(np.concatenate([imgFDK1, imgFDK2], axis=1), dim="Z") # but it can be seen that one has bigger errors in the whole image, while # hte other just in the boundaries tigre.plotimg(np.concatenate( [abs(head - imgFDK1), abs(head - imgFDK2)], axis=1), dim="Z")
#%% Load data and generate projections # define angles angles = np.linspace(0, 2 * np.pi, 100) # 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])) #%% Reconstruct image using OS-SART and FDK # FDK imgFDK = algs.fdk(noise_projections, geo, angles) niter = 50 imgOSSART = algs.ossart(noise_projections, geo, angles, 50) #%% Lets use PlotProj # # plotProj plots the projection data measure on the detector on each angle. # # exhaustive list of possible parameters: # 'Step' : Defines the step size for skippin projections when plotting, # usefull when there are a big amount of projections. Default is 1 step = 2 # 'Colormap': Defines the colormap used to plot. Default is 'gray'.