Beispiel #1
0
def test_astra_cuda_projector_parallel3d():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0, 0],
                                 max_pt=[4, 5, 6])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    geom = odl.tomo.Parallel3dAxisGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #2
0
def test_astra_cuda_projector_helical_conebeam():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0, 0],
                                 max_pt=[4, 5, 6])

    # Create circular cone beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    src_rad = 1000
    det_rad = 100
    pitch = 0.5
    geom = odl.tomo.HelicalConeFlatGeometry(angle_part, det_part, src_rad,
                                            det_rad, pitch)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #3
0
def test_astra_cpu_projector_parallel2d():
    """ASTRA CPU forward and back projection for 2d parallel geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[4, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #4
0
def load_data():
    """Get the data from disk.

    Returns
    -------
    mat1_sino, mat2_sino : numpy.ndarray
        projection of material 1 and 2
    geometry : odl.tomo.Geometry
        Geometry of the data
    """
    current_path = os.path.dirname(os.path.realpath(__file__))
    data_path = os.path.join(current_path, 'data',
                             'aux_corr_in_real_ct_image.mat')

    try:
        data_mat = sio.loadmat(data_path)
    except IOError:
        raise IOError('data/aux_corr_in_real_ct_image.mat missing, contact '
                      'developers for a copy of the data or use another data '
                      'source.')

    data = data_mat['decomposedBasisProjectionsmmObj']
    data = data.swapaxes(0, 2)

    angle_partition = odl.uniform_partition(0, np.pi, 180)
    detector_partition = odl.uniform_partition(-150 * np.sqrt(2),
                                               150 * np.sqrt(2), 853)
    geometry = odl.tomo.Parallel2dGeometry(angle_partition, detector_partition)

    return data, geometry
Beispiel #5
0
def test_astra_cpu_projector_fanflat():
    """ASTRA CPU forward and back projection for fanflat geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[4, 5])

    # Create fan beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    src_rad = 100
    det_rad = 10
    geom = odl.tomo.FanFlatGeometry(angle_part, det_part, src_rad, det_rad)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #6
0
def test_empty_partition():
    """Check if empty partitions behave as expected and all methods work."""
    part = odl.RectPartition(odl.IntervalProd([], []),
                             odl.uniform_grid([], [], ()))

    assert part.cell_boundary_vecs == ()
    assert part.nodes_on_bdry is True
    assert part.nodes_on_bdry_byaxis == ()
    assert part.has_isotropic_cells
    assert part.boundary_cell_fractions == ()
    assert part.cell_sizes_vecs == ()
    assert np.array_equal(part.cell_sides, [])
    assert part.cell_volume == 0

    same = odl.RectPartition(odl.IntervalProd([], []),
                             odl.uniform_grid([], [], ()))
    assert part == same
    assert hash(part) == hash(same)
    other = odl.uniform_partition(0, 1, 4)
    assert part != other

    assert part[[]] == part
    assert part.insert(0, other) == other
    assert other.insert(0, part) == other
    assert other.insert(1, part) == other
    assert part.squeeze() == part
    assert part.index([]) == ()
    part.byaxis
    assert part == odl.uniform_partition([], [], ())
    repr(part)
Beispiel #7
0
def test_circular_cone_flat():
    """Conebeam geometry with circular acquisition and a flat 2D detector."""

    # Parameters
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition([0, 0], [1, 1], [10, 10])
    src_rad = 10
    det_rad = 5

    with pytest.raises(TypeError):
        odl.tomo.CircularConeFlatGeometry([0, 1], dpart, src_rad, det_rad)
    with pytest.raises(TypeError):
        odl.tomo.CircularConeFlatGeometry(apart, [0, 1], src_rad, det_rad)
    with pytest.raises(ValueError):
        odl.tomo.CircularConeFlatGeometry(apart, dpart, -1, det_rad)
    with pytest.raises(ValueError):
        odl.tomo.CircularConeFlatGeometry(apart, dpart, src_rad, -1)

    # Initialize
    geom = odl.tomo.CircularConeFlatGeometry(apart, dpart, src_rad, det_rad)

    assert all_almost_equal(geom.angles, apart.points().ravel())

    with pytest.raises(ValueError):
        geom.det_refpoint(2 * full_angle)

    assert geom.ndim == 3
    assert np.linalg.norm(geom.det_refpoint(0)) == det_rad
    assert np.linalg.norm(geom.src_position(np.pi)) == src_rad
    assert isinstance(geom.detector, odl.tomo.Flat2dDetector)

    # check str and repr work without crashing and return something
    assert str(geom)
    assert repr(geom)
def test_fbp_reconstruction_filters(filter_type, frequency_scaling):
    """Validate that the various filters work as expected."""

    apart = odl.uniform_partition(0, np.pi, 500)

    discr_reco_space = odl.uniform_discr([-20, -20], [20, 20],
                                         [100, 100], dtype='float32')

    # Geometry
    dpart = odl.uniform_partition(-30, 30, 500)
    geom = tomo.Parallel2dGeometry(apart, dpart)

    # Ray transform
    projector = tomo.RayTransform(discr_reco_space, geom, impl='astra_cuda')

    # Create Shepp-Logan phantom
    vol = odl.phantom.shepp_logan(projector.domain, modified=False)

    # Project data
    projections = projector(vol)

    # Create FBP operator with filters and apply to projections
    fbp_operator = odl.tomo.fbp_op(projector,
                                   filter_type=filter_type,
                                   frequency_scaling=frequency_scaling)

    fbp_result = fbp_operator(projections)

    maxerr = vol.norm() / 5.0
    error = vol.dist(fbp_result)
    assert error < maxerr
Beispiel #9
0
def test_circular_cone_flat():
    """Conebeam geometry with circular acquisition and a flat 2D detector."""

    # Parameters
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition([0, 0], [1, 1], [10, 10])
    src_rad = 10
    det_rad = 5

    with pytest.raises(TypeError):
        odl.tomo.CircularConeFlatGeometry([0, 1], dpart, src_rad, det_rad)
    with pytest.raises(TypeError):
        odl.tomo.CircularConeFlatGeometry(apart, [0, 1], src_rad, det_rad)
    with pytest.raises(ValueError):
        odl.tomo.CircularConeFlatGeometry(apart, dpart, -1, det_rad)
    with pytest.raises(ValueError):
        odl.tomo.CircularConeFlatGeometry(apart, dpart, src_rad, -1)

    # Initialize
    geom = odl.tomo.CircularConeFlatGeometry(apart, dpart, src_rad, det_rad)

    assert all_almost_equal(geom.angles, apart.points().ravel())

    with pytest.raises(ValueError):
        geom.det_refpoint(2 * full_angle)

    assert geom.ndim == 3
    assert np.linalg.norm(geom.det_refpoint(0)) == det_rad
    assert np.linalg.norm(geom.src_position(np.pi)) == src_rad
    assert isinstance(geom.detector, odl.tomo.Flat2dDetector)

    # check str and repr work without crashing and return something
    assert str(geom)
    assert repr(geom)
Beispiel #10
0
def test_parallel_2d_orientation(det_pos_init_2d):
    """Check if the orientation is positive for any ``det_pos_init``."""
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition(0, 1, 10)
    det_pos_init = det_pos_init_2d
    geom = odl.tomo.Parallel2dGeometry(apart, dpart, det_pos_init=det_pos_init)

    assert all_almost_equal(geom.det_pos_init, det_pos_init)
    assert all_almost_equal(geom.det_refpoint(0), det_pos_init)
    assert all_almost_equal(geom.det_point_position(0, 0), det_pos_init)

    # The detector-to-source normal should always be perpendicular to the
    # detector axis and form a positively oriented system
    for angle in [0, np.pi / 2, 3 * np.pi / 4, np.pi]:
        dot = np.dot(geom.det_to_src(angle, 0), geom.det_axis(angle))
        assert dot == pytest.approx(0)

        normal_det_to_src = (geom.det_to_src(angle, 0) /
                             np.linalg.norm(geom.det_to_src(angle, 0)))

        orient = np.linalg.det(
            np.vstack([normal_det_to_src,
                       geom.det_axis(angle)]))
        assert orient == pytest.approx(1)
Beispiel #11
0
def test_fbp_reconstruction_filters(filter_type, frequency_scaling):
    """Validate that the various filters work as expected."""

    apart = odl.uniform_partition(0, np.pi, 500)

    discr_reco_space = odl.uniform_discr([-20, -20], [20, 20], [100, 100],
                                         dtype='float32')

    # Geometry
    dpart = odl.uniform_partition(-30, 30, 500)
    geom = tomo.Parallel2dGeometry(apart, dpart)

    # Ray transform
    projector = tomo.RayTransform(discr_reco_space, geom, impl='astra_cuda')

    # Create Shepp-Logan phantom
    vol = odl.phantom.shepp_logan(projector.domain, modified=False)

    # Project data
    projections = projector(vol)

    # Create FBP operator with filters and apply to projections
    fbp_operator = odl.tomo.fbp_op(projector,
                                   filter_type=filter_type,
                                   frequency_scaling=frequency_scaling)

    fbp_result = fbp_operator(projections)

    maxerr = vol.norm() / 5.0
    error = vol.dist(fbp_result)
    assert error < maxerr
Beispiel #12
0
def test_discretizedspace_init():
    """Test initialization and basic properties of DiscretizedSpace."""
    # Real space
    part = odl.uniform_partition([0, 0], [1, 1], (2, 4))
    tspace = odl.rn(part.shape)

    discr = DiscretizedSpace(part, tspace)
    assert discr.tspace == tspace
    assert discr.partition == part
    assert discr.exponent == tspace.exponent
    assert discr.axis_labels == ('$x$', '$y$')
    assert discr.is_real

    # Complex space
    tspace_c = odl.cn(part.shape)
    discr = DiscretizedSpace(part, tspace_c)
    assert discr.is_complex

    # Make sure repr shows something
    assert repr(discr) != ''

    # Error scenarios
    part_1d = odl.uniform_partition(0, 1, 2)
    with pytest.raises(ValueError):
        DiscretizedSpace(part_1d, tspace)  # wrong dimensionality

    part_diffshp = odl.uniform_partition([0, 0], [1, 1], (3, 4))
    with pytest.raises(ValueError):
        DiscretizedSpace(part_diffshp, tspace)  # shape mismatch
Beispiel #13
0
def test_geom_to_vec():
    """Create ASTRA projection geometry vectors using ODL geometries."""

    apart = odl.uniform_partition(0, 2 * np.pi, 5)
    dpart = odl.uniform_partition(-40, 40, 10)

    # Fanbeam flat
    src_rad = 10
    det_rad = 5
    geom_ff = odl.tomo.FanFlatGeometry(apart, dpart, src_rad, det_rad)
    vec = odl.tomo.astra_conebeam_2d_geom_to_vec(geom_ff)

    assert vec.shape == (apart.size, 6)

    # Circular cone flat
    dpart = odl.uniform_partition([-40, -3], [40, 3], (10, 5))
    geom_ccf = odl.tomo.CircularConeFlatGeometry(apart, dpart, src_rad,
                                                 det_rad)
    vec = odl.tomo.astra_conebeam_3d_geom_to_vec(geom_ccf)
    assert vec.shape == (apart.size, 12)

    # Helical cone flat
    pitch = 1
    geom_hcf = odl.tomo.HelicalConeFlatGeometry(apart, dpart, src_rad,
                                                det_rad, pitch)
    vec = odl.tomo.astra_conebeam_3d_geom_to_vec(geom_hcf)
    assert vec.shape == (apart.size, 12)
Beispiel #14
0
def test_astra_cuda_projector_helical_conebeam():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0, 0], end=[4, 5, 6])

    # Create circular cone beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    src_rad = 1000
    det_rad = 100
    pitch = 0.5
    geom = odl.tomo.HelicalConeFlatGeometry(angle_part, det_part, src_rad,
                                            det_rad, pitch)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #15
0
def test_parallel_3d_frommatrix():
    """Test the ``frommatrix`` constructor in 3d parallel geometry."""
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition([0, 0], [1, 1], (10, 10))
    # Need a somewhat simpler rotation in 3d to not go crazy imagining the
    # rotation.
    # This one rotates by +pi/2 in phi and -pi/2 in theta, resulting in the
    # axis remapping x->y, y->-z, z->-x.
    rot_matrix = np.array([[0, 0, -1], [1, 0, 0], [0, -1, 0]], dtype=float)
    geom = odl.tomo.Parallel3dAxisGeometry.frommatrix(apart, dpart, rot_matrix)

    # Axis was [0, 0, 1], gets mapped to [-1, 0, 0]
    assert all_almost_equal(geom.axis, [-1, 0, 0])

    # Detector position starts at [0, 1, 0] and gets mapped to [0, 0, -1]
    assert all_almost_equal(geom.det_pos_init, [0, 0, -1])

    # Detector axes start at [1, 0, 0] and [0, 0, 1], and get mapped to
    # [0, 1, 0] and [-1, 0, 0]
    assert all_almost_equal(geom.det_axes_init, ([0, 1, 0], [-1, 0, 0]))

    # With translation (1, 1, 1)
    matrix = np.hstack([rot_matrix, [[1], [1], [1]]])
    geom = odl.tomo.Parallel3dAxisGeometry.frommatrix(apart, dpart, matrix)

    assert all_almost_equal(geom.translation, (1, 1, 1))
    assert all_almost_equal(geom.det_pos_init, geom.translation + [0, 0, -1])
Beispiel #16
0
def test_parallel_2d_slanted_detector():
    """Check if non-standard detector axis is handled correctly."""
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition(0, 1, 10)

    # Detector forms a 45 degree angle with the x axis at initial position,
    # with positive direction upwards
    init_axis = [1, 1]
    geom = odl.tomo.Parallel2dGeometry(apart,
                                       dpart,
                                       det_pos_init=[0, 1],
                                       det_axis_init=init_axis)

    assert all_almost_equal(geom.det_pos_init, [0, 1])

    norm_axis = np.array(init_axis, dtype=float)
    norm_axis /= np.linalg.norm(norm_axis)
    assert all_almost_equal(geom.det_axis_init, norm_axis)

    sqrt_1_2 = np.sqrt(1.0 / 2.0)
    # At angle 0: detector position at param 1 should be
    # [0, 1] + [sqrt(1/2), sqrt(1/2)]
    assert all_almost_equal(geom.det_point_position(0, 1),
                            [sqrt_1_2, 1 + sqrt_1_2])

    # At angle pi/2: detector position at param 1 should be
    # [-1, 0] + [-sqrt(1/2), +sqrt(1/2)]
    assert all_almost_equal(geom.det_point_position(np.pi / 2, 1),
                            [-1 - sqrt_1_2, sqrt_1_2])
Beispiel #17
0
def test_parallel_3d_orientation(axis):
    """Check if the orientation is positive for any ``axis``."""
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition([0, 0], [1, 1], (10, 10))
    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=axis)

    norm_axis = np.array(axis, dtype=float) / np.linalg.norm(axis)
    assert all_almost_equal(geom.axis, norm_axis)
    # The symmetry axis should be the second detector axis by default
    assert all_almost_equal(geom.axis, geom.det_axes_init[1])

    # The detector-to-source normal should always be perpendicular to both
    # detector axes, and the triplet (normal, det_ax0, det_ax1) should form
    # a positively oriented system
    for angle in [0, np.pi / 2, 3 * np.pi / 4, np.pi]:
        dot0 = np.dot(geom.det_to_src(angle, [0, 0]), geom.det_axes(angle)[0])
        dot1 = np.dot(geom.det_to_src(angle, [0, 0]), geom.det_axes(angle)[1])
        assert dot0 == pytest.approx(0)
        assert dot1 == pytest.approx(0)

        normal_det_to_src = (geom.det_to_src(angle, [0, 0]) /
                             np.linalg.norm(geom.det_to_src(angle, [0, 0])))

        axis_0, axis_1 = geom.det_axes(angle)
        orient = np.linalg.det(np.vstack([normal_det_to_src, axis_0, axis_1]))
        assert orient == pytest.approx(1)

    # check str and repr work without crashing and return a non-empty string
    assert str(geom)
    assert repr(geom)
Beispiel #18
0
def test_scikit_radon_projector_parallel2d():
    """Parallel 2D forward and backward projectors on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5), dtype='float32')
    phantom = odl.util.phantom.cuboid(reco_space, begin=0.5, end=1)

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = scikit_radon_forward(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = scikit_radon_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #19
0
def geometry(request):
    geom = request.param
    m = 100
    n_angles = 100

    if geom == 'par2d':
        apart = odl.uniform_partition(0, np.pi, n_angles)
        dpart = odl.uniform_partition(-30, 30, m)
        return odl.tomo.Parallel2dGeometry(apart, dpart)
    elif geom == 'par3d':
        apart = odl.uniform_partition(0, np.pi, n_angles)
        dpart = odl.uniform_partition([-30, -30], [30, 30], (m, m))
        return odl.tomo.Parallel3dAxisGeometry(apart, dpart)
    elif geom == 'cone2d':
        apart = odl.uniform_partition(0, 2 * np.pi, n_angles)
        dpart = odl.uniform_partition(-30, 30, m)
        return odl.tomo.FanFlatGeometry(apart, dpart, src_radius=200,
                                        det_radius=100)
    elif geom == 'cone3d':
        apart = odl.uniform_partition(0, 2 * np.pi, n_angles)
        dpart = odl.uniform_partition([-60, -60], [60, 60], (m, m))
        return odl.tomo.ConeFlatGeometry(apart, dpart,
                                         src_radius=200, det_radius=100)
    elif geom == 'helical':
        apart = odl.uniform_partition(0, 8 * 2 * np.pi, n_angles)
        dpart = odl.uniform_partition([-30, -3], [30, 3], (m, m))
        return odl.tomo.ConeFlatGeometry(apart, dpart, pitch=5.0,
                                         src_radius=200, det_radius=100)
    else:
        raise ValueError('geom not valid')
Beispiel #20
0
def test_scikit_radon_projector_parallel2d():
    """Parallel 2D forward and backward projectors on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[5, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = scikit_radon_forward(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = scikit_radon_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #21
0
def test_astra_cuda_projector_parallel3d():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0, 0], end=[4, 5, 6])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    geom = odl.tomo.Parallel3dAxisGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #22
0
def test_geom_to_vec():
    """Create ASTRA projection geometry vectors using ODL geometries."""

    apart = odl.uniform_partition(0, 2 * np.pi, 5)
    dpart = odl.uniform_partition(-40, 40, 10)

    # Fanbeam flat
    src_rad = 10
    det_rad = 5
    geom_ff = odl.tomo.FanBeamGeometry(apart, dpart, src_rad, det_rad)
    vec = odl.tomo.astra_conebeam_2d_geom_to_vec(geom_ff)

    assert vec.shape == (apart.size, 6)

    # Circular cone flat
    dpart = odl.uniform_partition([-40, -3], [40, 3], (10, 5))
    geom_ccf = odl.tomo.ConeBeamGeometry(apart, dpart, src_rad, det_rad)
    vec = odl.tomo.astra_conebeam_3d_geom_to_vec(geom_ccf)
    assert vec.shape == (apart.size, 12)

    # Helical cone flat
    pitch = 1
    geom_hcf = odl.tomo.ConeBeamGeometry(apart, dpart, src_rad, det_rad,
                                         pitch=pitch)
    vec = odl.tomo.astra_conebeam_3d_geom_to_vec(geom_hcf)
    assert vec.shape == (apart.size, 12)
Beispiel #23
0
def test_astra_cpu_projector_fanflat():
    """ASTRA CPU forward and back projection for fanflat geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[4, 5])

    # Create fan beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    src_rad = 100
    det_rad = 10
    geom = odl.tomo.FanFlatGeometry(angle_part, det_part, src_rad, det_rad)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Beispiel #24
0
def test_astra_cpu_projector_parallel2d():
    """ASTRA CPU forward and back projection for 2d parallel geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[4, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
def prj_factory(Nx, Ny, Np, Nd, ret_A=False):
    '''
    returns cuda fwd and bwd projectors for given 2d geometry.

    Inputs
    Nx,Ny -> voxels in x and y dims
    Np -> number of angles
    Nd -> number of det elements

    Outputs
    fwd -> forward projector, calculates Ax
        Input Nx*Ny matrix
        Output Np*Nd matrix
    bwd -> backward projector, calculates A^Tx
        Input Nx*Ny matrix
        Output Np*Nd matrix
    '''
    reco_space = odl.uniform_discr([0, 0], [1, 1], [Nx, Ny], dtype='float32')
    angle_partition = odl.uniform_partition(0, 2 * pi, Np)
    detector_partition = odl.uniform_partition(-0.1, 1.1, Nd)
    geometry = odl.tomo.Parallel2dGeometry(angle_partition, detector_partition)
    ray_trafo = odl.tomo.RayTransform(reco_space, geometry, impl='astra_cuda')
    fwd = lambda X: ray_trafo(X).asarray()
    bwd = lambda X: ray_trafo.adjoint(X).asarray()
    return fwd, bwd
Beispiel #26
0
def test_parallel_3d_single_axis_geometry():
    """General parallel 3D geometries."""

    # Parameters
    full_angle = np.pi
    apart = odl.uniform_partition(0, full_angle, 10)
    dpart = odl.uniform_partition([0, 0], [1, 1], [10, 10])

    # Bad init
    with pytest.raises(TypeError):
        odl.tomo.Parallel3dAxisGeometry([0, 1], dpart)
    with pytest.raises(TypeError):
        odl.tomo.Parallel3dAxisGeometry(apart, [0, 1])

    # Initialize
    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[0, 0, 1])

    with pytest.raises(ValueError):
        geom.rotation_matrix(2 * full_angle)

    # rotation of cartesian basis vectors about each other
    coords = np.eye(3)

    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[1, 0, 0])
    rot_mat = geom.rotation_matrix(np.pi / 2)
    assert all_almost_equal(rot_mat.dot(coords),
                            [[1, 0, 0], [0, 0, -1], [0, 1, 0]])

    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[0, 1, 0])
    rot_mat = geom.rotation_matrix(np.pi / 2)
    assert all_almost_equal(rot_mat.dot(coords),
                            [[0, 0, 1], [0, 1, 0], [-1, 0, 0]])

    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[0, 0, 1])
    rot_mat = geom.rotation_matrix(np.pi / 2)
    assert all_almost_equal(rot_mat.dot(coords),
                            [[0, -1, 0], [1, 0, 0], [0, 0, 1]])

    # rotation axis
    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[1, 0, 0])
    assert all_equal(geom.axis, np.array([1, 0, 0]))
    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[0, 1, 0])
    assert all_equal(geom.axis, np.array([0, 1, 0]))
    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[0, 0, 1])
    assert all_equal(geom.axis, np.array([0, 0, 1]))
    geom = odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=[1, 2, 3])
    assert all_equal(geom.axis,
                     np.array([1, 2, 3]) / np.linalg.norm([1, 2, 3]))

    with pytest.raises(ValueError):
        odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=(1, ))
    with pytest.raises(ValueError):
        odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=(1, 2))
    with pytest.raises(ValueError):
        odl.tomo.Parallel3dAxisGeometry(apart, dpart, axis=(1, 2, 3, 4))

    # check str and repr work without crashing and return something
    assert str(geom)
    assert repr(geom)
    def _build_forward_op(self, upscale_shape, impl, num_angles):
        reco_space = self.space
        if self.inner_circle:
            space = odl.uniform_discr(min_pt=reco_space.min_pt,
                                      max_pt=reco_space.max_pt,
                                      shape=(upscale_shape, upscale_shape),
                                      dtype=np.float32)
            min_pt = reco_space.min_pt
            max_pt = reco_space.max_pt
            proj_space = odl.uniform_discr(
                min_pt,
                max_pt,
                2 * (2 * int(reco_space.max_pt[0]) - 1, ),
                dtype=np.float32)
            detector_length = get_detector_length(proj_space)
            det_partition = odl.uniform_partition(
                -np.sqrt((reco_space.shape[0] / 2.)**2 / 2),
                np.sqrt((reco_space.shape[0] / 2.)**2 / 2), detector_length)
        else:
            space = odl.uniform_discr(min_pt=reco_space.min_pt,
                                      max_pt=reco_space.max_pt,
                                      shape=(upscale_shape, upscale_shape),
                                      dtype=np.float32)
            min_pt = reco_space.min_pt
            max_pt = reco_space.max_pt
            proj_space = odl.uniform_discr(min_pt,
                                           max_pt,
                                           2 * (reco_space.shape[0], ),
                                           dtype=np.float32)
            detector_length = get_detector_length(proj_space)
            det_partition = odl.uniform_partition(-reco_space.shape[0] / 2.,
                                                  reco_space.shape[0] / 2.,
                                                  detector_length)
        angle_partition = odl.uniform_partition(0, np.pi, num_angles)
        reco_geometry = odl.tomo.Parallel2dGeometry(angle_partition,
                                                    det_partition)
        ray_trafo = odl.tomo.RayTransform(space, reco_geometry, impl=impl)

        def get_reco_ray_trafo(**kwargs):
            return odl.tomo.RayTransform(reco_space, reco_geometry, **kwargs)

        reco_ray_trafo = get_reco_ray_trafo(impl=impl)

        class _ResizeOperator(odl.Operator):
            def __init__(self):
                super().__init__(reco_space, space)

            def _call(self, x, out, **kwargs):
                out.assign(
                    space.element(
                        resize(x, (upscale_shape, upscale_shape), order=1)))

        # forward operator
        resize_op = _ResizeOperator()
        forward_op = ray_trafo * resize_op
        return forward_op, get_reco_ray_trafo, reco_ray_trafo
Beispiel #28
0
    def __init__(self, data_obj, data_struct=True, **kwargs):
        # %% Store the input in the object
        # BE F*****G CONSISTENT WITH RENAMING ETC.
        self.pix = data_obj.voxels[0]
        self.angles = data_obj.angles
        self.src_rad = data_obj.src_rad
        self.det_rad = data_obj.det_rad
        self.magn = self.src_rad / (self.src_rad + self.det_rad)
        self.data_struct = data_struct
        self.rec_methods = []

        # %% Set up the geometry
        self.phantom = data_obj
        # Make the reconstruction space
        self.reco_space = self.phantom.reco_space
        voxels = self.phantom.voxels
        factor = 2
        dpix = [int(factor * voxels[0]), voxels[1]]
        self.w_detu = (2 * self.phantom.detecsize[0]) / dpix[0]
        self.w_detv = (2 * self.phantom.detecsize[1]) / dpix[1]
        if self.phantom.data_type == 'simulated':
            self.PH = data_obj.PH
            self.noise = data_obj.noise
            # Do we need a mask?
            src_radius = self.src_rad * self.phantom.volumesize[0] * 2
            det_radius = self.det_rad * self.phantom.volumesize[0] * 2
            # Make a circular scanning geometry
            angle_partition = odl.uniform_partition(0, 2 * np.pi, self.angles)
            self.angle_space = odl.uniform_discr_frompartition(angle_partition)
            # Make a flat detector space
            det_partition = odl.uniform_partition(-self.phantom.detecsize,
                                                  self.phantom.detecsize, dpix)
            self.det_space = odl.uniform_discr_frompartition(det_partition,
                                                             dtype='float32')
            # Create geometry
            self.geometry = odl.tomo.ConeFlatGeometry(angle_partition,
                                                      det_partition,
                                                      src_radius=src_radius,
                                                      det_radius=det_radius,
                                                      axis=[0, 0, 1])
        else:
            src_radius = self.phantom.src_rad
            det_radius = self.phantom.det_rad
            self.pix_size = self.phantom.pix_size
            self.angle_space = self.phantom.angle_space
            self.angles = np.size(self.angle_space)
            self.det_space = self.phantom.det_space
            self.geometry = self.phantom.geometry

        # %% Create the FP and BP and the data
        # Forward Projection
        self.FwP = odl.tomo.RayTransform(self.reco_space,
                                         self.geometry,
                                         use_cache=False)
        self.rs_detu = int(2**(np.ceil(np.log2(dpix[0])) + 1))
        self.g = self.phantom.g
Beispiel #29
0
def test_astra_projection_geometry():
    """Create ASTRA projection geometry from geometry objects."""

    with pytest.raises(TypeError):
        odl.tomo.astra_projection_geometry(None)

    apart = odl.uniform_partition(0, 2 * np.pi, 5)
    dpart = odl.uniform_partition(-40, 40, 10)

    # motion sampling grid, detector sampling grid but not uniform
    dpart_0 = odl.RectPartition(odl.IntervalProd(0, 3), odl.RectGrid([0, 1,
                                                                      3]))
    geom_p2d = odl.tomo.Parallel2dGeometry(apart, dpart=dpart_0)
    with pytest.raises(ValueError):
        odl.tomo.astra_projection_geometry(geom_p2d)

    # detector sampling grid, motion sampling grid
    geom_p2d = odl.tomo.Parallel2dGeometry(apart, dpart)
    odl.tomo.astra_projection_geometry(geom_p2d)

    # Parallel 2D geometry
    geom_p2d = odl.tomo.Parallel2dGeometry(apart, dpart)
    astra_geom = odl.tomo.astra_projection_geometry(geom_p2d)
    assert astra_geom['type'] == 'parallel'

    # Fan flat
    src_rad = 10
    det_rad = 5
    geom_ff = odl.tomo.FanFlatGeometry(apart, dpart, src_rad, det_rad)
    astra_geom = odl.tomo.astra_projection_geometry(geom_ff)
    assert astra_geom['type'] == 'fanflat_vec'

    dpart = odl.uniform_partition([-40, -3], [40, 3], (10, 5))

    # Parallel 3D geometry
    geom_p3d = odl.tomo.Parallel3dAxisGeometry(apart, dpart)
    odl.tomo.astra_projection_geometry(geom_p3d)
    astra_geom = odl.tomo.astra_projection_geometry(geom_p3d)
    assert astra_geom['type'] == 'parallel3d_vec'

    # Circular conebeam flat
    geom_ccf = odl.tomo.ConeFlatGeometry(apart, dpart, src_rad, det_rad)
    astra_geom = odl.tomo.astra_projection_geometry(geom_ccf)
    assert astra_geom['type'] == 'cone_vec'

    # Helical conebeam flat
    pitch = 1
    geom_hcf = odl.tomo.ConeFlatGeometry(apart,
                                         dpart,
                                         src_rad,
                                         det_rad,
                                         pitch=pitch)
    astra_geom = odl.tomo.astra_projection_geometry(geom_hcf)
    assert astra_geom['type'] == 'cone_vec'
Beispiel #30
0
def test_detector_shifts_2d():
    """Check that detector shifts are handled correctly.

    We forward project a cubic phantom and check that ray transform
    and back-projection with and without detector shifts are
    numerically close (the error depends on domain discretization).
    """

    if not odl.tomo.ASTRA_AVAILABLE:
        pytest.skip(msg='ASTRA not available, skipping 2d test')

    d = 10
    space = odl.uniform_discr([-1] * 2, [1] * 2, [d] * 2)
    phantom = odl.phantom.cuboid(space, [-1 / 3] * 2, [1 / 3] * 2)

    full_angle = 2 * np.pi
    n_angles = 2 * 10
    src_rad = 2
    det_rad = 2
    apart = odl.uniform_partition(0, full_angle, n_angles)
    dpart = odl.uniform_partition(-4, 4, 8 * d)
    geom = odl.tomo.FanBeamGeometry(apart, dpart, src_rad, det_rad)
    k = 3
    shift = k * dpart.cell_sides[0]
    geom_shift = odl.tomo.FanBeamGeometry(
        apart, dpart, src_rad, det_rad,
        det_shift_func=lambda angle: [0.0, shift]
    )

    assert all_almost_equal(geom.angles, geom_shift.angles)
    angles = geom.angles
    assert all_almost_equal(geom.src_position(angles),
                            geom_shift.src_position(angles))
    assert all_almost_equal(geom.det_axis(angles),
                            geom_shift.det_axis(angles))
    assert all_almost_equal(geom.det_refpoint(angles),
                            geom_shift.det_refpoint(angles)
                            + shift * geom_shift.det_axis(angles))

    # check ray transform
    op = odl.tomo.RayTransform(space, geom)
    op_shift = odl.tomo.RayTransform(space, geom_shift)
    y = op(phantom).asarray()
    y_shift = op_shift(phantom).asarray()
    # projection on the shifted detector is shifted regular projection
    data_error = np.max(np.abs(y[:, :-k] - y_shift[:, k:]))
    assert data_error < space.cell_volume

    # check back-projection
    im = op.adjoint(y).asarray()
    im_shift = op_shift.adjoint(y_shift).asarray()
    error = np.abs(im_shift - im)
    rel_error = np.max(error[im > 0] / im[im > 0])
    assert rel_error < space.cell_volume
Beispiel #31
0
def test_partition_byaxis():
    """Test indexing a partition along the axes."""
    part = odl.uniform_partition([-1, -2, -3, -4], [1, 2, 3, 4], (1, 2, 4, 5))

    assert part.byaxis[0] == odl.uniform_partition(-1, 1, 1)
    assert part.byaxis[1:3] == odl.uniform_partition([-2, -3], [2, 3], (2, 4))
    assert (part.byaxis[[1, 3,
                         1]] == odl.uniform_partition([-2, -4, -2], [2, 4, 2],
                                                      (2, 5, 2)))
    assert part.byaxis[[1]] == part.byaxis[1]
    assert part.byaxis[...] == part
    assert part.byaxis[:] == part
Beispiel #32
0
def test_detector_shifts_3d():
    """Check that detector shifts are handled correctly.

    We forward project a cubic phantom and check that ray transform
    and back-projection with and without detector shifts are
    numerically close (the error depends on domain discretization).
    """
    if not odl.tomo.ASTRA_AVAILABLE:
        pytest.skip(msg='ASTRA not available, skipping 2d test')

    d = 100
    space = odl.uniform_discr([-1] * 3, [1] * 3, [d] * 3)
    phantom = odl.phantom.cuboid(space, [-1/3] * 3, [1/3] * 3)

    full_angle = 2 * np.pi
    n_angles = 2 * 100
    src_rad = 2
    det_rad = 2
    apart = odl.uniform_partition(0, full_angle, n_angles)
    dpart = odl.uniform_partition([-4] * 2, [4] * 2, [8 * d] * 2)
    geom = odl.tomo.ConeBeamGeometry(apart, dpart, src_rad, det_rad)
    k = 3
    l = 2
    shift = np.array([0, k, l]) * dpart.cell_sides[0]
    geom_shift = odl.tomo.ConeBeamGeometry(apart, dpart, src_rad, det_rad,
                                           det_shift_func=lambda angle: shift)

    angles = geom.angles

    assert all_almost_equal(angles, geom_shift.angles)
    assert all_almost_equal(geom.src_position(angles),
                            geom_shift.src_position(angles))
    assert all_almost_equal(geom.det_axes(angles),
                            geom_shift.det_axes(angles))
    assert all_almost_equal(geom.det_refpoint(angles),
                            geom_shift.det_refpoint(angles)
                            + geom_shift.det_axes(angles)[:, 0] * shift[1]
                            - geom_shift.det_axes(angles)[:, 1] * shift[2])

    # check forward pass
    op = odl.tomo.RayTransform(space, geom)
    op_shift = odl.tomo.RayTransform(space, geom_shift)
    y = op(phantom).asarray()
    y_shift = op_shift(phantom).asarray()
    data_error = np.max(np.abs(y[:, :-k, l:] - y_shift[:, k:, :-l]))
    assert data_error < 1e-3

    # check back-projection
    im = op.adjoint(y).asarray()
    im_shift = op_shift.adjoint(y_shift).asarray()
    error = np.max(np.abs(im_shift-im))
    assert error < 1e-3
Beispiel #33
0
def limited_view_parallel_beam_geometry(space, beam_num_angle):
    corners = space.domain.corners()[:, :2]
    rho = np.max(np.linalg.norm(corners, axis=1))
    min_side = min(space.partition.cell_sides[:2])
    omega = np.pi / min_side
    num_px_horiz = 2 * int(np.ceil(rho * omega / np.pi)) + 1
    det_min_pt = -rho
    det_max_pt = rho
    det_shape = num_px_horiz
    angle_partition = odl.uniform_partition(0, beam_num_angle * (np.pi / 180),
                                            beam_num_angle)
    det_partition = odl.uniform_partition(det_min_pt, det_max_pt, det_shape)
    return odl.tomo.Parallel2dGeometry(angle_partition, det_partition)
Beispiel #34
0
    def generate_data(self, voxels_up, reco_space_up, f_up, **kwargs):
        factor = 2
        dpix_up = [factor * voxels_up[0], voxels_up[1]]
        dpix = [int(factor * self.voxels[0]), self.voxels[0]]
        src_radius = self.src_rad * self.volumesize[0] * 2
        det_radius = self.det_rad * self.volumesize[0] * 2
        # Make a circular scanning geometry
        angle_partition = odl.uniform_partition(0, 2 * np.pi, self.angles)
        # Make a flat detector space
        det_partition = odl.uniform_partition(-self.detecsize, self.detecsize,
                                              dpix_up)
        # Create data_space_up and data_space
        data_space = odl.uniform_discr((0, *-self.detecsize),
                                       (2 * np.pi, *self.detecsize),
                                       [self.angles, *dpix],
                                       dtype='float32')
        data_space_up = odl.uniform_discr((0, *-self.detecsize),
                                          (2 * np.pi, *self.detecsize),
                                          [self.angles, *dpix_up],
                                          dtype='float32')
        # Create geometry
        geometry = odl.tomo.ConeFlatGeometry(angle_partition,
                                             det_partition,
                                             src_radius=src_radius,
                                             det_radius=det_radius,
                                             axis=[0, 0, 1])

        FP = odl.tomo.RayTransform(reco_space_up, geometry, use_cache=False)

        resamp = odl.Resampling(data_space_up, data_space)
        if 'load_data_g' in kwargs:
            if type(kwargs['load_data_g']) == str:
                self.g = data_space.element(np.load(kwargs['load_data_g']))
            else:
                self.g = data_space.element(kwargs['load_data_g'])
        else:
            self.g = resamp(FP(f_up))

            if self.noise == None:
                pass
            elif self.noise[0] == 'Gaussian':
                self.g += data_space.element(
                        odl.phantom.white_noise(resamp.range) * \
                        np.mean(self.g) * self.noise[1])
            elif self.noise[0] == 'Poisson':
                # 2**8 seems to be the minimal accepted I_0
                self.g = data_space.element(
                    self.add_poisson_noise(self.noise[1]))
            else:
                raise ValueError('unknown `noise type` ({})'
                                 ''.format(self.noise[0]))
def operators_smooth():
    size = 512
    space = odl.uniform_discr([-256, -256], [256, 256], [size, size],
                              dtype='float32',
                              weighting=1.0)
    angle_partition = odl.uniform_partition(0, 2 * np.pi, 1000)
    detector_partition = odl.uniform_partition(-360, 360, 1000)
    geometry = odl.tomo.Parallel2dGeometry(angle_partition, detector_partition)
    T = odl.tomo.RayTransform(space, geometry)
    fbp = odl.tomo.fbp_op(T, frequency_scaling=0.45, filter_type='Hann')
    T_norm = T.norm(estimate=True)
    T = (1 / T_norm) * T
    W = odl.Gradient(space)
    return [T, W]
Beispiel #36
0
def test_spect():
    det_nx_pix = 64
    det_ny_pix = 64
    det_nx_mm = 4
    det_radius = 200
    n_proj = 180
    det_param = det_nx_mm * det_nx_pix
    dpart = odl.uniform_partition([-det_param, -det_param],
                                  [det_param, det_param],
                                  [det_nx_pix, det_ny_pix])

    apart = odl.uniform_partition(0, 2 * np.pi, n_proj)
    geom = ParallelHoleCollimatorGeometry(apart, dpart, det_radius)
    assert isinstance(geom.detector, odl.tomo.Flat2dDetector)
    assert all_equal(geom.det_radius, det_radius)
Beispiel #37
0
def test_proj_geom_parallel_2d():
    """Create ASTRA 2D projection geometry."""

    apart = odl.uniform_partition(0, 2, 5)
    dpart = odl.uniform_partition(-1, 1, 10)
    geom = odl.tomo.Parallel2dGeometry(apart, dpart)

    proj_geom = astra_projection_geometry(geom)

    correct_subdict = {
        'type': 'parallel',
        'DetectorCount': 10, 'DetectorWidth': 0.2}

    assert is_subdict(correct_subdict, proj_geom)
    assert 'ProjectionAngles' in proj_geom
Beispiel #38
0
def xray(nviews=15, ndectectors=100):
    gtruth = resolution_phantom(case=1, nsamples=200, highres=800)
    sinfo = resolution_phantom(case=2, nsamples=200, highres=800)

    angle_partition = odl.uniform_partition(0, np.pi, nviews)
    detector_partition = odl.uniform_partition(-1.5, 1.5, ndectectors)
    geometry = odl.tomo.Parallel2dGeometry(angle_partition, detector_partition)

    operator = odl.tomo.RayTransform(gtruth.space, geometry, impl='astra_cpu')

    data = odl.phantom.salt_pepper_noise(operator(gtruth),
                                         fraction=0.05,
                                         seed=10)

    return gtruth, sinfo, operator, data