Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkGeometryClipImageFilter.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 
18 #include "mitkImageTimeSelector.h"
19 #include "mitkProperties.h"
20 #include "mitkTimeHelper.h"
21 
22 #include "mitkImageToItk.h"
23 
24 #include "itkImageRegionConstIterator.h"
25 #include "itkImageRegionIteratorWithIndex.h"
26 
27 #include <limits>
28 
30  : m_ClippingGeometry(nullptr),
31  m_ClipPartAboveGeometry(true),
32  m_OutsideValue(0),
33  m_AutoOutsideValue(false),
34  m_LabelBothSides(false),
35  m_AutoOrientLabels(false),
36  m_AboveGeometryLabel(1),
37  m_BelowGeometryLabel(2)
38 {
39  this->SetNumberOfIndexedInputs(2);
40  this->SetNumberOfRequiredInputs(2);
44 }
45 
47 {
48 }
49 
51 {
52  m_TimeClippingGeometry = timeClippingGeometry;
53  SetClippingGeometry(timeClippingGeometry->GetGeometryForTimeStep(0));
54 }
55 
57 {
58  if (aClippingGeometry != m_ClippingGeometry.GetPointer())
59  {
60  m_ClippingGeometry = aClippingGeometry;
61  m_ClippingGeometryData->SetGeometry(const_cast<mitk::BaseGeometry *>(aClippingGeometry));
62  SetNthInput(1, m_ClippingGeometryData);
63  Modified();
64  }
65 }
66 
68 {
69  return m_ClippingGeometry;
70 }
71 
73 {
74  return m_TimeClippingGeometry;
75 }
76 
78 {
79  Superclass::GenerateInputRequestedRegion();
80 
81  mitk::Image *output = this->GetOutput();
82  mitk::Image *input = const_cast<mitk::Image *>(this->GetInput());
83  if ((output->IsInitialized() == false) || (m_ClippingGeometry.IsNull()))
84  return;
85 
87 
88  GenerateTimeInInputRegion(output, input);
89 }
90 
92 {
93  mitk::Image::ConstPointer input = this->GetInput();
94  mitk::Image::Pointer output = this->GetOutput();
95 
96  if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
97  return;
98 
99  itkDebugMacro(<< "GenerateOutputInformation()");
100 
101  unsigned int i;
102  auto tmpDimensions = new unsigned int[input->GetDimension()];
103 
104  for (i = 0; i < input->GetDimension(); ++i)
105  tmpDimensions[i] = input->GetDimension(i);
106 
107  output->Initialize(input->GetPixelType(), input->GetDimension(), tmpDimensions, input->GetNumberOfChannels());
108 
109  delete[] tmpDimensions;
110 
111  output->SetGeometry(static_cast<mitk::BaseGeometry *>(input->GetGeometry()->Clone().GetPointer()));
112 
113  output->SetPropertyList(input->GetPropertyList()->Clone());
114 
115  m_TimeOfHeaderInitialization.Modified();
116 }
117 
118 template <typename TPixel, unsigned int VImageDimension>
119 void mitk::_InternalComputeClippedImage(itk::Image<TPixel, VImageDimension> *inputItkImage,
120  mitk::GeometryClipImageFilter *geometryClipper,
121  const mitk::PlaneGeometry *clippingPlaneGeometry)
122 {
123  typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
124  typedef itk::Image<TPixel, VImageDimension> ItkOutputImageType;
125 
126  typedef itk::ImageRegionConstIteratorWithIndex<ItkInputImageType> ItkInputImageIteratorType;
127  typedef itk::ImageRegionIteratorWithIndex<ItkOutputImageType> ItkOutputImageIteratorType;
128 
130  outputimagetoitk->SetInput(geometryClipper->m_OutputTimeSelector->GetOutput());
131  outputimagetoitk->Update();
132  typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
133 
134  // create the iterators
135  typename ItkInputImageType::RegionType inputRegionOfInterest = inputItkImage->GetLargestPossibleRegion();
136  ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
137  ItkOutputImageIteratorType outputIt(outputItkImage, inputRegionOfInterest);
138 
139  typename ItkOutputImageType::PixelType outsideValue;
140  if (geometryClipper->m_AutoOutsideValue)
142  else
143  outsideValue = (typename ItkOutputImageType::PixelType)geometryClipper->m_OutsideValue;
144 
145  mitk::BaseGeometry *inputGeometry = geometryClipper->m_InputTimeSelector->GetOutput()->GetGeometry();
146  typedef itk::Index<VImageDimension> IndexType;
147  Point3D indexPt;
148  indexPt.Fill(0);
149  int i, dim = IndexType::GetIndexDimension();
150  Point3D pointInMM;
151  bool above = geometryClipper->m_ClipPartAboveGeometry;
152  bool labelBothSides = geometryClipper->GetLabelBothSides();
153 
154  if (geometryClipper->GetAutoOrientLabels())
155  {
156  Point3D leftMostPoint;
157  leftMostPoint.Fill(std::numeric_limits<float>::min() / 2.0);
158  if (clippingPlaneGeometry->IsAbove(pointInMM) != above)
159  {
160  // invert meaning of above --> left is always the "above" side
161  above = !above;
162  MITK_INFO << leftMostPoint << " is BELOW geometry. Inverting meaning of above" << std::endl;
163  }
164  else
165  MITK_INFO << leftMostPoint << " is above geometry" << std::endl;
166  }
167 
168  typename ItkOutputImageType::PixelType aboveLabel =
169  (typename ItkOutputImageType::PixelType)geometryClipper->GetAboveGeometryLabel();
170  typename ItkOutputImageType::PixelType belowLabel =
171  (typename ItkOutputImageType::PixelType)geometryClipper->GetBelowGeometryLabel();
172 
173  for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
174  {
175  if ((typename ItkOutputImageType::PixelType)inputIt.Get() == outsideValue)
176  {
177  outputIt.Set(outsideValue);
178  }
179  else
180  {
181  for (i = 0; i < dim; ++i)
182  indexPt[i] = (mitk::ScalarType)inputIt.GetIndex()[i];
183  inputGeometry->IndexToWorld(indexPt, pointInMM);
184  if (clippingPlaneGeometry->IsAbove(pointInMM) == above)
185  {
186  if (labelBothSides)
187  outputIt.Set(aboveLabel);
188  else
189  outputIt.Set(outsideValue);
190  }
191  else
192  {
193  if (labelBothSides)
194  outputIt.Set(belowLabel);
195  else
196  outputIt.Set(inputIt.Get());
197  }
198  }
199  }
200 }
201 
202 #include "mitkImageAccessByItk.h"
203 
205 {
206  Image::ConstPointer input = this->GetInput();
207  Image::Pointer output = this->GetOutput();
208 
209  if ((output->IsInitialized() == false) || (m_ClippingGeometry.IsNull()))
210  return;
211 
212  const PlaneGeometry *clippingGeometryOfCurrentTimeStep = nullptr;
213 
214  if (m_TimeClippingGeometry.IsNull())
215  {
216  clippingGeometryOfCurrentTimeStep = dynamic_cast<const PlaneGeometry *>(m_ClippingGeometry.GetPointer());
217  }
218  else
219  {
220  clippingGeometryOfCurrentTimeStep =
221  dynamic_cast<const PlaneGeometry *>(m_TimeClippingGeometry->GetGeometryForTimeStep(0).GetPointer());
222  }
223 
224  if (clippingGeometryOfCurrentTimeStep == nullptr)
225  return;
226 
227  m_InputTimeSelector->SetInput(input);
228  m_OutputTimeSelector->SetInput(this->GetOutput());
229 
230  mitk::Image::RegionType outputRegion = output->GetRequestedRegion();
231  const mitk::TimeGeometry *outputTimeGeometry = output->GetTimeGeometry();
232  const mitk::TimeGeometry *inputTimeGeometry = input->GetTimeGeometry();
233  ScalarType timeInMS;
234 
235  int timestep = 0;
236  int tstart = outputRegion.GetIndex(3);
237  int tmax = tstart + outputRegion.GetSize(3);
238 
239  int t;
240  for (t = tstart; t < tmax; ++t)
241  {
242  timeInMS = outputTimeGeometry->TimeStepToTimePoint(t);
243  timestep = inputTimeGeometry->TimePointToTimeStep(timeInMS);
244 
245  m_InputTimeSelector->SetTimeNr(timestep);
246  m_InputTimeSelector->UpdateLargestPossibleRegion();
247  m_OutputTimeSelector->SetTimeNr(t);
248  m_OutputTimeSelector->UpdateLargestPossibleRegion();
249 
250  if (m_TimeClippingGeometry.IsNotNull())
251  {
252  timestep = m_TimeClippingGeometry->TimePointToTimeStep(timeInMS);
253  if (m_TimeClippingGeometry->IsValidTimeStep(timestep) == false)
254  continue;
255 
256  clippingGeometryOfCurrentTimeStep =
257  dynamic_cast<const PlaneGeometry *>(m_TimeClippingGeometry->GetGeometryForTimeStep(timestep).GetPointer());
258  }
259 
261  m_InputTimeSelector->GetOutput(), _InternalComputeClippedImage, this, clippingGeometryOfCurrentTimeStep);
262  }
263 
264  m_TimeOfHeaderInitialization.Modified();
265 }
virtual void SetRequestedRegionToLargestPossibleRegion() override
virtual void GenerateOutputInformation() override
itk::SmartPointer< Self > Pointer
mitk::ImageTimeSelector::Pointer m_InputTimeSelector
#define MITK_INFO
Definition: mitkLogMacros.h:22
double ScalarType
virtual ScalarType GetBelowGeometryLabel() const
const mitk::BaseGeometry * GetClippingGeometry() const
virtual void GenerateData() override
A version of GenerateData() specific for image processing filters.
mitk::ImageTimeSelector::Pointer m_OutputTimeSelector
void SetClippingGeometry(const mitk::BaseGeometry *aClippingGeometry)
virtual bool IsAbove(const Point3D &pt3d_mm, bool considerBoundingBox=false) const
Calculates, whether a point is below or above the plane. There are two different calculation methods...
mitk::GeometryData::Pointer m_ClippingGeometryData
const mitk::TimeGeometry * GetClippingTimeGeometry() const
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.
virtual bool GetLabelBothSides() const
virtual void GenerateInputRequestedRegion() override
static Pointer New()
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()
virtual ScalarType GetAboveGeometryLabel() const
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
unsigned short PixelType
virtual bool GetAutoOrientLabels() const
Describes a two-dimensional, rectangular plane.
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2)
BaseGeometry Describes the geometry of a data object.
Filter for clipping an image with a PlaneGeometry.
static Pointer New()