Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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.