1 /*===================================================================
3 The Medical Imaging Interaction Toolkit (MITK)
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 See LICENSE.txt or http://www.mitk.org for details.
15 ===================================================================*/
17 #ifndef MITKBOUNDINGOBJECTCUTTER_TXX
18 #define MITKBOUNDINGOBJECTCUTTER_TXX
20 #include "itkImageRegionIteratorWithIndex.h"
21 #include "mitkImageToItk.h"
22 #include "mitkStatusBar.h"
26 template <typename TPixel, unsigned int VImageDimension, typename TOutputPixel>
27 void CutImageWithOutputTypeSelect(itk::Image<TPixel, VImageDimension> *inputItkImage,
28 mitk::BoundingObjectCutter *cutter,
30 TOutputPixel * /* dummy */)
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;
38 if (cutter->m_BoundingObject.IsNull())
41 if (inputItkImage == nullptr)
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;
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.
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);
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);
68 // create the ITK-image-region out of index and size
69 ItkRegionType inputRegionOfInterest(index, size);
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();
78 // PART 3: iterate over input and output using ITK iterators
80 // create the iterators
81 ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
82 ItkOutputImageIteratorType outputIt(outputItkImage, outputItkImage->GetLargestPossibleRegion());
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;
89 mitk::BaseGeometry *inputGeometry = cutter->GetInput()->GetGeometry();
91 TOutputPixel outsideValue;
92 if (cutter->m_AutoOutsideValue)
94 outsideValue = itk::NumericTraits<TOutputPixel>::min();
98 outsideValue = (TOutputPixel)cutter->m_OutsideValue;
100 // shall we use a fixed value for each inside pixel?
101 if (cutter->GetUseInsideValue())
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)
107 vtk2itk(inputIt.GetIndex(), p);
108 inputGeometry->IndexToWorld(p, p);
109 if (cutter->m_BoundingObject->IsInside(p))
111 outputIt.Set(insideValue);
112 ++cutter->m_InsidePixelCount;
116 outputIt.Set(outsideValue);
117 ++cutter->m_OutsidePixelCount;
123 // no, use the pixel value of the original image (normal cutting)
124 for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
126 vtk2itk(inputIt.GetIndex(), p);
127 inputGeometry->IndexToWorld(p, p);
128 if (cutter->m_BoundingObject->IsInside(p))
130 outputIt.Set((TOutputPixel)inputIt.Value());
131 ++cutter->m_InsidePixelCount;
135 outputIt.Set(outsideValue);
136 ++cutter->m_OutsidePixelCount;
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 */)
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;
154 if (cutter->m_BoundingObject.IsNull())
157 if (inputItkImage == nullptr)
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;
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.
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);
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);
184 // create the ITK-image-region out of index and size
185 ItkRegionType inputRegionOfInterest(index, size);
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();
194 // PART 3: iterate over input and output using ITK iterators
196 // create the iterators
197 ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
198 ItkOutputImageIteratorType outputIt(outputItkImage, outputItkImage->GetLargestPossibleRegion());
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;
205 mitk::BaseGeometry *inputGeometry = cutter->GetInput()->GetGeometry();
207 typename ItkOutputImageType::PixelType outsideValue;
208 outsideValue.SetSize(outputItkImage->GetVectorLength());
209 if (cutter->m_AutoOutsideValue)
211 outsideValue.Fill(itk::NumericTraits<TOutputPixel>::min());
215 outsideValue.Fill(cutter->m_OutsideValue);
217 // shall we use a fixed value for each inside pixel?
218 if (cutter->GetUseInsideValue())
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)
225 vtk2itk(inputIt.GetIndex(), p);
226 inputGeometry->IndexToWorld(p, p);
227 if (cutter->m_BoundingObject->IsInside(p))
229 outputIt.Set(insideValue);
230 ++cutter->m_InsidePixelCount;
234 outputIt.Set(outsideValue);
235 ++cutter->m_OutsidePixelCount;
241 // no, use the pixel value of the original image (normal cutting)
242 for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
244 vtk2itk(inputIt.GetIndex(), p);
245 inputGeometry->IndexToWorld(p, p);
246 if (cutter->m_BoundingObject->IsInside(p))
248 outputIt.Set(inputIt.Get());
249 ++cutter->m_InsidePixelCount;
253 outputIt.Set(outsideValue);
254 ++cutter->m_OutsidePixelCount;
260 template <typename TPixel, unsigned int VImageDimension>
261 void CutImage(itk::Image<TPixel, VImageDimension> *inputItkImage, mitk::BoundingObjectCutter *cutter, int boTimeStep)
263 TPixel *dummy = nullptr;
264 CutImageWithOutputTypeSelect<TPixel, VImageDimension, TPixel>(inputItkImage, cutter, boTimeStep, dummy);
267 template <typename TPixel, unsigned int VImageDimension>
268 void CutImage(itk::VectorImage<TPixel, VImageDimension> *inputItkImage,
269 mitk::BoundingObjectCutter *cutter,
272 TPixel *dummy = nullptr;
273 CutImageWithOutputTypeSelect<TPixel, VImageDimension, TPixel>(inputItkImage, cutter, boTimeStep, dummy);
276 } // of namespace mitk
278 #include "mitkImageCast.h"
280 #endif // of MITKBOUNDINGOBJECTCUTTER_TXX