Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkMaskImageFilter.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkMaskImageFilter.h"
18 #include "mitkImageTimeSelector.h"
19 #include "mitkProperties.h"
20 #include "mitkTimeHelper.h"
21 
22 #include "mitkImageAccessByItk.h"
23 #include "mitkImageToItk.h"
24 
25 #include "itkImageRegionConstIterator.h"
26 #include "itkImageRegionIteratorWithIndex.h"
27 
28 #include <limits>
29 
31 {
32  this->SetNumberOfIndexedInputs(2);
33  this->SetNumberOfRequiredInputs(2);
37  m_OverrideOutsideValue = false;
38  m_OutsideValue = 0;
39 }
40 
42 {
43 }
44 
46 {
47  // Process object is not const-correct so the const_cast is required here
48  m_Mask = const_cast<mitk::Image *>(mask);
49  this->ProcessObject::SetNthInput(1, m_Mask);
50 }
51 
53 {
54  return m_Mask;
55 }
56 
58 {
59  Superclass::GenerateInputRequestedRegion();
60 
61  mitk::Image *output = this->GetOutput();
62  mitk::Image *input = const_cast<mitk::Image *>(this->GetInput());
63  mitk::Image *mask = m_Mask;
64  if ((output->IsInitialized() == false) || (mask == nullptr) || (mask->GetTimeGeometry()->CountTimeSteps() == 0))
65  return;
66 
69 
70  GenerateTimeInInputRegion(output, input);
71  GenerateTimeInInputRegion(output, mask);
72 }
73 
75 {
76  mitk::Image::ConstPointer input = this->GetInput();
77  mitk::Image::Pointer output = this->GetOutput();
78 
79  if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
80  return;
81 
82  itkDebugMacro(<< "GenerateOutputInformation()");
83 
84  output->Initialize(input->GetPixelType(), *input->GetTimeGeometry());
85 
86  output->SetPropertyList(input->GetPropertyList()->Clone());
87 
88  m_TimeOfHeaderInitialization.Modified();
89 }
90 
91 template <typename TPixel, unsigned int VImageDimension>
92 void mitk::MaskImageFilter::InternalComputeMask(itk::Image<TPixel, VImageDimension> *inputItkImage)
93 {
94  // dirty quick fix, duplicating code so both unsigned char and unsigned short are supported
95  // this should be changed once unsigned char segmentations can be converted to unsigned short
96  mitk::PixelType pixelType =
97  m_MaskTimeSelector->GetOutput()->GetImageDescriptor()->GetChannelDescriptor().GetPixelType();
98  if (pixelType.GetComponentType() == itk::ImageIOBase::UCHAR)
99  {
100  typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
101  typedef itk::Image<unsigned char, VImageDimension> ItkMaskImageType;
102  typedef itk::Image<TPixel, VImageDimension> ItkOutputImageType;
103 
104  typedef itk::ImageRegionConstIterator<ItkInputImageType> ItkInputImageIteratorType;
105  typedef itk::ImageRegionConstIterator<ItkMaskImageType> ItkMaskImageIteratorType;
106  typedef itk::ImageRegionIteratorWithIndex<ItkOutputImageType> ItkOutputImageIteratorType;
107 
109  maskimagetoitk->SetInput(m_MaskTimeSelector->GetOutput());
110  maskimagetoitk->Update();
111  typename ItkMaskImageType::Pointer maskItkImage = maskimagetoitk->GetOutput();
112 
113  typename mitk::ImageToItk<ItkOutputImageType>::Pointer outputimagetoitk =
115  outputimagetoitk->SetInput(m_OutputTimeSelector->GetOutput());
116  outputimagetoitk->Update();
117  typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
118 
119  // create the iterators
120  typename ItkInputImageType::RegionType inputRegionOfInterest = inputItkImage->GetLargestPossibleRegion();
121  ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
122  ItkMaskImageIteratorType maskIt(maskItkImage, inputRegionOfInterest);
123  ItkOutputImageIteratorType outputIt(outputItkImage, inputRegionOfInterest);
124 
125  // typename ItkOutputImageType::PixelType outsideValue = itk::NumericTraits<typename
126  // ItkOutputImageType::PixelType>::min();
127  if (!m_OverrideOutsideValue)
129 
132 
133  for (inputIt.GoToBegin(), maskIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd() && !maskIt.IsAtEnd();
134  ++inputIt, ++maskIt, ++outputIt)
135  {
136  if (maskIt.Get() > itk::NumericTraits<typename ItkMaskImageType::PixelType>::Zero)
137  {
138  outputIt.Set(inputIt.Get());
139  m_MinValue = vnl_math_min((float)inputIt.Get(), (float)m_MinValue);
140  m_MaxValue = vnl_math_max((float)inputIt.Get(), (float)m_MaxValue);
141  }
142  else
143  {
144  outputIt.Set(m_OutsideValue);
145  }
146  }
147  }
148  else
149  {
150  {
151  typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
152  typedef itk::Image<unsigned short, VImageDimension> ItkMaskImageType;
153  typedef itk::Image<TPixel, VImageDimension> ItkOutputImageType;
154 
155  typedef itk::ImageRegionConstIterator<ItkInputImageType> ItkInputImageIteratorType;
156  typedef itk::ImageRegionConstIterator<ItkMaskImageType> ItkMaskImageIteratorType;
157  typedef itk::ImageRegionIteratorWithIndex<ItkOutputImageType> ItkOutputImageIteratorType;
158 
160  maskimagetoitk->SetInput(m_MaskTimeSelector->GetOutput());
161  maskimagetoitk->Update();
162  typename ItkMaskImageType::Pointer maskItkImage = maskimagetoitk->GetOutput();
163 
164  typename mitk::ImageToItk<ItkOutputImageType>::Pointer outputimagetoitk =
166  outputimagetoitk->SetInput(m_OutputTimeSelector->GetOutput());
167  outputimagetoitk->Update();
168  typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
169 
170  // create the iterators
171  typename ItkInputImageType::RegionType inputRegionOfInterest = inputItkImage->GetLargestPossibleRegion();
172  ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
173  ItkMaskImageIteratorType maskIt(maskItkImage, inputRegionOfInterest);
174  ItkOutputImageIteratorType outputIt(outputItkImage, inputRegionOfInterest);
175 
176  // typename ItkOutputImageType::PixelType outsideValue = itk::NumericTraits<typename
177  // ItkOutputImageType::PixelType>::min();
178  if (!m_OverrideOutsideValue)
180 
183 
184  for (inputIt.GoToBegin(), maskIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd() && !maskIt.IsAtEnd();
185  ++inputIt, ++maskIt, ++outputIt)
186  {
187  if (maskIt.Get() > itk::NumericTraits<typename ItkMaskImageType::PixelType>::Zero)
188  {
189  outputIt.Set(inputIt.Get());
190  m_MinValue = vnl_math_min((float)inputIt.Get(), (float)m_MinValue);
191  m_MaxValue = vnl_math_max((float)inputIt.Get(), (float)m_MaxValue);
192  }
193  else
194  {
195  outputIt.Set(m_OutsideValue);
196  }
197  }
198  }
199  }
200 }
201 
203 {
204  mitk::Image::ConstPointer input = this->GetInput();
205  mitk::Image::Pointer mask = m_Mask;
206  mitk::Image::Pointer output = this->GetOutput();
207 
208  if ((output->IsInitialized() == false) || (mask.IsNull()) || (mask->GetTimeGeometry()->CountTimeSteps() == 0))
209  return;
210 
211  m_InputTimeSelector->SetInput(input);
212  m_MaskTimeSelector->SetInput(mask);
213  m_OutputTimeSelector->SetInput(this->GetOutput());
214 
215  mitk::Image::RegionType outputRegion = output->GetRequestedRegion();
216  const mitk::TimeGeometry *outputTimeGeometry = output->GetTimeGeometry();
217  const mitk::TimeGeometry *inputTimeGeometry = input->GetTimeGeometry();
218  const mitk::TimeGeometry *maskTimeGeometry = mask->GetTimeGeometry();
219  ScalarType timeInMS;
220 
221  int timestep = 0;
222  int tstart = outputRegion.GetIndex(3);
223  int tmax = tstart + outputRegion.GetSize(3);
224 
225  int t;
226  for (t = tstart; t < tmax; ++t)
227  {
228  timeInMS = outputTimeGeometry->TimeStepToTimePoint(t);
229 
230  timestep = inputTimeGeometry->TimePointToTimeStep(timeInMS);
231 
232  m_InputTimeSelector->SetTimeNr(timestep);
233  m_InputTimeSelector->UpdateLargestPossibleRegion();
234  m_OutputTimeSelector->SetTimeNr(t);
235  m_OutputTimeSelector->UpdateLargestPossibleRegion();
236 
237  timestep = maskTimeGeometry->TimePointToTimeStep(timeInMS);
238  m_MaskTimeSelector->SetTimeNr(timestep);
239  m_MaskTimeSelector->UpdateLargestPossibleRegion();
240 
241  AccessByItk(m_InputTimeSelector->GetOutput(), InternalComputeMask);
242  }
243 
244  m_TimeOfHeaderInitialization.Modified();
245 }
virtual void SetRequestedRegionToLargestPossibleRegion() override
itk::SmartPointer< Self > Pointer
double ScalarType
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:52
itk::ImageIOBase::IOPixelType GetPixelType() const
virtual void GenerateData() override
A version of GenerateData() specific for image processing filters.
itk::ImageRegion< RegionDimension > RegionType
virtual TimeStepType TimePointToTimeStep(TimePointType timePoint) const =0
Converts a time point to the corresponding time step.
Image class for storing images.
Definition: mitkImage.h:76
virtual TimePointType TimeStepToTimePoint(TimeStepType timeStep) const =0
Converts a time step to a time point.
#define AccessByItk(mitkImage, itkImageTypeFunction)
Access a MITK image by an ITK image.
int GetComponentType() const
Get the component type (the scalar (!) type). Each element may contain m_NumberOfComponents (more tha...
static T max(T x, T y)
Definition: svm.cpp:70
const mitk::Image * GetMask() const
void GenerateTimeInInputRegion(const mitk::TimeGeometry *outputTimeGeometry, const TOutputRegion &outputRegion, const mitk::TimeGeometry *inputTimeGeometry, TInputRegion &inputRegion)
static T min(T x, T y)
Definition: svm.cpp:67
static Pointer New()
void SetMask(const mitk::Image *mask)
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
void InternalComputeMask(itk::Image< TPixel, VImageDimension > *itkImage)
virtual void GenerateOutputInformation() override
mitk::ImageTimeSelector::Pointer m_InputTimeSelector
mitk::ScalarType m_OutsideValue
mitk::ImageTimeSelector::Pointer m_MaskTimeSelector
static Pointer New()
virtual void GenerateInputRequestedRegion() override
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
mitk::ImageTimeSelector::Pointer m_OutputTimeSelector