ART
This is a CPU implementation of the Iterative Reconstruction Technique (ART) for 2D data sets. It takes projection data and an initial reconstruction as input, and returns the reconstruction after a specified number of ART iterations. Each iteration of ART consists of an FP and BP of one single projection ray. The order of the rays can be specified.
Supported geometries: parallel, parallel_vec, fanflat, fanflat_vec, matrix.
Configuration options
Name |
Description |
---|---|
ProjectorId |
|
ProjectionDataId |
|
ReconstructionDataId |
ID of data object to store the result. The content of this when starting ART is used as the initial reconstruction. |
option.RayOrder |
This specifies the order in which the projections are used. Possible values are: ‘sequential’ (default) and ‘custom’. If ‘custom’ is specified, the option.RayOrderList is required. |
option.RayOrderList |
Required if option.RayOrder = ‘custom’, ignored otherwise. An 1D array containing the custom order in which the projections are used. |
option.MinConstraint |
If specified, all values below MinConstraint will be set to MinConstraint. This can, for example, be used to enforce non-negative reconstructions. |
option.MaxConstraint |
If specified, all values above MaxConstraint will be set to MaxConstraint. |
option.SinogramMaskId |
If specified, data object ID of a projection-data-sized volume to be used as a mask. |
option.ReconstructionMaskId |
If specified, data object ID of a volume-data-sized volume to be used as a mask. |
Example
import astra
import matplotlib.pyplot as plt
import numpy as np
# Create geometries and projector
N = 256
N_ANGLES = 180
det_spacing = 1.0
angles = np.linspace(0, np.pi, N_ANGLES)
proj_geom = astra.create_proj_geom('parallel', det_spacing, N, angles)
vol_geom = astra.create_vol_geom(N, N)
projector_id = astra.create_projector('linear', proj_geom, vol_geom)
# Generate phantom image
phantom_id, phantom = astra.data2d.shepp_logan(vol_geom)
# Create forward projection
sinogram_id, sinogram = astra.create_sino(phantom_id, projector_id)
# Reconstruct
recon_id = astra.data2d.create('-vol', vol_geom)
cfg = astra.astra_dict('ART')
cfg['ProjectorId'] = projector_id
cfg['ProjectionDataId'] = sinogram_id
cfg['ReconstructionDataId'] = recon_id
cfg['option'] = {'RayOrder': 'custom'}
# Set ray order to a random permutation (equivalent to cfg['option']['RayOrder'] = 'random')
full_ray_list = np.stack(np.meshgrid(range(N_ANGLES), range(N))).reshape(2, -1).T
cfg['option']['ray_order_list'] = np.random.permutation(full_ray_list).flatten()
algorithm_id = astra.algorithm.create(cfg)
astra.algorithm.run(algorithm_id, 3 * sinogram.size)
recon = astra.data2d.get(recon_id)
plt.imshow(recon, cmap='gray')
# Clean up
astra.data2d.delete([sinogram_id, recon_id, phantom_id])
astra.projector.delete(projector_id)
astra.algorithm.delete(algorithm_id)
%% Create phantom
N = 256;
phantom = phantom(N);
%% Create geometries and projector
det_spacing = 1.0;
N_ANGLES = 180;
angles = linspace(0, pi, N_ANGLES);
proj_geom = astra_create_proj_geom('parallel', det_spacing, N, angles);
vol_geom = astra_create_vol_geom(N, N);
projector_id = astra_create_projector('linear', proj_geom, vol_geom);
%% Create forward projection
[sinogram_id, sinogram] = astra_create_sino(phantom, projector_id);
%% Reconstruct
recon_id = astra_mex_data2d('create', '-vol', vol_geom);
cfg = astra_struct('ART');
cfg.ProjectorId = projector_id;
cfg.ProjectionDataId = sinogram_id;
cfg.ReconstructionDataId = recon_id;
cfg.option.RayOrder = 'custom';
% Set ray order to a random permutation (equivalent to cfg.option.RayOrder = 'random')
[p, q] = meshgrid(0:(N_ANGLES-1), 0:(N-1));
ray_order_list = [p(:) q(:)];
ray_order_list = ray_order_list(randperm(numel(p)), :);
cfg.option.ray_order_list = ray_order_list;
algorithm_id = astra_mex_algorithm('create', cfg);
astra_mex_algorithm('iterate', algorithm_id, 3 * numel(p));
recon = astra_mex_data2d('get', recon_id);
imshow(recon, []);
%% Clean up
astra_mex_data2d('delete', sinogram_id, recon_id);
astra_mex_projector('delete', projector_id);
astra_mex_algorithm('delete', algorithm_id);