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