Example #1
0
def test_comp_proj():
    r3 = odl.rn(3)
    r3xr3 = odl.ProductSpace(r3, 2)

    x = r3xr3.element([[1, 2, 3], [4, 5, 6]])
    proj_0 = odl.ComponentProjection(r3xr3, 0)
    assert x[0] == proj_0(x)
    assert x[0] == proj_0(x, out=proj_0.range.element())

    proj_1 = odl.ComponentProjection(r3xr3, 1)
    assert x[1] == proj_1(x)
    assert x[1] == proj_1(x, out=proj_1.range.element())
Example #2
0
def test_comp_proj_adjoint():
    r3 = odl.rn(3)
    r3xr3 = odl.ProductSpace(r3, 2)

    x = r3.element([1, 2, 3])

    result_0 = r3xr3.element([[1, 2, 3], [0, 0, 0]])
    proj_0 = odl.ComponentProjection(r3xr3, 0)

    assert result_0 == proj_0.adjoint(x)
    assert result_0 == proj_0.adjoint(x, out=proj_0.domain.element())

    result_1 = r3xr3.element([[0, 0, 0], [1, 2, 3]])
    proj_1 = odl.ComponentProjection(r3xr3, 1)

    assert result_1 == proj_1.adjoint(x)
    assert result_1 == proj_1.adjoint(x, out=proj_1.domain.element())
Example #3
0
def test_comp_proj_indices():
    r3 = odl.rn(3)
    r33 = odl.ProductSpace(r3, 3)

    x = r33.element([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

    proj = odl.ComponentProjection(r33, [0, 2])
    assert x[[0, 2]] == proj(x)
    assert x[[0, 2]] == proj(x, out=proj.range.element())
Example #4
0
def test_comp_proj_slice():
    r3 = odl.Rn(3)
    r33 = odl.ProductSpace(r3, 3)

    x = r33.element([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

    proj = odl.ComponentProjection(r33, slice(0, 2))
    assert x[0:2] == proj(x)
    assert x[0:2] == proj(x, out=proj.range.element())
Example #5
0
def test_comp_proj_adjoint_slice():
    r3 = odl.rn(3)
    r33 = odl.ProductSpace(r3, 3)

    x = r33[0:2].element([[1, 2, 3], [4, 5, 6]])

    result = r33.element([[1, 2, 3], [4, 5, 6], [0, 0, 0]])
    proj = odl.ComponentProjection(r33, slice(0, 2))

    assert result == proj.adjoint(x)
    assert result == proj.adjoint(x, out=proj.domain.element())
def tnv(operator, data, alpha, sinfo, eta, nonneg=True, datafit=None):

    space = operator.domain
    grad = odl.Gradient(space)

    P = odl.ComponentProjection(grad.range**2, 0)
    D = P.adjoint * grad
    Q = odl.ComponentProjection(grad.range**2, 1)
    A = odl.BroadcastOperator(operator, D)

    F1 = get_data_fit(datafit, data)
    N = odl.solvers.NuclearNorm(D.range, outer_exp=1, singular_vector_exp=1)
    F2 = alpha * N.translated(-Q.adjoint(eta * grad(sinfo)))
    F = odl.solvers.SeparableSum(F1, F2)

    if nonneg:
        G = odl.solvers.IndicatorNonnegativity(space)
    else:
        G = odl.solvers.ZeroFunctional(space)

    return G, F, A
Example #7
0
# Initialize gradient operator
gradient = odl.Gradient(reco_space, method='forward')

gradient_back = odl.Gradient(reco_space, method='backward')
eps = odl.DiagonalOperator(gradient_back, reco_space.ndim)

# Create the domain of the problem, given by the reconstruction space and the
# range of the gradient on the reconstruction space.
domain = odl.ProductSpace(reco_space, gradient.range)

# Column vector of three operators defined as:
# 1. Computes ``A(x)``
# 2. Computes ``grad(x) - y``
# 3. Computes ``eps(y)``
op = odl.BroadcastOperator(
    ray_trafo * odl.ComponentProjection(domain, 0),
    odl.ReductionOperator(gradient, odl.ScalingOperator(gradient.range, -1)),
    eps * odl.ComponentProjection(domain, 1))

# Do not use the g functional, set it to zero.
g = odl.solvers.ZeroFunctional(op.domain)

# Create functionals for the dual variable

# l2-squared data matching
l2_norm = odl.solvers.L2NormSquared(ray_trafo.range).translated(data)

# The l1-norms scaled by regularization paramters
l1_norm_1 = 0.001 * odl.solvers.L1Norm(gradient.range)
l1_norm_2 = 1e-4 * odl.solvers.L1Norm(eps.range)
Example #8
0
                                                  noisy_data,
                                                  niter=10,
                                                  callback=callback)
        multigrid.graphics.show_both(*reco)

    elif reco_method == 'TV':
        insert_grad = odl.Gradient(insert_discr, pad_mode='order1')

        coarse_grad = odl.Gradient(coarse_discr, pad_mode='order1')

        # Differentiable part, build as ||. - g||^2 o P
        data_func = odl.solvers.L2NormSquared(
            sum_ray_trafo.range).translated(noisy_data) * sum_ray_trafo
        reg_param_1 = 8e-3
        reg_func_1 = reg_param_1 * (odl.solvers.L2NormSquared(coarse_discr) *
                                    odl.ComponentProjection(pspace, 0))
        smooth_func = data_func + reg_func_1

        # Non-differentiable part composed with linear operators
        reg_param = 8e-3
        nonsmooth_func = reg_param * odl.solvers.L1Norm(insert_grad.range)

        if iter == 0:
            reg_param_2 = 8e-2
        elif iter == 1:
            reg_param_2 = 8e-3
        elif iter == 2:
            reg_param_2 = 8e-4
        elif iter == 3:
            reg_param_2 = 8e-5
        elif iter == 4:
# D = data matching functional: Y1 x Y2 -> R, ||. - g1||_Y1^2 + ||. - g2||_Y2^2
# S1 = squared L2-norm: X1^2 -> R, for Tikhonov functional
# S2 = (alpha * L12-Norm): X2^2 -> R, for isotropic TV

# Operators
# A = forward operator "matrix": X1 x X2 -> Y1 x Y2
# G1 = spatial gradient: X1 -> X1^2
# G2 = spatial gradient: X2 -> X2^2
# B1 = G1 extended to X1 x X2, B1(f1, f2) = G1(f1)
# B2 = G2 extended to X1 x X2, B2(f1, f2) = G2(f2)

A = odl.ProductSpaceOperator([[R11, 0], [A21, R22]])
G1 = odl.Gradient(X1, pad_mode='symmetric')
G2 = odl.Gradient(X2, pad_mode='order1')
# Extend gradients to product space
B1 = G1 * odl.ComponentProjection(A.domain, 0)
B2 = G2 * odl.ComponentProjection(A.domain, 1)

# TODO: weighting for differences in sizes (avoid large region domination)
D = odl.solvers.L2NormSquared(A.range).translated([g1, g2])

# For isotropic TV
# alpha1 = 1e-2
# S1 = alpha1 * odl.solvers.GroupL1Norm(G1.range)
# For Tikhonov
alpha1 = 1e-2
S1 = alpha1 * odl.solvers.L2NormSquared(G1.range)
# TV on second component
alpha2 = 1e-4
S2 = alpha2 * odl.solvers.GroupL1Norm(G2.range)
Example #10
0
#sym_gradient = odl.operator.ProductSpaceOperator(
#    [[Dx, 0], [0, Dy], [0.5*Dy, 0.5*Dx]], range=W)
E = odl.operator.ProductSpaceOperator(
    [[Dx, 0], [0, Dy], [0.5*Dy, 0.5*Dx], [0.5*Dy, 0.5*Dx]])
W = E.range

# Create the domain of the problem, given by the reconstruction space and the
# range of the gradient on the reconstruction space.
domain = odl.ProductSpace(U, V)

# Column vector of three operators defined as:
# 1. Computes ``Ax``
# 2. Computes ``Gx - y``
# 3. Computes ``Ey``
op = odl.BroadcastOperator(
    A * odl.ComponentProjection(domain, 0),
    odl.ReductionOperator(G, odl.ScalingOperator(V, -1)),
    E * odl.ComponentProjection(domain, 1))

# Do not use the g functional, set it to zero.
g = odl.solvers.ZeroFunctional(domain)

# l2-squared data matching
l2_norm = odl.solvers.L2NormSquared(A.range).translated(data)

# parameters
alpha = 1e-1
beta = 1

# The l1-norms scaled by regularization paramters
l1_norm_1 = alpha * odl.solvers.L1Norm(V)
Example #11
0
# Initialize gradient and 2nd order derivative operator
gradient = odl.Gradient(reco_space)
eps = odl.DiagonalOperator(gradient, reco_space.ndim)
domain = odl.ProductSpace(gradient.domain, eps.domain)

# Assemble operators and functionals for the solver

# The linear operators are
# 1. identity on the first component for the data matching
# 2. gradient of component 1 - component 2 for the auxiliary functional
# 3. eps on the second component
# 4. projection onto the first component

lin_ops = [
    odl.ComponentProjection(domain, 0),
    odl.ReductionOperator(gradient, odl.ScalingOperator(gradient.range, -1)),
    eps * odl.ComponentProjection(domain, 1),
    odl.ComponentProjection(domain, 0)
]

# The functionals are
# 1. L2 data matching
# 2. regularization parameter 1 times L1 norm on the range of the gradient
# 3. regularization parameter 2 times L1 norm on the range of eps
# 4. box indicator on the reconstruction space

data_matching = odl.solvers.L2NormSquared(reco_space).translated(data)
reg_param1 = 4e0
regularizer1 = reg_param1 * odl.solvers.L1Norm(gradient.range)
reg_param2 = 1e0
Example #12
0
R2 = odl.tomo.RayTransform(X2, geometry)
M = odl_multigrid.MaskingOperator(X1, roi_min_pt, roi_max_pt)

A1 = R1 * M
A2 = R2
A = odl.ReductionOperator(A1, A2)

G1 = odl.Gradient(X1, pad_mode='symmetric')
G2 = odl.Gradient(X2, pad_mode='order1')

alpha1 = 1e0
alpha2 = 5e-2
S1 = alpha1 * odl.solvers.L2NormSquared(G1.range)
S2 = alpha2 * odl.solvers.GroupL1Norm(G2.range)

B1 = G1 * odl.ComponentProjection(X1 * X2, 0)
B2 = G2 * odl.ComponentProjection(X1 * X2, 1)

D = odl.solvers.L2NormSquared(A.range).translated(y)

# We check how much we gained regarding runtimes:

get_ipython().run_line_magic('timeit', 'A(A.domain.zero())')
get_ipython().run_line_magic('timeit', 'A.adjoint(A.range.zero())')

# The forward operator is not so much faster, since we still have the same
# number of rays to compute, i.e., forward projection scales with the number
# of angles and detector pixels. That is something to improve later.
# However, the adjoint is much faster since it scales with the number voxels.

# Now we do the usual steps and reconstruct:
    else:
        odl.solvers.conjugate_gradient_normal(ray_trafo_combined,
                                              reco,
                                              data,
                                              niter=niter_cg,
                                              callback=callback)
    multigrid.graphics.show_both(*reco)

elif reco_method == 'TV':
    grad_detail = odl.Gradient(space_detail, pad_mode='order1')

    l2_norm_sq = odl.solvers.L2NormSquared(ray_trafo_combined.range)
    data_func = l2_norm_sq.translated(data)

    reg_func_lowres = odl.solvers.ZeroFunctional(space_lowres)
    comp_proj_lowres = odl.ComponentProjection(pspace, 0)

    reg_param_detail = 3e-3
    reg_func_detail = (reg_param_detail *
                       odl.solvers.L1Norm(grad_detail.range))
    comp_proj_detail = odl.ComponentProjection(pspace, 1)

    min_val, max_val = np.min(reco_fbp), np.max(reco_fbp)
    box_constr = odl.solvers.IndicatorBox(pspace, min_val, max_val)
    f = odl.solvers.ZeroFunctional(pspace)

    L = [ray_trafo_combined, comp_proj_lowres, grad_detail * comp_proj_detail]
    g = [data_func, reg_func_lowres, reg_func_detail]

    ray_trafo_norm = 1.2 * odl.power_method_opnorm(ray_trafo_combined,
                                                   maxiter=4)
Example #14
0
                            planes=planes)

        c = float(norm_K) / float(norm_D)
        D *= c
        norm_D *= c
        L1 = odl.solvers.SeparableSum(
            *[(alpha / c) *
              odl.solvers.GroupL1Norm(gradient.range), (alpha * beta / c) *
              odl.solvers.GroupL1Norm(E.range)])

        g = odl.solvers.SeparableSum(
            odl.solvers.IndicatorBox(U, lower=0),
            odl.solvers.ZeroFunctional(gradient.range))

        X = D.domain
        P = [odl.ComponentProjection(X, i) for i in range(2)]
        A_ = odl.BroadcastOperator(K * P[0], D)
        f_ = odl.solvers.SeparableSum(KL, L1)
        obj_fun = f_ * A_ + g  # objective functional

        fldr = '{}/pics'.format(folder_param)
        if not os.path.exists('{}/gray_image_pet.png'.format(fldr)):
            tmp = U.element()
            tmp_op = mMR.operator_mmr()
            tmp_op.toodl(image, tmp)
            misc.save_image(tmp.asarray(), 'image_pet', fldr, planes=planes)
            tmp_op.toodl(image_mr, tmp)
            misc.save_image(tmp.asarray(), 'image_mr', fldr, planes=planes)
            tmp_op.toodl(image_ct, tmp)
            misc.save_image(tmp.asarray(), 'image_ct', fldr, planes=planes)