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
mitkBoundingObjectCutter.txx
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 #ifndef MITKBOUNDINGOBJECTCUTTER_TXX
18 #define MITKBOUNDINGOBJECTCUTTER_TXX
19 
20 #include "itkImageRegionIteratorWithIndex.h"
21 #include "mitkImageToItk.h"
22 #include "mitkStatusBar.h"
23 
24 namespace mitk
25 {
26  template <typename TPixel, unsigned int VImageDimension, typename TOutputPixel>
27  void CutImageWithOutputTypeSelect(itk::Image<TPixel, VImageDimension> *inputItkImage,
28  mitk::BoundingObjectCutter *cutter,
29  int /* boTimeStep */,
30  TOutputPixel * /* dummy */)
31  {
32  typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
33  typedef itk::Image<TOutputPixel, VImageDimension> ItkOutputImageType;
34  typedef typename itk::ImageBase<VImageDimension>::RegionType ItkRegionType;
35  typedef itk::ImageRegionIteratorWithIndex<ItkInputImageType> ItkInputImageIteratorType;
36  typedef itk::ImageRegionIteratorWithIndex<ItkOutputImageType> ItkOutputImageIteratorType;
37 
38  if (cutter->m_BoundingObject.IsNull())
39  return;
40 
41  if (inputItkImage == nullptr)
42  {
43  mitk::StatusBar::GetInstance()->DisplayErrorText(
44  "An internal error occurred. Can't convert Image. Please report to bugs@mitk.org");
45  std::cout << " image is NULL...returning" << std::endl;
46  return;
47  }
48 
49  // PART 1: convert m_InputRequestedReg ion (type mitk::SlicedData::RegionType)
50  // into ITK-image-region (ItkImageType::RegionType)
51  // unfortunately, we cannot use input->GetRequestedRegion(), because it
52  // has been destroyed by the mitk::CastToItkImage call of PART 1
53  // (which sets the m_RequestedRegion to the LargestPossibleRegion).
54  // Thus, use our own member m_InputRequestedRegion insead.
55 
56  // first convert the index
57  typename ItkRegionType::IndexType::IndexValueType tmpIndex[3];
58  itk2vtk(cutter->m_InputRequestedRegion.GetIndex(), tmpIndex);
59  typename ItkRegionType::IndexType index;
60  index.SetIndex(tmpIndex);
61 
62  // then convert the size
63  typename ItkRegionType::SizeType::SizeValueType tmpSize[3];
64  itk2vtk(cutter->m_InputRequestedRegion.GetSize(), tmpSize);
65  typename ItkRegionType::SizeType size;
66  size.SetSize(tmpSize);
67 
68  // create the ITK-image-region out of index and size
69  ItkRegionType inputRegionOfInterest(index, size);
70 
71  // PART 2: get access to the MITK output image via an ITK image
72  typename mitk::ImageToItk<ItkOutputImageType>::Pointer outputimagetoitk =
73  mitk::ImageToItk<ItkOutputImageType>::New();
74  outputimagetoitk->SetInput(cutter->m_OutputTimeSelector->GetOutput());
75  outputimagetoitk->Update();
76  typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
77 
78  // PART 3: iterate over input and output using ITK iterators
79 
80  // create the iterators
81  ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
82  ItkOutputImageIteratorType outputIt(outputItkImage, outputItkImage->GetLargestPossibleRegion());
83 
84  // Cut the boundingbox out of the image by iterating through
85  // all pixels and checking if they are inside using IsInside()
86  cutter->m_OutsidePixelCount = 0;
87  cutter->m_InsidePixelCount = 0;
88  mitk::Point3D p;
89  mitk::BaseGeometry *inputGeometry = cutter->GetInput()->GetGeometry();
90 
91  TOutputPixel outsideValue;
92  if (cutter->m_AutoOutsideValue)
93  {
94  outsideValue = itk::NumericTraits<TOutputPixel>::min();
95  }
96  else
97  {
98  outsideValue = (TOutputPixel)cutter->m_OutsideValue;
99  }
100  // shall we use a fixed value for each inside pixel?
101  if (cutter->GetUseInsideValue())
102  {
103  TOutputPixel insideValue = (TOutputPixel)cutter->m_InsideValue;
104  // yes, use a fixed value for each inside pixel (create a binary mask of the bounding object)
105  for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
106  {
107  vtk2itk(inputIt.GetIndex(), p);
108  inputGeometry->IndexToWorld(p, p);
109  if (cutter->m_BoundingObject->IsInside(p))
110  {
111  outputIt.Set(insideValue);
112  ++cutter->m_InsidePixelCount;
113  }
114  else
115  {
116  outputIt.Set(outsideValue);
117  ++cutter->m_OutsidePixelCount;
118  }
119  }
120  }
121  else
122  {
123  // no, use the pixel value of the original image (normal cutting)
124  for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
125  {
126  vtk2itk(inputIt.GetIndex(), p);
127  inputGeometry->IndexToWorld(p, p);
128  if (cutter->m_BoundingObject->IsInside(p))
129  {
130  outputIt.Set((TOutputPixel)inputIt.Value());
131  ++cutter->m_InsidePixelCount;
132  }
133  else
134  {
135  outputIt.Set(outsideValue);
136  ++cutter->m_OutsidePixelCount;
137  }
138  }
139  }
140  }
141 
142  template <typename TPixel, unsigned int VImageDimension, typename TOutputPixel>
143  void CutImageWithOutputTypeSelect(itk::VectorImage<TPixel, VImageDimension> *inputItkImage,
144  mitk::BoundingObjectCutter *cutter,
145  int /* boTimeStep */,
146  TOutputPixel * /* dummy */)
147  {
148  typedef itk::VectorImage<TPixel, VImageDimension> ItkInputImageType;
149  typedef itk::VectorImage<TOutputPixel, VImageDimension> ItkOutputImageType;
150  typedef typename itk::ImageBase<VImageDimension>::RegionType ItkRegionType;
151  typedef itk::ImageRegionIteratorWithIndex<ItkInputImageType> ItkInputImageIteratorType;
152  typedef itk::ImageRegionIteratorWithIndex<ItkOutputImageType> ItkOutputImageIteratorType;
153 
154  if (cutter->m_BoundingObject.IsNull())
155  return;
156 
157  if (inputItkImage == nullptr)
158  {
159  mitk::StatusBar::GetInstance()->DisplayErrorText(
160  "An internal error occurred. Can't convert Image. Please report to bugs@mitk.org");
161  std::cout << " image is NULL...returning" << std::endl;
162  return;
163  }
164 
165  // PART 1: convert m_InputRequestedReg ion (type mitk::SlicedData::RegionType)
166  // into ITK-image-region (ItkImageType::RegionType)
167  // unfortunately, we cannot use input->GetRequestedRegion(), because it
168  // has been destroyed by the mitk::CastToItkImage call of PART 1
169  // (which sets the m_RequestedRegion to the LargestPossibleRegion).
170  // Thus, use our own member m_InputRequestedRegion insead.
171 
172  // first convert the index
173  typename ItkRegionType::IndexType::IndexValueType tmpIndex[3];
174  itk2vtk(cutter->m_InputRequestedRegion.GetIndex(), tmpIndex);
175  typename ItkRegionType::IndexType index;
176  index.SetIndex(tmpIndex);
177 
178  // then convert the size
179  typename ItkRegionType::SizeType::SizeValueType tmpSize[3];
180  itk2vtk(cutter->m_InputRequestedRegion.GetSize(), tmpSize);
181  typename ItkRegionType::SizeType size;
182  size.SetSize(tmpSize);
183 
184  // create the ITK-image-region out of index and size
185  ItkRegionType inputRegionOfInterest(index, size);
186 
187  // PART 2: get access to the MITK output image via an ITK image
188  typename mitk::ImageToItk<ItkOutputImageType>::Pointer outputimagetoitk =
189  mitk::ImageToItk<ItkOutputImageType>::New();
190  outputimagetoitk->SetInput(cutter->m_OutputTimeSelector->GetOutput());
191  outputimagetoitk->Update();
192  typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
193 
194  // PART 3: iterate over input and output using ITK iterators
195 
196  // create the iterators
197  ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
198  ItkOutputImageIteratorType outputIt(outputItkImage, outputItkImage->GetLargestPossibleRegion());
199 
200  // Cut the boundingbox out of the image by iterating through
201  // all pixels and checking if they are inside using IsInside()
202  cutter->m_OutsidePixelCount = 0;
203  cutter->m_InsidePixelCount = 0;
204  mitk::Point3D p;
205  mitk::BaseGeometry *inputGeometry = cutter->GetInput()->GetGeometry();
206 
207  typename ItkOutputImageType::PixelType outsideValue;
208  outsideValue.SetSize(outputItkImage->GetVectorLength());
209  if (cutter->m_AutoOutsideValue)
210  {
211  outsideValue.Fill(itk::NumericTraits<TOutputPixel>::min());
212  }
213  else
214  {
215  outsideValue.Fill(cutter->m_OutsideValue);
216  }
217  // shall we use a fixed value for each inside pixel?
218  if (cutter->GetUseInsideValue())
219  {
220  typename ItkOutputImageType::PixelType insideValue;
221  insideValue.Fill(cutter->m_InsideValue);
222  // yes, use a fixed value for each inside pixel (create a binary mask of the bounding object)
223  for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
224  {
225  vtk2itk(inputIt.GetIndex(), p);
226  inputGeometry->IndexToWorld(p, p);
227  if (cutter->m_BoundingObject->IsInside(p))
228  {
229  outputIt.Set(insideValue);
230  ++cutter->m_InsidePixelCount;
231  }
232  else
233  {
234  outputIt.Set(outsideValue);
235  ++cutter->m_OutsidePixelCount;
236  }
237  }
238  }
239  else
240  {
241  // no, use the pixel value of the original image (normal cutting)
242  for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
243  {
244  vtk2itk(inputIt.GetIndex(), p);
245  inputGeometry->IndexToWorld(p, p);
246  if (cutter->m_BoundingObject->IsInside(p))
247  {
248  outputIt.Set(inputIt.Get());
249  ++cutter->m_InsidePixelCount;
250  }
251  else
252  {
253  outputIt.Set(outsideValue);
254  ++cutter->m_OutsidePixelCount;
255  }
256  }
257  }
258  }
259 
260  template <typename TPixel, unsigned int VImageDimension>
261  void CutImage(itk::Image<TPixel, VImageDimension> *inputItkImage, mitk::BoundingObjectCutter *cutter, int boTimeStep)
262  {
263  TPixel *dummy = nullptr;
264  CutImageWithOutputTypeSelect<TPixel, VImageDimension, TPixel>(inputItkImage, cutter, boTimeStep, dummy);
265  }
266 
267  template <typename TPixel, unsigned int VImageDimension>
268  void CutImage(itk::VectorImage<TPixel, VImageDimension> *inputItkImage,
269  mitk::BoundingObjectCutter *cutter,
270  int boTimeStep)
271  {
272  TPixel *dummy = nullptr;
273  CutImageWithOutputTypeSelect<TPixel, VImageDimension, TPixel>(inputItkImage, cutter, boTimeStep, dummy);
274  }
275 
276 } // of namespace mitk
277 
278 #include "mitkImageCast.h"
279 
280 #endif // of MITKBOUNDINGOBJECTCUTTER_TXX