Esempio n. 1
0
 def matvec(self, v):
     sid, s = astra.create_sino(
         np.reshape(v,
                    (vol_geom['GridRowCount'], vol_geom['GridColCount'])),
         self.proj_id)  # , useCUDA=True)
     astra.data2d.delete(sid)
     return s.flatten()
Esempio n. 2
0
 def matvec(self, v):
     sid, s = astra.create_sino(
         np.reshape(v,
                    (vol_geom['GridRowCount'], vol_geom['GridColCount'])),
         self.proj_id)
     astra.data2d.delete(sid)
     return s.ravel()
Esempio n. 3
0
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)
Esempio n. 4
0
 def forwprojOS(self, image, no_os):
     """Applying forward projection for a specific subset"""
     sinogram_id, sinogram = astra.create_sino(image,
                                               self.proj_id_OS[no_os])
     astra.data2d.delete(sinogram_id)
     astra.data2d.delete(self.proj_id_OS[no_os])
     return sinogram
 def K(x: np.array) -> np.array:
     # Create sinogram.
     proj_id = astra.create_projector(proj_type, proj_geom, vol_geom)
     sino_id, sino = astra.create_sino(x, proj_id)
     astra.data2d.delete(sino_id)
     astra.projector.delete(proj_id)
     return sino
    def forward(self, x):
        Y = np.empty((x.shape[0], len(self.angles), x.shape[1]), dtype=np.float32)

        for i in range(x.shape[0]):
            pid, Y[i] = astra.create_sino(x[i], self.proj_id)
            self.data2d.append(pid)

        return Y
Esempio n. 7
0
    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)
Esempio n. 8
0
    def forward_single(self, x):
        vol_geom = astra.create_vol_geom(x.shape[0], x.shape[1])
        proj_geom = astra.create_proj_geom('parallel', 1.0, x.shape[0],
                                           self.angles)
        proj_id = astra.create_projector('cuda', proj_geom, vol_geom)

        self.projectors.append(proj_id)

        return astra.create_sino(x, proj_id)
Esempio n. 9
0
    def forward(self, x):
        device = x.device
        x = x.cpu().numpy()
        Y = np.empty((x.shape[0], len(self.angles), x.shape[1]), dtype=np.float32)

        for i in range(x.shape[0]):
            _, Y[i] = astra.create_sino(x[i], self.proj_id)

        return torch.from_numpy(Y).to(device)
Esempio n. 10
0
def test_fanbeam_error(device, batch_size, image_size, angles, spacing,
                       distances, det_count, clip_to_circle):
    # generate random images
    # generate random images
    det_count = int(det_count * image_size)
    mask_radius = det_count / 2.0 if clip_to_circle else -1
    x = generate_random_images(1, image_size, mask_radius)[0]

    s_dist, d_dist = distances
    s_dist *= image_size
    d_dist *= image_size

    # astra
    vol_geom = astra.create_vol_geom(x.shape[0], x.shape[1])
    proj_geom = astra.create_proj_geom('fanflat', spacing, det_count, angles,
                                       s_dist, d_dist)
    proj_id = astra.create_projector('cuda', proj_geom, vol_geom)

    id, astra_y = astra.create_sino(x, proj_id)
    _, astra_bp = astra.create_backprojection(astra_y, proj_id)
    if clip_to_circle:
        astra_bp *= circle_mask(image_size, mask_radius)

    # TODO clean astra structures

    # our implementation
    radon = RadonFanbeam(image_size,
                         angles,
                         s_dist,
                         d_dist,
                         det_count=det_count,
                         det_spacing=spacing,
                         clip_to_circle=clip_to_circle)
    x = torch.FloatTensor(x).to(device).view(1, x.shape[0], x.shape[1])
    # repeat data to fill batch size
    x = torch.cat([x] * batch_size, dim=0)

    our_fp = radon.forward(x)
    our_bp = radon.backprojection(our_fp)

    forward_error = relative_error(astra_y, our_fp[0].cpu().numpy())
    back_error = relative_error(astra_bp, our_bp[0].cpu().numpy())

    # if back_error > 5e-3:
    #     plt.imshow(astra_bp)
    #     plt.figure()
    #     plt.imshow(our_bp[0].cpu().numpy())
    #     plt.show()
    print(np.max(our_fp.cpu().numpy()), np.max(our_bp.cpu().numpy()))

    print(
        f"batch: {batch_size}, size: {image_size}, angles: {len(angles)}, spacing: {spacing}, distances: {distances} circle: {clip_to_circle}, forward: {forward_error}, back: {back_error}"
    )
    # TODO better checks
    assert_less(forward_error, 1e-2)
    assert_less(back_error, 5e-3)
Esempio n. 11
0
def _basic_par2d_fp(type):
  import astra
  import numpy as np
  vg = astra.create_vol_geom(2, 32)
  pg = astra.create_proj_geom('parallel', 1, 32, [0])
  proj_id = astra.create_projector(type, pg, vg)
  vol = np.random.rand(2, 32)
  (sino_id, sino) = astra.create_sino(vol, proj_id)
  astra.data2d.delete(sino_id)
  astra.projector.delete(proj_id)
  err = np.max(np.abs(sino[0,:] - np.sum(vol,axis=0)))
  return err < 1e-6
Esempio n. 12
0
def _basic_par2d_fp(type):
    import astra
    import numpy as np
    vg = astra.create_vol_geom(2, 32)
    pg = astra.create_proj_geom('parallel', 1, 32, [0])
    proj_id = astra.create_projector(type, pg, vg)
    vol = np.random.rand(2, 32)
    (sino_id, sino) = astra.create_sino(vol, proj_id)
    astra.data2d.delete(sino_id)
    astra.projector.delete(proj_id)
    err = np.max(np.abs(sino[0, :] - np.sum(vol, axis=0)))
    return err < 1e-6
Esempio n. 13
0
def proj(img, num_sen, sen_width, theta):
    shape = img.shape
    if not len(shape) == 2:
        raise ValueError('Invalid img shape {}.'.format(shape))
    vol_geom = astra.create_vol_geom(*shape)
    proj_geom = astra.create_proj_geom('parallel', sen_width, num_sen, theta)
    proj_id = astra.create_projector('cuda', proj_geom, vol_geom)
    sinogram_id, sinogram = astra.create_sino(img, proj_id)
    sinogram = np.array(sinogram)
    astra.data2d.clear()
    astra.projector.clear()
    astra.algorithm.clear()
    return sinogram
Esempio n. 14
0
def project(image, 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, vol_geom)
    sinogram_id, sino = astra.create_sino(image, proj_id) 
    astra.data2d.delete(sinogram_id)
    sinogram = copy.deepcopy(sino)
    return sinogram
Esempio n. 15
0
def sinogram(p, r, n, poisson_noise=False, s_and_p_noise = False, gaussian_noise = False, prob=10**-2, val=None, mean =0, std=None):
    # Create geometries and projector
    #adds noise to sinogram too 
    # p is phantom
    # r is range of angles eg pi
    # n is number of angles used
    #prob : float, optional
            #Independent probability that each element of a pixel might be
            #corrupted by the salt and pepper type noise.
    #val : float, optional
           #Value to be assigned to the corrupted pixels.
    
    projector_id = geom_setup(p.shape[0], r, n)[1]
    
    # Create sinogram.
    sinogram = astra.create_sino(p, projector_id)[1]
    #Noise section is 95% copied from tomopy 
    #https://tomopy.readthedocs.io/en/latest/_modules/tomopy/sim/project.html
    
    #if poisson_noise == True:
        #sinogram = np.random.poisson(sinogram)
    
        #return sinogram
    
        #sinogram = np.random.poisson(sinogram * 10000) / 10000
        #sinogram[sinogram > 1.1] = 1.1
        #sinogram /= 1.1

    
    if s_and_p_noise == True:
    
        dx, dy = sinogram.shape
        ind = np.random.rand(dx, dy) < prob
        if val is None:
            val = sinogram.max()
            sinogram[ind] = val
            return sinogram
        else:
            sinogram[ind] = val


    
    if gaussian_noise == True:
        #sinogram = np.ndarray.dtype.as_ndarray(sinogram)       
        
        if std is None:
            std = sinogram.max() * 0.5
        dx, dy = sinogram.shape
        sinogram += std * np.random.randn(dx, dy)  + mean
    return sinogram
Esempio n. 16
0
def fanflat_simulation(dectors_numbers, matrix_data):

    vol_geom = astra.create_vol_geom(256, 256)
    proj_geom = astra.create_proj_geom('fanflat_vec', dectors_numbers, matrix_data)

    # As before, create a sinogram from a phantom
    import scipy.io
    P = scipy.io.loadmat('phantom.mat')['phantom256']
    proj_id = astra.create_projector('line_fanflat', proj_geom, vol_geom) #TODO: fix that, maybe in cuda works
    sinogram_id, sinogram = astra.create_sino(P, proj_id)

    import pylab
    pylab.gray()
    pylab.figure(1)
    pylab.imshow(P)
    pylab.figure(2)
    pylab.imshow(sinogram)

    # Create a data object for the reconstruction
    rec_id = astra.data2d.create('-vol', vol_geom)

    # create configuration
    cfg = astra.astra_dict('FBP')
    cfg['ReconstructionDataId'] = rec_id
    cfg['ProjectionDataId'] = sinogram_id
    cfg['ProjectorId'] = proj_id
    cfg['option'] = { 'FilterType': 'Ram-Lak' }

    # possible values for FilterType:
    # none, ram-lak, shepp-logan, cosine, hamming, hann, tukey, lanczos,
    # triangular, gaussian, barlett-hann, blackman, nuttall, blackman-harris,
    # blackman-nuttall, flat-top, kaiser, parzen


    # 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)
    pylab.figure(3)
    pylab.imshow(rec)
    pylab.show()

    # 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.data2d.delete(rec_id)
    astra.data2d.delete(sinogram_id)
    astra.projector.delete(proj_id)
    def process(self, out=None):

        IM = self.get_input()
        sinogram_id, arr_out = astra.create_sino(IM.as_array(), self.proj_id)
        astra.data2d.delete(sinogram_id)

        if out is None:
            out = AcquisitionData(arr_out,
                                  deep_copy=False,
                                  geometry=self.sinogram_geometry.copy(),
                                  suppress_warning=True)
            return out
        else:
            out.fill(arr_out)
Esempio n. 18
0
def fp(image, projector_id):
    """Wrapper for astra forward projector

    :param image:
    :param projector_id:
    :return: sinogram
    """
    sino_id, sino = astra.create_sino(image, projector_id)
    sino *= voxel_size_mm

    sino /= sino.shape[0]

    astra.data2d.delete(sino_id)

    return sino
Esempio n. 19
0
def fp(image, projector_id):
    """Wrapper for astra forward projector

    :param image:
    :param projector_id:
    :return: sinogram
    """
    sino_id, sino = astra.create_sino(image, projector_id)
    sino *= voxel_size_mm

    sino /= sino.shape[0]

    astra.data2d.delete(sino_id)

    return sino
Esempio n. 20
0
    def process(self, out=None):
        IM = self.get_input()

        if out is None:
            DATA = self.sinogram_geometry.allocate(None)
        else:
            DATA = out

        for k in range(DATA.geometry.channels):
            vol_temp = IM.as_array()[k]
            sinogram_id, DATA.as_array()[k] = astra.create_sino(
                vol_temp, self.proj_id)
            astra.data2d.delete(sinogram_id)

        if out is None:
            return DATA
Esempio n. 21
0
    def process(self):
        IM = self.get_input()
        DATA = AcquisitionData(geometry=self.sinogram_geometry)
        #sinogram_id, DATA = astra.create_sino( IM.as_array(),
        #                           self.proj_id)
        sinogram_id, DATA.array = astra.create_sino(IM.as_array(),
                                                    self.proj_id)
        astra.data2d.delete(sinogram_id)

        if self.device == 'cpu':
            return DATA
        else:
            if self.sinogram_geometry.geom_type == 'cone':
                return DATA
            else:
                scaling = 1.0 / self.volume_geometry.voxel_size_x
                return scaling * DATA
Esempio n. 22
0
def astra_project(obj, angles, cuda=False):
    """
    Calculate projection of a 3D object using Astra-toolbox.

    Args
    ----------
    obj : NumPy array
        Either a 2D or 3D array containing the object to project.
        If 2D, the structure is of the form [z, x] where z is the
        projection axis.  If 3D, the strucutre is [y, z, x] where y is
        the tilt axis.
    angles : list or NumPy array
        The projection angles in degrees
    cuda : boolean
        If True, perform reconstruction using the GPU-accelerated algorithm.

    Returns
    ----------
    sino : Numpy array
        3D array of the form [y, angle, x] containing the projection of
        the input object

    """
    if len(obj.shape) == 2:
        obj = np.expand_dims(obj, 0)
    thetas = np.pi * angles / 180.
    y_pix, thickness, x_pix = obj.shape
    if cuda:
        vol_geom = astra.create_vol_geom(thickness, x_pix, y_pix)
        proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, y_pix,
                                           x_pix, thetas)
        sino_id, sino = astra.create_sino3d_gpu(obj, proj_geom, vol_geom)
        astra.data3d.delete(sino_id)
    else:
        sino = np.zeros([y_pix, len(angles), x_pix], np.float32)
        vol_geom = astra.create_vol_geom(thickness, x_pix)
        proj_geom = astra.create_proj_geom('parallel', 1.0, x_pix, thetas)
        proj_id = astra.create_projector('strip', proj_geom, vol_geom)
        for i in range(0, y_pix):
            sino_id, sino[i, :, :] = astra.create_sino(obj[i, :, :], proj_id,
                                                       vol_geom)
        astra.data2d.delete(sino_id)

    sino = np.rollaxis(sino, 1)
    return sino
Esempio n. 23
0
    def process(self):
        IM = self.get_input()
        #create the output AcquisitionData
        DATA = AcquisitionData(geometry=self.sinogram_geometry)

        for k in range(DATA.geometry.channels):
            sinogram_id, DATA.as_array()[k] = astra.create_sino(
                IM.as_array()[k], self.proj_id)
            astra.data2d.delete(sinogram_id)

        if self.device == 'cpu':
            return DATA
        else:
            if self.sinogram_geometry.geom_type == 'cone':
                return DATA
            else:
                scaling = (1.0 / self.volume_geometry.voxel_size_x)
                return scaling * DATA
def get_A_b(img, angles, det_row_count=1, det_col_count=256):
    '''
    Возвращает матрицу системы линейных уравнений
    params:
    img - изображение
    angles - количество углов проекций
    det_row_count - расстояние между 2 проекциями детектора
    det_col_count - количество измерений для каждого угла
    return:
    A - system matrix
    b - projection vector
    '''
    vol_geom = astra.create_vol_geom(img.shape[0], img.shape[1])
    proj_geom = astra.create_proj_geom('parallel', det_row_count, det_col_count, angles)
    proj_id = astra.create_projector('linear', proj_geom, vol_geom)
    matrix_id = astra.projector.matrix(proj_id)
    A = astra.matrix.get(matrix_id).astype(np.float)
    sinogram_id, sino = astra.create_sino(img, proj_id)
    return A, sino
Esempio n. 25
0
    def __getitem__(self, idx):
        if self.Dataset_name in ['Mayo_test', 'MayoRaw_test']:
            img, ld_img, imgname = self.imgset[idx]
        else:
            img, ld_img = self.imgset[idx]

        if self.Dataset_name in ['MayoRaw_test', 'MayoRaw']:
            sinogram = ld_img
        else:
            sinogram = []
            for i in range(self.recon_slices):
                sinogram_id, sinogram_tmp = astra.create_sino(
                    ld_img[i], self.proj_id)
                astra.data2d.delete(sinogram_id)
                sinogram.append(sinogram_tmp)

        if self.post_trans_img is not None:
            for i in range(self.recon_slices):
                img[i], _, _ = self.post_trans_img(img[i])
                sinogram[i] = self.img_a * sinogram[i] + self.img_Ab

        img, sinogram = np.array(img), np.array(sinogram)

        if self.post_trans_sino is not None:
            sinogram, _, _ = self.post_trans_sino(sinogram)

        if self.Dataset_name in ['Mayo', 'MayoRaw']:
            sample = {
                'ndct': torch.from_numpy(img).type(torch.FloatTensor),
                'sinogram': torch.from_numpy(sinogram).type(torch.FloatTensor)
            }
        else:
            sample = {
                'ndct': torch.from_numpy(img).type(torch.FloatTensor),
                'sinogram': torch.from_numpy(sinogram).type(torch.FloatTensor),
                'name': imgname,
                'RescaleSlope': self.img_a,
                'RescaleIntercept': self.img_Ab
            }

        return sample
Esempio n. 26
0
def create_model_tilt_series(model, angles=None):
    """
    Create a tilt series from a 3D volume.

    Args
    ----------
    model : NumPy array
        3D array containing the model volume to project to a tilt series
    angles : NumPy array
        Projection angles for tilt series

    Returns
    ----------
    model : TomoStack object
        Tilt series of the model data

    """
    if type(angles) is not np.ndarray:
        angles = np.arange(0, 180, 2)

    if type(model) is hs.signals.Signal2D:
        model = model.data

    xdim = model.shape[2]
    ydim = model.shape[1]
    thickness = model.shape[0]

    proj_data = np.zeros([len(angles), ydim, xdim])
    vol_geom = astra.create_vol_geom(thickness, xdim, ydim)
    tilts = angles * np.pi / 180
    proj_geom = astra.create_proj_geom('parallel', 1, xdim, tilts)
    proj_id = astra.create_projector('strip', proj_geom, vol_geom)

    for i in range(0, model.shape[1]):
        sino_id, proj_data[:,
                           i, :] = astra.create_sino(model[:, i, :], proj_id)

    stack = numpy_to_tomo_stack(proj_data)
    stack.axes_manager[0].offset = angles[0]
    stack.axes_manager[0].scale = np.abs(angles[1] - angles[0])
    return stack
Esempio n. 27
0
def fp0(image, det_col=111, num_angles=222, voxel_size_mm=1):
    """Wrapper for astra forward projector

    :param image:
    :return: sinogram
    """

    vol_geom = astra.create_vol_geom(image.shape)
    proj_id = astra.create_projector(
        'cuda',
        astra.create_proj_geom('parallel', 1.0, det_col,
                               np.linspace(0, np.pi, num_angles, False)),
        vol_geom)

    sino_id, sino = astra.create_sino(image, proj_id)
    sino *= voxel_size_mm

    astra.data2d.delete(sino_id)
    astra.projector.delete(proj_id)

    return sino
Esempio n. 28
0
def fp0(image, det_col=111, num_angles=222, voxel_size_mm=1):
    """Wrapper for astra forward projector

    :param image:
    :return: sinogram
    """

    vol_geom = astra.create_vol_geom(image.shape)
    proj_id = astra.create_projector(
        'cuda',
        astra.create_proj_geom('parallel', 1.0, det_col,
                               np.linspace(0, np.pi, num_angles, False)),
        vol_geom)

    sino_id, sino = astra.create_sino(image, proj_id)
    sino *= voxel_size_mm

    astra.data2d.delete(sino_id)
    astra.projector.delete(proj_id)

    return sino
Esempio n. 29
0
    def __init__(self,
                 root_dir,
                 folder,
                 geo,
                 pre_trans_img=None,
                 post_trans_img=None,
                 post_trans_sino=None,
                 Dataset_name='Mayo_test'):
        self.Dataset_name = Dataset_name
        self.imgset = TrainData(root_dir, folder, geo['nVoxelX'],
                                geo['slices'], pre_trans_img, Dataset_name)
        self.vol_geom = astra.create_vol_geom(
            geo['nVoxelY'], geo['nVoxelX'],
            -1 * geo['sVoxelY'] / 2 + geo['offOriginY'],
            geo['sVoxelY'] / 2 + geo['offOriginY'],
            -1 * geo['sVoxelX'] / 2 + geo['offOriginX'],
            geo['sVoxelX'] / 2 + geo['offOriginX'])
        self.proj_geom = astra.create_proj_geom(
            geo['mode'], geo['dDetecU'], geo['nDetecU'],
            np.linspace(geo['start_angle'], geo['end_angle'], geo['views'],
                        False), geo['DSO'], geo['DOD'])
        if geo['mode'] is 'parallel':
            self.proj_id = astra.create_projector('linear', self.proj_geom,
                                                  self.vol_geom)
        elif geo['mode'] is 'fanflat':
            self.proj_id = astra.create_projector('line_fanflat',
                                                  self.proj_geom,
                                                  self.vol_geom)  #line_fanflat

        _, img_a, img_b = post_trans_img(
            np.ones((geo['nVoxelX'], geo['nVoxelY'])))
        sinogram_id, img_Ab = astra.create_sino(
            np.ones((geo['nVoxelX'], geo['nVoxelY'])) * img_b, self.proj_id)
        astra.data2d.delete(sinogram_id)
        self.img_a, self.img_Ab = img_a, img_Ab

        self.recon_slices = geo['slices']
        self.post_trans_img = post_trans_img
        self.post_trans_sino = post_trans_sino
Esempio n. 30
0
def radon(f, theta):
    '''
    Takes a numpy.ndarray containing the discretisation of the data and theta
    containing the angles that the radon transform will be taken with 
    and returns a numpy.ndarray containing the radon transformed data i.e a
    sinogram of f.
    '''

    vol_geom = astra.create_vol_geom(f.shape[0], f.shape[1])
    proj_geom = astra.create_proj_geom('parallel', 1.0, 367, theta)

    f_id = astra.data2d.create('-vol', vol_geom, f)
    sin_id = astra.data2d.create('-sino', proj_geom)

    proj_id = astra.create_projector('line', proj_geom, vol_geom)

    sin_id, sin_data = astra.create_sino(f, proj_id)

    astra.data2d.clear()
    astra.projector.clear()
    
    return sin_data
def SIRT_libr(img, angles, det_row_count=1, det_col_count=256):
    '''
    Стандартный библиотечный SIRT
    '''
    vol_geom = astra.create_vol_geom(img.shape[0], img.shape[1])
    proj_geom = astra.create_proj_geom('parallel', det_row_count, det_col_count, angles)
    proj_id = astra.create_projector('linear', proj_geom, vol_geom)
    sinogram_id, sino = astra.create_sino(img, proj_id)
    start = time.time()
    recon_id = astra.data2d.create('-vol', vol_geom, 0)
    cfg = astra.astra_dict('SIRT')
    cfg['ProjectorId'] = proj_id
    cfg['ProjectionDataId'] = sinogram_id
    cfg['ReconstructionDataId'] = recon_id
    algorithm_id = astra.algorithm.create(cfg)
    astra.algorithm.run(algorithm_id, 200)
    new_img = astra.data2d.get(recon_id)
    end = time.time()
    plt.title('Стандартный SIRT')
    plt.imshow(new_img, cmap='gray')
    plt.show()
    print('Время работы SIRT из стандартной библиотеки: {} секунд'.format(end - start))
Esempio n. 32
0
 def forwproj(self, image):
     """Applying forward projection"""
     sinogram_id, sinogram = astra.create_sino(image, self.proj_id)
     astra.data2d.delete(sinogram_id)
     astra.data2d.delete(self.proj_id)
     return sinogram
Esempio n. 33
0
 def matvec(self,v):
     sid, s = astra.create_sino(np.reshape(v,(vol_geom['GridRowCount'],vol_geom['GridColCount'])),self.proj_id)
     astra.data2d.delete(sid)
     return s.ravel()
# --- ASTRA ---


# Define ASTRA geometry
vol_geom = astra.create_vol_geom(domain_size[0], domain_size[1])
proj_geom = astra.create_proj_geom('parallel',
                                   np.linalg.norm(domain_size) / det_size,
                                   det_size,
                                   np.linspace(0, np.pi, n_angles))

# Create ASTRA projector
proj_id = astra.create_projector('line', proj_geom, vol_geom)

# Create sinogram
sinogram_id, sinogram = astra.create_sino(data, proj_id)

# Create a data object for the reconstruction
rec_id = astra.data2d.create('-vol', vol_geom)

# Set up the parameters for a reconstruction algorithm using the CPU backend
cfg = astra.astra_dict('CGLS')
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)

with odl.util.Timer('ASTRA run'):
    # Run the algorithm
Esempio n. 35
0
# along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#
# -----------------------------------------------------------------------

import astra
import numpy as np

vol_geom = astra.create_vol_geom(256, 256)
proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
import scipy.io
P = scipy.io.loadmat('phantom.mat')['phantom256']

proj_id = astra.create_projector('cuda',proj_geom,vol_geom)

# Create a sinogram from a phantom, using GPU #1. (The default is #0)
sinogram_id, sinogram = astra.create_sino(P, proj_id, gpuIndex=1)


# Set up the parameters for a reconstruction algorithm using the GPU
rec_id = astra.data2d.create('-vol', vol_geom)
cfg = astra.astra_dict('SIRT_CUDA')
cfg['ReconstructionDataId'] = rec_id
cfg['ProjectionDataId'] = sinogram_id

# Use GPU #1 for the reconstruction. (The default is #0.)
cfg['option'] = {}
cfg['option']['GPUindex'] = 1

# Run 150 iterations of the algorithm
alg_id = astra.algorithm.create(cfg)
astra.algorithm.run(alg_id, 150)
Esempio n. 36
0
 def matvec(self, v):
     sid, s = astra.create_sino(
         np.reshape(v, (vol_geom['GridRowCount'], vol_geom[
             'GridColCount'])), self.proj_id)  # , useCUDA=True)
     astra.data2d.delete(sid)
     return s.flatten()
Esempio n. 37
0
 def proj(self, slice_data):
     sid, proj_data = astra.create_sino(slice_data, self.proj_id)
     astra.data2d.delete(sid)
     return proj_data
Esempio n. 38
0
#along with the Python interface to the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#
#-----------------------------------------------------------------------

import astra
import numpy as np

vol_geom = astra.create_vol_geom(256, 256)
proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
import scipy.io
P = scipy.io.loadmat('phantom.mat')['phantom256']

proj_id = astra.create_projector('line',proj_geom,vol_geom)

# Create a sinogram from a phantom, using GPU #1. (The default is #0)
sinogram_id, sinogram = astra.create_sino(P, proj_id, useCUDA=True, gpuIndex=1)


# Set up the parameters for a reconstruction algorithm using the GPU
rec_id = astra.data2d.create('-vol', vol_geom)
cfg = astra.astra_dict('SIRT_CUDA')
cfg['ReconstructionDataId'] = rec_id
cfg['ProjectionDataId'] = sinogram_id

# Use GPU #1 for the reconstruction. (The default is #0.)
cfg['option'] = {}
cfg['option']['GPUindex'] = 1

# Run 150 iterations of the algorithm
alg_id = astra.algorithm.create(cfg)
astra.algorithm.run(alg_id, 150)
Esempio n. 39
0
except ImportError:
    # six 1.3.0
    from six.moves import xrange as range
import astra
import numpy as np
import scipy.io
import matplotlib.pyplot as plt

vol_geom = astra.create_vol_geom(256, 256)
proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))

# As before, create a sinogram from a phantom

P = scipy.io.loadmat('phantom.mat')['phantom256']
proj_id = astra.create_projector('cuda',proj_geom,vol_geom)
sinogram_id, sinogram = astra.create_sino(P, proj_id)

plt.gray()
plt.figure(1)
plt.imshow(P)
plt.figure(2)
plt.imshow(sinogram)

# Create a data object for the reconstruction
rec_id = astra.data2d.create('-vol', vol_geom)

# 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
Esempio n. 40
0
x, y = np.meshgrid(c,c)
mask = np.array((x**2 + y**2 < 127.5**2),dtype=np.float)

import pylab
pylab.gray()
pylab.figure(1)
pylab.imshow(mask)

vol_geom = astra.create_vol_geom(256, 256)
proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,50,False))

# As before, create a sinogram from a phantom
import scipy.io
P = scipy.io.loadmat('phantom.mat')['phantom256']
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
Esempio n. 41
0
    from six.moves import range
except ImportError:
    # six 1.3.0
    from six.moves import xrange as range
import astra
import numpy as np

vol_geom = astra.create_vol_geom(256, 256)
proj_geom = astra.create_proj_geom('parallel', 1.0, 384,
                                   np.linspace(0, np.pi, 180, False))

# As before, create a sinogram from a phantom
import scipy.io
P = scipy.io.loadmat('phantom.mat')['phantom256']
proj_id = astra.create_projector('cuda', proj_geom, vol_geom)
sinogram_id, sinogram = astra.create_sino(P, proj_id)

import pylab
pylab.gray()
pylab.figure(1)
pylab.imshow(P)
pylab.figure(2)
pylab.imshow(sinogram)

# Create a data object for the reconstruction
rec_id = astra.data2d.create('-vol', vol_geom)

# 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
Esempio n. 42
0
  def single_test(self, type, proj_type):
      shape = np.random.randint(*range2d, size=2)
      # these rectangles are biased, but that shouldn't matter
      rect_min = [ np.random.randint(0, a) for a in shape ]
      rect_max = [ np.random.randint(rect_min[i]+1, shape[i]+1) for i in range(len(shape))]
      if FLEXVOL:
          if not NONSQUARE:
            pixsize = np.array([0.5, 0.5]) + np.random.random()
          else:
            pixsize = 0.5 + np.random.random(size=2)
          origin = 10 * np.random.random(size=2)
      else:
          pixsize = (1.,1.)
          origin = (0.,0.)
      vg = astra.create_vol_geom(shape[1], shape[0],
                                 origin[0] - 0.5 * shape[0] * pixsize[0],
                                 origin[0] + 0.5 * shape[0] * pixsize[0],
                                 origin[1] - 0.5 * shape[1] * pixsize[1],
                                 origin[1] + 0.5 * shape[1] * pixsize[1])

      if type == 'parallel':
        pg = gen_random_geometry_parallel()
        projector_id = astra.create_projector(proj_type, pg, vg)
      elif type == 'parallel_vec':
        pg = gen_random_geometry_parallel_vec()
        projector_id = astra.create_projector(proj_type, pg, vg)
      elif type == 'fanflat':
        pg = gen_random_geometry_fanflat()
        projector_id = astra.create_projector(proj_type_to_fan(proj_type), pg, vg)
      elif type == 'fanflat_vec':
        pg = gen_random_geometry_fanflat_vec()
        projector_id = astra.create_projector(proj_type_to_fan(proj_type), pg, vg)


      data = np.zeros((shape[1], shape[0]), dtype=np.float32)
      data[rect_min[1]:rect_max[1],rect_min[0]:rect_max[0]] = 1

      sinogram_id, sinogram = astra.create_sino(data, projector_id)

      self.assertTrue(np.all(np.isfinite(sinogram)))

      #print(pg)
      #print(vg)

      astra.data2d.delete(sinogram_id)

      astra.projector.delete(projector_id)

      # NB: Flipped y-axis here, since that is how astra interprets 2D volumes
      xmin = origin[0] + (-0.5 * shape[0] + rect_min[0]) * pixsize[0]
      xmax = origin[0] + (-0.5 * shape[0] + rect_max[0]) * pixsize[0]
      ymin = origin[1] + (+0.5 * shape[1] - rect_max[1]) * pixsize[1]
      ymax = origin[1] + (+0.5 * shape[1] - rect_min[1]) * pixsize[1]

      if proj_type == 'line':

        a = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
        b = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
        c = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)

        for i, (center, edge1, edge2) in enumerate(gen_lines(pg)):
          (src, det) = center

          try:
            detweight = pg['DetectorWidth']
          except KeyError:
            if 'fan' not in type:
              detweight = effective_detweight(src, det, pg['Vectors'][i//pg['DetectorCount'],4:6])
            else:
              detweight = np.linalg.norm(pg['Vectors'][i//pg['DetectorCount'],4:6], ord=2)

          # We compute line intersections with slightly bigger (cw) and
          # smaller (aw) rectangles, and see if the kernel falls
          # between these two values.
          (aw,bw,cw) = intersect_line_rectangle_interval(src, det,
                        xmin, xmax, ymin, ymax,
                        1e-3)
          a[i] = aw * detweight
          b[i] = bw * detweight
          c[i] = cw * detweight
        a = a.reshape(astra.functions.geom_size(pg))
        b = b.reshape(astra.functions.geom_size(pg))
        c = c.reshape(astra.functions.geom_size(pg))

        if not np.all(np.isfinite(a)):
          raise RuntimeError("Invalid value in reference sinogram")
        if not np.all(np.isfinite(b)):
          raise RuntimeError("Invalid value in reference sinogram")
        if not np.all(np.isfinite(c)):
          raise RuntimeError("Invalid value in reference sinogram")
        self.assertTrue(np.all(np.isfinite(sinogram)))

        # Check if sinogram lies between a and c
        y = np.min(sinogram-a)
        z = np.min(c-sinogram)
        if DISPLAY and (z < 0 or y < 0):
          display_mismatch_triple(data, sinogram, a, b, c)
        self.assertFalse(z < 0 or y < 0)
      elif proj_type == 'linear' or proj_type == 'cuda':
        a = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
        for i, (center, edge1, edge2) in enumerate(gen_lines(pg)):
          (src, det) = center
          (xd, yd) = det - src
          try:
            detweight = pg['DetectorWidth']
          except KeyError:
            if 'fan' not in type:
              detweight = effective_detweight(src, det, pg['Vectors'][i//pg['DetectorCount'],4:6])
            else:
              detweight = np.linalg.norm(pg['Vectors'][i//pg['DetectorCount'],4:6], ord=2)

          l = 0.0
          if np.abs(xd) > np.abs(yd): # horizontal ray
            length = math.sqrt(1.0 + abs(yd/xd)**2)
            y_seg = (ymin, ymax)
            for j in range(rect_min[0], rect_max[0]):
              x = origin[0] + (-0.5 * shape[0] + j + 0.5) * pixsize[0]
              w = intersect_line_vertical_segment_linear(center[0], center[1], x, y_seg, pixsize[1])
              # limited interpolation precision with cuda
              if CUDA_8BIT_LINEAR and proj_type == 'cuda':
                w = np.round(w * 256.0) / 256.0
              l += w * length * pixsize[0] * detweight
          else:
            length = math.sqrt(1.0 + abs(xd/yd)**2)
            x_seg = (xmin, xmax)
            for j in range(rect_min[1], rect_max[1]):
              y = origin[1] + (+0.5 * shape[1] - j - 0.5) * pixsize[1]
              w = intersect_line_horizontal_segment_linear(center[0], center[1], y, x_seg, pixsize[0])
              # limited interpolation precision with cuda
              if CUDA_8BIT_LINEAR and proj_type == 'cuda':
                w = np.round(w * 256.0) / 256.0
              l += w * length * pixsize[1] * detweight
          a[i] = l
        a = a.reshape(astra.functions.geom_size(pg))
        if not np.all(np.isfinite(a)):
          raise RuntimeError("Invalid value in reference sinogram")
        x = np.max(np.abs(sinogram-a))
        TOL = 2e-3 if proj_type != 'cuda' else CUDA_TOL
        if DISPLAY and x > TOL:
          display_mismatch(data, sinogram, a)
        self.assertFalse(x > TOL)
      elif proj_type == 'distance_driven':
        a = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
        for i, (center, edge1, edge2) in enumerate(gen_lines(pg)):
          (xd, yd) = center[1] - center[0]
          l = 0.0
          if np.abs(xd) > np.abs(yd): # horizontal ray
            y_seg = (ymin, ymax)
            for j in range(rect_min[0], rect_max[0]):
              x = origin[0] + (-0.5 * shape[0] + j + 0.5) * pixsize[0]
              l += intersect_ray_vertical_segment(edge1, edge2, x, y_seg) * pixsize[0]
          else:
            x_seg = (xmin, xmax)
            for j in range(rect_min[1], rect_max[1]):
              y = origin[1] + (+0.5 * shape[1] - j - 0.5) * pixsize[1]
              l += intersect_ray_horizontal_segment(edge1, edge2, y, x_seg) * pixsize[1]
          a[i] = l
        a = a.reshape(astra.functions.geom_size(pg))
        if not np.all(np.isfinite(a)):
          raise RuntimeError("Invalid value in reference sinogram")
        x = np.max(np.abs(sinogram-a))
        TOL = 2e-3
        if DISPLAY and x > TOL:
          display_mismatch(data, sinogram, a)
        self.assertFalse(x > TOL)
      elif proj_type == 'strip' and 'fan' in type:
        a = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
        for i, (center, edge1, edge2) in enumerate(gen_lines(pg)):
          (src, det) = center
          det_dist = np.linalg.norm(src-det, ord=2)
          l = 0.0
          for j in range(rect_min[0], rect_max[0]):
            xmin = origin[0] + (-0.5 * shape[0] + j) * pixsize[0]
            xmax = origin[0] + (-0.5 * shape[0] + j + 1) * pixsize[0]
            xcen = 0.5 * (xmin + xmax)
            for k in range(rect_min[1], rect_max[1]):
              ymin = origin[1] + (+0.5 * shape[1] - k - 1) * pixsize[1]
              ymax = origin[1] + (+0.5 * shape[1] - k) * pixsize[1]
              ycen = 0.5 * (ymin + ymax)
              scale = det_dist / np.linalg.norm( src - np.array((xcen,ycen)), ord=2 )
              w = intersect_ray_rect(edge1, edge2, xmin, xmax, ymin, ymax)
              l += w * scale
          a[i] = l
        a = a.reshape(astra.functions.geom_size(pg))
        if not np.all(np.isfinite(a)):
          raise RuntimeError("Invalid value in reference sinogram")
        x = np.max(np.abs(sinogram-a))
        TOL = 8e-3
        if DISPLAY and x > TOL:
          display_mismatch(data, sinogram, a)
        self.assertFalse(x > TOL)
      elif proj_type == 'strip':
        a = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
        for i, (center, edge1, edge2) in enumerate(gen_lines(pg)):
          a[i] = intersect_ray_rect(edge1, edge2, xmin, xmax, ymin, ymax)
        a = a.reshape(astra.functions.geom_size(pg))
        if not np.all(np.isfinite(a)):
          raise RuntimeError("Invalid value in reference sinogram")
        x = np.max(np.abs(sinogram-a))
        TOL = 8e-3
        if DISPLAY and x > TOL:
          display_mismatch(data, sinogram, a)
        self.assertFalse(x > TOL)