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
mitkShapeBasedInterpolationAlgorithm.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 "mitkImageAccessByItk.h"
19 #include "mitkImageCast.h"
20 #include <mitkITKImageImport.h>
21 
22 #include <itkFastChamferDistanceImageFilter.h>
23 #include <itkInvertIntensityImageFilter.h>
24 #include <itkIsoContourDistanceImageFilter.h>
25 #include <itkSubtractImageFilter.h>
26 
28  Image::ConstPointer lowerSlice,
29  unsigned int lowerSliceIndex,
30  Image::ConstPointer upperSlice,
31  unsigned int upperSliceIndex,
32  unsigned int requestedIndex,
33  unsigned int /*sliceDimension*/, // commented variables are not used
34  Image::Pointer resultImage,
35  unsigned int /*timeStep*/,
36  Image::ConstPointer /*referenceImage*/)
37 {
38  mitk::Image::Pointer lowerDistanceImage = mitk::Image::New();
39  AccessFixedDimensionByItk_1(lowerSlice, ComputeDistanceMap, 2, lowerDistanceImage);
40 
41  mitk::Image::Pointer upperDistanceImage = mitk::Image::New();
42  AccessFixedDimensionByItk_1(upperSlice, ComputeDistanceMap, 2, upperDistanceImage);
43 
44  // calculate where the current slice is in comparison to the lower and upper neighboring slices
45  float ratio = (float)(requestedIndex - lowerSliceIndex) / (float)(upperSliceIndex - lowerSliceIndex);
47  resultImage, InterpolateIntermediateSlice, 2, upperDistanceImage, lowerDistanceImage, ratio);
48 
49  return resultImage;
50 }
51 
52 template <typename TPixel, unsigned int VImageDimension>
53 void mitk::ShapeBasedInterpolationAlgorithm::ComputeDistanceMap(const itk::Image<TPixel, VImageDimension> *binaryImage,
54  mitk::Image::Pointer &result)
55 {
56  typedef itk::Image<TPixel, VImageDimension> DistanceFilterInputImageType;
57 
58  typedef itk::FastChamferDistanceImageFilter<DistanceFilterImageType, DistanceFilterImageType> DistanceFilterType;
59  typedef itk::IsoContourDistanceImageFilter<DistanceFilterInputImageType, DistanceFilterImageType> IsoContourType;
60  typedef itk::InvertIntensityImageFilter<DistanceFilterInputImageType> InvertIntensityImageFilterType;
61  typedef itk::SubtractImageFilter<DistanceFilterImageType, DistanceFilterImageType> SubtractImageFilterType;
62 
63  typename DistanceFilterType::Pointer distanceFilter = DistanceFilterType::New();
64  typename DistanceFilterType::Pointer distanceFilterInverted = DistanceFilterType::New();
65  typename IsoContourType::Pointer isoContourFilter = IsoContourType::New();
66  typename IsoContourType::Pointer isoContourFilterInverted = IsoContourType::New();
68  typename SubtractImageFilterType::Pointer subtractImageFilter = SubtractImageFilterType::New();
69 
70  // arbitrary maximum distance
71  int maximumDistance = 100;
72 
73  // this assumes the image contains only 1 and 0
74  invertFilter->SetInput(binaryImage);
75  invertFilter->SetMaximum(1);
76 
77  // do the processing on the image and the inverted image to get inside and outside distance
78  isoContourFilter->SetInput(binaryImage);
79  isoContourFilter->SetFarValue(maximumDistance + 1);
80  isoContourFilter->SetLevelSetValue(0.5);
81 
82  isoContourFilterInverted->SetInput(invertFilter->GetOutput());
83  isoContourFilterInverted->SetFarValue(maximumDistance + 1);
84  isoContourFilterInverted->SetLevelSetValue(0.5);
85 
86  distanceFilter->SetInput(isoContourFilter->GetOutput());
87  distanceFilter->SetMaximumDistance(maximumDistance);
88 
89  distanceFilterInverted->SetInput(isoContourFilterInverted->GetOutput());
90  distanceFilterInverted->SetMaximumDistance(maximumDistance);
91 
92  // inside distance should be negative, outside distance positive
93  subtractImageFilter->SetInput2(distanceFilter->GetOutput());
94  subtractImageFilter->SetInput1(distanceFilterInverted->GetOutput());
95  subtractImageFilter->Update();
96 
97  result = mitk::GrabItkImageMemory(subtractImageFilter->GetOutput());
98 }
99 
100 template <typename TPixel, unsigned int VImageDimension>
101 void mitk::ShapeBasedInterpolationAlgorithm::InterpolateIntermediateSlice(itk::Image<TPixel, VImageDimension> *result,
102  const mitk::Image::Pointer &lower,
103  const mitk::Image::Pointer &upper,
104  float ratio)
105 {
106  typedef itk::Image<TPixel, VImageDimension> ResultImageType;
107 
110 
111  CastToItkImage(lower, lowerITK);
112  CastToItkImage(upper, upperITK);
113 
114  itk::ImageRegionConstIteratorWithIndex<DistanceFilterImageType> lowerIter(lowerITK,
115  lowerITK->GetLargestPossibleRegion());
116 
117  lowerIter.GoToBegin();
118 
119  if (!lowerITK->GetLargestPossibleRegion().IsInside(upperITK->GetLargestPossibleRegion()) ||
120  !lowerITK->GetLargestPossibleRegion().IsInside(result->GetLargestPossibleRegion()))
121  {
122  // TODO Exception etc.
123  MITK_ERROR << "The regions of the slices for the 2D interpolation are not equally sized!";
124  return;
125  }
126 
127  float weight[2] = {1.0f - ratio, ratio};
128 
129  while (!lowerIter.IsAtEnd())
130  {
131  typename DistanceFilterImageType::PixelType lowerPixelVal = lowerIter.Get();
132  typename DistanceFilterImageType::PixelType upperPixelVal = upperITK->GetPixel(lowerIter.GetIndex());
133 
134  typename DistanceFilterImageType::PixelType intermediatePixelVal =
135  (weight[0] * upperPixelVal + weight[1] * lowerPixelVal > 0 ? 0 : 1);
136 
137  result->SetPixel(lowerIter.GetIndex(), static_cast<TPixel>(intermediatePixelVal));
138 
139  ++lowerIter;
140  }
141 }
itk::SmartPointer< Self > Pointer
#define MITK_ERROR
Definition: mitkLogMacros.h:24
#define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3)
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.
Image::Pointer Interpolate(Image::ConstPointer lowerSlice, unsigned int lowerSliceIndex, Image::ConstPointer upperSlice, unsigned int upperSliceIndex, unsigned int requestedIndex, unsigned int sliceDimension, Image::Pointer resultImage, unsigned int timeStep, Image::ConstPointer referenceImage) override
static Pointer New()
#define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1)
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
unsigned short PixelType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.