Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkBooleanOperation.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 "mitkBooleanOperation.h"
14 #include <itkAndImageFilter.h>
15 #include <itkNotImageFilter.h>
16 #include <itkOrImageFilter.h>
17 #include <mitkExceptionMacro.h>
18 #include <mitkImageCast.h>
19 #include <mitkImageTimeSelector.h>
20 
21 typedef itk::Image<mitk::Label::PixelType, 3> ImageType;
22 
23 static mitk::Image::Pointer Get3DSegmentation(mitk::Image::Pointer segmentation, unsigned int time)
24 {
25  if (segmentation->GetDimension() != 4)
26  return segmentation;
27 
28  auto imageTimeSelector = mitk::ImageTimeSelector::New();
29  imageTimeSelector->SetInput(segmentation);
30  imageTimeSelector->SetTimeNr(static_cast<int>(time));
31 
32  imageTimeSelector->UpdateLargestPossibleRegion();
33 
34  return imageTimeSelector->GetOutput();
35 }
36 
37 static ImageType::Pointer CastTo3DItkImage(mitk::Image::Pointer segmentation, unsigned int time)
38 {
39  ImageType::Pointer result;
40  mitk::CastToItkImage(Get3DSegmentation(segmentation, time), result);
41  return result;
42 }
43 
45  mitk::Image::Pointer segmentationA,
46  mitk::Image::Pointer segmentationB,
47  unsigned int time)
48  : m_Type(type), m_SegmentationA(segmentationA), m_SegmentationB(segmentationB), m_Time(time)
49 {
50  this->ValidateSegmentations();
51 }
52 
54 {
55 }
56 
58 {
59  switch (m_Type)
60  {
61  case Difference:
62  return this->GetDifference();
63 
64  case Intersection:
65  return this->GetIntersection();
66 
67  case Union:
68  return this->GetUnion();
69 
70  default:
71  mitkThrow() << "Unknown boolean operation type '" << m_Type << "'!";
72  }
73 }
74 
75 mitk::LabelSetImage::Pointer mitk::BooleanOperation::GetDifference() const
76 {
77  auto input1 = CastTo3DItkImage(m_SegmentationA, m_Time);
78  auto input2 = CastTo3DItkImage(m_SegmentationB, m_Time);
79 
80  auto notFilter = itk::NotImageFilter<ImageType, ImageType>::New();
81  notFilter->SetInput(input2);
82 
83  auto andFilter = itk::AndImageFilter<ImageType, ImageType>::New();
84  andFilter->SetInput1(input1);
85  andFilter->SetInput2(notFilter->GetOutput());
86 
87  andFilter->UpdateLargestPossibleRegion();
88 
89  auto tempResult = Image::New();
90  CastToMitkImage<ImageType>(andFilter->GetOutput(), tempResult);
91 
92  tempResult->DisconnectPipeline();
93 
94  auto result = mitk::LabelSetImage::New();
95  result->InitializeByLabeledImage(tempResult);
96 
97  return result;
98 }
99 
100 mitk::LabelSetImage::Pointer mitk::BooleanOperation::GetIntersection() const
101 {
102  auto input1 = CastTo3DItkImage(m_SegmentationA, m_Time);
103  auto input2 = CastTo3DItkImage(m_SegmentationB, m_Time);
104 
105  auto andFilter = itk::AndImageFilter<ImageType, ImageType>::New();
106  andFilter->SetInput1(input1);
107  andFilter->SetInput2(input2);
108 
109  andFilter->UpdateLargestPossibleRegion();
110 
111  auto tempResult = Image::New();
112  CastToMitkImage<ImageType>(andFilter->GetOutput(), tempResult);
113 
114  tempResult->DisconnectPipeline();
115 
116  auto result = mitk::LabelSetImage::New();
117  result->InitializeByLabeledImage(tempResult);
118 
119  return result;
120 }
121 
122 mitk::LabelSetImage::Pointer mitk::BooleanOperation::GetUnion() const
123 {
124  auto input1 = CastTo3DItkImage(m_SegmentationA, m_Time);
125  auto input2 = CastTo3DItkImage(m_SegmentationB, m_Time);
126 
127  auto orFilter = itk::OrImageFilter<ImageType, ImageType>::New();
128  orFilter->SetInput1(input1);
129  orFilter->SetInput2(input2);
130 
131  orFilter->UpdateLargestPossibleRegion();
132 
133  auto tempResult = Image::New();
134  CastToMitkImage<ImageType>(orFilter->GetOutput(), tempResult);
135 
136  tempResult->DisconnectPipeline();
137 
138  auto result = mitk::LabelSetImage::New();
139  result->InitializeByLabeledImage(tempResult);
140 
141  return result;
142 }
143 
144 void mitk::BooleanOperation::ValidateSegmentation(mitk::Image::Pointer segmentation) const
145 {
146  if (segmentation.IsNull())
147  mitkThrow() << "Segmentation is nullptr!";
148 
149  if (segmentation->GetImageDescriptor()->GetNumberOfChannels() != 1)
150  mitkThrow() << "Segmentation has more than one channel!";
151 
152  auto pixelType = segmentation->GetImageDescriptor()->GetChannelDescriptor().GetPixelType();
153 
154  if (pixelType.GetPixelType() != itk::ImageIOBase::SCALAR ||
155  (pixelType.GetComponentType() != itk::ImageIOBase::UCHAR &&
156  pixelType.GetComponentType() != itk::ImageIOBase::USHORT))
157  mitkThrow() << "Segmentation is neither of type 'unsigned char' nor type 'unsigned short'!";
158 
159  auto dimension = segmentation->GetDimension();
160 
161  if (dimension > 4)
162  mitkThrow() << "Segmentation has more than four dimensions!";
163 
164  if (m_Time != 0)
165  {
166  if (dimension < 4)
167  mitkThrow() << "Expected four-dimensional segmentation!";
168 
169  if (segmentation->GetDimension(3) < m_Time)
170  mitkThrow() << "Extent of fourth dimension of segmentation is less than specified time!";
171  }
172  else if (dimension < 3)
173  {
174  mitkThrow() << "Segmentation has less than three dimensions!";
175  }
176 }
177 
178 void mitk::BooleanOperation::ValidateSegmentations() const
179 {
180  this->ValidateSegmentation(m_SegmentationA);
181  this->ValidateSegmentation(m_SegmentationB);
182 
183  if (m_SegmentationA->GetDimension() != m_SegmentationB->GetDimension())
184  mitkThrow() << "Segmentations have different dimensions!";
185 }
itk::Image< mitk::Label::PixelType, 3 > ImageType
LabelSetImage::Pointer GetResult() const
static mitk::Image::Pointer Get3DSegmentation(mitk::Image::Pointer segmentation, unsigned int time)
#define mitkThrow()
static Pointer New()
BooleanOperation(Type type, Image::Pointer segmentationA, Image::Pointer segmentationB, unsigned int time=0)
static Pointer New()
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
static ImageType::Pointer CastTo3DItkImage(mitk::Image::Pointer segmentation, unsigned int time)
static Pointer New()