def run(self, iterations): self.fn = getFilterFile(self.fd, self.pg, iterations, self.rg, self.osz) if os.path.exists(self.fn): flt = np.load(self.fn) self.v[:] = self.customFBP(flt) return nd = self.nd if self.osz: nds = self.osz else: nds = nd na = len(self.ang) pgc = astra.create_proj_geom('parallel',1.0,nd,self.ang) vgc = astra.create_vol_geom((nds,nds)) pidc = astra.create_projector('strip',pgc,vgc) x = np.zeros((nds,nds)) xs = np.zeros((nds,nds)) sf = np.zeros((na,nd)) vid = astra.data2d.create('-vol',vgc) sid = astra.data2d.create('-sino',pgc) cfg = astra.astra_dict('FP') cfg['ProjectorId']=pidc cfg['ProjectionDataId']=sid cfg['VolumeDataId']=vid fpid = astra.algorithm.create(cfg) cfg = astra.astra_dict('BP') cfg['ProjectorId']=pidc cfg['ProjectionDataId']=sid cfg['ReconstructionDataId']=vid bpid = astra.algorithm.create(cfg) vc = astra.data2d.get_shared(vid) sc = astra.data2d.get_shared(sid) x[nds//2,nds//2]=1 alp = 1./(na*nds) if self.rg: if self.rg*alp >=0.1: alp = 0.1/self.rg astra.log.info('Computing filter...') for i in range(iterations): if i%10==0: astra.log.info('{:.2f} % done'.format(100*float(i)/iterations)) xs+=x vc[:] = x astra.algorithm.run(fpid) astra.algorithm.run(bpid) if self.rg: dx = x[:-1,:] - x[1:,:] dy = x[:,:-1] - x[:,1:] x[:-1,:] -= self.rg*dx*alp x[1:,:] += self.rg*dx*alp x[:,:-1] -= self.rg*dy*alp x[:,1:] += self.rg*dy*alp x -= vc*alp vc[:] = xs astra.algorithm.run(fpid) flt = sc.copy()*alp astra.algorithm.delete([fpid,bpid]) astra.algorithm.delete([vid,sid]) np.save(self.fn,flt) self.v[:] = self.customFBP(flt) astra.projector.delete(pidc)
def cgls2D(self, sinogram, iterations): """perform CGLS reconstruction""" rec_id = astra.data2d.create('-vol', self.vol_geom) # Create a data object to hold the sinogram data sinogram_id = astra.data2d.create('-sino', self.proj_geom, sinogram) if self.device == 1: cfg = astra.astra_dict('CGLS') cfg['ProjectorId'] = self.proj_id else: cfg = astra.astra_dict('CGLS_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id # Create and run the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, iterations) # Get the result recCGLS = astra.data2d.get(rec_id) astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) astra.data2d.delete(self.proj_id) return recCGLS
def init(self, volume_data=1, projection_data=1): # Create volume geometry self.volume_geom = astra.create_vol_geom(self.num_voxel) # Create projection geometry self.projection_geom = astra.create_proj_geom(self.geometry_type, self.detector_spacing_x, self.detector_spacing_y, self.det_row_count, self.det_col_count, self.angles, self.source_origin, self.origin_detector) # Allocate and store volume data in ASTRA memory self.volume_id = astra.data3d.create('-vol', self.volume_geom, volume_data) # Allocate and store projection data in ASTRA memeory self.projection_id = astra.data3d.create('-sino', self.projection_geom, projection_data) # Create algorithm object: forward projector cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['VolumeDataId'] = self.volume_id self.forward_alg_id = astra.algorithm.create(cfg) # Create algorithm object: backward projector cfg = astra.astra_dict('BP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['ReconstructionDataId'] = self.volume_id self.backward_alg_id = astra.algorithm.create(cfg)
def astrarecon(tilt_data,tilt_angles,iterations=1,geometry='parallel3d',SO_dist=1.0,OD_dist=1.0): proj_shape = np.shape(tilt_data) recon_shape = (proj_shape[2],proj_shape[2],proj_shape[1]) vol_geom = astra.create_vol_geom(recon_shape) angles = np.pi*tilt_angles/180 if geometry == 'parallel3d': proj_geom = astra.create_proj_geom(geometry, 1.0, 1.0, proj_shape[1], proj_shape[2], angles) cfg = astra.astra_dict('SIRT3D_CUDA') elif geometry == 'cone': proj_geom = astra.create_proj_geom(geometry, 1.0, 1.0, proj_shape[1], proj_shape[2], angles, SO_dist, OD_dist) cfg = astra.astra_dict('FDK_CUDA') proj_id = astra.data3d.create('-proj3d', proj_geom, np.swapaxes(tilt_data,0,1)) rec_id = astra.data3d.create('-vol', vol_geom) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = proj_id alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, iterations) rec = astra.data3d.get(rec_id) astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(proj_id) return(rec)
def fbp2D(self, sinogram): """perform FBP reconstruction""" rec_id = astra.data2d.create('-vol', self.vol_geom) # Create a data object to hold the sinogram data sinogram_id = astra.data2d.create('-sino', self.proj_geom, sinogram) if self.device == 1: cfg = astra.astra_dict('FBP') cfg['ProjectorId'] = self.proj_id else: cfg = astra.astra_dict('FBP_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['FilterType'] = 'Ram-Lak' # Create and run the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) # Get the result recFBP = astra.data2d.get(rec_id) astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) astra.data2d.delete(self.proj_id) return recFBP
def init(self, volume_data=1, projection_data=1): # Create volume geometry self.volume_geom = astra.create_vol_geom(self.num_voxel) # Create projection geometry self.projection_geom = astra.create_proj_geom( self.geometry_type, self.detector_spacing_x, self.detector_spacing_y, self.det_row_count, self.det_col_count, self.angles, self.source_origin, self.origin_detector) # Allocate and store volume data in ASTRA memory self.volume_id = astra.data3d.create('-vol', self.volume_geom, volume_data) # Allocate and store projection data in ASTRA memeory self.projection_id = astra.data3d.create('-sino', self.projection_geom, projection_data) # Create algorithm object: forward projector cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['VolumeDataId'] = self.volume_id self.forward_alg_id = astra.algorithm.create(cfg) # Create algorithm object: backward projector cfg = astra.astra_dict('BP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['ReconstructionDataId'] = self.volume_id self.backward_alg_id = astra.algorithm.create(cfg)
def __init__(self, geometry_type='cone', num_voxel=(100, 100, 100), det_row_count=100, det_col_count=100, angles=np.linspace(0, 2 * np.pi, 180, endpoint=False), det_col_spacing=1.0, det_row_spacing=1.0, source_origin=100.0, origin_detector=10.0, volume_data=1, projection_data=1, gpu_index=0): self.geometry_type = geometry_type self.num_voxel = num_voxel self.detector_spacing_x = det_col_spacing self.detector_spacing_y = det_row_spacing self.det_row_count = det_row_count self.det_col_count = det_col_count self.angles = angles self.source_origin = source_origin self.origin_detector = origin_detector self.volume_data = volume_data self.projection_data = projection_data self.gpu_index = gpu_index # Create volume geometry self.volume_geom = astra.create_vol_geom(self.num_voxel) # Create projection geometry self.projection_geom = astra.create_proj_geom( self.geometry_type, self.detector_spacing_x, self.detector_spacing_y, self.det_row_count, self.det_col_count, self.angles, self.source_origin, self.origin_detector) # Allocate and store volume data in ASTRA memory self.volume_id = astra.data3d.create( '-vol', self.volume_geom, self.volume_data) # Allocate and store projection data in ASTRA memory self.projection_id = astra.data3d.create( '-sino', self.projection_geom, self.projection_data) # Create algorithm object: forward projector cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['VolumeDataId'] = self.volume_id self.forward_alg_id = astra.algorithm.create(cfg) # Create algorithm object: backward projector cfg = astra.astra_dict('BP3D_CUDA') # classmethod? cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['ReconstructionDataId'] = self.volume_id self.backward_alg_id = astra.algorithm.create(cfg)
def __init__(self, geometry_type='cone', num_voxel=(100, 100, 100), det_row_count=100, det_col_count=100, angles=np.linspace(0, 2 * np.pi, 180, endpoint=False), det_col_spacing=1.0, det_row_spacing=1.0, source_origin=100.0, origin_detector=10.0, volume_data=1, projection_data=1, gpu_index=0): self.geometry_type = geometry_type self.num_voxel = num_voxel self.detector_spacing_x = det_col_spacing self.detector_spacing_y = det_row_spacing self.det_row_count = det_row_count self.det_col_count = det_col_count self.angles = angles self.source_origin = source_origin self.origin_detector = origin_detector self.volume_data = volume_data self.projection_data = projection_data self.gpu_index = gpu_index # Create volume geometry self.volume_geom = astra.create_vol_geom(self.num_voxel) # Create projection geometry self.projection_geom = astra.create_proj_geom( self.geometry_type, self.detector_spacing_x, self.detector_spacing_y, self.det_row_count, self.det_col_count, self.angles, self.source_origin, self.origin_detector) # Allocate and store volume data in ASTRA memory self.volume_id = astra.data3d.create('-vol', self.volume_geom, self.volume_data) # Allocate and store projection data in ASTRA memory self.projection_id = astra.data3d.create('-sino', self.projection_geom, self.projection_data) # Create algorithm object: forward projector cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['VolumeDataId'] = self.volume_id self.forward_alg_id = astra.algorithm.create(cfg) # Create algorithm object: backward projector cfg = astra.astra_dict('BP3D_CUDA') # classmethod? cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.projection_id cfg['ReconstructionDataId'] = self.volume_id self.backward_alg_id = astra.algorithm.create(cfg)
def _fp_id(self): """Create algorithms object of forward projection.""" geom_type = self.geom.geom_type.lower() cfg = None if geom_type in self.type2d: cfg = astra.astra_dict('FP_CUDA') elif geom_type in self.type3d: cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['VolumeDataId'] = self.vol_id return astra.algorithm.create(cfg)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--width', type=int, required=True) parser.add_argument('--num-projections', type=int, required=True) parser.add_argument('--num-slices', type=int, required=True) args = parser.parse_args() angles = np.linspace(0, np.pi, args.num_projections, False, dtype=np.float64) vol_geom = astra.create_vol_geom(args.width, args.width, args.num_slices) proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, args.num_slices, args.width, angles) vid = astra.data3d.create('-vol', vol_geom) pid = astra.data3d.create('-proj3d', proj_geom, 0.0) config = astra.astra_dict('BP3D_CUDA') config['ProjectionDataId'] = pid config['ReconstructionDataId'] = vid aid = astra.algorithm.create(config) astra.algorithm.run(aid)
def SIRT2D_cpu(sinogram, Niter, proj_geom, vol_geom): # Create a data object for the reconstruction rec_id = astra.data2d.create('-vol', vol_geom) proj_id = astra.create_projector('strip',proj_geom,vol_geom) sinogram_id = astra.data2d.create('-sino', proj_geom, sinogram) # Set up the parameters for a reconstruction algorithm using the CPU cfg = astra.astra_dict('SIRT') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['ProjectorId'] = proj_id cfg['option']={} cfg['option']['MinConstraint'] = 0 # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, Niter) # Get the result rec = astra.data2d.get(rec_id) # Clean up. astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) astra.projector.delete(proj_id) return rec;
def single_sino(sino: np.ndarray, cor: ScalarCoR, proj_angles: ProjectionAngles, recon_params: ReconstructionParameters, progress: Optional[Progress] = None) -> np.ndarray: assert sino.ndim == 2, "Sinogram must be a 2D image" sino = BaseRecon.prepare_sinogram(sino, recon_params) image_width = sino.shape[1] if astra_mutex.locked(): LOG.warning("Astra recon already in progress. Waiting") with astra_mutex: vectors = vec_geom_init2d(proj_angles, 1.0, cor.to_vec(image_width).value) vol_geom = astra.create_vol_geom((image_width, image_width)) proj_geom = astra.create_proj_geom('parallel_vec', image_width, vectors) cfg = astra.astra_dict(recon_params.algorithm) cfg['FilterType'] = recon_params.filter_name with _managed_recon(sino, cfg, proj_geom, vol_geom) as (alg_id, rec_id): astra.algorithm.run(alg_id, iterations=recon_params.num_iter) return astra.data2d.get(rec_id)
def backward(self, proj_vector=None): """Backprojection.""" # Store projection data in ASTRA memory if proj_vector is None: astra.data3d.store(self.proj_id, self.proj.data.reshape( self.geom.det_row_count, self.geom.angles.size, self.geom.det_col_count)) else: astra.data3d.store(self.proj_id, proj_vector.data.reshape( self.geom.det_row_count, self.geom.angles.size, self.geom.det_col_count)) # Create algorithm object cfg = astra.astra_dict('BP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.volume_id self.bp_id = astra.algorithm.create(cfg) # Run algorithms astra.algorithm.run(self.bp_id) # Retrieve projection from ASTRA memory self.vol.data[:] = np.ravel(astra.data3d.get(self.volume_id))
def fbp_cpu(sinogram, proj_id): # Get projection geometry from projector proj_geom = astra.projector.projection_geometry(proj_id) vol_geom = astra.projector.volume_geometry(proj_id) # Create a data object for the reconstruction rec_id = astra.data2d.create('-vol', vol_geom) # Create a data object to hold the sinogram data sinogram_id = astra.data2d.create('-sino', proj_geom, sinogram) # Create configuration for reconstruction algorithm cfg = astra.astra_dict('FBP') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['ProjectorId'] = proj_id # Create and run the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) # Get the result rec = astra.data2d.get(rec_id) # Clean up. astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) return rec
def astra_rec_cuda(tomo, center, recon, theta, vol_geom, niter, proj_type, gpu_index, opts): # Lazy import ASTRA import astra as astra_mod nslices, nang, ndet = tomo.shape cfg = astra_mod.astra_dict(opts['method']) if 'extra_options' in opts: # NOTE: we are modifying 'extra_options' and so need to make a copy cfg['option'] = copy.deepcopy(opts['extra_options']) else: cfg['option'] = {} if gpu_index is not None: cfg['option']['GPUindex'] = gpu_index oc = None const_theta = np.ones(nang) proj_geom = astra_mod.create_proj_geom('parallel', 1.0, ndet, theta.astype(np.float64)) for i in range(nslices): if center[i] != oc: oc = center[i] proj_geom['option'] = { 'ExtraDetectorOffset': (center[i] - ndet / 2.) * const_theta } pid = astra_mod.create_projector(proj_type, proj_geom, vol_geom) cfg['ProjectorId'] = pid sid = astra_mod.data2d.link('-sino', proj_geom, tomo[i]) cfg['ProjectionDataId'] = sid vid = astra_mod.data2d.link('-vol', vol_geom, recon[i]) cfg['ReconstructionDataId'] = vid alg_id = astra_mod.algorithm.create(cfg) astra_mod.algorithm.run(alg_id, niter) astra_mod.algorithm.delete(alg_id) astra_mod.data2d.delete(vid) astra_mod.data2d.delete(sid) astra_mod.projector.delete(pid)
def reconstruct(self, data, algo="SIRT3D_CUDA", iterations=25, pars={}): if self.data_id is None: self.data_id = astra.data3d.create("-sino", self.proj_geom, data) else: astra.data3d.store(self.data_id, data) if self.vol_id is None: self.vol_id = astra.data3d.create("-vol", self.vol_geom, 0) else: astra.data3d.store(self.vol_id, 0) cfg = astra.astra_dict(algo) cfg["ProjectorId"] = self.projector_id cfg["ProjectionDataId"] = self.data_id cfg["ReconstructionDataId"] = self.vol_id if self.gpu_index is not None: cfg["options"] = {"GPUindex": self.gpu_index} else: cfg["options"] = {} if "lower_limit" in pars: cfg["options"]["UseMinConstraint"] = True cfg["options"]["MinConstraintValue"] = pars["lower_limit"] if "upper_limit" in pars: cfg["options"]["UseMaxConstraint"] = True cfg["options"]["MaxConstraintValue"] = pars["upper_limit"] self.algo_id = astra.algorithm.create(cfg) astra.algorithm.run(self.algo_id, iterations) astra.algorithm.delete(self.algo_id) self.algo_id = None return astra.data3d.get(self.vol_id)
def reconstruct(s, alg, iterations, rnge=np.pi): # Create reconstruction. # s is the sinogram to reconstruct # alg is the algorithm to use (string) eg 'SIRT' or 'FBP' # iterations is number of iterations # rnge is the range of angles used (if not set the default is pi)... # ... r should be >=pi for an accurate reconstruction if alg == 'FBP': iterations = 1 vol_geom, projector_id, proj_geom = geom_setup(s.shape[1], rnge, s.shape[0]) # create an astratoolbox id for the projections(sinogram) projections_id = astra.data2d.create('-sino', proj_geom, s) # set up reconstruction reconstruction_id = astra.data2d.create('-vol', vol_geom) cfg = astra.astra_dict(alg) cfg['ReconstructionDataId'] = reconstruction_id cfg['ProjectionDataId'] = projections_id cfg['ProjectorId'] = projector_id cfg['option'] = {} cfg['option']['MinConstraint'] = 0. # Force solution to be nonnegative. algorithm_id = astra.algorithm.create(cfg) astra.algorithm.run(algorithm_id, iterations) return astra.data2d.get(reconstruction_id)
def astra_rec_cuda(tomo, center, recon, theta, vol_geom, niter, proj_type, gpu_index, opts): # Lazy import ASTRA import astra as astra_mod nslices, nang, ndet = tomo.shape cfg = astra_mod.astra_dict(opts['method']) if 'extra_options' in opts: # NOTE: we are modifying 'extra_options' and so need to make a copy cfg['option'] = copy.deepcopy(opts['extra_options']) else: cfg['option'] = {} if gpu_index is not None: cfg['option']['GPUindex'] = gpu_index oc = None const_theta = np.ones(nang) proj_geom = astra_mod.create_proj_geom( 'parallel', 1.0, ndet, theta.astype(np.float64)) for i in range(nslices): if center[i] != oc: oc = center[i] proj_geom['option'] = { 'ExtraDetectorOffset': (center[i] - ndet / 2.) * const_theta} pid = astra_mod.create_projector(proj_type, proj_geom, vol_geom) cfg['ProjectorId'] = pid sid = astra_mod.data2d.link('-sino', proj_geom, tomo[i]) cfg['ProjectionDataId'] = sid vid = astra_mod.data2d.link('-vol', vol_geom, recon[i]) cfg['ReconstructionDataId'] = vid alg_id = astra_mod.algorithm.create(cfg) astra_mod.algorithm.run(alg_id, niter) astra_mod.algorithm.delete(alg_id) astra_mod.data2d.delete(vid) astra_mod.data2d.delete(sid) astra_mod.projector.delete(pid)
def fbp(sinogram, geo): vol_geom = astra.create_vol_geom(geo["nVoxelY"], geo["nVoxelX"], -1 * geo["sVoxelY"] / 2, geo["sVoxelY"] / 2, -1 * geo["sVoxelX"] / 2, geo["sVoxelX"] / 2) proj_geom = astra.create_proj_geom( geo["mode"], geo["dDetecU"], geo["nDetecU"], np.linspace(geo["start_angle"], geo["end_angle"], geo["sino_views"], False), geo["DSO"], geo["DOD"]) if geo["mode"] is "parallel": proj_id = astra.create_projector("linear", proj_geom, vol_geom) elif geo["mode"] is "fanflat": proj_id = astra.create_projector("line_fanflat", proj_geom_full, vol_geom) rec_id = astra.data2d.create('-vol', vol_geom) sinogram_id = astra.data2d.create('-sino', proj_geom, sinogram) cfg = astra.astra_dict('FBP') cfg['ProjectorId'] = proj_id cfg["FilterType"] = "Ram-Lak" cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) image_recon = astra.data2d.get(rec_id) astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) return image_recon
def backward(self, proj_vector=None): """Backprojection.""" # Store projection data in ASTRA memory if proj_vector is None: astra.data3d.store( self.proj_id, self.proj.data.reshape(self.geom.det_row_count, self.geom.angles.size, self.geom.det_col_count)) else: astra.data3d.store( self.proj_id, proj_vector.data.reshape(self.geom.det_row_count, self.geom.angles.size, self.geom.det_col_count)) # Create algorithm object cfg = astra.astra_dict('BP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.volume_id self.bp_id = astra.algorithm.create(cfg) # Run algorithms astra.algorithm.run(self.bp_id) # Retrieve projection from ASTRA memory self.vol.data[:] = np.ravel(astra.data3d.get(self.volume_id))
def FBP_reconstruction(projections, scanner_params, proj_vecs, voxel_size=.1, rec_shape=501, vol_center=0, **kwargs): astra.astra.set_gpu_index(globals().get('GPU_ID', kwargs.get('gpu_id', -1))) # from [proj_slc,rows,cols] to [rows,proj_slc,cols] projections = np.transpose(projections, (1,0,2)) proj_geom = astra.create_proj_geom('cone_vec', *scanner_params.detector_effective_size, proj_vecs) projections_id = astra.data3d.create('-sino', proj_geom, projections) # [z,x,y] to [y,x,z] axis transposition vol_center = tuple([vol_center[i] for i in [2,1,0]]) if isinstance(vol_center, tuple) else (vol_center,) *3 reconstructed_shape = tuple([rec_shape[i] for i in [2,1,0]]) if isinstance(rec_shape, tuple) else (rec_shape,) *3 vol_geom = astra.creators.create_vol_geom(*reconstructed_shape, *[center+sign*size/2*voxel_size for center, size in zip(vol_center, reconstructed_shape) for sign in [-1, 1]] ) reconstruction_id = astra.data3d.create('-vol', vol_geom, data=0) alg_cfg = astra.astra_dict('BP3D_CUDA') alg_cfg['ProjectionDataId'] = projections_id alg_cfg['ReconstructionDataId'] = reconstruction_id algorithm_id = astra.algorithm.create(alg_cfg) astra.algorithm.run(algorithm_id) reconstruction = astra.data3d.get(reconstruction_id) # Free ressources astra.algorithm.delete(algorithm_id) astra.data3d.delete([projections_id, reconstruction_id]) return reconstruction
def full_reconstruct(p): # Create geometries and projector. vol_geom = astra.create_vol_geom(128, 128) angles = np.linspace(0, np.pi, 180, endpoint=False) proj_geom = astra.create_proj_geom('parallel', 1., 128, angles) projector_id = astra.create_projector('linear', proj_geom, vol_geom) # Create sinogram. sinogram_id, sinogram = astra.create_sino(p, projector_id) # Create reconstruction. reconstruction_id = astra.data2d.create('-vol', vol_geom) cfg = astra.astra_dict('FBP') cfg['ReconstructionDataId'] = reconstruction_id cfg['ProjectionDataId'] = sinogram_id cfg['ProjectorId'] = projector_id cfg['option'] = {} cfg['option']['MinConstraint'] = 0. # Force solution to be nonnegative. algorithm_id = astra.algorithm.create(cfg) astra.algorithm.run(algorithm_id, 100) # 100 iterations. reconstruction = astra.data2d.get(reconstruction_id) return reconstruction # Cleanup. astra.algorithm.delete(algorithm_id) astra.data2d.delete(reconstruction_id) astra.data2d.delete(sinogram_id) astra.projector.delete(projector_id)
def astra_fp_3d(volume, proj_geom): """ :param proj_geom: :param volume: :return:3D sinogram """ detector_size = volume.shape[1] slices_number = volume.shape[0] rec_size = detector_size vol_geom = build_volume_geometry_3d(rec_size, slices_number) sinogram_id = astra.data3d.create('-sino', proj_geom) # Create a data object for the reconstruction rec_id = astra.data3d.create('-vol', vol_geom, data=volume) # Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict('FP3D_CUDA') cfg['VolumeDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['option'] = {} alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, 1) res_sino = astra.data3d.get(sinogram_id) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(sinogram_id) astra.clear() return res_sino
def performBP(self, proj_id, rec_id): cfg = astra.astra_dict('BP3D_CUDA') cfg['ProjectionDataId'] = proj_id cfg['ReconstructionDataId'] = rec_id alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) astra.algorithm.delete(alg_id)
def astra_rec_cpu(tomo, center, recon, theta, vol_geom, niter, proj_type, opts): # Lazy import ASTRA import astra as astra_mod nslices, nang, ndet = tomo.shape cfg = astra_mod.astra_dict(opts['method']) if 'extra_options' in opts: cfg['option'] = opts['extra_options'] proj_geom = astra_mod.create_proj_geom('parallel', 1.0, ndet, theta.astype(np.float64)) pid = astra_mod.create_projector(proj_type, proj_geom, vol_geom) sino = np.zeros((nang, ndet), dtype=np.float32) sid = astra_mod.data2d.link('-sino', proj_geom, sino) cfg['ProjectorId'] = pid cfg['ProjectionDataId'] = sid for i in range(nslices): shft = int(np.round(ndet / 2. - center[i])) if not shft == 0: sino[:] = np.roll(tomo[i], shft) l = shft r = ndet + shft if l < 0: l = 0 if r > ndet: r = ndet sino[:, :l] = 0 sino[:, r:] = 0 else: sino[:] = tomo[i] vid = astra_mod.data2d.link('-vol', vol_geom, recon[i]) cfg['ReconstructionDataId'] = vid alg_id = astra_mod.algorithm.create(cfg) astra_mod.algorithm.run(alg_id, niter) astra_mod.algorithm.delete(alg_id) astra_mod.data2d.delete(vid) astra_mod.data2d.delete(sid) astra_mod.projector.delete(pid)
def fbp(g, theta, n, filter='ram-lak'): ''' Computes the filtered backprojection of the given numpy.ndarray g with the desired filter. ''' vol_geom = astra.create_vol_geom(n) proj_geom = astra.create_proj_geom('parallel', 1.0, 367, theta) f_id = astra.data2d.create('-vol', vol_geom) g_id = astra.data2d.create('-sino', proj_geom, g) cfg = astra.astra_dict("FBP_CUDA") cfg["ProjectionDataId"] = g_id cfg["ReconstructionDataId"] = f_id cfg['option'] = {} cfg['option']["FilterType"] = filter alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) rec_data = astra.data2d.get(f_id) astra.algorithm.delete(alg_id) astra.data2d.delete(f_id) astra.data2d.delete(g_id) return rec_data
def cfg_setup(self): cfg = astra.astra_dict(self.name) cfg['ReconstructionDataId'] = self.rec_id cfg['ProjectionDataId'] = self.sino_id if 'CUDA' in self.name: cfg['option'] = {'GPUindex': self.parameters['GPU_index']} return cfg
def _backproject(self, y, algorithm='FDK_CUDA', iterations=1, min_constraint=None, short_scan=False): cfg = astra.astra_dict(algorithm) cfg['option'] = {'ShortScan': short_scan} if (min_constraint is not None): cfg['option']['MinConstraint'] = min_constraint output = numpy.zeros(astra.functions.geom_size(self.vol_geom), dtype=numpy.float32) rec_id = astra.data3d.link('-vol', self.vol_geom, output) sinogram_id = astra.data3d.link('-sino', self.proj_geom, y) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id #print(cfg['option']) alg_id = astra.algorithm.create(cfg) #astra.data3d.store(self.sinogram_id, y) astra.algorithm.run(alg_id, iterations) astra.algorithm.delete(alg_id) astra.data3d.delete([rec_id, sinogram_id]) return output #astra.data3d.get(self.rec_id)
def Kadj(sino: np.array) -> np.array: # Create objects for the reconstruction rec_id = astra.data2d.create('-vol', vol_geom) sino_id = astra.data2d.create('-sino', proj_geom, sino) proj_id = astra.create_projector(proj_type, proj_geom, vol_geom) # Set up the parameters for the backpropagation reconstruction. cfg = astra.astra_dict(alg) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id cfg['ProjectorId'] = proj_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # Run algorithm. astra.algorithm.run(alg_id) # Get the result rec = astra.data2d.get(rec_id) # Clean up and return result. astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sino_id) astra.projector.delete(proj_id) return rec
def backward(self, proj_vector): """Backprojection.""" if self.geom.vol_ndim == 2: # Store projection data in ASTRA memory astra.data2d.store( self.proj_id, proj_vector.data.reshape(self.geom.angles.size, self.geom.det_col_count)) # Create algorithm object cfg = astra.astra_dict('BP_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.volume_id self.bp_id = astra.algorithm.create(cfg) # Run algorithms astra.algorithm.run(self.bp_id) # Retrieve projection from ASTRA memory return self.vol_space.element( self.scal_fac * np.ravel(astra.data2d.get(self.volume_id))) elif self.geom.vol_ndim == 3: # Store projection data in ASTRA memory astra.data3d.store( self.proj_id, proj_vector.data.reshape(self.geom.det_row_count, self.geom.angles.size, self.geom.det_col_count)) # Create algorithm object cfg = astra.astra_dict('BP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.volume_id self.bp_id = astra.algorithm.create(cfg) # Run algorithms astra.algorithm.run(self.bp_id) # Retrieve projection from ASTRA memory return self.vol_space.element( self.scal_fac * np.ravel(astra.data3d.get(self.volume_id)))
def FDK_reconstruction(projections, scanner_params, proj_vecs, voxel_size=.1, rec_shape=501, **kwargs): """Uses FDK method to reconstruct CT volume from CB projections Args: ----- projections (np.ndarray): [proj_slc, rows, cols] CBCT projections scanner_params (class): class containing scanner data proj_vecs (np.ndarray): vects describing the scanning used for reconstruction voxel_size (float): size of the voxels in the reconstructed volume rec_shape (int/tuple): shape of the reconstructed volume tuple with 3 dims [z,x,y] or int if isotropic --optional-- gpu_id (int): GPU for astra to use if not set globaly, defaults to -1 Returns: -------- reconstruction (np.ndarray): [z,x,y] recontructed CT volume """ astra.astra.set_gpu_index(globals().get('GPU_ID', kwargs.get('gpu_id', -1))) # from [proj_slc,rows,cols] to [rows,proj_slc,cols] projections = np.transpose(projections, (1, 0, 2)) proj_geom = astra.create_proj_geom('cone_vec', *scanner_params.detector_binned_size, proj_vecs) projections_id = astra.data3d.create('-sino', proj_geom, projections) # [z,x,y] to [y,x,z] axis transposition reconstructed_shape = tuple([rec_shape[i] for i in [2, 1, 0]]) if isinstance( rec_shape, tuple) else (rec_shape, ) * 3 vol_geom = astra.creators.create_vol_geom( *reconstructed_shape, *[ sign * size / 2 * voxel_size for size in reconstructed_shape for sign in [-1, 1] ]) reconstruction_id = astra.data3d.create('-vol', vol_geom, data=0) alg_cfg = astra.astra_dict('FDK_CUDA') alg_cfg['ProjectionDataId'] = projections_id alg_cfg['ReconstructionDataId'] = reconstruction_id alg_cfg['option'] = {'ShortScan': False} algorithm_id = astra.algorithm.create(alg_cfg) astra.algorithm.run(algorithm_id) reconstruction = astra.data3d.get(reconstruction_id) # Free ressources astra.algorithm.delete(algorithm_id) astra.data3d.delete([projections_id, reconstruction_id]) return reconstruction
def single_test(self, geom_type, proj_type, alg, iters, vss, dss): if alg == 'FBP' and 'fanflat' in geom_type: self.skipTest('CPU FBP is parallel-beam only') is3D = (geom_type in ['parallel3d', 'cone']) for vg in VolumeGeometries(is3D, 'FDK' not in alg): for pg in ProjectionGeometries(geom_type): if not is3D: vol = np.zeros((128, 128), dtype=np.float32) vol[50:70, 50:70] = 1 else: vol = np.zeros((64, 64, 64), dtype=np.float32) vol[25:35, 25:35, 25:35] = 1 options = {} if vss > 1: options["VoxelSuperSampling"] = vss if dss > 1: options["DetectorSuperSampling"] = vss proj_id = astra.create_projector(proj_type, pg, vg, options=options) if not is3D: sino_id, sinogram = astra.create_sino(vol, proj_id) else: sino_id, sinogram = astra.create_sino3d_gpu(vol, pg, vg) if not is3D: DATA = astra.data2d else: DATA = astra.data3d rec_id = DATA.create('-vol', vg, 0.0 if 'EM' not in alg else 1.0) cfg = astra.astra_dict(alg) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id cfg['ProjectorId'] = proj_id alg_id = astra.algorithm.create(cfg) for i in range(iters): astra.algorithm.run(alg_id, 1) rec = DATA.get(rec_id) astra.astra.delete([sino_id, alg_id, alg_id, proj_id]) if not is3D: val = np.sum(rec[55:65, 55:65]) / 100. else: val = np.sum(rec[27:32, 27:32, 27:32]) / 125. TOL = 5e-2 if DISPLAY and abs(val - 1.0) >= TOL: print(geom_type, proj_type, alg, vg, pg) print(val) pylab.gray() if not is3D: pylab.imshow(rec) else: pylab.imshow(rec[:, 32, :]) pylab.show() self.assertTrue(abs(val - 1.0) < TOL)
def backward(self, proj_vector): """Backprojection.""" if self.geom.vol_ndim == 2: # Store projection data in ASTRA memory astra.data2d.store(self.proj_id, proj_vector.data.reshape( self.geom.angles.size, self.geom.det_col_count)) # Create algorithm object cfg = astra.astra_dict('BP_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.volume_id self.bp_id = astra.algorithm.create(cfg) # Run algorithms astra.algorithm.run(self.bp_id) # Retrieve projection from ASTRA memory return self.vol_space.element(self.scal_fac * np.ravel( astra.data2d.get(self.volume_id))) elif self.geom.vol_ndim == 3: # Store projection data in ASTRA memory astra.data3d.store(self.proj_id, proj_vector.data.reshape( self.geom.det_row_count, self.geom.angles.size, self.geom.det_col_count)) # Create algorithm object cfg = astra.astra_dict('BP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.volume_id self.bp_id = astra.algorithm.create(cfg) # Run algorithms astra.algorithm.run(self.bp_id) # Retrieve projection from ASTRA memory return self.vol_space.element(self.scal_fac * np.ravel( astra.data3d.get(self.volume_id)))
def reconstruct(self, sinogram, centre_of_rotation, angles, shape, center): ctr = centre_of_rotation width = sinogram.shape[1] pad = 50 sino = np.nan_to_num(sinogram) # pad the array so that the centre of rotation is in the middle alen = ctr blen = width - ctr mid = width / 2.0 if (ctr > mid): plow = pad phigh = (alen - blen) + pad else: plow = (blen - alen) + pad phigh = pad logdata = np.log(sino+1) sinogram = np.pad(logdata, ((0, 0), (int(plow), int(phigh))), mode='reflect') width = sinogram.shape[1] vol_geom = astra.create_vol_geom(shape[0], shape[1]) proj_geom = astra.create_proj_geom('parallel', 1.0, width, np.deg2rad(angles)) sinogram_id = astra.data2d.create("-sino", proj_geom, sinogram) # Create a data object for the reconstruction rec_id = astra.data2d.create('-vol', vol_geom) proj_id = astra.create_projector('strip', proj_geom, vol_geom) cfg = astra.astra_dict(self.parameters['reconstruction_type']) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['ProjectorId'] = proj_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # Run 20 iterations of the algorithm itterations = int(self.parameters['number_of_iterations']) # This will have a runtime in the order of 10 seconds. astra.algorithm.run(alg_id, itterations) # Get the result rec = astra.data2d.get(rec_id) # Clean up. astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) return rec
def check_recon(folder, alg, iterations, bin_num): raw_data = np.load(os.path.join(directory, folder, 'Data', 'data_corr.npy'))[:, :, :, 6] raw_data = np.transpose(raw_data, axes=(1, 0, 2)) # Transpose to (rows, angles, columns) # Change if isocentre is not directly in the center of the detector # raw_data = np.roll(raw_data, -2, axis=2) # Create a 3D projection geometry with our cone-beam data # Parameters: 'acquisition type', number of detector rows, number of detector columns, data ndarray proj_geom = astra.create_proj_geom('cone', pixel_pitch, pixel_pitch, det_row_count, det_col_count, angles, source_origin, origin_det) proj_id = astra.data3d.create('-proj3d', proj_geom, raw_data) # Create a 3D volume geometry. # Parameter order: rows, columns, slices (y, x, z) vol_geom = astra.create_vol_geom(det_col_count, det_col_count, det_row_count) # Create a data object for the reconstruction if alg == 'FDK_CUDA': recon_id = astra.data3d.create('-vol', vol_geom) else: ct_data = np.load(os.path.join(directory, folder, 'CT', 'FDK_CT.npy')) recon_id = astra.data3d.create('-vol', vol_geom, data=ct_data) # Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict(alg) cfg['ReconstructionDataId'] = recon_id cfg['ProjectionDataId'] = proj_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # Run the specified number of iterations of the algorithm rec_data = np.zeros((iterations // 5, 576, 576)) for i in range(0, iterations, 5): astra.algorithm.run(alg_id, 5) # Get the result rec = astra.data3d.get(recon_id)[11] print(alg[0:4] + f': {i + 5} Iterations') rec_data[i // 5] = rec np.save( os.path.join(directory, folder, 'CT', alg[0:4] + '_iteration_check.npy'), rec_data) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.algorithm.delete(alg_id) astra.data3d.delete(recon_id) astra.data3d.delete(proj_id)
def forward(self, vol_space_vector): """Forward projection.""" if self.geom.vol_ndim == 2: # Store volume data in ASTRA memory astra.data2d.store( self.volume_id, vol_space_vector.data.reshape(self.geom.vol_shape)) # Create algorithm object cfg = astra.astra_dict('FP_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['VolumeDataId'] = self.volume_id self.fp_id = astra.algorithm.create(cfg) # Run algorithm astra.algorithm.run(self.fp_id) # Retrieve projection data from ASTRA memory return self.proj_space.element( self.scal_fac * np.ravel(astra.data2d.get(self.proj_id))) elif self.geom.vol_ndim == 3: # Store volume data in ASTRA memory astra.data3d.store( self.volume_id, vol_space_vector.data.reshape(self.geom.vol_shape)) # Create algorithm object cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['VolumeDataId'] = self.volume_id self.fp_id = astra.algorithm.create(cfg) # Run algorithm astra.algorithm.run(self.fp_id) # Retrieve projection data from ASTRA memory return self.proj_space.element( self.scal_fac * np.ravel(astra.data3d.get(self.proj_id)))
def forward(self, vol_space_vector): """Forward projection.""" if self.geom.vol_ndim == 2: # Store volume data in ASTRA memory astra.data2d.store(self.volume_id, vol_space_vector.data.reshape( self.geom.vol_shape)) # Create algorithm object cfg = astra.astra_dict('FP_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['VolumeDataId'] = self.volume_id self.fp_id = astra.algorithm.create(cfg) # Run algorithm astra.algorithm.run(self.fp_id) # Retrieve projection data from ASTRA memory return self.proj_space.element(self.scal_fac * np.ravel( astra.data2d.get(self.proj_id))) elif self.geom.vol_ndim == 3: # Store volume data in ASTRA memory astra.data3d.store(self.volume_id, vol_space_vector.data.reshape( self.geom.vol_shape)) # Create algorithm object cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['VolumeDataId'] = self.volume_id self.fp_id = astra.algorithm.create(cfg) # Run algorithm astra.algorithm.run(self.fp_id) # Retrieve projection data from ASTRA memory return self.proj_space.element(self.scal_fac * np.ravel( astra.data3d.get(self.proj_id)))
def _fbp_id(self): """Create algorithms object of back-projection.""" geom_type = self.geom.geom_type.lower() if geom_type == 'parallel3d': return None cfg = None if geom_type in self.type2d: cfg = astra.astra_dict('FBP_CUDA') elif geom_type == 'cone': cfg = astra.astra_dict('FDK_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['ReconstructionDataId'] = self.vol_id return astra.algorithm.create(cfg)
def set_config(self, rec_id, sino_id, proj_geom, vol_geom): cfg = astra.astra_dict(self.alg) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id if 'FBP' in self.alg: cfg['FilterType'] = self.parameters['FBP_filter'] if 'projector' in self.parameters.keys(): proj_id = astra.create_projector(self.parameters['projector'], proj_geom, vol_geom) cfg['ProjectorId'] = proj_id cfg = self.set_options(cfg) return cfg
def do_AGD(meta, vecs, sc, g, niter): start = time.time() ang, u, v = g.shape g_vec = np.transpose(g.copy(), (2, 0, 1)) vox = 1024 // sc pix_size = meta['pix_size'] * sc src_rad = meta['s2o'] det_rad = meta['o2d'] magn = src_rad / (src_rad + det_rad) bounds = vox * pix_size * magn / 2 vol_geom = astra.create_vol_geom(vox, vox, vox, -bounds, bounds, -bounds, bounds, -bounds, bounds) proj_geom = astra.create_proj_geom('cone_vec', v, u, vecs) rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) # %% projector_id = astra.create_projector('cuda3d', proj_geom, vol_geom) # rec_id = astra.data3d.create('-vol', vol_geom) proj_id = astra.data3d.create('-proj3d', proj_geom, g_vec) astra.plugin.register(NesterovGradient.AcceleratedGradientPlugin) cfg_agd = astra.astra_dict('AGD-PLUGIN') cfg_agd['ProjectionDataId'] = proj_id cfg_agd['ReconstructionDataId'] = rec_id cfg_agd['ProjectorId'] = projector_id cfg_agd['option'] = {} cfg_agd['option']['MinConstraint'] = 0 alg_id = astra.algorithm.create(cfg_agd) # Run Nesterov Accelerated Gradient Descent algorithm with 'nb_iter' iterations astra.algorithm.run(alg_id, niter) rec = np.transpose(rec, (2, 1, 0)) # %% pylab.figure() pylab.imshow(rec[vox // 2, :, :]) pylab.figure() pylab.imshow(rec[:, vox // 2, :]) pylab.figure() pylab.imshow(rec[:, :, vox // 2]) # release memory allocated by ASTRA structures astra.algorithm.delete(alg_id) astra.data3d.delete(proj_id) astra.data3d.delete(rec_id) print((time.time() - start), 'Finished AGD 50 reconstructionn') return rec
def set_config(self, rec_id, sino_id, proj_geom, vol_geom): cfg = astra.astra_dict(self.alg) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id if 'FBP' in self.alg: fbp_filter = self.parameters['FBP_filter'] if 'FBP_filter' in \ self.parameters.keys() else 'none' cfg['FilterType'] = fbp_filter if 'projector' in self.parameters.keys(): proj_id = astra.create_projector( self.parameters['projector'], proj_geom, vol_geom) cfg['ProjectorId'] = proj_id cfg = self.set_options(cfg) return cfg
def run_algorithm(self, alg, n_it, data): rec_id = astra.data2d.create('-vol', self.vol_geom) sino_id = astra.data2d.create('-sino', self.proj_geom, data) cfg = astra.astra_dict(alg) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id alg_id = astra.algorithm.create(cfg) print("Running %s" %alg) astra.algorithm.run(alg_id, n_it) rec = astra.data2d.get(rec_id) astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sino_id) return rec
def cg_alg(proj_id, sid, vid): # CG algorithm cfg = astra.astra_dict('CG') cfg['ProjectorId'] = proj_id cfg['ProjectionDataId'] = sid cfg['ReconstructionDataId'] = vid cfg['option'] = {} alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, 100) rec = astra.data2d.get(vid) rec = np.flipud(rec) plt.imsave('rec_cg.png', rec, cmap = plt.cm.gray) save_one_image(rec, 'reconstruct', 'rec_cg_.png') astra.algorithm.delete(alg_id) return rec
def set_config(self, rec_id, sino_id, proj_geom, vol_geom): cfg = astra.astra_dict(self.alg) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id if 'FBP' in self.alg: cfg['FilterType'] = self.parameters['FBP_filter'] if 'projector' in self.parameters.keys(): proj_id = astra.create_projector( self.parameters['projector'], proj_geom, vol_geom) cfg['ProjectorId'] = proj_id # mask not currently working correctly for SIRT or SART algorithms sirt_or_sart = [a for a in ['SIRT', 'SART'] if a in self.alg] if self.mask_id and not sirt_or_sart: cfg['option'] = {} cfg['option']['ReconstructionMaskId'] = self.mask_id cfg = self.set_options(cfg) return cfg
def cp_alg(proj_id, sid, vid): # CP algorithm cfg = astra.astra_dict('CP') cfg['ProjectorId'] = proj_id cfg['ProjectionDataId'] = sid cfg['ReconstructionDataId'] = vid cfg['option'] = {} cfg['option']['its_PM'] = 150 cfg['option']['Lambda'] = 10000.0 alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, 100) rec = astra.data2d.get(vid) rec = np.flipud(rec) rec = rec.astype('float32') plt.imsave('rec_cp.png', rec, cmap = plt.cm.gray) save_one_image(rec, 'reconstruct', 'rec_cp_.png') astra.algorithm.delete(alg_id) return rec
def reconstruct3D(self, sinogram, angles, shape, depth, alg_name, iterations): det_rows = sinogram.shape[0] det_cols = sinogram.shape[2] # sinogram = np.transpose(sinogram, (2,1,0)) vol_geom = astra.create_vol_geom(shape[0], depth, shape[1]) proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, det_cols, \ det_rows, np.deg2rad(angles)) sinogram_id = astra.data3d.create("-sino", proj_geom, sinogram) # Create a data object for the reconstruction rec_id = astra.data3d.create('-vol', vol_geom) cfg = astra.astra_dict(alg_name) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # This will have a runtime in the order of 10 seconds. astra.algorithm.run(alg_id, iterations) #if "CUDA" in params[0] and "FBP" not in params[0]: #self.res += astra.algorithm.get_res_norm(alg_id)**2 #print math.sqrt(self.res) # Get the result rec = astra.data3d.get(rec_id) astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(sinogram_id) rec = rec[:160,:160,1] return rec
def forward(self, vol_vector=None): """Forward projection.""" # Store volume data in ASTRA memory if vol_vector is None: astra.data3d.store(self.volume_id, self.vol.data.reshape(self.geom.vol_shape)) else: astra.data3d.store(self.volume_id, vol_vector.data.reshape(self.geom.vol_shape)) # Create algorithm object cfg = astra.astra_dict('FP3D_CUDA') cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = self.proj_id cfg['VolumeDataId'] = self.volume_id self.fp_id = astra.algorithm.create(cfg) # Run algorithm astra.algorithm.run(self.fp_id) # Retrieve projection data from ASTRA memory self.proj.data[:] = np.ravel(astra.data3d.get(self.proj_id))
def run_all_experiment(proj_id, sid, vid, sino): cfg = astra.astra_dict('CP') cfg['ProjectorId'] = proj_id cfg['ProjectionDataId'] = sid cfg['ReconstructionDataId'] = vid cfg['option'] = {} cfg['option']['its_PM'] = 100 for i in np.arange(1.0, 1.01, 0.1): cfg['option']['Lambda'] = i alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, 100) rec = astra.data2d.get(vid) rec = np.flipud(rec) rec = rec.astype('float32') tv, l2 = calculate_error(proj_id, rec, sino) print 'tv rec: ', tv, 'l2 norm rec: ', l2 astra.algorithm.delete(alg_id) plt.imsave('rec_cp_Lamda_' + str(i) + '.png', rec, cmap = plt.cm.gray) save_one_image(rec, 'reconstruct', 'rec_cp_Lamda_' + str(i) + '_.png') return
def reconstruct2D(self, sinogram, angles, shape, alg_name, iterations): vol_geom = astra.create_vol_geom(shape[0], shape[1]) proj_geom = astra.create_proj_geom('parallel', 1.0, sinogram.shape[1], np.deg2rad(angles)) sinogram_id = astra.data2d.create("-sino", proj_geom, sinogram) # Create a data object for the reconstruction rec_id = astra.data2d.create('-vol', vol_geom) cfg = astra.astra_dict(alg_name) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id if not "CUDA" in alg_name: proj_id = astra.create_projector('strip', proj_geom, vol_geom) cfg['ProjectorId'] = proj_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # This will have a runtime in the order of 10 seconds. astra.algorithm.run(alg_id, iterations) if "CUDA" in alg_name and "FBP" not in alg_name: self.res += astra.algorithm.get_res_norm(alg_id)**2 print math.sqrt(self.res) # Get the result rec = astra.data2d.get(rec_id) astra.algorithm.delete(alg_id) astra.data2d.delete(rec_id) astra.data2d.delete(sinogram_id) return rec
def recon_multi_part(algon,proj_data,proj_data_low,det_move,angles,x_sub_boundaries,y_sub_boundaries,z_sub_boundaries,vol_size,det_spacing_x,det_spacing_y,x_subvol_width,y_subvol_width,z_subvol_width,n_x,n_y,n_z,nr_iterations_high,source_origin, origin_det,relaxation): # this part performs the reconstruction of the subvolume. pro_proj = proj_data - proj_data_low # we only want to have the projection data that comes from the sub volume det_row_count= pro_proj.shape[0] det_col_count=pro_proj.shape[2] vectors_ROI = np.zeros((len(angles), 12)) # this vector will contain the information of the source and detector position. move_x,move_y,move_z=how_to_move(x_sub_boundaries,y_sub_boundaries,z_sub_boundaries,vol_size,x_subvol_width,y_subvol_width,z_subvol_width,n_x,n_y,n_z) for i in range(0,len(angles)): # source vectors_ROI[i,0] = np.sin(angles[i]) * (source_origin) +move_x vectors_ROI[i,1] = -np.cos(angles[i]) * (source_origin) + move_y vectors_ROI[i,2] = move_z # center of detector vectors_ROI[i,3] = -np.sin(angles[i]) * (origin_det) + move_x vectors_ROI[i,4] = np.cos(angles[i]) * (origin_det) + move_y vectors_ROI[i,5] = move_z +det_move # vector from detector pixel 0 to 1 vectors_ROI[i,6] = np.cos(angles[i]) *det_spacing_x vectors_ROI[i,7] = np.sin(angles[i])*det_spacing_x vectors_ROI[i,8] = 0 # vector from detector pixel (0,0) to (1,0) vectors_ROI[i,9] = 0 vectors_ROI[i,10] = 0 vectors_ROI[i,11] = det_spacing_y #ROI=cube[:,:,z_sub_boundaries[n_z,0]:z_sub_boundaries[n_z+1,0]] # mlab.figure() # mlab.contour3d(ROI) width_z=z_sub_boundaries[n_z+1,2]-z_sub_boundaries[n_z,1] width_y=y_sub_boundaries[n_y+1,2]-y_sub_boundaries[n_y,1] width_x=x_sub_boundaries[n_x+1,2]-x_sub_boundaries[n_x,1] vol_geom_ROI= astra.create_vol_geom(width_y.astype(int), width_z.astype(int), width_x.astype(int)) proj_geom_ROI = astra.create_proj_geom('cone_vec', det_row_count, det_col_count, vectors_ROI) if algon[0:4] != 'EGEN': # Create a data object for the reconstruction rec_id_ROI = astra.data3d.create('-vol', vol_geom_ROI) sinogram_id_ROI = astra.data3d.create('-proj3d', proj_geom_ROI, pro_proj) if algon=='SIRT': algon='SIRT3D_CUDA' elif algon=='CGLS': algon='CGLS3D_CUDA' # Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict(algon) cfg['ReconstructionDataId'] = rec_id_ROI cfg['ProjectionDataId'] = sinogram_id_ROI cfg['option']={} cfg['option']['MinConstraint'] = 0 #attenuation coefficient can't be negative #cfg['option']['VoxelSuperSampling'] = np.round(float(det_spacing_x)/vol_size,decimals=2) alg_id = astra.algorithm.create(cfg) print "startar algo" if algon == 'SIRT3D_CUDA' or algon=='CGLS3D_CUDA': astra.algorithm.run(alg_id,nr_iterations_high) elif algon=='EGEN_SART': rec_volume=(width_x.astype(int), width_y.astype(int), width_z.astype(int)) rec_volume=np.zeros(rec_volume,dtype= np.float16) sides=[rec_volume.shape[0],rec_volume.shape[1],rec_volume.shape[2]] max_side=np.max(sides) print max_side h=relaxation*float(1)/(max_side)#0.00001 change to max size of y o z vectors=np.matrix('0 0 0 0 0 0 0 0 0 0 0 0',dtype= np.float16) for ii in range(0,nr_iterations_high): angles_ind = np.linspace(0, len(angles), len(angles),False) np.random.shuffle(angles_ind) #shuffle the projection angles to get faster convergence for jj in angles_ind: #proj_geom = astra.create_proj_geom('cone', det_spacing, det_spacing, det_size[1], det_size[1], angles[jj], source_to_origin_pixels,origin_to_detector_pixels) vectors[:,:]=vectors_ROI[jj,:] proj_geom_SART = astra.create_proj_geom('cone_vec', det_row_count, det_col_count, vectors) sinogram_id, proj_it = astra.create_sino3d_gpu(rec_volume, proj_geom_SART,vol_geom_ROI) proj_it=proj_it[:,0,:] residual=np.zeros((det_row_count,1,det_col_count)) residual[:,0,:]=proj_it-pro_proj[:,jj,:] astra.data3d.store(sinogram_id, residual) #h=0.001 [id, rec_volume_it] = astra.create_backprojection3d_gpu(residual, proj_geom_SART, vol_geom_ROI) rec_volume= rec_volume -h*rec_volume_it rec_volume=rec_volume*(rec_volume>0) astra.data3d.delete(id) astra.data3d.delete(sinogram_id) else: print"algorithm is not supported" print "s**t algo" if algon[0:4] != 'EGEN': # Get the result rec_sub_vol=astra.data3d.get(rec_id_ROI) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id_ROI) astra.data3d.delete(sinogram_id_ROI) return rec_sub_vol else: return rec_volume
def astra(*args): """ Reconstruct object using the ASTRA toolbox Extra options ---------- method : str ASTRA reconstruction method to use. num_iter : int, optional Number of algorithm iterations performed. proj_type : str, optional ASTRA projector type to use: 'line', 'linear', or 'strip' (CPU only). extra_options : dict, optional Extra options for the ASTRA config (i.e. those in cfg['option']) Warning ------- When using CUDA, only 1 CPU core can be used. Example ------- >>> import tomopy >>> obj = tomopy.shepp3d() # Generate an object. >>> ang = tomopy.angles(180) # Generate uniformly spaced tilt angles. >>> sim = tomopy.project(obj, ang) # Calculate projections. >>> >>> # Reconstruct object: >>> rec = tomopy.recon(sim, ang, algorithm=tomopy.astra, >>> options={'method':'SART', 'num_iter':10*180, 'proj_type':'linear', >>> 'extra_options':{'MinConstraint':0}}) >>> >>> # Show 64th slice of the reconstructed object. >>> import pylab >>> pylab.imshow(rec[64], cmap='gray') >>> pylab.show() """ # Lazy import ASTRA import astra as astra_mod # Get shared arrays tomo = mproc.SHARED_TOMO recon = mproc.SHARED_ARRAY # Unpack arguments nang = args[0] nslices = args[1] ndet = args[2] centers = args[3] angles = args[4] num_gridx = args[5]['num_gridx'] num_gridy = args[5]['num_gridy'] opts = args[5]['options'] istart = args[6] iend = args[7] # Check options for o in needed_options['astra']: if not o in opts: logger.error("Option %s needed for ASTRA reconstruction." % (o,)) raise ValueError() for o in default_options['astra']: if not o in opts: opts[o] = default_options['astra'][o] # Create ASTRA geometries vol_geom = astra_mod.create_vol_geom((num_gridx,num_gridy)) proj_geom = astra_mod.create_proj_geom('parallel',1.0,ndet,angles.astype(np.float64)) # Create ASTRA data id sino = np.zeros((nang, ndet), dtype=np.float32) # Create ASTRA config cfg = astra_mod.astra_dict(opts['method']) if opts['proj_type']!='cuda': pi = astra_mod.create_projector(opts['proj_type'], proj_geom, vol_geom) sid = astra_mod.data2d.link('-sino', proj_geom, sino) cfg['ProjectorId'] = pi cfg['ProjectionDataId'] = sid use_cuda=False else: use_cuda=True if 'extra_options' in opts: cfg['option'] = opts['extra_options'] else: cfg['option'] = {} # Perform reconstruction for i in xrange(istart, iend): sino[:] = tomo[:,i,:] cfg['option']['z_id']=i # Fix center of rotation if use_cuda: proj_geom['option'] = {'ExtraDetectorOffset': (centers[i]-ndet/2.)*np.ones(nang)} sid = astra_mod.data2d.link('-sino', proj_geom, sino) cfg['ProjectionDataId'] = sid pi = astra_mod.create_projector(opts['proj_type'], proj_geom, vol_geom) cfg['ProjectorId'] = pi else: # Temporary workaround, will be fixed in later ASTRA version shft = int(np.round(ndet/2.-centers[i])) sino[:] = np.roll(sino,shft) l = shft r = sino.shape[1]+shft if l<0: l=0 if r>sino.shape[1]: r=sino.shape[1] sino[:,0:l]=0 sino[:,r:sino.shape[1]]=0 vid = astra_mod.data2d.link('-vol', vol_geom, recon[i]) cfg['ReconstructionDataId'] = vid alg_id = astra_mod.algorithm.create(cfg) astra_mod.algorithm.run(alg_id, opts['num_iter']) astra_mod.algorithm.delete(alg_id) astra_mod.data2d.delete(vid) if use_cuda: astra_mod.projector.delete(pi) astra_mod.data2d.delete(sid) # Clean up if not use_cuda: astra_mod.projector.delete(pi) astra_mod.data2d.delete(sid)
proj_id = astra.create_projector('line',proj_geom,vol_geom) sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True) pylab.figure(2) pylab.imshow(P) pylab.figure(3) pylab.imshow(sinogram) # Create a data object for the reconstruction rec_id = astra.data2d.create('-vol', vol_geom) # Create a data object for the mask mask_id = astra.data2d.create('-vol', vol_geom, mask) # Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict('SIRT_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['option'] = {} cfg['option']['ReconstructionMaskId'] = mask_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # Run 150 iterations of the algorithm astra.algorithm.run(alg_id, 150) # Get the result rec = astra.data2d.get(rec_id) pylab.figure(4)
def _apply(self, projections, volume): """ Apply back projector. Parameters ---------- projections : RNVector RNVector of dimension self.range.n which contains the projection data (sinogram). volume_data : RNVector RNVector of dimension self.domain.n onto which the projection will be projected back. Examples -------- >>> num_voxel = (100, 100, 100) >>> det_row_count = 100 >>> det_col_count = 100 >>> angles = np.linspace(0, 2 * np.pi, 180, endpoint=False) >>> phantom = Cuboid(shape=num_voxel).data # <class 'RL.space.euclidean.RN'> >>> rn = Rn(phantom.size) # <class 'RL.space.euclidean.Vector'> >>> rn_phantom = rn.element(phantom.ravel()) # <class 'astra.ForwardProjector'> >>> fp = ForwardProjector(num_voxel=num_voxel, \ det_row_count=det_row_count, det_col_count=det_col_count, \ angles=angles) # <class 'RL.space.euclidean.Vector'> >>> rn_proj = fp(rn_phantom) >>> bp = BackwardProjector(num_voxel=num_voxel,\ det_row_count=det_row_count, det_col_count=det_col_count, \ angles=angles) >>> type(bp) <class 'pyastra.BackwardProjector'> # <class 'RL.space.euclidean.Vector'> >>> rn_rec = bp(rn_proj) >>> rec = np.reshape(rn_rec.data, num_voxel) >>> rec.shape (100, 100, 100) """ # Create volume geometry vol_geom = astra.create_vol_geom(self.num_voxel) # Create projection geometry proj_geom = astra.create_proj_geom( self.geometry_type, self.detector_spacing_x, self.detector_spacing_y, self.det_row_count, self.det_col_count, self.angles, self.source_origin, self.origin_detector) # Allocate ASTRA memeory and store projection data in it proj_id = astra.data3d.create( '-sino', proj_geom, projections.data.reshape( self.det_row_count, self.angles.size, self.det_col_count)) # proj_data = np.reshape( # np.ravel(projections.data), # (self.det_row_count, self.angles.size, self.det_col_count)) # proj_id = astra.data3d.create('-sino', proj_geom, proj_data) # Allocate ASTRA memory for volume data volume_id = astra.data3d.create('-vol', vol_geom, 0) # Create algorithm object cfg = astra.astra_dict(self.alg_string) cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = proj_id cfg['ReconstructionDataId'] = volume_id alg_id = astra.algorithm.create(cfg) # Run algorithms # with(Timer("Projection")): astra.algorithm.run(alg_id) # Retrieve projection from ASTRA memory volume.data[:] = np.ravel(astra.data3d.get(volume_id)) # Free ASTRA memory astra.data3d.delete(volume_id) astra.data3d.delete(proj_id) astra.algorithm.delete(alg_id)
import s018_plugin # Then, we register the plugin class with ASTRA astra.plugin.register(s018_plugin.LandweberPlugin) # Get a list of registered plugins six.print_(astra.plugin.get_registered()) # To get help on a registered plugin, use get_help six.print_(astra.plugin.get_help('LANDWEBER-PLUGIN')) # Create data structures sid = astra.data2d.create('-sino', proj_geom, sinogram) vid = astra.data2d.create('-vol', vol_geom) # Create config using plugin name cfg = astra.astra_dict('LANDWEBER-PLUGIN') cfg['ProjectorId'] = proj_id cfg['ProjectionDataId'] = sid cfg['ReconstructionDataId'] = vid # Create algorithm object alg_id = astra.algorithm.create(cfg) # Run algorithm for 100 iterations astra.algorithm.run(alg_id, 100) # Get reconstruction rec = astra.data2d.get(vid) # Options for the plugin go in cfg['option'] cfg = astra.astra_dict('LANDWEBER-PLUGIN')
def make_reconsruction(proj_data,number_of_projections,vol_size_ratio,det_size,rec_volume,source_to_origin_pixels,origin_to_detector_pixels,nr_iterations,algo,relaxation,initializer): vol_geom = astra.create_vol_geom(rec_volume) angles = np.linspace(0, 2*np.pi, number_of_projections, False) det_spacing=np.round((float(det_size[0])/det_size[1])/vol_size_ratio,decimals=3) proj_geom = astra.create_proj_geom('cone', det_spacing, det_spacing, det_size[1], det_size[1], angles, source_to_origin_pixels,origin_to_detector_pixels) #np.round(float(rec_volume[0])/new_size[0],decimals=2) if algo[0:4] != 'EGEN': # Create projection data from this proj_id=4 # Create a data object for the reconstruction rec_id = astra.data3d.create('-vol', vol_geom,initializer) sinogram_id = astra.data3d.create('-proj3d', proj_geom, proj_data) #Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict(algo) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['option']={} cfg['option']['MinConstraint'] = 0 #attenuation coefficient can't be negative # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) print "startar algo" if algo == 'SIRT3D_CUDA' or algo=='CGLS3D_CUDA': astra.algorithm.run(alg_id,nr_iterations) elif algo=='FDK_CUDA': astra.algorithm.run(alg_id) elif algo=='EGEN_SIRT': if isinstance( initializer, ( int, long ) ): rec_volume=np.zeros(rec_volume,dtype= np.float16) else: rec_volume=initializer for ii in range(0,nr_iterations): sinogram_id, proj_it = astra.create_sino3d_gpu(rec_volume, proj_geom,vol_geom) residual=proj_it-proj_data h=relaxation*float(1)/(rec_volume.shape[0]*number_of_projections) [id, rec_volume_it] = astra.create_backprojection3d_gpu(residual, proj_geom, vol_geom) rec_volume= rec_volume -h*rec_volume_it rec_volume=rec_volume*(rec_volume>0) astra.data3d.delete(id) astra.data3d.delete(sinogram_id) elif algo=='EGEN_SART': if isinstance( initializer, ( int, long ) ): rec_volume=np.zeros(rec_volume,dtype= np.float16) else: rec_volume=initializer #print rec_volume.shape[0] for ii in range(0,nr_iterations): angles_ind = np.linspace(0, number_of_projections, number_of_projections,False) np.random.shuffle(angles_ind) for jj in angles_ind: proj_geom = astra.create_proj_geom('cone', det_spacing, det_spacing, det_size[1], det_size[1], angles[jj], source_to_origin_pixels,origin_to_detector_pixels) #print np.min(sub_volume_high) sinogram_id, proj_it = astra.create_sino3d_gpu(rec_volume, proj_geom,vol_geom) proj_it=proj_it[:,0,:] residual=np.zeros((det_size[1],1,det_size[1])) residual[:,0,:]=proj_it-proj_data[:,jj,:] #print np.shape(proj_it),np.shape(residual),np.shape(proj_data[:,jj,:]) #astra.data3d.store(sinogram_id, residual) h=relaxation*float(1)/(rec_volume.shape[0])#0.00001 [id, rec_volume_it] = astra.create_backprojection3d_gpu(residual, proj_geom, vol_geom) rec_volume= rec_volume -h*rec_volume_it rec_volume=rec_volume*(rec_volume>0) astra.data3d.delete(id) astra.data3d.delete(sinogram_id) # pylab.figure() # pylab.gray() # pylab.imshow(rec_volume[:,:,128]) else: print"algorithm is not supported" print "s**t algo" if algo[0:4] != 'EGEN': # Get the result rec = astra.data3d.get(rec_id) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(proj_id) astra.data3d.delete(sinogram_id) return rec else: return rec_volume
def _apply(self, volume, projections): """Apply forward projector. Parameters ---------- volume_data : RNVector RNVector of dimension self.domain.n which contains the data be projected. projections : RNVector RNVector of dimension self.range.n the projections are written to. Examples -------- >>> num_voxel = (100, 100, 100) #>>> phantom = Cuboid(shape=num_voxel).data >>> phantom = np.zeros(num_voxel) # <class 'RL.space.euclidean.RN'> >>> rn = Rn(phantom.size) # <class 'RL.space.euclidean.Vector'> >>> rn_phantom = rn.element(phantom.flatten()) # <class 'astra.ForwardProjector'> >>> fp = ForwardProjector(num_voxel=num_voxel) # <class 'RL.space.euclidean.Vector'> >>> rn_proj = fp(rn_phantom) >>> proj = np.reshape(rn_proj.data, (100, 180, 100)) >>> proj.shape (100, 180, 100) """ # Create volume geometry vol_geom = astra.create_vol_geom(self.num_voxel) # Create projection geometry proj_geom = astra.create_proj_geom( self.geometry_type, self.detector_spacing_x, self.detector_spacing_y, self.det_row_count, self.det_col_count, self.angles, self.source_origin, self.origin_detector) # Allocate and store volume data in ASTRA memory volume_id = astra.data3d.create( '-vol', vol_geom, volume.data.reshape(self.num_voxel)) # Allocate ASTRA memeory for projection data proj_id = astra.data3d.create('-sino', proj_geom, 0) # Create algorithm object cfg = astra.astra_dict(self.alg_string) cfg['option'] = {'GPUindex': self.gpu_index} cfg['ProjectionDataId'] = proj_id cfg['VolumeDataId'] = volume_id alg_id = astra.algorithm.create(cfg) # Run algorithms # with(Timer("Projection")): astra.algorithm.run(alg_id) # Retrieve projection from ASTRA memory projections.data[:] = np.ravel(astra.data3d.get(proj_id)) # Free ASTRA memory astra.data3d.delete(volume_id) astra.data3d.delete(proj_id) astra.algorithm.delete(alg_id)
def conebeam_test(data_obj=ctdata.Data(), alg_type='fdk', num_iterations=10, padding=None, scale_factor=1, vol_init=None, gpu_index=0, num_voxel=None): """Test conebeam reconstruction of ASTRA. conebeam_sim() """ t = time.time() # Default arguments if not num_voxel: num_voxel = [100, 100, 100] if not padding: padding = 0 if scale_factor: pass # Extract paramaters from data class detector_spacing_x = 1 detector_spacing_y = 1 det_row_count = data_obj.shape[0] det_col_count = data_obj.shape[2] + 2 * padding angles_rad = data_obj.angles__rad source_origin = data_obj.distance_source_origin__mm source_det = data_obj.distance_source_detector__mm # Create volume geometry vol_geom = astra.create_vol_geom(*num_voxel) # Create projection geometry proj_geom = astra.create_proj_geom('cone', detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles_rad, source_origin, source_det) # Create a sinogram from phantom sinogram = np.pad(data_obj.projections, ((0, 0), (0, 0), (padding, padding)), mode='edge') sino_id = astra.data3d.create('-sino', proj_geom, sinogram) # Set up the parameters for a reconstruction algorithm using the GPU rec_id = astra.data3d.create('-vol', vol_geom, vol_init) alg_type += '_CUDA' alg_type = alg_type.upper() cfg = astra.astra_dict(alg_type) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sino_id # Use GPU cfg['option'] = {} cfg['option']['GPUindex'] = gpu_index # Iterate algorithm alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id, num_iterations) rec_vol = astra.data3d.get(rec_id) print("Algorithm: %s" % cfg['type']) print("Elapsed time: %g s" % (time.time() - t)) # Clean up. astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(sino_id) return rec_vol, sinogram