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
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.