Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPixelBasedParameterFitImageGenerator.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 
13 #include "itkCommand.h"
15 
17 #include "mitkImageTimeSelector.h"
18 #include "mitkImageAccessByItk.h"
19 #include "mitkImageCast.h"
21 
22 #include "mitkExtractTimeGrid.h"
23 
24 void
26  onFitProgressEvent(::itk::Object* caller, const ::itk::EventObject& /*eventObject*/)
27 {
28  this->InvokeEvent(::itk::ProgressEvent());
29 
30  auto* process = dynamic_cast<itk::ProcessObject*>(caller);
31  if (process)
32  {
33  this->m_Progress = process->GetProgress();
34  }
35 };
36 
37 template <typename TPixel, unsigned int VDim>
38 void
40 {
41  m_InternalMask = dynamic_cast<InternalMaskType*>(image);
42 
43  if (m_InternalMask.IsNull())
44  {
45  MITK_INFO << "Parameter Fit Generator. Need to cast mask for parameter fit.";
46  using InputImageType = itk::Image<TPixel, VDim>;
47  using CastFilterType = itk::CastImageFilter< InputImageType, InternalMaskType >;
48  typename CastFilterType::Pointer spImageCaster = CastFilterType::New();
49 
50  spImageCaster->SetInput(image);
51 
52  m_InternalMask = spImageCaster->GetOutput();
53  spImageCaster->Update();
54  }
55 }
56 
57 template<typename TImage>
58 mitk::PixelBasedParameterFitImageGenerator::ParameterImageMapType StoreResultImages( mitk::ModelFitFunctorBase::ParameterNamesType &paramNames, itk::ImageSource<TImage>* source, mitk::ModelFitFunctorBase::ParameterNamesType::size_type startPos, mitk::ModelFitFunctorBase::ParameterNamesType::size_type& endPos )
59 {
61  for (mitk::ModelFitFunctorBase::ParameterNamesType::size_type j = 0; j < paramNames.size(); ++j)
62  {
63  if (source->GetNumberOfOutputs() < startPos+j)
64  {
65  mitkThrow() << "Error while generating fitted parameter images. Number of sources is too low and does not match expected parameter number. Output size: "<< source->GetNumberOfOutputs()<<"; number of param names: "<<paramNames.size()<<";source start pos: " << startPos;
66  }
67 
69  typename TImage::ConstPointer outputImg = source->GetOutput(startPos+j);
70  mitk::CastToMitkImage(outputImg, paramImage);
71 
72  result.insert(std::make_pair(paramNames[j],paramImage));
73  }
74 
75  endPos = startPos + paramNames.size();
76 
77  return result;
78 }
79 
80 template <typename TPixel, unsigned int VDim>
81 void
83 {
84  using InputFrameImageType = itk::Image<TPixel, VDim-1>;
85  using ParameterImageType = itk::Image<ScalarType, VDim-1>;
86 
88 
89  typename FitFilterType::Pointer fitFilter = FitFilterType::New();
90 
91  typename ::itk::MemberCommand<Self>::Pointer spProgressCommand = ::itk::MemberCommand<Self>::New();
92  spProgressCommand->SetCallbackFunction(this, &Self::onFitProgressEvent);
93  fitFilter->AddObserver(::itk::ProgressEvent(), spProgressCommand);
94 
95  //add the time frames to the fit filter
97  imageTimeSelector->SetInput(this->m_DynamicImage);
98  std::vector<Image::Pointer> frameCache;
99  for (unsigned int i = 0; i < this->m_DynamicImage->GetTimeSteps(); ++i)
100  {
101  typename InputFrameImageType::Pointer frameImage;
102  imageTimeSelector->SetTimeNr(i);
103  imageTimeSelector->UpdateLargestPossibleRegion();
104 
105  Image::Pointer frameMITKImage = imageTimeSelector->GetOutput();
106  frameCache.push_back(frameMITKImage);
107  mitk::CastToItkImage(frameMITKImage, frameImage);
108  fitFilter->SetInput(i,frameImage);
109  }
110 
111  ModelBaseType::TimeGridType timeGrid = ExtractTimeGrid(m_DynamicImage);
112  if (m_TimeGridByParameterizer)
113  {
114  if (timeGrid.GetSize() != m_ModelParameterizer->GetDefaultTimeGrid().GetSize())
115  {
116  mitkThrow() << "Cannot do fitting. Filter is set to use default time grid of the parameterizer, but grid size does not match the number of input image frames. Grid size: " << m_ModelParameterizer->GetDefaultTimeGrid().GetSize() << "; frame count: " << timeGrid.GetSize();
117  }
118 
119  }
120  else
121  {
122  this->m_ModelParameterizer->SetDefaultTimeGrid(timeGrid);
123  }
124 
125  ModelFitFunctorPolicy functor;
126 
127  functor.SetModelFitFunctor(this->m_FitFunctor);
128  functor.SetModelParameterizer(this->m_ModelParameterizer);
129  fitFilter->SetFunctor(functor);
130  if (this->m_InternalMask.IsNotNull())
131  {
132  fitFilter->SetMask(this->m_InternalMask);
133  }
134 
135  //generate the fits
136  fitFilter->Update();
137 
138  //convert the outputs into mitk images and fill the parameter image map
139  ModelBaseType::Pointer refModel = this->m_ModelParameterizer->GenerateParameterizedModel();
140  ModelFitFunctorBase::ParameterNamesType paramNames = refModel->GetParameterNames();
141  ModelFitFunctorBase::ParameterNamesType derivedParamNames = refModel->GetDerivedParameterNames();
142  ModelFitFunctorBase::ParameterNamesType criterionNames = this->m_FitFunctor->GetCriterionNames();
143  ModelFitFunctorBase::ParameterNamesType evaluationParamNames = this->m_FitFunctor->GetEvaluationParameterNames();
144  ModelFitFunctorBase::ParameterNamesType debugParamNames = this->m_FitFunctor->GetDebugParameterNames();
145 
146  if (fitFilter->GetNumberOfOutputs() != (paramNames.size() + derivedParamNames.size() + criterionNames.size() + evaluationParamNames.size() + debugParamNames.size()))
147  {
148  mitkThrow() << "Error while generating fitted parameter images. Fit filter output size does not match expected parameter number. Output size: "<< fitFilter->GetNumberOfOutputs();
149  }
150 
151  ModelFitFunctorBase::ParameterNamesType::size_type resultPos = 0;
152  this->m_TempResultMap = StoreResultImages<ParameterImageType>(paramNames,fitFilter,resultPos, resultPos);
153  this->m_TempDerivedResultMap = StoreResultImages<ParameterImageType>(derivedParamNames,fitFilter,resultPos, resultPos);
154  this->m_TempCriterionResultMap = StoreResultImages<ParameterImageType>(criterionNames,fitFilter,resultPos, resultPos);
155  this->m_TempEvaluationResultMap = StoreResultImages<ParameterImageType>(evaluationParamNames,fitFilter,resultPos, resultPos);
156  //also add debug params (if generated) to the evaluation result map
157  mitk::PixelBasedParameterFitImageGenerator::ParameterImageMapType debugMap = StoreResultImages<ParameterImageType>(debugParamNames, fitFilter, resultPos, resultPos);
158  this->m_TempEvaluationResultMap.insert(debugMap.begin(), debugMap.end());
159 }
160 
161 bool
163 {
164  bool result = Superclass::HasOutdatedResult();
165 
166  if (m_ModelParameterizer.IsNotNull())
167  {
168  if (m_ModelParameterizer->GetMTime() > this->m_GenerationTimeStamp)
169  {
170  result = true;
171  }
172  }
173 
174  if (m_FitFunctor.IsNotNull())
175  {
176  if (m_FitFunctor->GetMTime() > this->m_GenerationTimeStamp)
177  {
178  result = true;
179  }
180  }
181 
182  if (m_DynamicImage.IsNotNull())
183  {
184  if (m_DynamicImage->GetMTime() > this->m_GenerationTimeStamp)
185  {
186  result = true;
187  }
188  }
189 
190  if (m_Mask.IsNotNull())
191  {
192  if (m_Mask->GetMTime() > this->m_GenerationTimeStamp)
193  {
194  result = true;
195  }
196  }
197 
198  return result;
199 
200 };
201 
202 void
204 {
205  Superclass::CheckValidInputs();
206 
207  if (m_DynamicImage.IsNull())
208  {
209  mitkThrow() << "Cannot generate fitted parameter images. Input dynamic image is not set.";
210  }
211 
212 };
213 
214 void mitk::PixelBasedParameterFitImageGenerator::DoFitAndGetResults(ParameterImageMapType& parameterImages, ParameterImageMapType& derivedParameterImages, ParameterImageMapType& criterionImages, ParameterImageMapType& evaluationParameterImages)
215 {
216  this->m_Progress = 0;
217 
218  if(this->m_Mask.IsNotNull())
219  {
221  }
222  else
223  {
224  this->m_InternalMask = nullptr;
225  }
226 
228 
229  parameterImages = this->m_TempResultMap;
230  derivedParameterImages = this->m_TempDerivedResultMap;
231  criterionImages = this->m_TempCriterionResultMap;
232  evaluationParameterImages = this->m_TempEvaluationResultMap;
233 
234 };
235 
236 double
238 {
239  return m_Progress;
240 };
241 
244 {
245  ParameterizerType::ModelBasePointer parameterizedModel =
246  m_ModelParameterizer->GenerateParameterizedModel();
247 
248  return parameterizedModel->GetParameterNames();
249 }
250 
253 {
254  ParameterizerType::ModelBasePointer parameterizedModel =
255  m_ModelParameterizer->GenerateParameterizedModel();
256 
257  return parameterizedModel->GetDerivedParameterNames();
258 }
259 
262 {
263  return this->m_FitFunctor->GetCriterionNames();
264 }
265 
268 {
269  auto evals = this->m_FitFunctor->GetEvaluationParameterNames();
270  auto debugs = this->m_FitFunctor->GetDebugParameterNames();
271 
272  evals.insert(evals.end(), debugs.begin(), debugs.end());
273 
274  return evals;
275 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
double ScalarType
ParameterFitImageGeneratorBase::ParameterImageMapType ParameterImageMapType
ModelBaseType::ParameterNamesType ParameterNamesType
ModelBase::ParameterNamesType ParameterNamesType
itk::Array< double > TimeGridType
Definition: mitkModelBase.h:62
mitk::PixelBasedParameterFitImageGenerator::ParameterImageMapType StoreResultImages(mitk::ModelFitFunctorBase::ParameterNamesType &paramNames, itk::ImageSource< TImage > *source, mitk::ModelFitFunctorBase::ParameterNamesType::size_type startPos, mitk::ModelFitFunctorBase::ParameterNamesType::size_type &endPos)
void SetModelFitFunctor(const mitk::ModelFitFunctorBase *functor)
Perform a generic pixel-wise operation on N images and produces m output images.
void DoFitAndGetResults(ParameterImageMapType &parameterImages, ParameterImageMapType &derivedParameterImages, ParameterImageMapType &criterionImages, ParameterImageMapType &evaluationParameterImages) override
class ITK_EXPORT Image
void onFitProgressEvent(::itk::Object *caller, const ::itk::EventObject &eventObject)
MITKMODELFIT_EXPORT ModelBase::TimeGridType ExtractTimeGrid(const Image *image)
#define mitkThrow()
std::map< ParameterNameType, Image::Pointer > ParameterImageMapType
mitk::Image::Pointer image
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.
void SetModelParameterizer(const ParameterizerType *parameterizer)
static Pointer New()