RTK  2.7.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
38 #endif
39 
40 #include <random>
41 #include <algorithm>
42 
43 namespace rtk
44 {
45 
58 template <class TOutputImage, class ProjectionStackType = TOutputImage>
59 class ITK_TEMPLATE_EXPORT IterativeConeBeamReconstructionFilter
60  : public itk::ImageToImageFilter<TOutputImage, TOutputImage>
61 {
62 public:
63  ITK_DISALLOW_COPY_AND_MOVE(IterativeConeBeamReconstructionFilter);
64 
70 
72  using VolumeType = ProjectionStackType;
74  typedef enum
75  {
76  FP_JOSEPH = 0,
77  FP_CUDARAYCAST = 2,
78  FP_JOSEPHATTENUATED = 3,
79  FP_ZENG = 4,
80  FP_CUDAWARP = 5
81  } ForwardProjectionType;
82  typedef enum
83  {
84  BP_VOXELBASED = 0,
85  BP_JOSEPH = 1,
86  BP_CUDAVOXELBASED = 2,
87  BP_CUDARAYCAST = 4,
88  BP_JOSEPHATTENUATED = 5,
89  BP_ZENG = 6,
90  BP_CUDAWARP = 7
91  } BackProjectionType;
92 
98 
100  itkNewMacro(Self);
101 
103  itkOverrideGetNameOfClassMacro(IterativeConeBeamReconstructionFilter);
104 
106  virtual void
107  SetForwardProjectionFilter(ForwardProjectionType fwtype);
110  {
111  return m_CurrentForwardProjectionConfiguration;
112  }
113  virtual void
114  SetBackProjectionFilter(BackProjectionType bptype);
115  BackProjectionType
117  {
118  return m_CurrentBackProjectionConfiguration;
119  }
121 
124  void
125  SetAttenuationMap(const VolumeType * attenuationMap)
126  {
127  // Process object is not const-correct so the const casting is required.
128  this->SetNthInput(2, const_cast<VolumeType *>(attenuationMap));
129  }
130  typename VolumeType::ConstPointer
132  {
133  return static_cast<const VolumeType *>(this->itk::ProcessObject::GetInput(2));
134  }
136 
140  void
141  SetInferiorClipImage(const TClipImageType * inferiorClipImage)
142  {
143  // Process object is not const-correct so the const casting is required.
144  this->SetInput("InferiorClipImage", const_cast<TClipImageType *>(inferiorClipImage));
145  }
146  typename TClipImageType::ConstPointer
148  {
149  return static_cast<const TClipImageType *>(this->itk::ProcessObject::GetInput("InferiorClipImage"));
150  }
152 
156  void
157  SetSuperiorClipImage(const TClipImageType * superiorClipImage)
158  {
159  // Process object is not const-correct so the const casting is required.
160  this->SetInput("SuperiorClipImage", const_cast<TClipImageType *>(superiorClipImage));
161  }
162  typename TClipImageType::ConstPointer
164  {
165  return static_cast<const TClipImageType *>(this->itk::ProcessObject::GetInput("SuperiorClipImage"));
166  }
168 
170  itkGetMacro(SigmaZero, double);
171  itkSetMacro(SigmaZero, double);
173 
175  itkGetMacro(AlphaPSF, double);
176  itkSetMacro(AlphaPSF, double);
178 
180  itkGetConstMacro(StepSize, double);
181  itkSetMacro(StepSize, double);
183 
184 protected:
186  ~IterativeConeBeamReconstructionFilter() override = default;
187 
190  virtual BackProjectionPointerType
191  InstantiateBackProjectionFilter(int bptype);
192 
195  virtual ForwardProjectionPointerType
196  InstantiateForwardProjectionFilter(int fwtype);
197 
202 
205  std::default_random_engine m_DefaultRandomEngine = std::default_random_engine{};
206 
208  double m_SigmaZero{ 1.5417233052142099 };
209  double m_AlphaPSF{ 0.016241189545787734 };
210 
212  double m_StepSize{ 1.0 };
213 
215  using CPUImageType =
217  template <typename ImageType>
218  using EnableCudaScalarAndVectorType = typename std::enable_if<
219  !std::is_same_v<CPUImageType, ImageType> &&
220  std::is_same_v<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float> &&
224  template <typename ImageType>
225  using DisableCudaScalarAndVectorType = typename std::enable_if<
226  std::is_same_v<CPUImageType, ImageType> ||
227  !std::is_same_v<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float> ||
231  template <typename ImageType>
232  using EnableCudaScalarType = typename std::enable_if<
233  !std::is_same_v<CPUImageType, ImageType> &&
234  std::is_same_v<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float> &&
236  template <typename ImageType>
237  using DisableCudaScalarType = typename std::enable_if<
238  std::is_same_v<CPUImageType, ImageType> ||
239  !std::is_same_v<typename itk::PixelTraits<typename ImageType::PixelType>::ValueType, float> ||
241  template <typename ImageType>
242  using EnableVectorType =
243  typename std::enable_if<itk::PixelTraits<typename ImageType::PixelType>::Dimension != 1>::type;
244  template <typename ImageType>
245  using DisableVectorType =
246  typename std::enable_if<itk::PixelTraits<typename ImageType::PixelType>::Dimension == 1>::type;
248 
249  template <typename ImageType, EnableCudaScalarAndVectorType<ImageType> * = nullptr>
252  {
254 #ifdef RTK_USE_CUDA
256  dynamic_cast<rtk::CudaForwardProjectionImageFilter<ImageType, ImageType> *>(fw.GetPointer())
257  ->SetStepSize(m_StepSize);
258 #endif
259  return fw;
260  }
261 
262 
263  template <typename ImageType, DisableCudaScalarAndVectorType<ImageType> * = nullptr>
264  ForwardProjectionPointerType
266  {
267  itkGenericExceptionMacro(
268  << "CudaRayCastBackProjectionImageFilter only available with 3D CudaImage of float or itk::Vector<float,3>.");
269  return nullptr;
270  }
271 
272 
273  template <typename ImageType, EnableCudaScalarType<ImageType> * = nullptr>
274  ForwardProjectionPointerType
276  {
278 #ifdef RTK_USE_CUDA
280  dynamic_cast<rtk::CudaWarpForwardProjectionImageFilter *>(fw.GetPointer())->SetStepSize(m_StepSize);
281 #endif
282  return fw;
283  }
284 
285 
286  template <typename ImageType, DisableCudaScalarType<ImageType> * = nullptr>
287  ForwardProjectionPointerType
289  {
290  itkGenericExceptionMacro(
291  << "CudaWarpForwardProjectionImageFilter only available with 3D CudaImage of float or itk::Vector<float,3>.");
292  return nullptr;
293  }
294 
295 
296  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
297  ForwardProjectionPointerType
299  {
300  itkGenericExceptionMacro(<< "JosephForwardAttenuatedProjectionImageFilter only available with scalar pixel types.");
301  return nullptr;
302  }
303 
304 
305  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
306  ForwardProjectionPointerType
308  {
311  if (this->GetAttenuationMap().IsNotNull())
312  {
313  fw->SetInput(2, this->GetAttenuationMap());
314  }
315  else
316  {
317  itkExceptionMacro(<< "Set Joseph attenuated forward projection filter but no attenuation map is given");
318  return nullptr;
319  }
320  if (this->GetSuperiorClipImage().IsNotNull())
321  {
323  fw.GetPointer())
324  ->SetSuperiorClipImage(this->GetSuperiorClipImage());
325  }
326  if (this->GetInferiorClipImage().IsNotNull())
327  {
329  fw.GetPointer())
330  ->SetInferiorClipImage(this->GetInferiorClipImage());
331  }
332  return fw;
333  }
334 
335  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
336  ForwardProjectionPointerType
338  {
339  itkGenericExceptionMacro(<< "JosephForwardAttenuatedProjectionImageFilter only available with scalar pixel types.");
340  return nullptr;
341  }
342 
343 
344  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
345  ForwardProjectionPointerType
347  {
350  if (this->GetAttenuationMap().IsNotNull())
351  {
352  fw->SetInput(2, this->GetAttenuationMap());
353  }
355  ->SetSigmaZero(m_SigmaZero);
357  ->SetAlpha(m_AlphaPSF);
358  return fw;
359  }
360 
361  template <typename ImageType, EnableCudaScalarAndVectorType<ImageType> * = nullptr>
362  BackProjectionPointerType
364  {
366 #ifdef RTK_USE_CUDA
368 #endif
369  return bp;
370  }
371 
372 
373  template <typename ImageType, DisableCudaScalarAndVectorType<ImageType> * = nullptr>
374  BackProjectionPointerType
376  {
377  itkGenericExceptionMacro(
378  << "CudaBackProjectionImageFilter only available with 3D CudaImage of float or itk::Vector<float,3>.");
379  return nullptr;
380  }
381 
382 
383  template <typename ImageType, EnableCudaScalarType<ImageType> * = nullptr>
384  BackProjectionPointerType
386  {
388 #ifdef RTK_USE_CUDA
390 #endif
391  return bp;
392  }
393 
394 
395  template <typename ImageType, DisableCudaScalarType<ImageType> * = nullptr>
396  BackProjectionPointerType
398  {
399  itkGenericExceptionMacro(
400  << "CudaWarpBackProjectionImageFilter only available with 3D CudaImage of float or itk::Vector<float,3>.");
401  return nullptr;
402  }
403 
404  template <typename ImageType, EnableCudaScalarType<ImageType> * = nullptr>
405  BackProjectionPointerType
407  {
409 #ifdef RTK_USE_CUDA
411  dynamic_cast<rtk::CudaRayCastBackProjectionImageFilter *>(bp.GetPointer())->SetStepSize(m_StepSize);
412 #endif
413  return bp;
414  }
415 
416 
417  template <typename ImageType, DisableCudaScalarType<ImageType> * = nullptr>
418  BackProjectionPointerType
420  {
421  itkGenericExceptionMacro(<< "CudaRayCastBackProjectionImageFilter only available with 3D CudaImage of float.");
422  return nullptr;
423  }
424 
425 
426  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
427  BackProjectionPointerType
429  {
430  itkGenericExceptionMacro(<< "JosephBackAttenuatedProjectionImageFilter only available with scalar pixel types.");
431  return nullptr;
432  }
433 
434 
435  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
436  BackProjectionPointerType
438  {
441  if (this->GetAttenuationMap().IsNotNull())
442  {
443  bp->SetInput(2, this->GetAttenuationMap());
444  return bp;
445  }
446  else
447  {
448  itkExceptionMacro(<< "Set Joseph attenuated backprojection filter but no attenuation map is given");
449  return nullptr;
450  }
451  }
452 
453  template <typename ImageType, EnableVectorType<ImageType> * = nullptr>
454  BackProjectionPointerType
456  {
457  itkGenericExceptionMacro(<< "JosephBackAttenuatedProjectionImageFilter only available with scalar pixel types.");
458  return nullptr;
459  }
460 
461 
462  template <typename ImageType, DisableVectorType<ImageType> * = nullptr>
463  BackProjectionPointerType
465  {
468  if (this->GetAttenuationMap().IsNotNull())
469  {
470  bp->SetInput(2, this->GetAttenuationMap());
471  }
473  ->SetSigmaZero(m_SigmaZero);
475  ->SetAlpha(m_AlphaPSF);
476  return bp;
477  }
478 
479 }; // end of class
480 
481 } // end namespace rtk
482 
483 #ifndef ITK_MANUAL_INSTANTIATION
484 # include "rtkIterativeConeBeamReconstructionFilter.hxx"
485 #endif
486 
487 #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_v< CPUImageType, ImageType >||!std::is_same_v< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float >||(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< std::is_same_v< CPUImageType, ImageType >||!std::is_same_v< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float >||itk::PixelTraits< typename ImageType::PixelType >::Dimension !=1 >::type DisableCudaScalarType
#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_v< CPUImageType, ImageType > &&std::is_same_v< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float > &&(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< itk::PixelTraits< typename ImageType::PixelType >::Dimension !=1 >::type EnableVectorType
typename std::enable_if< !std::is_same_v< CPUImageType, ImageType > &&std::is_same_v< typename itk::PixelTraits< typename ImageType::PixelType >::ValueType, float > &&itk::PixelTraits< typename ImageType::PixelType >::Dimension==1 >::type EnableCudaScalarType