RTK  2.6.0
Reconstruction Toolkit
rtkIterativeConeBeamReconstructionFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright RTK Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * https://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #ifndef rtkIterativeConeBeamReconstructionFilter_h
20 #define rtkIterativeConeBeamReconstructionFilter_h
21 
22 #include <itkPixelTraits.h>
23 
24 // Forward projection filters
25 #include "rtkConfiguration.h"
28 // Back projection filters
31 
32 #ifdef RTK_USE_CUDA
36 #endif
37 
38 #include <random>
39 #include <algorithm>
40 
41 namespace rtk
42 {
43 
56 template <class TOutputImage, class ProjectionStackType = TOutputImage>
57 class ITK_TEMPLATE_EXPORT IterativeConeBeamReconstructionFilter
58  : public itk::ImageToImageFilter<TOutputImage, TOutputImage>
59 {
60 public:
61  ITK_DISALLOW_COPY_AND_MOVE(IterativeConeBeamReconstructionFilter);
62 
68 
70  using VolumeType = ProjectionStackType;
72  typedef enum
73  {
74  FP_JOSEPH = 0,
75  FP_CUDARAYCAST = 2,
76  FP_JOSEPHATTENUATED = 3,
77  FP_ZENG = 4
78  } ForwardProjectionType;
79  typedef enum
80  {
81  BP_VOXELBASED = 0,
82  BP_JOSEPH = 1,
83  BP_CUDAVOXELBASED = 2,
84  BP_CUDARAYCAST = 4,
85  BP_JOSEPHATTENUATED = 5,
86  BP_ZENG = 6
87  } BackProjectionType;
88 
94 
96  itkNewMacro(Self);
97 
99  itkOverrideGetNameOfClassMacro(IterativeConeBeamReconstructionFilter);
100 
102  virtual void
103  SetForwardProjectionFilter(ForwardProjectionType fwtype);
106  {
107  return m_CurrentForwardProjectionConfiguration;
108  }
109  virtual void
110  SetBackProjectionFilter(BackProjectionType bptype);
111  BackProjectionType
113  {
114  return m_CurrentBackProjectionConfiguration;
115  }
117 
120  void
121  SetAttenuationMap(const VolumeType * attenuationMap)
122  {
123  // Process object is not const-correct so the const casting is required.
124  this->SetNthInput(2, const_cast<VolumeType *>(attenuationMap));
125  }
126  typename VolumeType::ConstPointer
128  {
129  return static_cast<const VolumeType *>(this->itk::ProcessObject::GetInput(2));
130  }
132 
136  void
137  SetInferiorClipImage(const TClipImageType * inferiorClipImage)
138  {
139  // Process object is not const-correct so the const casting is required.
140  this->SetInput("InferiorClipImage", const_cast<TClipImageType *>(inferiorClipImage));
141  }
142  typename TClipImageType::ConstPointer
144  {
145  return static_cast<const TClipImageType *>(this->itk::ProcessObject::GetInput("InferiorClipImage"));
146  }
148 
152  void
153  SetSuperiorClipImage(const TClipImageType * superiorClipImage)
154  {
155  // Process object is not const-correct so the const casting is required.
156  this->SetInput("SuperiorClipImage", const_cast<TClipImageType *>(superiorClipImage));
157  }
158  typename TClipImageType::ConstPointer
160  {
161  return static_cast<const TClipImageType *>(this->itk::ProcessObject::GetInput("SuperiorClipImage"));
162  }
164 
166  itkGetMacro(SigmaZero, double);
167  itkSetMacro(SigmaZero, double);
169 
171  itkGetMacro(AlphaPSF, double);
172  itkSetMacro(AlphaPSF, double);
174 
176  itkGetConstMacro(StepSize, double);
177  itkSetMacro(StepSize, double);
179 
180 protected:
182  ~IterativeConeBeamReconstructionFilter() override = default;
183 
186  virtual BackProjectionPointerType
187  InstantiateBackProjectionFilter(int bptype);
188 
191  virtual ForwardProjectionPointerType
192  InstantiateForwardProjectionFilter(int fwtype);
193 
198 
201  std::default_random_engine m_DefaultRandomEngine = std::default_random_engine{};
202 
204  double m_SigmaZero{ 1.5417233052142099 };
205  double m_AlphaPSF{ 0.016241189545787734 };
206 
208  double m_StepSize{ 1.0 };
209 
211  using CPUImageType =
213  template <typename ImageType>
214  using EnableCudaScalarAndVectorType = typename std::enable_if<
215  !std::is_same<CPUImageType, ImageType>::value &&
216  std::is_same<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float>::value &&
220  template <typename ImageType>
221  using DisableCudaScalarAndVectorType = typename std::enable_if<
222  std::is_same<CPUImageType, ImageType>::value ||
223  !std::is_same<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float>::value ||
227  template <typename ImageType>
228  using EnableCudaScalarType = typename std::enable_if<
229  !std::is_same<CPUImageType, ImageType>::value &&
230  std::is_same<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float>::value &&
232  template <typename ImageType>
233  using DisableCudaScalarType = typename std::enable_if<
234  std::is_same<CPUImageType, ImageType>::value ||
235  !std::is_same<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float>::value ||
237  template <typename ImageType>
238  using EnableVectorType =
239  typename std::enable_if<itk::PixelTraits<typename ImageType::PixelType>::Dimension != 1>::type;
240  template <typename ImageType>
241  using DisableVectorType =
242  typename std::enable_if<itk::PixelTraits<typename ImageType::PixelType>::Dimension == 1>::type;
244 
245  template <typename ImageType, EnableCudaScalarAndVectorType<ImageType> * = nullptr>
248  {
250 #ifdef RTK_USE_CUDA
251  fw = CudaForwardProjectionImageFilter<ImageType, ImageType>::New();
252  dynamic_cast<rtk::CudaForwardProjectionImageFilter<ImageType, ImageType> *>(fw.GetPointer())
253  ->SetStepSize(m_StepSize);
254 #endif
255  return fw;
256  }
257 
258 
259  template <typename ImageType, DisableCudaScalarAndVectorType<ImageType> * = nullptr>
260  ForwardProjectionPointerType
262  {
263  itkGenericExceptionMacro(
264  << "CudaRayCastBackProjectionImageFilter only available with 3D CudaImage of float or itk::Vector<float,3>.");
265  return nullptr;
266  }
267 
268 
269  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
270  ForwardProjectionPointerType
272  {
273  itkGenericExceptionMacro(<< "JosephForwardAttenuatedProjectionImageFilter only available with scalar pixel types.");
274  return nullptr;
275  }
276 
277 
278  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
279  ForwardProjectionPointerType
281  {
284  if (this->GetAttenuationMap().IsNotNull())
285  {
286  fw->SetInput(2, this->GetAttenuationMap());
287  }
288  else
289  {
290  itkExceptionMacro(<< "Set Joseph attenuated forward projection filter but no attenuation map is given");
291  return nullptr;
292  }
293  if (this->GetSuperiorClipImage().IsNotNull())
294  {
296  fw.GetPointer())
297  ->SetSuperiorClipImage(this->GetSuperiorClipImage());
298  }
299  if (this->GetInferiorClipImage().IsNotNull())
300  {
302  fw.GetPointer())
303  ->SetInferiorClipImage(this->GetInferiorClipImage());
304  }
305  return fw;
306  }
307 
308  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
309  ForwardProjectionPointerType
311  {
312  itkGenericExceptionMacro(<< "JosephForwardAttenuatedProjectionImageFilter only available with scalar pixel types.");
313  return nullptr;
314  }
315 
316 
317  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
318  ForwardProjectionPointerType
320  {
323  if (this->GetAttenuationMap().IsNotNull())
324  {
325  fw->SetInput(2, this->GetAttenuationMap());
326  }
328  ->SetSigmaZero(m_SigmaZero);
330  ->SetAlpha(m_AlphaPSF);
331  return fw;
332  }
333 
334  template <typename ImageType, EnableCudaScalarAndVectorType<ImageType> * = nullptr>
335  BackProjectionPointerType
337  {
339 #ifdef RTK_USE_CUDA
340  bp = CudaBackProjectionImageFilter<ImageType>::New();
341 #endif
342  return bp;
343  }
344 
345 
346  template <typename ImageType, DisableCudaScalarAndVectorType<ImageType> * = nullptr>
347  BackProjectionPointerType
349  {
350  itkGenericExceptionMacro(
351  << "CudaBackProjectionImageFilter only available with 3D CudaImage of float or itk::Vector<float,3>.");
352  return nullptr;
353  }
354 
355 
356  template <typename ImageType, EnableCudaScalarType<ImageType> * = nullptr>
357  BackProjectionPointerType
359  {
361 #ifdef RTK_USE_CUDA
362  bp = CudaRayCastBackProjectionImageFilter::New();
363  dynamic_cast<rtk::CudaRayCastBackProjectionImageFilter *>(bp.GetPointer())->SetStepSize(m_StepSize);
364 #endif
365  return bp;
366  }
367 
368 
369  template <typename ImageType, DisableCudaScalarType<ImageType> * = nullptr>
370  BackProjectionPointerType
372  {
373  itkGenericExceptionMacro(<< "CudaRayCastBackProjectionImageFilter only available with 3D CudaImage of float.");
374  return nullptr;
375  }
376 
377 
378  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
379  BackProjectionPointerType
381  {
382  itkGenericExceptionMacro(<< "JosephBackAttenuatedProjectionImageFilter only available with scalar pixel types.");
383  return nullptr;
384  }
385 
386 
387  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
388  BackProjectionPointerType
390  {
393  if (this->GetAttenuationMap().IsNotNull())
394  {
395  bp->SetInput(2, this->GetAttenuationMap());
396  return bp;
397  }
398  else
399  {
400  itkExceptionMacro(<< "Set Joseph attenuated backprojection filter but no attenuation map is given");
401  return nullptr;
402  }
403  }
404 
405  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
406  BackProjectionPointerType
408  {
409  itkGenericExceptionMacro(<< "JosephBackAttenuatedProjectionImageFilter only available with scalar pixel types.");
410  return nullptr;
411  }
412 
413 
414  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
415  BackProjectionPointerType
417  {
420  if (this->GetAttenuationMap().IsNotNull())
421  {
422  bp->SetInput(2, this->GetAttenuationMap());
423  }
425  ->SetSigmaZero(m_SigmaZero);
427  ->SetAlpha(m_AlphaPSF);
428  return bp;
429  }
430 
431 }; // end of class
432 
433 } // end namespace rtk
434 
435 #ifndef ITK_MANUAL_INSTANTIATION
436 # include "rtkIterativeConeBeamReconstructionFilter.hxx"
437 #endif
438 
439 #endif
Base class for forward projection, i.e. accumulation along x-ray lines.
DataObject * GetInput(const DataObjectIdentifierType &key)
void SetSuperiorClipImage(const TClipImageType *superiorClipImage)
typename std::enable_if< itk::PixelTraits< typename ImageType::PixelType >::Dimension==1 >::type DisableVectorType
typename std::enable_if< !std::is_same< CPUImageType, ImageType >::value &&std::is_same< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float >::value &&(itk::PixelTraits< typename ImageType::PixelType >::Dimension==1||itk::PixelTraits< typename ImageType::PixelType >::Dimension==2||itk::PixelTraits< typename ImageType::PixelType >::Dimension==3)>::type EnableCudaScalarAndVectorType
typename std::enable_if< !std::is_same< CPUImageType, ImageType >::value &&std::is_same< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float >::value &&itk::PixelTraits< typename ImageType::PixelType >::Dimension==1 >::type EnableCudaScalarType
#define itkSetMacro(name, type)
void SetInferiorClipImage(const TClipImageType *inferiorClipImage)
Mother class for cone beam reconstruction filters which need runtime selection of their forward and b...
typename std::enable_if< std::is_same< CPUImageType, ImageType >::value||!std::is_same< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float >::value||(itk::PixelTraits< typename ImageType::PixelType >::Dimension !=1 &&itk::PixelTraits< typename ImageType::PixelType >::Dimension !=2 &&itk::PixelTraits< typename ImageType::PixelType >::Dimension !=3)>::type DisableCudaScalarAndVectorType
typename std::enable_if< itk::PixelTraits< typename ImageType::PixelType >::Dimension !=1 >::type EnableVectorType
typename std::enable_if< std::is_same< CPUImageType, ImageType >::value||!std::is_same< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float >::value||itk::PixelTraits< typename ImageType::PixelType >::Dimension !=1 >::type DisableCudaScalarType