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