Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkConcentrationCurveGenerator.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
17 #include "mitkImageTimeSelector.h"
18 #include "mitkImageCast.h"
19 #include "mitkITKImageImport.h"
20 #include "mitkModelBase.h"
21 #include "mitkExtractTimeGrid.h"
23 #include "itkNaryAddImageFilter.h"
24 #include "mitkImageAccessByItk.h"
25 #include "itkImageIOBase.h"
26 #include "itkBinaryFunctorImageFilter.h"
27 #include "itkTernaryFunctorImageFilter.h"
28 #include <itkExtractImageFilter.h>
29 #include "itkMeanProjectionImageFilter.h"
30 
31 mitk::ConcentrationCurveGenerator::ConcentrationCurveGenerator() : m_isT2weightedImage(false), m_isTurboFlashSequence(false),
32  m_AbsoluteSignalEnhancement(false), m_RelativeSignalEnhancement(0.0), m_UsingT1Map(false), m_Factor(0.0), m_RecoveryTime(0.0), m_RelaxationTime(0.0),
33  m_Relaxivity(0.0), m_FlipAngle(0.0), m_T2Factor(0.0), m_T2EchoTime(0.0)
34 {
35 }
36 
38 {
39 
40 }
41 
43 {
44  if(this->m_DynamicImage.IsNull())
45  {
46  itkExceptionMacro( << "Dynamic Image not set!");
47  }
48  else {
49  Convert();
50  }
51  return m_ConvertedImage;
52 
53 }
54 
56 {
57 
59  mitk::PixelType pixeltype = mitk::MakeScalarPixelType<double>();
60 
61  tempImage->Initialize(pixeltype,*this->m_DynamicImage->GetTimeGeometry());
62 
63  mitk::TimeGeometry::Pointer timeGeometry = (this->m_DynamicImage->GetTimeGeometry())->Clone();
64  tempImage->SetTimeGeometry(timeGeometry);
65 
68  imageTimeSelector->SetInput(this->m_DynamicImage);
69 
70  for(unsigned int i = 0; i< this->m_DynamicImage->GetTimeSteps(); ++i)
71  {
72  imageTimeSelector->SetTimeNr(i);
73  imageTimeSelector->UpdateLargestPossibleRegion();
74 
75  mitk::Image::Pointer mitkInputImage = imageTimeSelector->GetOutput();
76  mitk::Image::Pointer outputImage = mitk::Image::New();
77 
78  outputImage = ConvertSignalToConcentrationCurve(mitkInputImage,this->m_BaselineImage);
79 
80  mitk::ImageReadAccessor accessor(outputImage);
81  tempImage->SetVolume(accessor.GetData(), i);
82  }
83 
84  this->m_ConvertedImage = tempImage;
85 
86 }
87 
89 {
90 
92  imageTimeSelector->SetInput(this->m_DynamicImage);
93  imageTimeSelector->SetTimeNr(0);
94  imageTimeSelector->UpdateLargestPossibleRegion();
95  mitk::Image::Pointer baselineImage;
96  baselineImage = imageTimeSelector->GetOutput();
97 
98  if (m_BaselineStartTimeStep == m_BaselineEndTimeStep)
99  {
100  this->m_BaselineImage = imageTimeSelector->GetOutput();
101  }
102  else
103  {
104  try
105  {
107  }
108  catch (itk::ExceptionObject & err)
109  {
110  std::cerr << "ExceptionObject in ConcentrationCurveGenerator::CalculateAverageBaselineImage caught!" << std::endl;
111  std::cerr << err << std::endl;
112  }
113  }
114 }
115 
116 template<class TPixel>
117 void mitk::ConcentrationCurveGenerator::CalculateAverageBaselineImage(const itk::Image<TPixel, 4> *itkBaselineImage)
118 {
119  if (itkBaselineImage == NULL)
120  {
121  mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. Input image is NULL.";
122  }
123  if (m_BaselineStartTimeStep > m_BaselineEndTimeStep)
124  {
125  mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. End time point is before start time point.";
126  }
127 
128  typedef itk::Image<TPixel, 4> TPixel4DImageType;
129  typedef itk::Image<double, 3> Double3DImageType;
130  typedef itk::Image<double, 4> Double4DImageType;
131  typedef itk::ExtractImageFilter<TPixel4DImageType, TPixel4DImageType> ExtractImageFilterType;
132  typedef itk::ExtractImageFilter<Double4DImageType, Double3DImageType> Extract3DImageFilterType;
133  typedef itk::MeanProjectionImageFilter<TPixel4DImageType,Double4DImageType> MeanProjectionImageFilterType;
134 
135  typename MeanProjectionImageFilterType::Pointer MeanProjectionImageFilter = MeanProjectionImageFilterType::New();
136  typename Extract3DImageFilterType::Pointer Extract3DImageFilter = Extract3DImageFilterType::New();
137  typename TPixel4DImageType::RegionType region_input = itkBaselineImage->GetLargestPossibleRegion();
138 
139  if (m_BaselineEndTimeStep > region_input.GetSize()[3])
140  {
141  mitkThrow() << "Error in ConcentrationCurveGenerator::CalculateAverageBaselineImage. End time point is larger than total number of time points.";
142  }
143 
144  typename ExtractImageFilterType::Pointer ExtractFilter = ExtractImageFilterType::New();
145  typename TPixel4DImageType::Pointer baselineTimeFrameImage = TPixel4DImageType::New();
146  typename TPixel4DImageType::RegionType extractionRegion;
147  typename TPixel4DImageType::SizeType size_input_aux = region_input.GetSize();
148  size_input_aux[3] = m_BaselineEndTimeStep - m_BaselineStartTimeStep + 1;
149  typename TPixel4DImageType::IndexType start_input_aux = region_input.GetIndex();
150  start_input_aux[3] = m_BaselineStartTimeStep;
151  extractionRegion.SetSize(size_input_aux);
152  extractionRegion.SetIndex(start_input_aux);
153  ExtractFilter->SetExtractionRegion(extractionRegion);
154  ExtractFilter->SetInput(itkBaselineImage);
155  ExtractFilter->SetDirectionCollapseToSubmatrix();
156  try
157  {
158  ExtractFilter->Update();
159  }
160  catch (itk::ExceptionObject & err)
161  {
162  std::cerr << "ExceptionObject caught!" << std::endl;
163  std::cerr << err << std::endl;
164  }
165  baselineTimeFrameImage = ExtractFilter->GetOutput();
166  MeanProjectionImageFilter->SetProjectionDimension(3);
167  MeanProjectionImageFilter->SetInput(baselineTimeFrameImage);
168  try
169  {
170  MeanProjectionImageFilter->Update();
171  }
172  catch (itk::ExceptionObject & err)
173  {
174  std::cerr << "ExceptionObject caught!" << std::endl;
175  std::cerr << err << std::endl;
176  }
177  Extract3DImageFilter->SetInput(MeanProjectionImageFilter->GetOutput());
178  size_input_aux[3] = 0;
179  start_input_aux[3] = 0;
180  extractionRegion.SetSize(size_input_aux);
181  extractionRegion.SetIndex(start_input_aux);
182  Extract3DImageFilter->SetExtractionRegion(extractionRegion);
183  Extract3DImageFilter->SetDirectionCollapseToSubmatrix();
184  try
185  {
186  Extract3DImageFilter->Update();
187  }
188  catch (itk::ExceptionObject & err)
189  {
190  std::cerr << "ExceptionObject caught!" << std::endl;
191  std::cerr << err << std::endl;
192  }
193 
194  Image::Pointer mitkBaselineImage = Image::New();
195  CastToMitkImage(Extract3DImageFilter->GetOutput(), mitkBaselineImage);
196  this->m_BaselineImage = mitkBaselineImage;
197 }
198 
199 
201 {
202  mitk::PixelType m_PixelType = inputImage->GetPixelType();
204  return m_ConvertSignalToConcentrationCurve_OutputImage;
205 
206 }
207 
208 
209 template<class TPixel_input, class TPixel_baseline>
210 mitk::Image::Pointer mitk::ConcentrationCurveGenerator::convertToConcentration(const itk::Image<TPixel_input, 3> *itkInputImage, const itk::Image<TPixel_baseline, 3> *itkBaselineImage)
211 {
212  typedef itk::Image<TPixel_input, 3> InputImageType;
213  typedef itk::Image<TPixel_baseline, 3> BaselineImageType;
214 
215 
216  if (this->m_isT2weightedImage)
217  {
219  typedef itk::BinaryFunctorImageFilter<InputImageType, BaselineImageType, ConvertedImageType, ConversionFunctorT2Type> FilterT2Type;
220 
221 
222  ConversionFunctorT2Type ConversionT2Functor;
223  ConversionT2Functor.initialize(this->m_T2Factor, this->m_T2EchoTime);
224 
225  typename FilterT2Type::Pointer ConversionT2Filter = FilterT2Type::New();
226 
227  ConversionT2Filter->SetFunctor(ConversionT2Functor);
228  ConversionT2Filter->SetInput1(itkInputImage);
229  ConversionT2Filter->SetInput2(itkBaselineImage);
230 
231  ConversionT2Filter->Update();
232 
233  m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionT2Filter->GetOutput())->Clone();
234  }
235 
236  else
237  {
238  if(this->m_isTurboFlashSequence)
239  {
241  typedef itk::BinaryFunctorImageFilter<InputImageType, BaselineImageType, ConvertedImageType, ConversionFunctorTurboFlashType> FilterTurboFlashType;
242 
243  ConversionFunctorTurboFlashType ConversionTurboFlashFunctor;
244  ConversionTurboFlashFunctor.initialize(this->m_RelaxationTime, this->m_Relaxivity, this->m_RecoveryTime);
245 
246  typename FilterTurboFlashType::Pointer ConversionTurboFlashFilter = FilterTurboFlashType::New();
247 
248  ConversionTurboFlashFilter->SetFunctor(ConversionTurboFlashFunctor);
249  ConversionTurboFlashFilter->SetInput1(itkInputImage);
250  ConversionTurboFlashFilter->SetInput2(itkBaselineImage);
251 
252  ConversionTurboFlashFilter->Update();
253  m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionTurboFlashFilter->GetOutput())->Clone();
254 
255 
256  }
257  else if(this->m_UsingT1Map)
258  {
259  typename ConvertedImageType::Pointer itkT10Image = ConvertedImageType::New();
260  mitk::CastToItkImage(m_T10Image, itkT10Image);
261 
263  typedef itk::TernaryFunctorImageFilter<InputImageType, BaselineImageType, ConvertedImageType, ConvertedImageType, ConvertToConcentrationViaT1CalcFunctorType> FilterT1MapType;
264 
265  ConvertToConcentrationViaT1CalcFunctorType ConversionT1MapFunctor;
266  ConversionT1MapFunctor.initialize(this->m_Relaxivity, this->m_RecoveryTime, this->m_FlipAngle);
267 
268  typename FilterT1MapType::Pointer ConversionT1MapFilter = FilterT1MapType::New();
269 
270  ConversionT1MapFilter->SetFunctor(ConversionT1MapFunctor);
271  ConversionT1MapFilter->SetInput1(itkInputImage);
272  ConversionT1MapFilter->SetInput2(itkBaselineImage);
273  ConversionT1MapFilter->SetInput3(itkT10Image);
274 
275  ConversionT1MapFilter->Update();
276  m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionT1MapFilter->GetOutput())->Clone();
277 
278 
279  }
280 
281  else if(this->m_AbsoluteSignalEnhancement)
282  {
284  typedef itk::BinaryFunctorImageFilter<InputImageType, BaselineImageType, ConvertedImageType, ConversionFunctorAbsoluteType> FilterAbsoluteType;
285 
286  ConversionFunctorAbsoluteType ConversionAbsoluteFunctor;
287  ConversionAbsoluteFunctor.initialize(this->m_Factor);
288 
289  typename FilterAbsoluteType::Pointer ConversionAbsoluteFilter = FilterAbsoluteType::New();
290 
291  ConversionAbsoluteFilter->SetFunctor(ConversionAbsoluteFunctor);
292  ConversionAbsoluteFilter->SetInput1(itkInputImage);
293  ConversionAbsoluteFilter->SetInput2(itkBaselineImage);
294 
295  ConversionAbsoluteFilter->Update();
296 
297  m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionAbsoluteFilter->GetOutput())->Clone();
298  }
299 
300  else if(this->m_RelativeSignalEnhancement)
301  {
303  typedef itk::BinaryFunctorImageFilter<InputImageType, BaselineImageType, ConvertedImageType, ConversionFunctorRelativeType> FilterRelativeType;
304 
305  ConversionFunctorRelativeType ConversionRelativeFunctor;
306  ConversionRelativeFunctor.initialize(this->m_Factor);
307 
308  typename FilterRelativeType::Pointer ConversionRelativeFilter = FilterRelativeType::New();
309 
310  ConversionRelativeFilter->SetFunctor(ConversionRelativeFunctor);
311  ConversionRelativeFilter->SetInput1(itkInputImage);
312  ConversionRelativeFilter->SetInput2(itkBaselineImage);
313 
314  ConversionRelativeFilter->Update();
315 
316  m_ConvertSignalToConcentrationCurve_OutputImage = mitk::ImportItkImage(ConversionRelativeFilter->GetOutput())->Clone();
317  }
318 
319  }
320  return m_ConvertSignalToConcentrationCurve_OutputImage;
321 
322 }
323 
324 
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
mitk::Image::Pointer convertToConcentration(const itk::Image< TPixel_input, 3 > *itkInputImage, const itk::Image< TPixel_baseline, 3 > *itkBaselineImage)
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
Definition: mitkImage.cpp:101
void PrepareBaselineImage()
Takes the 3D image of the first timepoint to set as baseline image.
virtual void Convert()
loops over all timepoints, casts the current timepoint 3D mitk::image to itk and passes it to Convert...
Image::Pointer ImportItkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, const BaseGeometry *geometry=nullptr, bool update=true)
Imports an itk::Image (with a specific type) as an mitk::Image.Instantiates instance of ITKImageImpor...
void CalculateAverageBaselineImage(const itk::Image< TPixel, 4 > *itkBaselineImage)
#define mitkThrow()
Image class for storing images.
Definition: mitkImage.h:72
void initialize(double relaxationtime, double relaxivity, double recoverytime)
mitk::Image::Pointer ConvertSignalToConcentrationCurve(const mitk::Image *inputImage, const mitk::Image *baselineImage)
static Pointer New()
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:74
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
#define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension)
Access two mitk-images with known dimension by itk-images.
void initialize(double relaxivity, double TR, double flipangle)
ImageReadAccessor class to get locked read access for a particular image part.
static mitk::PlanarFigure::Pointer Clone(mitk::PlanarFigure::Pointer original)
const void * GetData() const
Gives const access to the data.
static Pointer New()
Class for defining the data type of pixels.
Definition: mitkPixelType.h:51