forked from RTKConsortium/RTK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FirstReconstruction.cxx
117 lines (101 loc) · 3.97 KB
/
FirstReconstruction.cxx
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
// RTK includes
#include <rtkConstantImageSource.h>
#include <rtkThreeDCircularProjectionGeometryXMLFileWriter.h>
#include <rtkRayEllipsoidIntersectionImageFilter.h>
#include <rtkFDKConeBeamReconstructionFilter.h>
#include <rtkFieldOfViewImageFilter.h>
// ITK includes
#include <itkImageFileWriter.h>
int
main(int argc, char ** argv)
{
if (argc < 3)
{
std::cout << "Usage: FirstReconstruction <outputimage> <outputgeometry>" << std::endl;
return EXIT_FAILURE;
}
// Defines the image type
using ImageType = itk::Image<float, 3>;
// Defines the RTK geometry object
using GeometryType = rtk::ThreeDCircularProjectionGeometry;
GeometryType::Pointer geometry = GeometryType::New();
unsigned int numberOfProjections = 360;
double firstAngle = 0;
double angularArc = 360;
unsigned int sid = 600; // source to isocenter distance
unsigned int sdd = 1200; // source to detector distance
for (unsigned int noProj = 0; noProj < numberOfProjections; noProj++)
{
double angle = firstAngle + noProj * angularArc / numberOfProjections;
geometry->AddProjection(sid, sdd, angle);
}
// Write the geometry to disk
rtk::ThreeDCircularProjectionGeometryXMLFileWriter::Pointer xmlWriter;
xmlWriter = rtk::ThreeDCircularProjectionGeometryXMLFileWriter::New();
xmlWriter->SetFilename(argv[2]);
xmlWriter->SetObject(geometry);
xmlWriter->WriteFile();
// Create a stack of empty projection images
using ConstantImageSourceType = rtk::ConstantImageSource<ImageType>;
ConstantImageSourceType::Pointer constantImageSource = ConstantImageSourceType::New();
ConstantImageSourceType::PointType origin;
ConstantImageSourceType::SpacingType spacing;
ConstantImageSourceType::SizeType sizeOutput;
origin[0] = -127;
origin[1] = -127;
origin[2] = 0.;
sizeOutput[0] = 128;
sizeOutput[1] = 128;
sizeOutput[2] = numberOfProjections;
spacing.Fill(2.);
constantImageSource->SetOrigin(origin);
constantImageSource->SetSpacing(spacing);
constantImageSource->SetSize(sizeOutput);
constantImageSource->SetConstant(0.);
// Create projections of an ellipse
using REIType = rtk::RayEllipsoidIntersectionImageFilter<ImageType, ImageType>;
REIType::Pointer rei = REIType::New();
REIType::VectorType semiprincipalaxis, center;
semiprincipalaxis.Fill(50.);
center.Fill(0.);
center[2] = 10.;
rei->SetDensity(2.);
rei->SetAngle(0.);
rei->SetCenter(center);
rei->SetAxis(semiprincipalaxis);
rei->SetGeometry(geometry);
rei->SetInput(constantImageSource->GetOutput());
// Create reconstructed image
ConstantImageSourceType::Pointer constantImageSource2 = ConstantImageSourceType::New();
sizeOutput.Fill(128);
origin.Fill(-63.5);
spacing.Fill(1.);
constantImageSource2->SetOrigin(origin);
constantImageSource2->SetSpacing(spacing);
constantImageSource2->SetSize(sizeOutput);
constantImageSource2->SetConstant(0.);
// FDK reconstruction
std::cout << "Reconstructing..." << std::endl;
using FDKCPUType = rtk::FDKConeBeamReconstructionFilter<ImageType>;
FDKCPUType::Pointer feldkamp = FDKCPUType::New();
feldkamp->SetInput(0, constantImageSource2->GetOutput());
feldkamp->SetInput(1, rei->GetOutput());
feldkamp->SetGeometry(geometry);
feldkamp->GetRampFilter()->SetTruncationCorrection(0.);
feldkamp->GetRampFilter()->SetHannCutFrequency(0.0);
// Field-of-view masking
using FOVFilterType = rtk::FieldOfViewImageFilter<ImageType, ImageType>;
FOVFilterType::Pointer fieldofview = FOVFilterType::New();
fieldofview->SetInput(0, feldkamp->GetOutput());
fieldofview->SetProjectionsStack(rei->GetOutput());
fieldofview->SetGeometry(geometry);
// Writer
std::cout << "Writing output image..." << std::endl;
using WriterType = itk::ImageFileWriter<ImageType>;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(argv[1]);
writer->SetInput(fieldofview->GetOutput());
writer->Update();
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;
}