Example #1
0
    def load_projections(self):
        '''
        Load projections and return AcquisitionData container
        '''

        # get path to projections
        path_projection = os.path.dirname(self.xtek_file)

        # get number of projections
        num_projections = numpy.shape(self._ag.angles)[0]

        # allocate array to store projections
        data = numpy.zeros(
            (num_projections, self._ag.pixel_num_v, self._ag.pixel_num_h),
            dtype=float)

        for i in range(num_projections):

            filename = (path_projection + '/' + self._experiment_name +
                        '_{:04d}.tif').format(i + 1)

            try:
                tmp = numpy.asarray(Image.open(filename), dtype=float)
            except:
                print('Error reading\n {}\n file.'.format(filename))
                raise

            if (self.binning == [1, 1]):
                data[i, :, :] = tmp[self._roi_par[0][0]:self._roi_par[0][1],
                                    self._roi_par[1][0]:self._roi_par[1][1]]
            else:
                shape = (self._ag.pixel_num_v, self.binning[0],
                         self._ag.pixel_num_h, self.binning[1])
                data[i, :, :] = tmp[self._roi_par[0][0]:(self._roi_par[0][0] + (((self._roi_par[0][1] - self._roi_par[0][0]) // self.binning[0]) * self.binning[0])), \
                                    self._roi_par[1][0]:(self._roi_par[1][0] + (((self._roi_par[1][1] - self._roi_par[1][0]) // self.binning[1]) * self.binning[1]))].reshape(shape).mean(-1).mean(1)

        if (self.normalize):
            data /= self._white_level
            data[data > 1] = 1

        if self.flip:
            return AcquisitionData(array = data[:, :, ::-1],
                                   deep_copy = False,
                                   geometry = self._ag,
                                   dimension_labels = ['angle', \
                                                       'vertical', \
                                                       'horizontal'])
        else:
            return AcquisitionData(array = data,
                                   deep_copy = False,
                                   geometry = self._ag,
                                   dimension_labels = ['angle', \
                                                       'vertical', \
                                                       'horizontal'])
Example #2
0
 def process(self):
     IM = self.get_input()
     DATA = AcquisitionData(geometry=self.sinogram_geometry,
                            dimension_labels=self.output_axes_order)
     sinogram_id, DATA.array = astra.create_sino3d_gpu(
         IM.as_array(), self.proj_geom, self.vol_geom)
     astra.data3d.delete(sinogram_id)
     # 3D CUDA FP does not need scaling
     return DATA
Example #3
0
 def allocate_direct(self):
     if issubclass(type(self.geometry), ImageGeometry):
         return ImageData(geometry=self.geometry)
     elif issubclass(type(self.geometry), AcquisitionGeometry):
         return AcquisitionData(geometry=self.geometry)
     else:
         raise ValueError(
             "Wrong geometry type: expected ImageGeometry of AcquisitionGeometry, got ",
             type(self.geometry))
Example #4
0
 def test_AcquisitionData(self):
     sgeometry = AcquisitionGeometry(dimension=2,
                                     angles=numpy.linspace(0, 180, num=10),
                                     geom_type='parallel',
                                     pixel_num_v=3,
                                     pixel_num_h=5,
                                     channels=2)
     sino = AcquisitionData(geometry=sgeometry)
     self.assertEqual(sino.shape, (2, 10, 3, 5))
Example #5
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 setupCCPiGeometries(voxel_num_x, voxel_num_y, voxel_num_z, angles, counter):
    
    vg = ImageGeometry(voxel_num_x=voxel_num_x,voxel_num_y=voxel_num_y, voxel_num_z=voxel_num_z)
    Phantom_ccpi = ImageData(geometry=vg,
                        dimension_labels=['horizontal_x','horizontal_y','vertical'])
    #.subset(['horizontal_x','horizontal_y','vertical'])
    # ask the ccpi code what dimensions it would like
        
    voxel_per_pixel = 1
    geoms = pbalg.pb_setup_geometry_from_image(Phantom_ccpi.as_array(),
                                                angles,
                                                voxel_per_pixel )
    
    pg = AcquisitionGeometry('parallel',
                              '3D',
                              angles,
                              geoms['n_h'], 1.0,
                              geoms['n_v'], 1.0 #2D in 3D is a slice 1 pixel thick
                              )
    
    center_of_rotation = Phantom_ccpi.get_dimension_size('horizontal_x') / 2
    ad = AcquisitionData(geometry=pg,dimension_labels=['angle','vertical','horizontal'])
    geoms_i = pbalg.pb_setup_geometry_from_acquisition(ad.as_array(),
                                                angles,
                                                center_of_rotation,
                                                voxel_per_pixel )
    
    counter+=1
    
    if counter < 4:
        if (not ( geoms_i == geoms )):
            print ("not equal and {0}".format(counter))
            X = max(geoms['output_volume_x'], geoms_i['output_volume_x'])
            Y = max(geoms['output_volume_y'], geoms_i['output_volume_y'])
            Z = max(geoms['output_volume_z'], geoms_i['output_volume_z'])
            return setupCCPiGeometries(X,Y,Z,angles, counter)
        else:
            return geoms
    else:
        return geoms_i
Example #7
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
Example #8
0
 def get_acquisition_data(self, dimensions=None):
     '''
     This method load the acquisition data and given dimension and returns an AcquisitionData Object
     '''
     data = self.load_projection(dimensions)
     dims = self.get_projection_dimensions()
     geometry = AcquisitionGeometry('parallel',
                                    '3D',
                                    self.get_projection_angles(),
                                    pixel_num_h=dims[2],
                                    pixel_size_h=1,
                                    pixel_num_v=dims[1],
                                    pixel_size_v=1,
                                    dist_source_center=None,
                                    dist_center_detector=None,
                                    channels=1)
     return AcquisitionData(
         data,
         geometry=geometry,
         dimension_labels=['angle', 'vertical', 'horizontal'])
Example #9
0
 def test_AcquisitionGeometry_allocate(self):
     ageometry = AcquisitionGeometry(dimension=2, 
                         angles=numpy.linspace(0, 180, num=10),
                         geom_type='parallel', pixel_num_v=3,
                         pixel_num_h=5, channels=2)
     sino = ageometry.allocate()
     shape = sino.shape
     print ("shape", shape)
     self.assertEqual(0,sino.as_array()[0][0][0][0])
     self.assertEqual(0,sino.as_array()[shape[0]-1][shape[1]-1][shape[2]-1][shape[3]-1])
     
     sino = ageometry.allocate(1)
     self.assertEqual(1,sino.as_array()[0][0][0][0])
     self.assertEqual(1,sino.as_array()[shape[0]-1][shape[1]-1][shape[2]-1][shape[3]-1])
     print (sino.dimension_labels, sino.shape, ageometry)
     
     default_order = ['channel' , 'angle' ,
                      'vertical' , 'horizontal']
     self.assertEqual(default_order[0], sino.dimension_labels[0])
     self.assertEqual(default_order[1], sino.dimension_labels[1])
     self.assertEqual(default_order[2], sino.dimension_labels[2])
     self.assertEqual(default_order[3], sino.dimension_labels[3])
     order = ['vertical' , 'horizontal', 'channel' , 'angle' ]
     sino = ageometry.allocate(0,dimension_labels=order)
     print (sino.dimension_labels, sino.shape, ageometry)
     self.assertEqual(order[0], sino.dimension_labels[0])
     self.assertEqual(order[1], sino.dimension_labels[1])
     self.assertEqual(order[2], sino.dimension_labels[2])
     self.assertEqual(order[2], sino.dimension_labels[2])
     
     
     try:
         z = AcquisitionData(numpy.random.randint(10, size=(2,3)), geometry=ageometry)
         self.assertTrue(False)
     except ValueError as ve:
         print (ve)
         self.assertTrue(True)
    def process(self):
        
        volume = self.get_input()
        volume_axes = volume.get_data_axes_order(new_order=self.default_image_axes_order)
        if not volume_axes == [0,1,2]:
            volume.array = numpy.transpose(volume.array, volume_axes)
        pixel_per_voxel = 1 # should be estimated from image_geometry and 
                            # acquisition_geometry
        if self.acquisition_geometry.geom_type == 'parallel':

            pixels = pbalg.pb_forward_project(volume.as_array(), 
                                                  self.acquisition_geometry.angles, 
                                                  pixel_per_voxel)
            out = AcquisitionData(geometry=self.acquisition_geometry, 
                                  label_dimensions=self.default_acquisition_axes_order)
            out.fill(pixels)
            out_axes = out.get_data_axes_order(new_order=self.output_axes_order)
            if not out_axes == [0,1,2]:
                out.array = numpy.transpose(out.array, out_axes)
            return out
        else:
            raise ValueError('Cannot process cone beam')
Example #11
0
 def get_acquisition_data(self, dimensions=None):
     '''
     This method load the acquisition data and given dimension and returns an AcquisitionData Object
     '''
     data = self.load_projection(dimensions)
     return AcquisitionData(data, geometry=self.geometry)
Example #12
0
    def get_acquisition_data_batch(self, bmin=None, bmax=None):
        if not h5pyAvailable:
            raise Exception("Error: h5py is not installed")
        if self.filename is None:
            return
        try:

            with NexusFile(self.filename, 'r') as file:
                try:
                    dims = self.get_projection_dimensions()
                except KeyError:
                    dims = file[self.data_path].shape
                if bmin is None or bmax is None:
                    raise ValueError(
                        'get_acquisition_data_batch: please specify fastest index batch limits'
                    )

                if bmin >= 0 and bmin < bmax and bmax <= dims[0]:
                    data = np.array(file[self.data_path][bmin:bmax])
                else:
                    raise ValueError(
                        'get_acquisition_data_batch: bmin {0}>0 bmax {1}<{2}'.
                        format(bmin, bmax, dims[0]))

        except:
            print("Error reading nexus file")
            raise

        try:
            angles = self.get_projection_angles()[bmin:bmax]
        except KeyError as ke:
            n = data.shape[0]
            angles = np.linspace(0, n, n + 1, dtype=np.float32)[bmin:bmax]

        if bmax - bmin > 1:

            geometry = AcquisitionGeometry('parallel',
                                           '3D',
                                           angles,
                                           pixel_num_h=dims[2],
                                           pixel_size_h=1,
                                           pixel_num_v=bmax - bmin,
                                           pixel_size_v=1,
                                           dist_source_center=None,
                                           dist_center_detector=None,
                                           channels=1)
            return AcquisitionData(
                data,
                False,
                geometry=geometry,
                dimension_labels=['angle', 'vertical', 'horizontal'])
        elif bmax - bmin == 1:
            geometry = AcquisitionGeometry('parallel',
                                           '2D',
                                           angles,
                                           pixel_num_h=dims[2],
                                           pixel_size_h=1,
                                           dist_source_center=None,
                                           dist_center_detector=None,
                                           channels=1)
            return AcquisitionData(data.squeeze(),
                                   False,
                                   geometry=geometry,
                                   dimension_labels=['angle', 'horizontal'])
Example #13
0
    def get_acquisition_data_subset(self, ymin=None, ymax=None):
        '''
        This method load the acquisition data and given dimension and returns an AcquisitionData Object
        '''
        if not h5pyAvailable:
            raise Exception("Error: h5py is not installed")
        if self.filename is None:
            return
        try:

            with NexusFile(self.filename, 'r') as file:
                try:
                    dims = self.get_projection_dimensions()
                except KeyError:
                    pass
                dims = file[self.data_path].shape
                if ymin is None and ymax is None:
                    data = np.array(file[self.data_path])
                else:
                    if ymin is None:
                        ymin = 0
                        if ymax > dims[1]:
                            raise ValueError('ymax out of range')
                        data = np.array(file[self.data_path][:, :ymax, :])
                    elif ymax is None:
                        ymax = dims[1]
                        if ymin < 0:
                            raise ValueError('ymin out of range')
                        data = np.array(file[self.data_path][:, ymin:, :])
                    else:
                        if ymax > dims[1]:
                            raise ValueError('ymax out of range')
                        if ymin < 0:
                            raise ValueError('ymin out of range')

                        data = np.array(file[self.data_path][:, ymin:ymax, :])

        except:
            print("Error reading nexus file")
            raise

        try:
            angles = self.get_projection_angles()
        except KeyError as ke:
            n = data.shape[0]
            angles = np.linspace(0, n, n + 1, dtype=np.float32)

        if ymax - ymin > 1:

            geometry = AcquisitionGeometry('parallel',
                                           '3D',
                                           angles,
                                           pixel_num_h=dims[2],
                                           pixel_size_h=1,
                                           pixel_num_v=ymax - ymin,
                                           pixel_size_v=1,
                                           dist_source_center=None,
                                           dist_center_detector=None,
                                           channels=1)
            return AcquisitionData(
                data,
                False,
                geometry=geometry,
                dimension_labels=['angle', 'vertical', 'horizontal'])
        elif ymax - ymin == 1:
            geometry = AcquisitionGeometry('parallel',
                                           '2D',
                                           angles,
                                           pixel_num_h=dims[2],
                                           pixel_size_h=1,
                                           dist_source_center=None,
                                           dist_center_detector=None,
                                           channels=1)
            return AcquisitionData(data.squeeze(),
                                   False,
                                   geometry=geometry,
                                   dimension_labels=['angle', 'horizontal'])
Example #14
0
plt.show() 

    
ig = ImageGeometry(voxel_num_x = N, voxel_num_y = N, channels = np.shape(phantom_2Dt)[0])
data = ImageData(phantom_2Dt, geometry=ig)

detectors = N
angles = np.linspace(0,np.pi,180)

ag = AcquisitionGeometry('parallel','2D', angles, detectors, channels = np.shape(phantom_2Dt)[0])
Aop = AstraProjectorMC(ig, ag, dev)
sin = Aop.direct(data)

scale = 2
n1 = scale * np.random.poisson(sin.as_array()/scale)
noisy_data = AcquisitionData(n1, ag)

# Regularisation Parameter
alpha = 10

# Create operators
#op1 = Gradient(ig)
op1 = Gradient(ig, correlation='SpaceChannels')
op2 = Aop

# Create BlockOperator
operator = BlockOperator(op1, op2, shape=(2,1) ) 

# Create functions
      
f1 = alpha * MixedL21Norm()
ag = AcquisitionGeometry(
    'cone',
    '3D',
    angles,
    pixel_num_h=num_pixels_h,
    pixel_size_h=0.25,
    pixel_num_v=num_pixels_v,
    pixel_size_v=0.25,
    dist_source_center=233.0,
    dist_center_detector=245.0,
    channels=num_channels,
    dimension_labels=['channel', 'vertical', 'angle', 'horizontal'])

# AcquisitionData 3D + channels
data = AcquisitionData(
    X, ag, dimension_labels=['channel', 'vertical', 'angle', 'horizontal'])

# First need the geometric magnification to scale the voxel size relative
# to the detector pixel size.
# magnification factor  =  250/1.76
# dist_source , dist center do not matter

ig = ImageGeometry(voxel_num_x=ag.pixel_num_h,
                   voxel_num_y=ag.pixel_num_h,
                   voxel_num_z=ag.pixel_num_h,
                   voxel_size_x=0.142,
                   voxel_size_y=0.142,
                   voxel_size_z=0.142,
                   channels=num_channels)

# Setup Astra Projector for 3DMC
Example #16
0
# Set angles to use
angles = numpy.linspace(-numpy.pi, numpy.pi, num_angles, endpoint=False)

# Define full 3D acquisition geometry and data container.
# Geometric info is taken from the txt-file in the same dir as the mat-file
ag = AcquisitionGeometry('cone',
                         '3D',
                         angles,
                         pixel_num_h=num_pixels_h,
                         pixel_size_h=0.25,
                         pixel_num_v=num_pixels_v,
                         pixel_size_v=0.25,
                         dist_source_center=233.0,
                         dist_center_detector=245.0,
                         channels=num_channels)
data = AcquisitionData(X, geometry=ag)

# Reduce to central slice by extracting relevant parameters from data and its
# geometry. Perhaps create function to extract central slice automatically?
data2d = data.subset(vertical=40)
ag2d = AcquisitionGeometry('cone',
                           '2D',
                           ag.angles,
                           pixel_num_h=ag.pixel_num_h,
                           pixel_size_h=ag.pixel_size_h,
                           pixel_num_v=1,
                           pixel_size_v=ag.pixel_size_h,
                           dist_source_center=ag.dist_source_center,
                           dist_center_detector=ag.dist_center_detector,
                           channels=ag.channels)
data2d.geometry = ag2d
Example #17
0
    def process(self, out=None):
        projections = self.get_input()
        w = projections.get_dimension_size('horizontal')
        delta = w - 2 * self.center_of_rotation

        padded_width = int(numpy.ceil(abs(delta)) + w)
        delta_pix = padded_width - w

        voxel_per_pixel = 1
        geom = pbalg.pb_setup_geometry_from_acquisition(
            projections.as_array(), self.acquisition_geometry.angles,
            self.center_of_rotation, voxel_per_pixel)

        padded_geometry = self.acquisition_geometry.clone()

        padded_geometry.pixel_num_h = geom['n_h']
        padded_geometry.pixel_num_v = geom['n_v']

        delta_pix_h = padded_geometry.pixel_num_h - self.acquisition_geometry.pixel_num_h
        delta_pix_v = padded_geometry.pixel_num_v - self.acquisition_geometry.pixel_num_v

        if delta_pix_h == 0:
            delta_pix_h = delta_pix
            padded_geometry.pixel_num_h = padded_width
        #initialize a new AcquisitionData with values close to 0
        out = AcquisitionData(geometry=padded_geometry)
        out = out + self.pad_value

        #pad in the horizontal-vertical plane -> slice on angles
        if delta > 0:
            #pad left of middle
            command = "out.array["
            for i in range(out.number_of_dimensions):
                if out.dimension_labels[i] == 'horizontal':
                    value = '{0}:{1}'.format(delta_pix_h, delta_pix_h + w)
                    command = command + str(value)
                else:
                    if out.dimension_labels[i] == 'vertical':
                        value = '{0}:'.format(delta_pix_v)
                        command = command + str(value)
                    else:
                        command = command + ":"
                if i < out.number_of_dimensions - 1:
                    command = command + ','
            command = command + '] = projections.array'
            #print (command)
        else:
            #pad right of middle
            command = "out.array["
            for i in range(out.number_of_dimensions):
                if out.dimension_labels[i] == 'horizontal':
                    value = '{0}:{1}'.format(0, w)
                    command = command + str(value)
                else:
                    if out.dimension_labels[i] == 'vertical':
                        value = '{0}:'.format(delta_pix_v)
                        command = command + str(value)
                    else:
                        command = command + ":"
                if i < out.number_of_dimensions - 1:
                    command = command + ','
            command = command + '] = projections.array'
            #print (command)
            #cleaned = eval(command)
        exec(command)
        return out
Example #18
0
if device == '1':
    dev = 'gpu'
else:
    dev = 'cpu'

Aop = AstraProjectorSimple(ig, ag, dev)
sin = Aop.direct(data)

# Create noisy data. Apply Gaussian noise
noises = ['gaussian', 'poisson']
noise = noises[which_noise]

if noise == 'poisson':
    scale = 5
    eta = 0
    noisy_data = AcquisitionData(
        np.random.poisson(scale * (eta + sin.as_array())) / scale, ag)
elif noise == 'gaussian':
    n1 = np.random.normal(0, 1, size=ag.shape)
    noisy_data = AcquisitionData(n1 + sin.as_array(), ag)
else:
    raise ValueError('Unsupported Noise ', noise)

# Show Ground Truth and Noisy Data
plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 2)
plt.imshow(data.as_array())
plt.title('Ground Truth')
plt.colorbar()
plt.subplot(1, 2, 1)
plt.imshow(noisy_data.as_array())
plt.title('Noisy Data')
Example #19
0
# Apply centering correction by zero padding, amount found manually
cor_pad = 30
sino_pad = np.zeros((sino.shape[0],sino.shape[1]+cor_pad))
sino_pad[:,cor_pad:] = sino

# Extract AcquisitionGeometry for central slice for 2D fanbeam reconstruction
ag2d = AcquisitionGeometry('cone',
                          '2D',
                          angles=-np.pi/180*data.geometry.angles,
                          pixel_num_h=data.geometry.pixel_num_h + cor_pad,
                          pixel_size_h=data.geometry.pixel_size_h,
                          dist_source_center=-data.geometry.dist_source_center, 
                          dist_center_detector=data.geometry.dist_center_detector)

# Set up AcquisitionData object for central slice 2D fanbeam
data2d = AcquisitionData(sino_pad,geometry=ag2d)

# Choose the number of voxels to reconstruct onto as number of detector pixels
N = data.geometry.pixel_num_h

# Geometric magnification
mag = (np.abs(data.geometry.dist_center_detector) + \
      np.abs(data.geometry.dist_source_center)) / \
      np.abs(data.geometry.dist_source_center)

# Voxel size is detector pixel size divided by mag
voxel_size_h = data.geometry.pixel_size_h / mag

# Construct the appropriate ImageGeometry
ig2d = ImageGeometry(voxel_num_x=N,
                   voxel_num_y=N,
Example #20
0
path = os.path.dirname(tomophantom.__file__)
path_library2D = os.path.join(path, "Phantom2DLibrary.dat")
phantom_2D = TomoP2D.Model(model, N, path_library2D)

ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
data = ImageData(phantom_2D)

detectors = N
angles = np.linspace(0, np.pi, 128, dtype=np.float32)

ag = AcquisitionGeometry('parallel', '2D', angles, detectors)

Aop = AstraProjectorSimple(ig, ag, dev)
sin = Aop.direct(data)
#noisy_data = AcquisitionData( sin.as_array() + np.random.normal(0,1,ag.shape))
noisy_data = AcquisitionData(sin.as_array())

# Show Ground Truth and Noisy Data
plt.figure(figsize=(10, 10))
plt.subplot(2, 1, 1)
plt.imshow(data.as_array())
plt.title('Ground Truth')
plt.colorbar()
plt.subplot(2, 1, 2)
plt.imshow(noisy_data.as_array())
plt.title('Noisy Data')
plt.colorbar()
plt.show()

# Setup and run the CGLS algorithm
alpha = 2
Example #21
0
from ccpi.io.reader import XTEKReader
import numpy as np
import matplotlib.pyplot as plt
from ccpi.framework import ImageGeometry, AcquisitionData, ImageData
from ccpi.astra.ops import AstraProjector3DSimple
from ccpi.optimisation.algs import CGLS

import numpy

# Set up reader object and read the data
datareader = XTEKReader("REPLACE_THIS_BY_PATH_TO_DATASET/SophiaBeads_256_averaged.xtekct")
data = datareader.get_acquisition_data()

# Crop data and fix dimension labels
data = AcquisitionData(data.array[:,:,901:1101],
                            geometry=data.geometry,
                            dimension_labels=['angle','horizontal','vertical'])
data.geometry.pixel_num_v = 200

# Scale and negative-log transform
data.array = -np.log(data.as_array()/60000.0)

# Apply centering correction by zero padding, amount found manually
cor_pad = 30
data_pad = np.zeros((data.shape[0],data.shape[1]+cor_pad,data.shape[2]))
data_pad[:,cor_pad:,:] = data.array
data.geometry.pixel_num_h = data.geometry.pixel_num_h + cor_pad
data.array = data_pad

# Choose the number of voxels to reconstruct onto as number of detector pixels
N = data.geometry.pixel_num_h
Example #22
0
angles = np.linspace(0, np.pi, 180, dtype=np.float32)

ag = AcquisitionGeometry('parallel', '2D', angles, detectors)

device = input('Available device: GPU==1 / CPU==0 ')

if device == '1':
    dev = 'gpu'
else:
    dev = 'cpu'

Aop = AstraProjectorSimple(ig, ag, dev)
sin = Aop.direct(data)

np.random.seed(10)
noisy_data = AcquisitionData(sin.as_array() + np.random.normal(0, 1, ag.shape))

# Show Ground Truth and Noisy Data
plt.figure(figsize=(10, 10))
plt.subplot(2, 1, 1)
plt.imshow(data.as_array())
plt.title('Ground Truth')
plt.colorbar()
plt.subplot(2, 1, 2)
plt.imshow(noisy_data.as_array())
plt.title('Noisy Data')
plt.colorbar()
plt.show()

# Setup and run the simple CGLS algorithm
x_init = ig.allocate()
Example #23
0
    def load_data(self):
        '''
        Parse NEXUS file and returns either ImageData or Acquisition Data 
        depending on file content
        '''

        try:
            with h5py.File(self.nexus_file, 'r') as file:

                if np.string_(file.attrs['creator']) != np.string_(
                        'NEXUSDataWriter.py'):
                    raise Exception(
                        'We can parse only files created by NEXUSDataWriter.py'
                    )

                ds_data = file['entry1/tomo_entry/data/data']
                data = np.array(ds_data, dtype='float32')

                dimension_labels = []

                for i in range(data.ndim):
                    dimension_labels.append(ds_data.attrs['dim{}'.format(i)])

                if ds_data.attrs['data_type'] == 'ImageData':
                    self._geometry = ImageGeometry(
                        voxel_num_x=ds_data.attrs['voxel_num_x'],
                        voxel_num_y=ds_data.attrs['voxel_num_y'],
                        voxel_num_z=ds_data.attrs['voxel_num_z'],
                        voxel_size_x=ds_data.attrs['voxel_size_x'],
                        voxel_size_y=ds_data.attrs['voxel_size_y'],
                        voxel_size_z=ds_data.attrs['voxel_size_z'],
                        center_x=ds_data.attrs['center_x'],
                        center_y=ds_data.attrs['center_y'],
                        center_z=ds_data.attrs['center_z'],
                        channels=ds_data.attrs['channels'])

                    return ImageData(array=data,
                                     deep_copy=False,
                                     geometry=self._geometry,
                                     dimension_labels=dimension_labels)

                else:  # AcquisitionData
                    if ds_data.attrs.__contains__('dist_source_center'):
                        dist_source_center = ds_data.attrs[
                            'dist_source_center']
                    else:
                        dist_source_center = None

                    if ds_data.attrs.__contains__('dist_center_detector'):
                        dist_center_detector = ds_data.attrs[
                            'dist_center_detector']
                    else:
                        dist_center_detector = None

                    self._geometry = AcquisitionGeometry(
                        geom_type=ds_data.attrs['geom_type'],
                        dimension=ds_data.attrs['dimension'],
                        dist_source_center=dist_source_center,
                        dist_center_detector=dist_center_detector,
                        pixel_num_h=ds_data.attrs['pixel_num_h'],
                        pixel_size_h=ds_data.attrs['pixel_size_h'],
                        pixel_num_v=ds_data.attrs['pixel_num_v'],
                        pixel_size_v=ds_data.attrs['pixel_size_v'],
                        channels=ds_data.attrs['channels'],
                        angles=np.array(
                            file['entry1/tomo_entry/data/rotation_angle'],
                            dtype='float32'))
                    #angle_unit = file['entry1/tomo_entry/data/rotation_angle'].attrs['units'])

                    return AcquisitionData(array=data,
                                           deep_copy=False,
                                           geometry=self._geometry,
                                           dimension_labels=dimension_labels)

        except:
            print("Error reading nexus file")
            raise
plt.imshow(b.array)
plt.title('Simulated data')
plt.colorbar()
plt.show()

plt.imshow(z.array)
plt.title('Backprojected data')
plt.colorbar()
plt.show()


One = ImageData(geometry=ig)
xOne = One.as_array()
xOne[:,:] = 1.0

OneD = AcquisitionData(geometry=ag)
y1 = OneD.as_array()
y1[:,:] = 1.0

s1 = (OneD*(Aop.direct(One))).sum()
s2 = (One*(Aop.adjoint(OneD))).sum()
print(s1)
print(s2)
print(s2/s1)

print((b*b).sum())
print((z*Phantom).sum())
print((z*Phantom).sum() / (b*b).sum())

#print(N/det_num)
#print(0.5*det_w/dx)
Example #25
0
def SIRT(x_init, operator, data, opt=None, constraint=None):
    '''Simultaneous Iterative Reconstruction Technique
    
    Parameters:
      x_init: initial guess
      operator: operator for forward/backward projections
      data: data to operate on
      opt: additional algorithm 
      constraint: func of Indicator type specifying convex constraint.
    '''

    if opt is None:
        opt = {'tol': 1e-4, 'iter': 1000}
    else:
        try:
            max_iter = opt['iter']
        except KeyError as ke:
            opt[ke] = 1000
        try:
            opt['tol'] = 1000
        except KeyError as ke:
            opt[ke] = 1e-4
    tol = opt['tol']
    max_iter = opt['iter']

    # Set default constraint to unconstrained
    if constraint == None:
        constraint = Function()

    x = x_init.clone()

    timing = numpy.zeros(max_iter)
    criter = numpy.zeros(max_iter)

    # Relaxation parameter must be strictly between 0 and 2. For now fix at 1.0
    relax_par = 1.0

    # Set up scaling matrices D and M.
    im1 = ImageData(geometry=x_init.geometry)
    im1.array[:] = 1.0
    M = 1 / operator.direct(im1)
    del im1
    aq1 = AcquisitionData(geometry=M.geometry)
    aq1.array[:] = 1.0
    D = 1 / operator.adjoint(aq1)
    del aq1

    # algorithm loop
    for it in range(0, max_iter):
        t = time.time()
        r = data - operator.direct(x)

        x = constraint.prox(x + relax_par * (D * operator.adjoint(M * r)),
                            None)

        timing[it] = time.time() - t
        if it > 0:
            criter[it - 1] = (r**2).sum()

    r = data - operator.direct(x)
    criter[it] = (r**2).sum()
    return x, it, timing, criter
Example #26
0
    OrigDetec = 0
    angles = np.linspace(0, 2 * np.pi, angles_num)
    ag = AcquisitionGeometry('cone',
                             '2D',
                             angles,
                             detectors,
                             det_w,
                             dist_source_center=SourceOrig,
                             dist_center_detector=OrigDetec)
else:
    NotImplemented

Aop = AstraProjectorSimple(ig, ag, dev)
sin = Aop.direct(data)
eta = 0
noisy_data = AcquisitionData(sin.as_array() + np.random.normal(0, 1, ag.shape))
back_proj = Aop.adjoint(noisy_data)

# Define Least Squares
f = FunctionOperatorComposition(L2NormSquared(b=noisy_data), Aop)

# Allocate solution
x_init = ig.allocate()

# Run FISTA for least squares
fista = FISTA(x_init=x_init, f=f, g=ZeroFunction())
fista.max_iteration = 10
fista.update_objective_interval = 2
fista.run(100, verbose=True)

# Run FISTA for least squares with lower/upper bound
data_rel = -numpy.log(data)

# Permute order to get: angles, vertical, horizontal, as default in framework.
data_rel = numpy.transpose(data_rel,(0,2,1))

# Set angles to use
angles = numpy.linspace(-numpy.pi,numpy.pi,num_angles,endpoint=False)

# Create 3D acquisition geometry and acquisition data
ag = AcquisitionGeometry('parallel',
                         '3D',
                         angles,
                         pixel_num_h=imsize,
                         pixel_num_v=imsize)
b = AcquisitionData(data_rel, geometry=ag)

# Reduce to single (noncentral) slice by extracting relevant parameters from data and its
# geometry. Perhaps create function to extract central slice automatically?
b2d = b.subset(vertical=128)
ag2d = AcquisitionGeometry('parallel',
                         '2D',
                         ag.angles,
                         pixel_num_h=ag.pixel_num_h)
b2d.geometry = ag2d

# Create 2D image geometry
ig2d = ImageGeometry(voxel_num_x=ag2d.pixel_num_h, 
                     voxel_num_y=ag2d.pixel_num_h)

# Create GPU projector/backprojector operator with ASTRA.
Example #28
0
ig = data.geometry

detectors = N
angles = np.linspace(0, np.pi, N, dtype=np.float32)
ag = AcquisitionGeometry('parallel', '2D', angles, detectors)

device = input('Available device: GPU==1 / CPU==0 ')
if device == '1':
    dev = 'gpu'
else:
    dev = 'cpu'

Aop = AstraProjectorSimple(ig, ag, dev)
sin = Aop.direct(data)

noisy_data = AcquisitionData(sin.as_array() + np.random.normal(0, 3, ig.shape))

# Setup and run the CGLS algorithm
alpha = 50
Grad = Gradient(ig)

# Form Tikhonov as a Block CGLS structure
op_CGLS = BlockOperator(Aop, alpha * Grad, shape=(2, 1))
block_data = BlockDataContainer(noisy_data, Grad.range_geometry().allocate())

x_init = ig.allocate()
cgls = CGLS(x_init=x_init, operator=op_CGLS, data=block_data)
cgls.max_iteration = 1000
cgls.update_objective_interval = 200
cgls.run(1000, verbose=False)
Example #29
0
# Create Acquisition data
detectors = N
angles = np.linspace(0, np.pi, 180, dtype=np.float32)

ag = AcquisitionGeometry('parallel', '2D', angles, detectors)

device = input('Available device: GPU==1 / CPU==0 ')
if device == '1':
    dev = 'gpu'
else:
    dev = 'cpu'

Aop = AstraProjectorSimple(ig, ag, dev)
sin = Aop.direct(data)
projection_data = AcquisitionData(sin.as_array())

# Show Ground Truth and Noisy Data
plt.figure(figsize=(10, 10))
plt.subplot(2, 1, 1)
plt.imshow(data.as_array())
plt.title('Ground Truth')
plt.colorbar()
plt.subplot(2, 1, 2)
plt.imshow(projection_data.as_array())
plt.title('Projection Data')
plt.colorbar()
plt.show()

# Setup and run the CGLS algorithm
x_init = ig.allocate()