def process(self): projections = self.get_input() projections_axes = projections.get_data_axes_order(new_order=self.default_acquisition_axes_order) if not projections_axes == [0,1,2]: projections.array = numpy.transpose(projections.array, projections_axes) pixel_per_voxel = 1 # should be estimated from image_geometry and acquisition_geometry image_geometry = ImageGeometry(voxel_num_x = self.acquisition_geometry.pixel_num_h, voxel_num_y = self.acquisition_geometry.pixel_num_h, voxel_num_z = self.acquisition_geometry.pixel_num_v) # input centered/padded acquisitiondata center_of_rotation = projections.get_dimension_size('horizontal') / 2 if self.acquisition_geometry.geom_type == 'parallel': back = pbalg.pb_backward_project( projections.as_array(), self.acquisition_geometry.angles, center_of_rotation, pixel_per_voxel ) out = ImageData(geometry=self.image_geometry, dimension_labels=self.default_image_axes_order) out_axes = out.get_data_axes_order(new_order=self.output_axes_order) if not out_axes == [0,1,2]: back = numpy.transpose(back, out_axes) out.fill(back) return out else: raise ValueError('Cannot process cone beam')
def test_FISTA_catch_Lipschitz(self): print ("Test FISTA catch Lipschitz") ig = ImageGeometry(127,139,149) x_init = ImageData(geometry=ig) x_init = ig.allocate() b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) x_init = ig.allocate(ImageGeometry.RANDOM) identity = Identity(ig) #### it seems FISTA does not work with Nowm2Sq norm2sq = LeastSquares(identity, b) print ('Lipschitz', norm2sq.L) norm2sq.L = None #norm2sq.L = 2 * norm2sq.c * identity.norm()**2 #norm2sq = FunctionOperatorComposition(L2NormSquared(b=b), identity) opt = {'tol': 1e-4, 'memopt':False} print ("initial objective", norm2sq(x_init)) try: alg = FISTA(x_init=x_init, f=norm2sq, g=ZeroFunction()) self.assertTrue(False) except ValueError as ve: print (ve) self.assertTrue(True)
def skiptest_BlockDataContainerShapeArithmetic(self): print("test block data container") ig0 = ImageGeometry(2, 3, 4) ig1 = ImageGeometry(2, 3, 4) data0 = ImageData(geometry=ig0) data1 = ImageData(geometry=ig1) + 1 data2 = ImageData(geometry=ig0) + 2 data3 = ImageData(geometry=ig1) + 3 cp0 = BlockDataContainer(data0, data1) #cp1 = BlockDataContainer(data2,data3) cp1 = cp0 + 1 self.assertTrue(cp1.shape == cp0.shape) cp1 = cp0.T + 1 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T - 1 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = (cp0.T + 1) * 2 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = (cp0.T + 1) / 2 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.power(2.2) transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.maximum(3) transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.abs() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.sign() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.sqrt() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.conjugate() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape)
def create_simple_ImageData(self): N = 64 ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[int(round(N/4)):int(round(3*N/4)), int(round(N/4)):int(round(3*N/4))] = 0.5 x[int(round(N/8)):int(round(7*N/8)), int(round(3*N/8)):int(round(5*N/8))] = 1 return (ig, Phantom)
def test_CGLS(self): print ("Test CGLS") ig = ImageGeometry(124,153,154) x_init = ImageData(geometry=ig) b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) identity = TomoIdentity(geometry=ig) alg = CGLS(x_init=x_init, operator=identity, data=b) alg.max_iteration = 1 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def skiptest_BlockDataContainerShape(self): print("test block data container") ig0 = ImageGeometry(12, 42, 55, 32) ig1 = ImageGeometry(12, 42, 55, 32) data0 = ImageData(geometry=ig0) data1 = ImageData(geometry=ig1) + 1 data2 = ImageData(geometry=ig0) + 2 data3 = ImageData(geometry=ig1) + 3 cp0 = BlockDataContainer(data0, data1) cp1 = BlockDataContainer(data2, data3) transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp0.T.shape == transpose_shape)
def process(self): DATA = self.get_input() IM = ImageData(geometry=self.volume_geometry) for k in range(IM.geometry.channels): rec_id, IM.as_array()[k] = astra.create_backprojection( DATA.as_array()[k], self.proj_id) astra.data2d.delete(rec_id) if self.device == 'cpu': return IM else: scaling = self.volume_geometry.voxel_size_x**3 return scaling * IM
def test_FISTA_Denoising(self): print ("FISTA Denoising Poisson Noise Tikhonov") # adapted from demo FISTA_Tikhonov_Poisson_Denoising.py in CIL-Demos repository #loader = TestData(data_dir=os.path.join(sys.prefix, 'share','ccpi')) loader = TestData() data = loader.load(TestData.SHAPES) ig = data.geometry ag = ig N=300 # Create Noisy data with Poisson noise scale = 5 n1 = TestData.random_noise( data.as_array()/scale, mode = 'poisson', seed = 10)*scale noisy_data = ImageData(n1) # Regularisation Parameter alpha = 10 # Setup and run the FISTA algorithm operator = Gradient(ig) fid = KullbackLeibler(b=noisy_data) reg = FunctionOperatorComposition(alpha * L2NormSquared(), operator) x_init = ig.allocate() fista = FISTA(x_init=x_init , f=reg, g=fid) fista.max_iteration = 3000 fista.update_objective_interval = 500 fista.run(verbose=True) rmse = (fista.get_output() - data).norm() / data.as_array().size print ("RMSE", rmse) self.assertLess(rmse, 4.2e-4)
def sum_abs_col(self): res = np.array( np.reshape( abs(self.matrix()).sum(axis=1), self.gm_domain.shape, 'F')) #res[res==0]=0 return ImageData(res)
def allocate_direct(self): if issubclass(type(self.geometry), ImageGeometry): return ImageData(geometry=self.geometry) elif issubclass(type(self.geometry), AcquisitionGeometry): return AcquisitionData(geometry=self.geometry) else: raise ValueError( "Wrong geometry type: expected ImageGeometry of AcquisitionGeometry, got ", type(self.geometry))
def test_GradientDescent(self): print ("Test GradientDescent") ig = ImageGeometry(12,13,14) x_init = ImageData(geometry=ig) b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) identity = TomoIdentity(geometry=ig) norm2sq = Norm2sq(identity, b) alg = GradientDescent(x_init=x_init, objective_function=norm2sq, rate=0.3) alg.max_iteration = 20 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def process(self): DATA = self.get_input() IM = ImageData(geometry=self.volume_geometry, dimension_labels=self.output_axes_order) rec_id, IM.array = astra.create_backprojection3d_gpu( DATA.as_array(), self.proj_geom, self.vol_geom) astra.data3d.delete(rec_id) # Scaling of 3D ASTRA backprojector, works both parallel and cone. scaling = 1 / self.volume_geometry.voxel_size_x**2 return scaling * IM
def setupCCPiGeometries(voxel_num_x, voxel_num_y, voxel_num_z, angles, counter): vg = ImageGeometry(voxel_num_x=voxel_num_x,voxel_num_y=voxel_num_y, voxel_num_z=voxel_num_z) Phantom_ccpi = ImageData(geometry=vg, dimension_labels=['horizontal_x','horizontal_y','vertical']) #.subset(['horizontal_x','horizontal_y','vertical']) # ask the ccpi code what dimensions it would like voxel_per_pixel = 1 geoms = pbalg.pb_setup_geometry_from_image(Phantom_ccpi.as_array(), angles, voxel_per_pixel ) pg = AcquisitionGeometry('parallel', '3D', angles, geoms['n_h'], 1.0, geoms['n_v'], 1.0 #2D in 3D is a slice 1 pixel thick ) center_of_rotation = Phantom_ccpi.get_dimension_size('horizontal_x') / 2 ad = AcquisitionData(geometry=pg,dimension_labels=['angle','vertical','horizontal']) geoms_i = pbalg.pb_setup_geometry_from_acquisition(ad.as_array(), angles, center_of_rotation, voxel_per_pixel ) counter+=1 if counter < 4: if (not ( geoms_i == geoms )): print ("not equal and {0}".format(counter)) X = max(geoms['output_volume_x'], geoms_i['output_volume_x']) Y = max(geoms['output_volume_y'], geoms_i['output_volume_y']) Z = max(geoms['output_volume_z'], geoms_i['output_volume_z']) return setupCCPiGeometries(X,Y,Z,angles, counter) else: return geoms else: return geoms_i
def process(self, out=None): DATA = self.get_input() IM = ImageData(geometry=self.volume_geometry) rec_id, IM.array = astra.create_backprojection(DATA.as_array(), self.proj_id) astra.data2d.delete(rec_id) if self.device == 'cpu': ret = IM else: scaling = self.volume_geometry.voxel_size_x**3 ret = scaling * IM if out is None: return ret else: out.fill(ret)
def sum_abs_row(self): res = [] for row in range(self.shape[0]): for col in range(self.shape[1]): if col == 0: prod = self.get_item(row, col).sum_abs_row() else: prod += self.get_item(row, col).sum_abs_row() res.append(prod) if self.shape[1] == 1: tmp = sum(res) return ImageData(tmp) else: return BlockDataContainer(*res)
def test_FISTA(self): print ("Test FISTA") ig = ImageGeometry(127,139,149) x_init = ImageData(geometry=ig) b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) x_init = ImageData(geometry=ig) x_init.fill(numpy.random.random(x_init.shape)) identity = TomoIdentity(geometry=ig) norm2sq = Norm2sq(identity, b) opt = {'tol': 1e-4, 'memopt':False} alg = FISTA(x_init=x_init, f=norm2sq, g=None, opt=opt) alg.max_iteration = 2 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array()) alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def test_ImageGeometry_allocate(self): vgeometry = ImageGeometry(voxel_num_x=4, voxel_num_y=3, channels=2) image = vgeometry.allocate() self.assertEqual(0,image.as_array()[0][0][0]) image = vgeometry.allocate(1) self.assertEqual(1,image.as_array()[0][0][0]) default_order = ['channel' , 'horizontal_y' , 'horizontal_x'] self.assertEqual(default_order[0], image.dimension_labels[0]) self.assertEqual(default_order[1], image.dimension_labels[1]) self.assertEqual(default_order[2], image.dimension_labels[2]) order = [ 'horizontal_x' , 'horizontal_y', 'channel' ] image = vgeometry.allocate(0,dimension_labels=order) self.assertEqual(order[0], image.dimension_labels[0]) self.assertEqual(order[1], image.dimension_labels[1]) self.assertEqual(order[2], image.dimension_labels[2]) ig = ImageGeometry(2,3,2) try: z = ImageData(numpy.random.randint(10, size=(2,3)), geometry=ig) self.assertTrue(False) except ValueError as ve: print (ve) self.assertTrue(True)
def test_ImageData(self): # create ImageData from geometry vgeometry = ImageGeometry(voxel_num_x=4, voxel_num_y=3, channels=2) vol = ImageData(geometry=vgeometry) self.assertEqual(vol.shape, (2, 3, 4)) vol1 = vol + 1 self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape)) vol1 = vol - 1 self.assertNumpyArrayEqual(vol1.as_array(), -numpy.ones(vol.shape)) vol1 = 2 * (vol + 1) self.assertNumpyArrayEqual(vol1.as_array(), 2 * numpy.ones(vol.shape)) vol1 = (vol + 1) / 2 self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape) / 2) vol1 = vol + 1 self.assertEqual(vol1.sum(), 2*3*4) vol1 = (vol + 2) ** 2 self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape) * 4) self.assertEqual(vol.number_of_dimensions, 3)
noise = noises[which_noise] if noise == 's&p': n1 = TestData.random_noise(data.as_array(), mode=noise, salt_vs_pepper=0.9, amount=0.2, seed=10) elif noise == 'poisson': scale = 5 n1 = TestData.random_noise(data.as_array() / scale, mode=noise, seed=10) * scale elif noise == 'gaussian': n1 = TestData.random_noise(data.as_array(), mode=noise, seed=10) else: raise ValueError('Unsupported Noise ', noise) noisy_data = ImageData(n1) # Show Ground Truth and Noisy Data plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.imshow(data.as_array()) plt.title('Ground Truth') plt.colorbar() plt.subplot(1, 2, 2) plt.imshow(noisy_data.as_array()) plt.title('Noisy Data') plt.colorbar() plt.show() # Regularisation Parameter depending on the noise distribution if noise == 's&p':
plt.figure() plt.loglog(iternum[[0,-1]],[objective1.value, objective1.value], label='CVX LS+1') plt.loglog(iternum,criter1,label='FISTA LS+1') plt.loglog(iternum,criterfbpd1,label='FBPD LS+1') plt.legend() plt.show() # Now try 1-norm and TV denoising with FBPD, first 1-norm. # Set up phantom size NxN by creating ImageGeometry, initialising the # ImageData object with this geometry and empty array and finally put some # data into its array, and display as image. N = 64 ig = ImageGeometry(voxel_num_x=N,voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 0.5 x[round(N/8):round(7*N/8),round(3*N/8):round(5*N/8)] = 1 plt.imshow(x) plt.title('Phantom image') plt.show() # Identity operator for denoising I = TomoIdentity(ig) # Data and add noise y = I.direct(Phantom) y.array = y.array + 0.1*np.random.randn(N, N)
import tomophantom from tomophantom import TomoP2D # user supplied input if len(sys.argv) > 1: which_noise = int(sys.argv[1]) else: which_noise = 0 model = 1 # select a model number from the library N = 128 # set dimension of the phantom path = os.path.dirname(tomophantom.__file__) path_library2D = os.path.join(path, "Phantom2DLibrary.dat") phantom_2D = TomoP2D.Model(model, N, path_library2D) data = ImageData(phantom_2D) ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N) # Create acquisition data and geometry detectors = N angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors) # Select device device = input('Available device: GPU==1 / CPU==0 ') if device == '1': dev = 'gpu' else: dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev)
from ccpi.optimisation.algs import FISTA, FBPD, CGLS from ccpi.optimisation.funcs import Norm2sq, Norm1, TV2D from ccpi.astra.ops import AstraProjectorSimple import numpy as np import matplotlib.pyplot as plt # Choose either a parallel-beam (1=parallel2D) or fan-beam (2=cone2D) test case test_case = 1 # Set up phantom size NxN by creating ImageGeometry, initialising the # ImageData object with this geometry and empty array and finally put some # data into its array, and display as image. N = 128 ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 0.5 x[round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 1 plt.imshow(x) plt.title('Phantom image') plt.show() # Set up AcquisitionGeometry object to hold the parameters of the measurement # setup geometry: # Number of angles, the actual angles from 0 to # pi for parallel beam and 0 to 2pi for fanbeam, set the width of a detector # pixel relative to an object pixel, the number of detector pixels, and the # source-origin and origin-detector distance (here the origin-detector distance # set to 0 to simulate a "virtual detector" with same detector pixel size as
# Choose either a parallel-beam (1=parallel2D) or fan-beam (2=cone2D) test case test_case = 2 # Set up phantom size NxN by creating ImageGeometry, initialising the # ImageData object with this geometry and empty array and finally put some # data into its array, and display as image. N = 300 x1 = -1 x2 = 1 dx = (x2-x1)/N ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N, voxel_size_x=dx, voxel_size_y=dx) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 0.5 x[:,round(3*N/8):round(5*N/8)] = 1 plt.imshow(x) plt.title('Phantom image') plt.colorbar() plt.show() # Set up AcquisitionGeometry object to hold the parameters of the measurement # setup geometry: # Number of angles, the actual angles from 0 to # pi for parallel beam and 0 to 2pi for fanbeam, set the width of a detector # pixel relative to an object pixel, the number of detector pixels, and the # source-origin and origin-detector distance (here the origin-detector distance
FunctionOperatorComposition, L2NormSquared from ccpi.astra.operators import AstraProjectorMC import numpy import matplotlib.pyplot as plt # Choose either a parallel-beam (1=parallel2D) or fan-beam (2=cone2D) test case test_case = 1 # Set up phantom NxN pixels and 3 channels. Set up the ImageGeometry and fill # some test data in each of the channels. Display each channel as image. N = 128 numchannels = 3 ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N, channels=numchannels) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[0, round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 1.0 x[0, round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 2.0 x[1, round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 0.7 x[1, round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 1.2 x[2, round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 1.5 x[2, round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 2.2 f, axarr = plt.subplots(1, numchannels) for k in numpy.arange(3): axarr[k].imshow(x[k], vmin=0, vmax=2.5) plt.show()
def load_data(self): ''' Parse NEXUS file and returns either ImageData or Acquisition Data depending on file content ''' try: with h5py.File(self.nexus_file, 'r') as file: if np.string_(file.attrs['creator']) != np.string_( 'NEXUSDataWriter.py'): raise Exception( 'We can parse only files created by NEXUSDataWriter.py' ) ds_data = file['entry1/tomo_entry/data/data'] data = np.array(ds_data, dtype='float32') dimension_labels = [] for i in range(data.ndim): dimension_labels.append(ds_data.attrs['dim{}'.format(i)]) if ds_data.attrs['data_type'] == 'ImageData': self._geometry = ImageGeometry( voxel_num_x=ds_data.attrs['voxel_num_x'], voxel_num_y=ds_data.attrs['voxel_num_y'], voxel_num_z=ds_data.attrs['voxel_num_z'], voxel_size_x=ds_data.attrs['voxel_size_x'], voxel_size_y=ds_data.attrs['voxel_size_y'], voxel_size_z=ds_data.attrs['voxel_size_z'], center_x=ds_data.attrs['center_x'], center_y=ds_data.attrs['center_y'], center_z=ds_data.attrs['center_z'], channels=ds_data.attrs['channels']) return ImageData(array=data, deep_copy=False, geometry=self._geometry, dimension_labels=dimension_labels) else: # AcquisitionData if ds_data.attrs.__contains__('dist_source_center'): dist_source_center = ds_data.attrs[ 'dist_source_center'] else: dist_source_center = None if ds_data.attrs.__contains__('dist_center_detector'): dist_center_detector = ds_data.attrs[ 'dist_center_detector'] else: dist_center_detector = None self._geometry = AcquisitionGeometry( geom_type=ds_data.attrs['geom_type'], dimension=ds_data.attrs['dimension'], dist_source_center=dist_source_center, dist_center_detector=dist_center_detector, pixel_num_h=ds_data.attrs['pixel_num_h'], pixel_size_h=ds_data.attrs['pixel_size_h'], pixel_num_v=ds_data.attrs['pixel_num_v'], pixel_size_v=ds_data.attrs['pixel_size_v'], channels=ds_data.attrs['channels'], angles=np.array( file['entry1/tomo_entry/data/rotation_angle'], dtype='float32')) #angle_unit = file['entry1/tomo_entry/data/rotation_angle'].attrs['units']) return AcquisitionData(array=data, deep_copy=False, geometry=self._geometry, dimension_labels=dimension_labels) except: print("Error reading nexus file") raise
import numpy as np import numpy import matplotlib.pyplot as plt from ccpi.optimisation.algorithms import CGLS from ccpi.optimisation.operators import BlockOperator, Gradient, Identity from ccpi.framework import TestData import os, sys loader = TestData(data_dir=os.path.join(sys.prefix, 'share', 'ccpi')) data = loader.load(TestData.SHAPES) ig = data.geometry ag = ig noisy_data = ImageData( TestData.random_noise(data.as_array(), mode='gaussian', seed=1)) #noisy_data = ImageData(data.as_array()) # Show Ground Truth and Noisy Data plt.figure(figsize=(10, 10)) plt.subplot(2, 1, 1) plt.imshow(data.as_array()) plt.title('Ground Truth') plt.colorbar() plt.subplot(2, 1, 2) plt.imshow(noisy_data.as_array()) plt.title('Noisy Data') plt.colorbar() plt.show() # Setup and run the regularised CGLS algorithm (Tikhonov with Gradient)
from ccpi.optimisation.algs import FISTA, FBPD, CGLS, SIRT from ccpi.optimisation.funcs import Norm2sq, Norm1, TV2D, IndicatorBox from ccpi.astra.ops import AstraProjectorSimple import numpy as np import matplotlib.pyplot as plt # Choose either a parallel-beam (1=parallel2D) or fan-beam (2=cone2D) test case test_case = 1 # Set up phantom size NxN by creating ImageGeometry, initialising the # ImageData object with this geometry and empty array and finally put some # data into its array, and display as image. N = 128 ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 0.5 x[round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 1 plt.imshow(x) plt.title('Phantom image') plt.show() # Set up AcquisitionGeometry object to hold the parameters of the measurement # setup geometry: # Number of angles, the actual angles from 0 to # pi for parallel beam and 0 to 2pi for fanbeam, set the width of a detector # pixel relative to an object pixel, the number of detector pixels, and the # source-origin and origin-detector distance (here the origin-detector distance # set to 0 to simulate a "virtual detector" with same detector pixel size as
#This will generate a N_size x N_size x Time frames phantom (2D + time) phantom_2Dt = TomoP2D.ModelTemporal(model, N, path_library2D)[0:-1:2] fig = plt.figure() ims1 = [] for sl in range(0,np.shape(phantom_2Dt)[0]): im1 = plt.imshow(phantom_2Dt[sl,:,:], animated=True, vmin=0, vmax=1) ims1.append([im1]) ani1 = animation.ArtistAnimation(fig, ims1, interval=500,repeat_delay=10) plt.show() ig = ImageGeometry(voxel_num_x = N, voxel_num_y = N, channels = np.shape(phantom_2Dt)[0]) data = ImageData(phantom_2Dt, geometry=ig) detectors = N angles = np.linspace(0,np.pi,180) ag = AcquisitionGeometry('parallel','2D', angles, detectors, channels = np.shape(phantom_2Dt)[0]) Aop = AstraProjectorMC(ig, ag, dev) sin = Aop.direct(data) scale = 2 n1 = scale * np.random.poisson(sin.as_array()/scale) noisy_data = AcquisitionData(n1, ag) # Regularisation Parameter alpha = 10
def test_BlockDataContainer_fill(self): print("test block data container") ig0 = ImageGeometry(2, 3, 4) ig1 = ImageGeometry(2, 3, 5) data0 = ImageData(geometry=ig0) data1 = ImageData(geometry=ig1) + 1 data2 = ImageData(geometry=ig0) + 2 data3 = ImageData(geometry=ig1) + 3 cp0 = BlockDataContainer(data0, data1) #cp1 = BlockDataContainer(data2,data3) cp2 = BlockDataContainer(data0 + 1, data1 + 1) data0.fill(data2) self.assertNumpyArrayEqual(data0.as_array(), data2.as_array()) data0 = ImageData(geometry=ig0) for el, ot in zip(cp0, cp2): print(el.shape, ot.shape) cp0.fill(cp2) self.assertBlockDataContainerEqual(cp0, cp2)