forked from Diagonalizable/HelTomo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtomorecon_2d_fan_fbp_astra_cuda.m
134 lines (112 loc) · 5.13 KB
/
tomorecon_2d_fan_fbp_astra_cuda.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
function [ recon ] = tomorecon_2d_fan_fbp_astra_cuda(CtData, xDim, yDim, varargin)
%TOMORECON_2D_FAN_FBP_ASTRA_CUDA Analytical 2D fan-beam GPU reconstruction.
% recon = tomorecon_2d_fan_fbp_astra_cuda(CtData, xDim, yDim) computes
% the analytical 2D reconstruction of the fan-beam CT data in ''CtData''
% using the FBP algorithm. The x- and y-dimensions of the reconstruction
% are specified by the input parameters ''xDim'' and ''yDim'',
% respectively. It is assumed that a flat detector has been used for the
% X-ray projection measurements.
%
% recon = tomorecon_2d_fan_fbp_astra_cuda(CtData, xDim, yDim, energyBin)
% is used if a photon counting detector (PCD) has been used to collect
% the X-ray data. The input parameter ''energyBin'' is a string
% specifying the energy bin that will be reconstructed. Its allowed
% values are 'total', 'low' and 'high'.
%
% Use of this function requires that the ASTRA Tomography Toolbox
% (https://www.astra-toolbox.com/) and the Spot Linear-Operator Toolbox
% (https://www.cs.ubc.ca/labs/scl/spot/) have been added to the MATLAB
% path. The computer must also be equipped with a CUDA-enabled GPU to
% compute the reconstruction. The function has been verified to work with
% ASTRA version 2.0.0.
%
% This function is part of the HelTomo Toolbox, and was created primarily
% for use with CT data measured in the Industrial Mathematics Computed
% Tomography Laboratory at the University of Helsinki.
%
% Alexander Meaney, University of Helsinki
% Created: 1.7.2019
% Last edited: 3.8.2022
% Validate input parameters
if ~isscalar(xDim) || xDim < 1 || floor(xDim) ~= xDim
error('Parameter ''xDim'' must be a positive integer.');
end
if ~isscalar(yDim) || yDim < 1 || floor(yDim) ~= yDim
error('Parameter ''yDim'' must be a positive integer.');
end
% Validate CT data type
if ~strcmpi(CtData.type, '2D')
error('ctData must be of type ''2D''.');
end
% If the data is from a PCD, the energy bin must be specified
if strcmpi(CtData.parameters.detectorType, 'PCD')
if length(varargin) ~= 1
error('For PCD data, specify energy bin to reconstruct (total, high, or low).');
end
if ~ismember(lower(varargin{1}), {'total', 'high', 'low'})
error('For PCD data, specify energy bin to reconstruct (total, high, or low).');
end
if strcmpi(varargin{1}, 'total')
sinogram = CtData.sinogramTotal;
elseif strcmpi(varargin{1}, 'high')
sinogram = CtData.sinogramHigh;
elseif strcmpi(varargin{1}, 'low')
sinogram = CtData.sinogramLow;
else
error('Unknown error occurred in sinogram identification.');
end
else
% EID data
sinogram = CtData.sinogram;
end
% Create shorthands for needed variables
DSD = CtData.parameters.distanceSourceDetector;
DSO = CtData.parameters.distanceSourceOrigin;
M = CtData.parameters.geometricMagnification;
angles = CtData.parameters.angles;
numDetectors = CtData.parameters.numDetectorsPost;
effPixel = CtData.parameters.effectivePixelSizePost;
% Distance from origin to detector
DOD = DSD - DSO;
% Distance from source to origin specified in terms of effective pixel size
DSO = DSO / effPixel;
% Distance from origin to detector specified in terms of effective pixel size
DOD = DOD /effPixel;
% ASTRA uses angles in radians
anglesRad = deg2rad(angles);
% ASTRA code begins here
fprintf('Creating geometries and data objects in ASTRA... ');
% Create volume geometry, i.e. reconstruction geometry
volumeGeometry = astra_create_vol_geom(yDim, xDim);
% Create projection geometry
projectionGeometry = astra_create_proj_geom('fanflat', M, numDetectors, ...
anglesRad, DSO, DOD);
% Create 2D data object for reconstruction
reconstructionObject = astra_mex_data2d('create', '-vol', ...
volumeGeometry, 0);
% Create 2D data object for sinogram
projectionsObject = astra_mex_data2d('create', '-sino', ...
projectionGeometry, sinogram);
fprintf('done.\n');
% Create and initialize reconstruction algorithm
fprintf('Creating reconstruction algorithm in ASTRA... ');
cfg = astra_struct('FBP_CUDA');
cfg.ReconstructionDataId = reconstructionObject;
cfg.ProjectionDataId = projectionsObject;
reconstructionAlgorithm = astra_mex_algorithm('create', cfg);
fprintf('done.\n');
% Run reconstruction algorithm
fprintf('Running reconstruction algorithm in ASTRA... ');
astra_mex_algorithm('run', reconstructionAlgorithm);
fprintf('done.\n');
% Get reconstruction as a matrix
recon = astra_mex_data2d('get', reconstructionObject);
% Memory cleanup
astra_mex_data2d('delete', volumeGeometry);
astra_mex_data2d('delete', projectionGeometry);
astra_mex_data2d('delete', reconstructionObject);
astra_mex_data2d('delete', projectionsObject);
astra_mex_algorithm('delete', reconstructionAlgorithm);
astra_clear;
clearvars -except recon
end