コード例 #1
0
    def create_simple_ImageData(self):
        N = 64
        ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
        Phantom = ImageData(geometry=ig)

        x = Phantom.as_array()

        x[int(round(N/4)):int(round(3*N/4)),
          int(round(N/4)):int(round(3*N/4))] = 0.5
        x[int(round(N/8)):int(round(7*N/8)),
          int(round(3*N/8)):int(round(5*N/8))] = 1

        return (ig, Phantom)
コード例 #2
0
    def test_BlockDataContainer_fill(self):
        print("test block data container")
        ig0 = ImageGeometry(2, 3, 4)
        ig1 = ImageGeometry(2, 3, 5)

        data0 = ImageData(geometry=ig0)
        data1 = ImageData(geometry=ig1) + 1

        data2 = ImageData(geometry=ig0) + 2
        data3 = ImageData(geometry=ig1) + 3

        cp0 = BlockDataContainer(data0, data1)
        #cp1 = BlockDataContainer(data2,data3)

        cp2 = BlockDataContainer(data0 + 1, data1 + 1)

        data0.fill(data2)
        self.assertNumpyArrayEqual(data0.as_array(), data2.as_array())
        data0 = ImageData(geometry=ig0)

        for el, ot in zip(cp0, cp2):
            print(el.shape, ot.shape)
        cp0.fill(cp2)
        self.assertBlockDataContainerEqual(cp0, cp2)
コード例 #3
0
    def process(self):
        DATA = self.get_input()

        IM = ImageData(geometry=self.volume_geometry)

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

        if self.device == 'cpu':
            return IM
        else:
            scaling = self.volume_geometry.voxel_size_x**3
            return scaling * IM
コード例 #4
0
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
コード例 #5
0
    scale = 5
    n1 = TestData.random_noise(data.as_array()/scale, mode = noise, seed = 10)*scale
elif noise == 'gaussian':
    n1 = TestData.random_noise(data.as_array(), mode = noise, seed = 10)
else:
    raise ValueError('Unsupported Noise ', noise)
noisy_data = ImageData(n1)

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

# Regularisation Parameter depending on the noise distribution
if noise == 's&p':
    alpha = 0.8
elif noise == 'poisson':
    alpha = .3
elif noise == 'gaussian':
    alpha = .2

beta = 2 * alpha

# Fidelity
コード例 #6
0
                                 ims1,
                                 interval=500,
                                 blit=True,
                                 repeat_delay=10)
plt.show()

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

# Create noisy data. Apply Gaussian noise
np.random.seed(10)
noisy_data = ImageData(data.as_array() +
                       np.random.normal(0, 0.25, size=ig.shape))

# time-frames index
tindex = [8, 16, 24]

fig1, axes1 = plt.subplots(nrows=1, ncols=3, figsize=(10, 10))
plt.subplot(1, 3, 1)
plt.imshow(noisy_data.as_array()[tindex[0], :, :])
plt.axis('off')
plt.title('Time {}'.format(tindex[0]))
plt.subplot(1, 3, 2)
plt.imshow(noisy_data.as_array()[tindex[1], :, :])
plt.axis('off')
plt.title('Time {}'.format(tindex[1]))
plt.subplot(1, 3, 3)
コード例 #7
0
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')
plt.colorbar()
plt.show()

# Create operators
op1 = Gradient(ig)
op2 = Aop

# Create BlockOperator
operator = BlockOperator(op1, op2, shape=(2, 1))
コード例 #8
0
test_case = 2

# Set up phantom size NxN by creating ImageGeometry, initialising the 
# ImageData object with this geometry and empty array and finally put some
# data into its array, and display as image.
N = 300
x1 = -1
x2 = 1
dx = (x2-x1)/N
ig = ImageGeometry(voxel_num_x=N,
                   voxel_num_y=N,
                   voxel_size_x=dx,
                   voxel_size_y=dx)
Phantom = ImageData(geometry=ig)

x = Phantom.as_array()
x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 0.5
x[:,round(3*N/8):round(5*N/8)] = 1

plt.imshow(x)
plt.title('Phantom image')
plt.colorbar()
plt.show()

# Set up AcquisitionGeometry object to hold the parameters of the measurement
# setup geometry: # Number of angles, the actual angles from 0 to 
# pi for parallel beam and 0 to 2pi for fanbeam, set the width of a detector 
# pixel relative to an object pixel, the number of detector pixels, and the 
# source-origin and origin-detector distance (here the origin-detector distance 
# set to 0 to simulate a "virtual detector" with same detector pixel size as
# object pixel size).
コード例 #9
0
    def test_FISTA_denoise_cvx(self):
        if not cvx_not_installable:
            opt = {'memopt': True}
            N = 64
            ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
            Phantom = ImageData(geometry=ig)

            x = Phantom.as_array()

            x[int(round(N / 4)):int(round(3 * N / 4)),
              int(round(N / 4)):int(round(3 * N / 4))] = 0.5
            x[int(round(N / 8)):int(round(7 * N / 8)),
              int(round(3 * N / 8)):int(round(5 * N / 8))] = 1

            # Identity operator for denoising
            I = TomoIdentity(ig)

            # Data and add noise
            y = I.direct(Phantom)
            y.array = y.array + 0.1 * np.random.randn(N, N)

            # Data fidelity term
            f_denoise = Norm2sq(I, y, c=0.5, memopt=True)

            # 1-norm regulariser
            lam1_denoise = 1.0
            g1_denoise = Norm1(lam1_denoise)

            # Initial guess
            x_init_denoise = ImageData(np.zeros((N, N)))

            # Combine with least squares and solve using generic FISTA implementation
            x_fista1_denoise, it1_denoise, timing1_denoise, \
                criter1_denoise = \
                FISTA(x_init_denoise, f_denoise, g1_denoise, opt=opt)

            print(x_fista1_denoise)
            print(criter1_denoise[-1])

            # Now denoise LS + 1-norm with FBPD
            x_fbpd1_denoise, itfbpd1_denoise, timingfbpd1_denoise,\
                criterfbpd1_denoise = \
                FBPD(x_init_denoise, I, None, f_denoise, g1_denoise)
            print(x_fbpd1_denoise)
            print(criterfbpd1_denoise[-1])

            # Compare to CVXPY

            # Construct the problem.
            x1_denoise = Variable(N**2, 1)
            objective1_denoise = Minimize(
                0.5 * sum_squares(x1_denoise - y.array.flatten()) +
                lam1_denoise * norm(x1_denoise, 1))
            prob1_denoise = Problem(objective1_denoise)

            # The optimal objective is returned by prob.solve().
            result1_denoise = prob1_denoise.solve(verbose=False,
                                                  solver=SCS,
                                                  eps=1e-12)

            # The optimal solution for x is stored in x.value and optimal objective value
            # is in result as well as in objective.value
            print(
                "CVXPY least squares plus 1-norm solution and objective value:"
            )
            print(x1_denoise.value)
            print(objective1_denoise.value)
            self.assertNumpyArrayAlmostEqual(x_fista1_denoise.array.flatten(),
                                             x1_denoise.value, 5)

            self.assertNumpyArrayAlmostEqual(x_fbpd1_denoise.array.flatten(),
                                             x1_denoise.value, 5)
            x1_cvx = x1_denoise.value
            x1_cvx.shape = (N, N)

            # Now TV with FBPD
            lam_tv = 0.1
            gtv = TV2D(lam_tv)
            gtv(gtv.op.direct(x_init_denoise))

            opt_tv = {'tol': 1e-4, 'iter': 10000}

            x_fbpdtv_denoise, itfbpdtv_denoise, timingfbpdtv_denoise,\
                criterfbpdtv_denoise = \
                FBPD(x_init_denoise, gtv.op, None, f_denoise, gtv, opt=opt_tv)
            print(x_fbpdtv_denoise)
            print(criterfbpdtv_denoise[-1])

            # Compare to CVXPY

            # Construct the problem.
            xtv_denoise = Variable((N, N))
            objectivetv_denoise = Minimize(0.5 *
                                           sum_squares(xtv_denoise - y.array) +
                                           lam_tv * tv(xtv_denoise))
            probtv_denoise = Problem(objectivetv_denoise)

            # The optimal objective is returned by prob.solve().
            resulttv_denoise = probtv_denoise.solve(verbose=False,
                                                    solver=SCS,
                                                    eps=1e-12)

            # The optimal solution for x is stored in x.value and optimal objective value
            # is in result as well as in objective.value
            print(
                "CVXPY least squares plus 1-norm solution and objective value:"
            )
            print(xtv_denoise.value)
            print(objectivetv_denoise.value)

            self.assertNumpyArrayAlmostEqual(x_fbpdtv_denoise.as_array(),
                                             xtv_denoise.value, 1)

        else:
            self.assertTrue(cvx_not_installable)
コード例 #10
0
ag = ig
N = 300
# Create Noisy data with Poisson noise
scale = 5
n1 = TestData.random_noise(data.as_array() / scale, mode='poisson',
                           seed=10) * scale
noisy_data = ImageData(n1)

# 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()

# Regularisation Parameter
alpha = 10

# Setup and run the FISTA algorithm
operator = Gradient(ig)
fid = KullbackLeibler(noisy_data)


def KL_Prox_PosCone(x, tau, out=None):

    if out is None:
コード例 #11
0
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
Grad = Gradient(ig)
Id = Identity(ig)

# Form Tikhonov as a Block CGLS structure
op_CGLS = BlockOperator(Aop, alpha * Grad, shape=(2, 1))
コード例 #12
0
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')
plt.colorbar()
plt.show()

# Create Operators
op11 = Gradient(ig)
op12 = Identity(op11.range_geometry())

op22 = SymmetrizedGradient(op11.domain_geometry())
op21 = ZeroOperator(ig, op22.range_geometry())
コード例 #13
0
while i < vert:
    if vert > 1:
        x = Phantom.subset(vertical=i).array
    else:
        x = Phantom.array
    x[round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 0.5
    x[round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 0.98
    if vert > 1:
        Phantom.fill(x, vertical=i)
    i += 1

# Display slice of phantom
if vert > 1:
    plt.imshow(Phantom.subset(vertical=0).as_array())
else:
    plt.imshow(Phantom.as_array())
plt.show()

# Set up AcquisitionGeometry object to hold the parameters of the measurement
# setup geometry: # Number of angles, the actual angles from 0 to
# pi for parallel beam, set the width of a detector
# pixel relative to an object pixe and the number of detector pixels.
angles_num = 20
det_w = 1.0
det_num = N

angles = np.linspace(0,np.pi,angles_num,endpoint=False,dtype=np.float32)*\
             180/np.pi

# Inputs: Geometry, 2D or 3D, angles, horz detector pixel count,
#         horz detector pixel size, vert detector pixel count,
コード例 #14
0
data = loader.load(TestData.SHAPES)
ig = data.geometry
ag = ig

noisy_data = ImageData(
    TestData.random_noise(data.as_array(), mode='gaussian', seed=1))
#noisy_data = ImageData(data.as_array())

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

# Setup and run the regularised CGLS algorithm  (Tikhonov with Gradient)
x_init = ig.allocate()
alpha = 2
op = Gradient(ig)

block_op = BlockOperator(Identity(ig), alpha * op, shape=(2, 1))
block_data = BlockDataContainer(noisy_data, op.range_geometry().allocate())

cgls = CGLS(x_init=x_init, operator=block_op, data=block_data)
cgls.max_iteration = 200
cgls.update_objective_interval = 5
コード例 #15
0
# Create noisy data. Apply Gaussian noise
ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N, voxel_num_z=N)
ag = ig
n1 = TestData.random_noise(phantom_tm,
                           mode='gaussian',
                           mean=0,
                           var=0.001,
                           seed=10)
noisy_data = ImageData(n1)

# Show results
sliceSel = int(0.5 * N)
plt.figure(figsize=(15, 15))
plt.subplot(3, 1, 1)
plt.imshow(noisy_data.as_array()[sliceSel, :, :], vmin=0, vmax=1)
plt.title('Axial View')
plt.colorbar()
plt.subplot(3, 1, 2)
plt.imshow(noisy_data.as_array()[:, sliceSel, :], vmin=0, vmax=1)
plt.title('Coronal View')
plt.colorbar()
plt.subplot(3, 1, 3)
plt.imshow(noisy_data.as_array()[:, :, sliceSel], vmin=0, vmax=1)
plt.title('Sagittal View')
plt.colorbar()
plt.show()

# Regularisation Parameter
alpha = 0.05
コード例 #16
0
from ccpi.astra.ops import AstraProjectorSimple

import numpy as np
import matplotlib.pyplot as plt

# Choose either a parallel-beam (1=parallel2D) or fan-beam (2=cone2D) test case
test_case = 1

# Set up phantom size NxN by creating ImageGeometry, initialising the
# ImageData object with this geometry and empty array and finally put some
# data into its array, and display as image.
N = 128
ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
Phantom = ImageData(geometry=ig)

x = Phantom.as_array()
x[round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 0.5
x[round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 1

plt.imshow(x)
plt.title('Phantom image')
plt.show()

# Set up AcquisitionGeometry object to hold the parameters of the measurement
# setup geometry: # Number of angles, the actual angles from 0 to
# pi for parallel beam and 0 to 2pi for fanbeam, set the width of a detector
# pixel relative to an object pixel, the number of detector pixels, and the
# source-origin and origin-detector distance (here the origin-detector distance
# set to 0 to simulate a "virtual detector" with same detector pixel size as
# object pixel size).
angles_num = 20
コード例 #17
0
#%%
# Show Ground Truth/Noisy Data & BackProjection

from mpl_toolkits.axes_grid1 import make_axes_locatable


def colorbar(mappable):
    ax = mappable.axes
    fig = ax.figure
    divider = make_axes_locatable(ax)
    cax = divider.append_axes("right", size="5%", pad=0.15)
    return fig.colorbar(mappable, cax=cax)


fig, ax = plt.subplots(1, 3)
img1 = ax[0].imshow(data.as_array())
ax[0].set_title('Ground Truth')
colorbar(img1)
img2 = ax[1].imshow(noisy_data.as_array())
ax[1].set_title('Projection Data')
colorbar(img2)
img3 = ax[2].imshow(back_proj.as_array())
ax[2].set_title('BackProjection')
colorbar(img3)
plt.tight_layout(h_pad=1.5)

fig1, ax1 = plt.subplots(1, 3)
img4 = ax1[0].imshow(fista.get_output().as_array())
ax1[0].set_title('LS unconstrained')
colorbar(img4)
img5 = ax1[1].imshow(fista0.get_output().as_array())
コード例 #18
0
plt.loglog(iternum[[0,-1]],[objective1.value, objective1.value], label='CVX LS+1')
plt.loglog(iternum,criter1,label='FISTA LS+1')
plt.loglog(iternum,criterfbpd1,label='FBPD LS+1')
plt.legend()
plt.show()

# Now try 1-norm and TV denoising with FBPD, first 1-norm.

# Set up phantom size NxN by creating ImageGeometry, initialising the 
# ImageData object with this geometry and empty array and finally put some
# data into its array, and display as image.
N = 64
ig = ImageGeometry(voxel_num_x=N,voxel_num_y=N)
Phantom = ImageData(geometry=ig)

x = Phantom.as_array()
x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 0.5
x[round(N/8):round(7*N/8),round(3*N/8):round(5*N/8)] = 1

plt.imshow(x)
plt.title('Phantom image')
plt.show()

# Identity operator for denoising
I = TomoIdentity(ig)

# Data and add noise
y = I.direct(Phantom)
y.array = y.array + 0.1*np.random.randn(N, N)

plt.imshow(y.array)
コード例 #19
0
from ccpi.optimisation.operators import BlockOperator, Gradient, Identity
from ccpi.optimisation.functions import L2NormSquared, L1Norm, \
                                         FunctionOperatorComposition, BlockFunction, ZeroFunction

# Create Ground truth and Noisy data
N = 100

data = np.zeros((N, N))
data[round(N / 4):round(3 * N / 4), round(N / 4):round(3 * N / 4)] = 0.5
data[round(N / 8):round(7 * N / 8), round(3 * N / 8):round(5 * N / 8)] = 1
data = ImageData(data)
ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
ag = ig

n1 = TestData.random_noise(data.as_array(),
                           mode='s&p',
                           salt_vs_pepper=0.9,
                           amount=0.2)
noisy_data = ImageData(n1)

# Regularisation Parameter
alpha = 5

###############################################################################
# Setup and run the FISTA algorithm
operator = Gradient(ig)
fidelity = L1Norm(b=noisy_data)
regulariser = FunctionOperatorComposition(alpha * L2NormSquared(), operator)

x_init = ig.allocate()
    n1 = TestData.random_noise(data.as_array() / scale, mode=noise,
                               seed=10) * scale
elif noise == 'gaussian':
    n1 = TestData.random_noise(data.as_array(), mode=noise, seed=10)
else:
    raise ValueError('Unsupported Noise ', noise)
noisy_data = ImageData(n1)

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

# Regularisation Parameter depending on the noise distribution
if noise == 's&p':
    alpha = 0.8
elif noise == 'poisson':
    alpha = .3
elif noise == 'gaussian':
    alpha = .2

beta = 2 * alpha

# Fidelity
コード例 #21
0
plt.imshow(cgls.get_output().as_array())
plt.colorbar()
plt.title('CGLS reconstruction')

plt.subplot(2, 2, 2)
plt.imshow(fista.get_output().as_array())
plt.colorbar()
plt.title('FISTA reconstruction')

plt.subplot(2, 2, 3)
plt.imshow(pdhg.get_output().as_array())
plt.colorbar()
plt.title('PDHG reconstruction')

plt.subplot(2, 2, 4)
plt.imshow(recon_cgls_astra.as_array())
plt.colorbar()
plt.title('CGLS astra')

plt.show()

diff1 = pdhg.get_output() - recon_cgls_astra
diff2 = fista.get_output() - recon_cgls_astra
diff3 = cgls.get_output() - recon_cgls_astra

plt.figure(figsize=(15, 15))

plt.subplot(3, 1, 1)
plt.imshow(diff1.abs().as_array())
plt.title('Diff PDHG vs CGLS astra')
plt.colorbar()