def generate_3d_phantom_data(model_number, L, H, n, m, geometry, from_volume_accuracy=256): N_size = from_volume_accuracy M_size = int(np.ceil(N_size / n * m)) assert M_size <= N_size phantom_3Dt = TomoP3D.ModelTemporal(model_number, N_size, '../resources/phantoms_3D.dat') timesteps = phantom_3Dt.shape[0] # make an upscaled xray transform (we need accurate sinograms) reco_space_copy = odl.uniform_discr(min_pt=[-L, -L, -H], max_pt=[L, L, H], shape=[N_size, N_size, M_size]) xray_transform = odl.tomo.RayTransform(reco_space_copy, geometry) p_lst = list() for t in range(timesteps): x = xray_transform.domain.element(phantom_3Dt[t, ..., :M_size]) p = xray_transform(x).data p_lst.append(p) # plot_3d(phantom_3Dt[t, ..., :M_size]) # plot_sino(p) return np.array(p_lst)
print("MAE" , mae(res1, res2)) np.testing.assert_array_almost_equal(res1.as_array(), res2.as_array(), decimal=3) ################################################################### ################################################################### ################################################################### ################################################################### print("Compare CIL_FGP_TV vs CCPiReg_FGP_TV no tolerance (3D)") print ("Building 3D phantom using TomoPhantom software") model = 13 # select a model number from the library N_size = 64 # Define phantom dimensions using a scalar value (cubic phantom) path = os.path.dirname(tomophantom.__file__) path_library3D = os.path.join(path, "Phantom3DLibrary.dat") #This will generate a N_size x N_size x N_size phantom (3D) phantom_tm = TomoP3D.Model(model, N_size, path_library3D) ig = ImageGeometry(N_size, N_size, N_size) data = ig.allocate() data.fill(phantom_tm) n1 = TestData.random_noise(data.as_array(), mode = 'gaussian', seed = 10) noisy_data = ig.allocate() noisy_data.fill(n1) # Show Ground Truth and Noisy Data plt.figure(figsize=(10,5)) plt.subplot(1,2,1) plt.imshow(data.as_array()[32]) plt.title('Ground Truth')
obj3D_2 = { 'Obj': Objects3D.CUBOID, 'C0': 1.00, 'x0': 0.1, 'y0': 0.2, 'z0': 0.0, 'a': 0.15, 'b': 0.35, 'c': 0.6, 'phi1': -60.0 } print("Building 3D object using TomoPhantom software") myObjects = [obj3D_1, obj3D_2] # dictionary of objects Object3D = TomoP3D.Object(N3D_size, myObjects) sliceSel = int(0.5 * N3D_size) #plt.gray() plt.figure() plt.subplot(131) plt.imshow(Object3D[sliceSel, :, :], vmin=0, vmax=1) plt.title('3D Object, axial view') plt.subplot(132) plt.imshow(Object3D[:, sliceSel, :], vmin=0, vmax=1) plt.title('3D Object, coronal view') plt.subplot(133) plt.imshow(Object3D[:, :, sliceSel], vmin=0, vmax=1) plt.title('3D Object, sagittal view')
import timeit import os import matplotlib.pyplot as plt import numpy as np import tomophantom from tomophantom import TomoP3D from tomophantom.supp.qualitymetrics import QualityTools print("Building 3D phantom using TomoPhantom software") tic = timeit.default_timer() model = 13 # select a model number from the library N_size = 256 # Define phantom dimensions using a scalar value (cubic phantom) path = os.path.dirname(tomophantom.__file__) path_library3D = os.path.join(path, "Phantom3DLibrary.dat") #This will generate a N_size x N_size x N_size phantom (3D) phantom_tm = TomoP3D.Model(model, N_size, path_library3D) toc = timeit.default_timer() Run_time = toc - tic print("Phantom has been built in {} seconds".format(Run_time)) sliceSel = int(0.5 * N_size) #plt.gray() plt.figure() plt.subplot(131) plt.imshow(phantom_tm[sliceSel, :, :], vmin=0, vmax=1) plt.title('3D Phantom, axial view') plt.subplot(132) plt.imshow(phantom_tm[:, sliceSel, :], vmin=0, vmax=1) plt.title('3D Phantom, coronal view')
N3D_size = 256 obj3D = { 'Obj': Objects3D.GAUSSIAN, 'C0': 1.00, 'x0': -0.25, 'y0': 0.1, 'z0': 0.0, 'a': 0.2, 'b': 0.35, 'c': 0.7, 'phi1': 30.0, 'phi2': 60.0, 'phi3': -25.0 } Object3D = TomoP3D.Object(N3D_size, [obj3D]) sliceSel = int(0.5 * N3D_size) #plt.gray() plt.figure(7) plt.subplot(121) plt.imshow(Object3D[sliceSel, :, :], vmin=0, vmax=1) plt.title('3D Phantom, axial view') plt.subplot(122) plt.imshow(Object3D[:, sliceSel, :], vmin=0, vmax=1) plt.title('3D Phantom, coronal view') plt.show() #%%
def get_ImageData(num_model, geometry): '''Returns an ImageData relative to geometry with the model num_model from tomophantom :param num_model: model number :type num_model: int :param geometry: geometrical info that describes the phantom :type geometry: ImageGeometry Example usage: .. code-block:: python ndim = 2 N=128 angles = np.linspace(0, 360, 50, True, dtype=np.float32) offset = 0.4 channels = 3 if ndim == 2: ag = AcquisitionGeometry.create_Cone2D((offset,-100), (offset,100)) ag.set_panel(N) else: ag = AcquisitionGeometry.create_Cone3D((offset,-100, 0), (offset,100,0)) ag.set_panel((N,N-2)) ag.set_channels(channels) ag.set_angles(angles, angle_unit=AcquisitionGeometry.DEGREE) ig = ag.get_ImageGeometry() num_model = 1 phantom = TomoPhantom.get_ImageData(num_model=num_model, geometry=ig) ''' ig = geometry.copy() ig.set_labels(DataOrder.TOMOPHANTOM_IG_LABELS) num_dims = len(ig.dimension_labels) if ImageGeometry.CHANNEL in ig.dimension_labels: if not is_model_temporal(num_model): raise ValueError('Selected model {} is not a temporal model, please change your selection'.format(num_model)) if num_dims == 4: # 3D+time for tomophantom # output dimensions channel and then spatial, # e.g. [ 'channel', 'vertical', 'horizontal_y', 'horizontal_x' ] num_model = num_model shape = tuple(ig.shape[1:]) phantom_arr = TomoP3D.ModelTemporal(num_model, shape, path_library3D) elif num_dims == 3: # 2D+time for tomophantom # output dimensions channel and then spatial, # e.g. [ 'channel', 'horizontal_y', 'horizontal_x' ] N = ig.shape[1] num_model = num_model phantom_arr = TomoP2D.ModelTemporal(num_model, ig.shape[1], path_library2D) else: raise ValueError('Wrong ImageGeometry') if ig.channels != phantom_arr.shape[0]: raise ValueError('The required model {} has {} channels. The ImageGeometry you passed has {}. Please update your ImageGeometry.'\ .format(num_model, ig.channels, phantom_arr.shape[0])) else: if num_dims == 3: # 3D num_model = num_model phantom_arr = TomoP3D.Model(num_model, ig.shape, path_library3D) elif num_dims == 2: # 2D if ig.shape[0] != ig.shape[1]: raise ValueError('Can only handle square ImageData, got shape'.format(ig.shape)) N = ig.shape[0] num_model = num_model phantom_arr = TomoP2D.Model(num_model, N, path_library2D) else: raise ValueError('Wrong ImageGeometry') im_data = ImageData(phantom_arr, geometry=ig, suppress_warning=True) im_data.reorder(list(geometry.dimension_labels)) return im_data
'Obj': Objects3D.ELLIPSOID, 'C0': 1.00, 'x0': -0.5, 'y0': -0.5, 'z0': z_coord_steps[i], 'a': 0.18, 'b': 0.07, 'c': 0.13, 'phi1': 0.0, 'phi2': 0.0, 'phi3': 0.0 } myObjects = [obj3D1, obj3D2, obj3D3, obj3D4] # dictionary of objects object3D = TomoP3D.Object(ObjSize, myObjects) """ sliceSel = 200 #plt.gray() plt.figure() plt.subplot(121) plt.imshow(Object3D[sliceSel,:,:],vmin=0, vmax=1) plt.title('3D Phantom, axial view') plt.subplot(122) plt.imshow(Object3D[:,sliceSel,:],vmin=0, vmax=1) plt.title('3D Phantom, coronal view') plt.show() """ # obtain projections using ASTRA-toolbox Atools = AstraTools3D(DetRows, DetColumns, angles_rad,
def test_compare_regularisation_toolkit_tomophantom(self): print("Compare CIL_FGP_TV vs CCPiReg_FGP_TV no tolerance (3D)") print("Building 3D phantom using TomoPhantom software") model = 13 # select a model number from the library N_size = 64 # Define phantom dimensions using a scalar value (cubic phantom) path = os.path.dirname(tomophantom.__file__) path_library3D = os.path.join(path, "Phantom3DLibrary.dat") #This will generate a N_size x N_size x N_size phantom (3D) phantom_tm = TomoP3D.Model(model, N_size, path_library3D) ig = ImageGeometry(N_size, N_size, N_size) data = ig.allocate() data.fill(phantom_tm) noisy_data = noise.gaussian(data, seed=10) alpha = 0.1 iters = 1000 print("Use tau as an array of ones") # CIL_TotalVariation no tolerance g_CIL = alpha * TotalVariation(iters, tolerance=None, info=True) res1 = g_CIL.proximal(noisy_data, ig.allocate(1.)) t0 = timer() res1 = g_CIL.proximal(noisy_data, ig.allocate(1.)) t1 = timer() print(t1 - t0) # CCPi Regularisation toolkit high tolerance r_alpha = alpha r_iterations = iters r_tolerance = 1e-9 r_iso = 0 r_nonneg = 0 r_printing = 0 g_CCPI_reg_toolkit = CCPiReg_FGP_TV(r_alpha, r_iterations, r_tolerance, r_iso, r_nonneg, r_printing, 'cpu') t2 = timer() res2 = g_CCPI_reg_toolkit.proximal(noisy_data, 1.) t3 = timer() print(t3 - t2) np.testing.assert_array_almost_equal(res1.as_array(), res2.as_array(), decimal=3) # CIL_FGP_TV no tolerance #g_CIL = FGP_TV(ig, alpha, iters, tolerance=None, info=True) g_CIL.tolerance = None t0 = timer() res1 = g_CIL.proximal(noisy_data, 1.) t1 = timer() print(t1 - t0) ################################################################### ################################################################### ################################################################### ################################################################### data = dataexample.PEPPERS.get(size=(256, 256)) ig = data.geometry ag = ig noisy_data = noise.gaussian(data, seed=10) alpha = 0.1 iters = 1000 # CIL_FGP_TV no tolerance g_CIL = alpha * TotalVariation(iters, tolerance=None) t0 = timer() res1 = g_CIL.proximal(noisy_data, 1.) t1 = timer() print(t1 - t0) # CCPi Regularisation toolkit high tolerance r_alpha = alpha r_iterations = iters r_tolerance = 1e-8 r_iso = 0 r_nonneg = 0 r_printing = 0 g_CCPI_reg_toolkit = CCPiReg_FGP_TV(r_alpha, r_iterations, r_tolerance, r_iso, r_nonneg, r_printing, 'cpu') t2 = timer() res2 = g_CCPI_reg_toolkit.proximal(noisy_data, 1.) t3 = timer() print(t3 - t2)
print("append", end1 - start) while (nop.append_for(np.random.uniform(low=-1, high=1, size=3)) < M): pass end2 = time.time() print("append_for", end2 - end1) #%% gaussians = [{ 'Obj': tp3.Objects3D.PARABOLOID, 'C0': 1., 'x0': float(nop.apoints[loc][0]), 'y0': float(nop.apoints[loc][1]), 'z0': float(nop.apoints[loc][2]), 'a': .2, 'b': .1, 'c': .15, 'phi1': np.random.uniform(low=0, high=360), 'phi2': np.random.uniform(low=0, high=360), 'phi3': np.random.uniform(low=0, high=360) } for loc in range(len(nop.apoints))] vol = tp3.Object(128, gaussians) plt.imshow(vol[0]) plt.show() writer = vtk.vtkMetaImageWriter() conv = Converter.numpy2vtkImporter(vol) conv.Update() writer.SetInputData(conv.GetOutput()) writer.SetFileName("dvc_phantom0.mha") writer.Write()
# > **NOTE**: NVIDIA GPU is must for 3D reconstruction to work. Since, all ASTRA 3D reconstruction algorithms are implemented using CUDA. # In[2]: astra.test() # ## Creating a __3D Phantom__ \& visualizing it. # In[3]: model = 13 ##Shepp-logan Phantom in the "Phantom3DLibrary.dat" file path_library3D = "Phantom3DLibrary.dat" N_size = 400 phantom = TomoP3D.Model(model, N_size, path_library3D) slice_ = int(0.5 * N_size) plt.figure(figsize=[20, 30]) plt.subplot(131) plt.imshow(phantom[slice_, :, :], vmin=0, vmax=1, interpolation="gaussian") plt.title('Axial view') plt.subplot(132) plt.imshow(phantom[:, slice_, :], vmin=0, vmax=1) plt.title('Coronal view') plt.show() # ## Analytical Projection Data at different angles
import os from tomophantom import TomoP3D import matplotlib.pyplot as plt import tomophantom print("Building 3D phantom using TomoPhantom software") tic = timeit.default_timer() model = 2 # select a model number from the library # Define phantom dimensions using a scalar (cubic) or a tuple [N1, N2, N3] N_size = 256 # or as a tuple of a custom size (256,256,256) # one can specify an exact path to the parameters file # path_library2D = '../../../PhantomLibrary/models/Phantom3DLibrary.dat' path = os.path.dirname(tomophantom.__file__) path_library3D = os.path.join(path, "Phantom3DLibrary.dat") #This will generate a N_size x N_size x N_size phantom (3D) or non-cubic phantom phantom_tm = TomoP3D.Model(model, N_size, path_library3D) toc = timeit.default_timer() Run_time = toc - tic print("Phantom has been built in {} seconds".format(Run_time)) sliceSel = int(0.5 * N_size) #plt.gray() plt.figure(1) plt.subplot(131) plt.imshow(phantom_tm[sliceSel, :, :], vmin=0, vmax=1) plt.title('3D Phantom, axial view') plt.subplot(132) plt.imshow(phantom_tm[:, sliceSel, :], vmin=0, vmax=1) plt.title('3D Phantom, coronal view') plt.subplot(133)
def process_frames(self, data): # print "The input data shape is", data[0].shape if (self.out_shape_sino[1] == 1): # create a 2D phantom model = TomoP2D.Model(self.model, self.dims, self.path_library2D) # create a 2D sinogram projdata_clean = TomoP2D.ModelSino(self.model, self.dims, self.detectors_num, self.angles, self.path_library2D) # Adding artifacts and noise # forming dictionaries with artifact types _noise_ = { 'type': self.parameters['artifacts_noise_type'], 'sigma': self.parameters['artifacts_noise_sigma'], 'seed': 0, 'prelog': False } # misalignment dictionary _sinoshifts_ = {} if self.parameters[ 'artifacts_misalignment_maxamplitude'] is not None: _sinoshifts_ = { 'maxamplitude': self.parameters['artifacts_misalignment_maxamplitude'] } # adding zingers and stripes _zingers_ = {} if self.parameters['artifacts_zingers_percentage'] is not None: _zingers_ = { 'percentage': self.parameters['artifacts_zingers_percentage'], 'modulus': 10 } _stripes_ = {} if self.parameters['artifacts_stripes_percentage'] is not None: _stripes_ = { 'percentage': self.parameters['artifacts_stripes_percentage'], 'maxthickness': self.parameters['artifacts_stripes_maxthickness'], 'intensity': self.parameters['artifacts_stripes_intensity'], 'type': self.parameters['artifacts_stripes_type'], 'variability': self.parameters['artifacts_stripes_variability'] } if self.parameters[ 'artifacts_misalignment_maxamplitude'] is not None: [projdata, shifts] = _Artifacts_(projdata_clean, _noise_, _zingers_, _stripes_, _sinoshifts_) else: projdata = _Artifacts_(projdata_clean, _noise_, _zingers_, _stripes_, _sinoshifts_) else: # create a 3D phantom frame_idx = self.out_pData[0].get_current_frame_idx()[0] model = TomoP3D.ModelSub(self.model, self.dims, (frame_idx, frame_idx + 1), self.path_library3D) model = np.swapaxes(model, 0, 1) model = np.flipud(model[:, 0, :]) # create a 3D projection data projdata_clean = TomoP3D.ModelSinoSub( self.model, self.dims, self.detectors_num, self.dims, (frame_idx, frame_idx + 1), self.angles, self.path_library3D) # Adding artifacts and noise # forming dictionaries with artifact types _noise_ = { 'type': self.parameters['artifacts_noise_type'], 'sigma': self.parameters['artifacts_noise_sigma'], 'seed': 0, 'prelog': False } # misalignment dictionary _sinoshifts_ = {} if self.parameters[ 'artifacts_misalignment_maxamplitude'] is not None: _sinoshifts_ = { 'maxamplitude': self.parameters['artifacts_misalignment_maxamplitude'] } # adding zingers and stripes _zingers_ = {} if self.parameters['artifacts_zingers_percentage'] is not None: _zingers_ = { 'percentage': self.parameters['artifacts_zingers_percentage'], 'modulus': 10 } _stripes_ = {} if self.parameters['artifacts_stripes_percentage'] is not None: _stripes_ = { 'percentage': self.parameters['artifacts_stripes_percentage'], 'maxthickness': self.parameters['artifacts_stripes_maxthickness'], 'intensity': self.parameters['artifacts_stripes_intensity'], 'type': self.parameters['artifacts_stripes_type'], 'variability': self.parameters['artifacts_stripes_variability'] } if self.parameters[ 'artifacts_misalignment_maxamplitude'] is not None: [projdata, shifts] = _Artifacts_(projdata_clean, _noise_, _zingers_, _stripes_, _sinoshifts_) else: projdata = _Artifacts_(projdata_clean, _noise_, _zingers_, _stripes_, _sinoshifts_) projdata = np.swapaxes(projdata, 0, 1) return [projdata, model]
import matplotlib.pyplot as plt import numpy as np import tomophantom from tomophantom import TomoP3D print("Building 4D phantom using TomoPhantom software") tic = timeit.default_timer() model = 100 # note that the selected model is temporal (3D + time) # Define phantom dimensions using a scalar (cubic) or a tuple [N1, N2, N3] N_size = 256 # or as a tuple of a custom size (256,256,256) # one can specify an exact path to the parameters file # path_library2D = '../../../PhantomLibrary/models/Phantom3DLibrary.dat' path = os.path.dirname(tomophantom.__file__) path_library3D = os.path.join(path, "Phantom3DLibrary.dat") #This will generate a Time x N_size x N_size x N_size phantom (4D) phantom_tm = TomoP3D.ModelTemporal(model, N_size, path_library3D) toc = timeit.default_timer() Run_time = toc - tic print("Phantom has been built in {} seconds".format(Run_time)) for i in range(0, np.size(phantom_tm, 0)): sliceSel = int(0.5 * N_size) #plt.gray() plt.figure(1) plt.subplot(131) plt.imshow(phantom_tm[i, sliceSel, :, :], vmin=0, vmax=1) plt.title('3D Phantom, axial view') plt.subplot(132) plt.imshow(phantom_tm[i, :, sliceSel, :], vmin=0, vmax=1) plt.title('3D Phantom, coronal view')
phi_max = 180.0 phi1 = random.uniform(phi_min, phi_max) el3 = { 'Obj': Objects3D.CUBOID, 'C0': C_0, 'x0': x0_rand, 'y0': y0_rand, 'z0': z0_rand, 'a': a_el3, 'b': b_el3, 'c': c_el3, 'phi1': phi1 } GROUND_TRUTH = TomoP3D.Object(N_size, [el1, el2, el3]) GROUND_TRUTH[GROUND_TRUTH > 0.7] = 0.43336788 GROUND_TRUTH[(GROUND_TRUTH > 0.0) & (GROUND_TRUTH < 0.29999998)] = 0.43336788 sliceSel = (int)(N_size / 2) plt.figure() plt.subplot(131) plt.imshow(GROUND_TRUTH[sliceSel, :, :]) plt.title('Ideal Phantom1') plt.subplot(132) plt.imshow(GROUND_TRUTH[:, sliceSel, :]) plt.title('Ideal Phantom2') plt.subplot(133) plt.imshow(GROUND_TRUTH[:, :, sliceSel]) plt.title('Ideal Phantom3')
def foam3D(x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max, N_size, tot_objects, object_type): import numpy as np import math import random #3D functions from tomophantom import TomoP3D from tomophantom.TomoP3D import Objects3D attemptsNo = 2000 # objects accepted: 'ellipsoid', 'paraboloid', 'gaussian', 'mix' mix_objects = False if (object_type == 'ellipsoid'): object_type = Objects3D.ELLIPSOID elif (object_type == 'paraboloid'): object_type = Objects3D.PARABOLOID elif (object_type == 'gaussian'): object_type = Objects3D.GAUSSIAN elif (object_type == 'mix'): mix_objects = True else: raise TypeError( 'object_type can be only ellipse, parabola, gaussian or mix') X0 = np.float32(np.zeros(tot_objects)) Y0 = np.float32(np.zeros(tot_objects)) Z0 = np.float32(np.zeros(tot_objects)) AB = np.float32(np.zeros(tot_objects)) C0_var = np.float32(np.zeros(tot_objects)) for i in range(0, tot_objects): (x0, y0, z0, c0, ab) = rand_init3D(x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max) if (i > 0): breakj = False for j in range(0, attemptsNo): if breakj: (x0, y0, z0, c0, ab) = rand_init3D(x0min, x0max, y0min, y0max, z0min, z0max, c0min, c0max, ab_min, ab_max) breakj = False else: for l in range( 0, i ): # checks consistency with previously created objects dist = math.sqrt((X0[l] - x0)**2 + (Y0[l] - y0)**2 + (Z0[l] - z0)**2) if (dist < (ab + AB[l])) or ((abs(x0) + ab)**2 + (abs(y0) + ab)**2 + (abs(z0) + ab)**2 > 1.0): breakj = True break if (breakj == False ): # re-initialise if doesn't fit the criteria X0[i] = x0 Y0[i] = y0 Z0[i] = z0 AB[i] = ab C0_var[i] = c0 break if (AB[i] == 0.0): X0[i] = x0 Y0[i] = y0 AB[i] = 0.0001 C0_var[i] = c0 myObjects = [] # dictionary of objects for obj in range(0, len(X0)): if (mix_objects == True): rand_obj = random.randint(0, 2) if (rand_obj == 0): object_type = Objects3D.ELLIPSOID if (rand_obj == 1): object_type = Objects3D.PARABOLOID if (rand_obj == 2): object_type = Objects3D.GAUSSIAN curr_obj = { 'Obj': object_type, 'C0': C0_var[obj], 'x0': X0[obj], 'y0': Y0[obj], 'z0': Z0[obj], 'a': AB[obj], 'b': AB[obj], 'c': AB[obj], 'phi1': 0.0 } myObjects.append(curr_obj) Object3D = TomoP3D.Object(N_size, myObjects) return (Object3D, myObjects)