Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
mitkExtractImageFilter.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkExtractImageFilter.h"
14 #include "mitkITKImageImport.h"
15 #include "mitkImageCast.h"
16 #include "mitkImageTimeSelector.h"
17 #include "mitkPlaneGeometry.h"
18 
19 #include <itkExtractImageFilter.h>
20 
21 #include <mitkImageAccessByItk.h>
22 
24  : m_SliceIndex(0), m_SliceDimension(0), m_TimeStep(0), m_DirectionCollapseToStrategy(DIRECTIONCOLLAPSETOGUESS)
25 {
26  MITK_WARN << "Class ExtractImageFilter is deprecated! Use ExtractSliceFilter instead.";
27 }
28 
30 {
31 }
32 
34 {
36 
37  if ((input->GetDimension() > 4) || (input->GetDimension() < 2))
38  {
39  MITK_ERROR << "mitk::ExtractImageFilter:GenerateData works only with 3D and 3D+t images, sorry." << std::endl;
40  itkExceptionMacro("mitk::ExtractImageFilter works only with 3D and 3D+t images, sorry.");
41  return;
42  }
43  else if (input->GetDimension() == 4)
44  {
46  timeSelector->SetInput(input);
47  timeSelector->SetTimeNr(m_TimeStep);
48  timeSelector->UpdateLargestPossibleRegion();
49  input = timeSelector->GetOutput();
50  }
51  else if (input->GetDimension() == 2)
52  {
54  resultImage = const_cast<Image *>(input.GetPointer());
55  ImageToImageFilter::SetNthOutput(0, resultImage);
56  return;
57  }
58 
59  if (m_SliceDimension >= input->GetDimension())
60  {
61  MITK_ERROR << "mitk::ExtractImageFilter:GenerateData m_SliceDimension == " << m_SliceDimension
62  << " makes no sense with an " << input->GetDimension() << "D image." << std::endl;
63  itkExceptionMacro("This is not a sensible value for m_SliceDimension.");
64  return;
65  }
66 
68 
69  // set a nice geometry for display and point transformations
70  BaseGeometry *inputImageGeometry = ImageToImageFilter::GetInput(0)->GetGeometry();
71  if (!inputImageGeometry)
72  {
73  MITK_ERROR << "In ExtractImageFilter::ItkImageProcessing: Input image has no geometry!" << std::endl;
74  return;
75  }
76 
78 
79  switch (m_SliceDimension)
80  {
81  default:
82  case 2:
83  orientation = PlaneGeometry::Axial;
84  break;
85  case 1:
86  orientation = PlaneGeometry::Frontal;
87  break;
88  case 0:
89  orientation = PlaneGeometry::Sagittal;
90  break;
91  }
92 
94  planeGeometry->InitializeStandardPlane(inputImageGeometry, orientation, (ScalarType)m_SliceIndex, true, false);
96  planeGeometry->ChangeImageGeometryConsideringOriginOffset(true);
97  resultImage->SetGeometry(planeGeometry);
98 }
99 
100 template <typename TPixel, unsigned int VImageDimension>
101 void mitk::ExtractImageFilter::ItkImageProcessing(const itk::Image<TPixel, VImageDimension> *itkImage)
102 {
103  // use the itk::ExtractImageFilter to get a 2D image
104  typedef itk::Image<TPixel, VImageDimension> ImageType3D;
105  typedef itk::Image<TPixel, VImageDimension - 1> ImageType2D;
106 
107  typedef itk::ExtractImageFilter<ImageType3D, ImageType2D> ExtractImageFilterType;
108  typename ImageType3D::RegionType inSliceRegion = itkImage->GetLargestPossibleRegion();
109 
110  inSliceRegion.SetSize(m_SliceDimension, 0);
111 
112  typename ExtractImageFilterType::Pointer sliceExtractor = ExtractImageFilterType::New();
113 
114  typename ExtractImageFilterType::DIRECTIONCOLLAPSESTRATEGY collapseStrategy;
116  {
118  collapseStrategy = ExtractImageFilterType::DIRECTIONCOLLAPSETOUNKOWN;
119  break;
121  collapseStrategy = ExtractImageFilterType::DIRECTIONCOLLAPSETOIDENTITY;
122  break;
124  collapseStrategy = ExtractImageFilterType::DIRECTIONCOLLAPSETOSUBMATRIX;
125  break;
127  default:
128  collapseStrategy = ExtractImageFilterType::DIRECTIONCOLLAPSETOGUESS;
129  break;
130  }
131 
132  sliceExtractor->SetDirectionCollapseToStrategy(collapseStrategy);
133  sliceExtractor->SetInput(itkImage);
134 
135  inSliceRegion.SetIndex(m_SliceDimension, m_SliceIndex);
136 
137  sliceExtractor->SetExtractionRegion(inSliceRegion);
138 
139  // calculate the output
140  sliceExtractor->UpdateLargestPossibleRegion();
141 
142  typename ImageType2D::Pointer slice = sliceExtractor->GetOutput();
143 
144  // re-import to MITK
146  GrabItkImageMemory(slice, resultImage, nullptr, false);
147 }
148 
149 /*
150  * What is the input requested region that is required to produce the output
151  * requested region? By default, the largest possible region is always
152  * required but this is overridden in many subclasses. For instance, for an
153  * image processing filter where an output pixel is a simple function of an
154  * input pixel, the input requested region will be set to the output
155  * requested region. For an image processing filter where an output pixel is
156  * a function of the pixels in a neighborhood of an input pixel, then the
157  * input requested region will need to be larger than the output requested
158  * region (to avoid introducing artificial boundary conditions). This
159  * function should never request an input region that is outside the the
160  * input largest possible region (i.e. implementations of this method should
161  * crop the input requested region at the boundaries of the input largest
162  * possible region).
163  */
165 {
166  Superclass::GenerateInputRequestedRegion();
167 
169  Image::Pointer output = this->GetOutput();
170 
171  if (input->GetDimension() == 2)
172  {
173  input->SetRequestedRegionToLargestPossibleRegion();
174  return;
175  }
176 
177  Image::RegionType requestedRegion;
178  requestedRegion = output->GetRequestedRegion();
179  requestedRegion.SetIndex(0, 0);
180  requestedRegion.SetIndex(1, 0);
181  requestedRegion.SetIndex(2, 0);
182  requestedRegion.SetSize(0, input->GetDimension(0));
183  requestedRegion.SetSize(1, input->GetDimension(1));
184  requestedRegion.SetSize(2, input->GetDimension(2));
185 
186  requestedRegion.SetIndex(m_SliceDimension, m_SliceIndex); // only one slice needed
187  requestedRegion.SetSize(m_SliceDimension, 1);
188 
189  input->SetRequestedRegion(&requestedRegion);
190 }
191 
192 /*
193  * Generate the information decribing the output data. The default
194  * implementation of this method will copy information from the input to the
195  * output. A filter may override this method if its output will have different
196  * information than its input. For instance, a filter that shrinks an image will
197  * need to provide an implementation for this method that changes the spacing of
198  * the pixels. Such filters should call their superclass' implementation of this
199  * method prior to changing the information values they need (i.e.
200  * GenerateOutputInformation() should call
201  * Superclass::GenerateOutputInformation() prior to changing the information.
202  */
204 {
205  Image::Pointer output = this->GetOutput();
206  Image::ConstPointer input = this->GetInput();
207  if (input.IsNull())
208  return;
209 
210  if (m_SliceDimension >= input->GetDimension() && input->GetDimension() != 2)
211  {
212  MITK_ERROR << "mitk::ExtractImageFilter:GenerateOutputInformation m_SliceDimension == " << m_SliceDimension
213  << " makes no sense with an " << input->GetDimension() << "D image." << std::endl;
214  itkExceptionMacro("This is not a sensible value for m_SliceDimension.");
215  return;
216  }
217 
218  unsigned int sliceDimension(m_SliceDimension);
219  if (input->GetDimension() == 2)
220  {
221  sliceDimension = 2;
222  }
223 
224  unsigned int tmpDimensions[2];
225 
226  switch (sliceDimension)
227  {
228  default:
229  case 2:
230  // orientation = PlaneGeometry::Axial;
231  tmpDimensions[0] = input->GetDimension(0);
232  tmpDimensions[1] = input->GetDimension(1);
233  break;
234  case 1:
235  // orientation = PlaneGeometry::Frontal;
236  tmpDimensions[0] = input->GetDimension(0);
237  tmpDimensions[1] = input->GetDimension(2);
238  break;
239  case 0:
240  // orientation = PlaneGeometry::Sagittal;
241  tmpDimensions[0] = input->GetDimension(1);
242  tmpDimensions[1] = input->GetDimension(2);
243  break;
244  }
245 
246  output->Initialize(input->GetPixelType(), 2, tmpDimensions, 1 /*input->GetNumberOfChannels()*/);
247 
248  // initialize the spacing of the output
249  /*
250  Vector3D spacing = input->GetSlicedGeometry()->GetSpacing();
251  if(input->GetDimension()>=2)
252  spacing[2]=spacing[1];
253  else
254  spacing[2] = 1.0;
255  output->GetSlicedGeometry()->SetSpacing(spacing);
256  */
257 
258  output->SetPropertyList(input->GetPropertyList()->Clone());
259 }
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
#define MITK_ERROR
Definition: mitkLogMacros.h:20
double ScalarType
DIRECTIONCOLLAPSESTRATEGY m_DirectionCollapseToStrategy
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
class ITK_EXPORT Image
#define MITK_WARN
Definition: mitkLogMacros.h:19
itk::ImageRegion< RegionDimension > RegionType
Image class for storing images.
Definition: mitkImage.h:72
void GenerateInputRequestedRegion() override
void ItkImageProcessing(const itk::Image< TPixel, VImageDimension > *image)
InputImageType * GetInput(void)
static Pointer New()
OutputType * GetOutput()
Get the output data of this image source object.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:138
BaseGeometry Describes the geometry of a data object.
static Pointer New()