示例#1
0
    def process(self, out=None):

        DATA = self.get_input()

        pad = False
        if len(DATA.shape) == 2:
            #for 2D cases
            pad = True
            data_temp = numpy.expand_dims(DATA.as_array(), axis=0)
        else:
            data_temp = DATA.as_array()

        rec_id, arr_out = astra.create_backprojection3d_gpu(
            data_temp, self.proj_geom, self.vol_geom)

        astra.data3d.delete(rec_id)

        if pad is True:
            arr_out = numpy.squeeze(arr_out, axis=0)

        if out is None:
            out = ImageData(arr_out,
                            deep_copy=False,
                            geometry=self.volume_geometry.copy(),
                            suppress_warning=True)
            return out
        else:
            out.fill(arr_out)
示例#2
0
    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
示例#3
0
    def backward(ctx, grad_out):
        astra.set_gpu_index([grad_out.device.index],
                            memory=10 * 1024 * 1024 * 1024)

        grad_input = gradProjSize = gradVectors = None

        if ctx.needs_input_grad[0]:
            # permute here to handle opposite data layouts
            bproj_id, bproj_data = astra.create_backprojection3d_gpu(
                grad_out.squeeze(1).permute(2, 0, 1).data.cpu().numpy(),
                ctx.proj_geom, ctx.vol_geom)
            astra.data3d.delete(bproj_id)
            grad_input = Tensor(bproj_data).cuda(non_blocking=True).permute(
                2, 1, 0)

        return grad_input, gradProjSize, gradVectors
示例#4
0
    def single_test_adjoint3D(self, geom_type, proj_type):
        for vg in VolumeGeometries(True, True):
            for pg in ProjectionGeometries(geom_type):
                for i in range(5):
                    X = np.random.random(astra.geom_size(vg))
                    Y = np.random.random(astra.geom_size(pg))
                    proj_id, fX = astra.create_sino3d_gpu(X, pg, vg)
                    bp_id, fTY = astra.create_backprojection3d_gpu(Y, pg, vg)

                    astra.data3d.delete([proj_id, bp_id])

                    da = np.dot(fX.ravel(), Y.ravel())
                    db = np.dot(X.ravel(), fTY.ravel())
                    m = np.abs(da - db)
                    TOL = 1e-1
                    if m / da >= TOL:
                        print(vg)
                        print(pg)
                        print(m / da, da / db, da, db)
                    self.assertTrue(m / da < TOL)
import numpy as np

# Set up multi-GPU usage.
# This only works for 3D GPU forward projection and back projection.
astra.astra.set_gpu_index([0,1])

# Optionally, you can also restrict the amount of GPU memory ASTRA will use.
# The line commented below sets this to 1GB.
#astra.astra.set_gpu_index([0,1], memory=1024*1024*1024)

vol_geom = astra.create_vol_geom(1024, 1024, 1024)

angles = np.linspace(0, np.pi, 1024,False)
proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, 1024, 1024, angles)

# Create a simple hollow cube phantom
cube = np.zeros((1024,1024,1024))
cube[128:895,128:895,128:895] = 1
cube[256:767,256:767,256:767] = 0

# Create projection data from this
proj_id, proj_data = astra.create_sino3d_gpu(cube, proj_geom, vol_geom)

# Backproject projection data
bproj_id, bproj_data = astra.create_backprojection3d_gpu(proj_data, proj_geom, vol_geom)

# Clean up. Note that GPU memory is tied up in the algorithm object,
# and main RAM in the data objects.
astra.data3d.delete(proj_id)
astra.data3d.delete(bproj_id)
示例#6
0
 def backprojOS(self, proj_data, no_os):
     """Applying back-projection to a specific subset"""
     rec_id, object3D = astra.create_backprojection3d_gpu(
         proj_data, self.proj_geom_OS[no_os], self.vol_geom)
     astra.data3d.delete(rec_id)
     return object3D
示例#7
0
 def backproj(self, proj_data):
     """Applying backprojection"""
     rec_id, object3D = astra.create_backprojection3d_gpu(
         proj_data, self.proj_geom, self.vol_geom)
     astra.data3d.delete(rec_id)
     return object3D
示例#8
0
# Set up multi-GPU usage.
# This only works for 3D GPU forward projection and back projection.
astra.set_gpu_index([0, 1])

# Optionally, you can also restrict the amount of GPU memory ASTRA will use.
# The line commented below sets this to 1GB.
#astra.set_gpu_index([0,1], memory=1024*1024*1024)

vol_geom = astra.create_vol_geom(1024, 1024, 1024)

angles = np.linspace(0, np.pi, 1024, False)
proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, 1024, 1024, angles)

# Create a simple hollow cube phantom
cube = np.zeros((1024, 1024, 1024))
cube[128:895, 128:895, 128:895] = 1
cube[256:767, 256:767, 256:767] = 0

# Create projection data from this
proj_id, proj_data = astra.create_sino3d_gpu(cube, proj_geom, vol_geom)

# Backproject projection data
bproj_id, bproj_data = astra.create_backprojection3d_gpu(
    proj_data, proj_geom, vol_geom)

# Clean up. Note that GPU memory is tied up in the algorithm object,
# and main RAM in the data objects.
astra.data3d.delete(proj_id)
astra.data3d.delete(bproj_id)
示例#9
0
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 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
示例#11
0
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