Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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