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