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
mitkMorphologicalOperations.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 <itkBinaryBallStructuringElement.h>
19 #include <itkBinaryCrossStructuringElement.h>
20 #include <itkBinaryDilateImageFilter.h>
21 #include <itkBinaryErodeImageFilter.h>
22 #include <itkBinaryFillholeImageFilter.h>
23 #include <itkBinaryMorphologicalClosingImageFilter.h>
24 #include <itkBinaryMorphologicalOpeningImageFilter.h>
25 #include <mitkImageAccessByItk.h>
26 #include <mitkImageCast.h>
27 #include <mitkImageReadAccessor.h>
28 #include <mitkImageTimeSelector.h>
29 
31  int factor,
33 {
34  MITK_INFO << "Start Closing...";
35 
36  int timeSteps = static_cast<int>(image->GetTimeSteps());
37 
38  if (timeSteps > 1)
39  {
41  timeSelector->SetInput(image);
42 
43  for (int t = 0; t < timeSteps; ++t)
44  {
45  MITK_INFO << " Processing time step " << t;
46 
47  timeSelector->SetTimeNr(t);
48  timeSelector->Update();
49 
50  mitk::Image::Pointer img3D = timeSelector->GetOutput();
51  img3D->DisconnectPipeline();
52 
53  AccessByItk_3(img3D, itkClosing, img3D, factor, structuralElement);
54 
55  mitk::ImageReadAccessor accessor(img3D);
56  image->SetVolume(accessor.GetData(), t);
57  }
58  }
59  else
60  {
61  AccessByItk_3(image, itkClosing, image, factor, structuralElement);
62  }
63 
64  MITK_INFO << "Finished Closing";
65 }
66 
68  int factor,
70 {
71  MITK_INFO << "Start Erode...";
72 
73  int timeSteps = static_cast<int>(image->GetTimeSteps());
74 
75  if (timeSteps > 1)
76  {
78  timeSelector->SetInput(image);
79 
80  for (int t = 0; t < timeSteps; ++t)
81  {
82  MITK_INFO << " Processing time step " << t;
83 
84  timeSelector->SetTimeNr(t);
85  timeSelector->Update();
86 
87  mitk::Image::Pointer img3D = timeSelector->GetOutput();
88  img3D->DisconnectPipeline();
89 
90  AccessByItk_3(img3D, itkErode, img3D, factor, structuralElement);
91 
92  mitk::ImageReadAccessor accessor(img3D);
93  image->SetVolume(accessor.GetData(), t);
94  }
95  }
96  else
97  {
98  AccessByItk_3(image, itkErode, image, factor, structuralElement);
99  }
100 
101  MITK_INFO << "Finished Erode";
102 }
103 
105  int factor,
107 {
108  MITK_INFO << "Start Dilate...";
109 
110  int timeSteps = static_cast<int>(image->GetTimeSteps());
111 
112  if (timeSteps > 1)
113  {
115  timeSelector->SetInput(image);
116 
117  for (int t = 0; t < timeSteps; ++t)
118  {
119  MITK_INFO << " Processing time step " << t;
120 
121  timeSelector->SetTimeNr(t);
122  timeSelector->Update();
123 
124  mitk::Image::Pointer img3D = timeSelector->GetOutput();
125  img3D->DisconnectPipeline();
126 
127  AccessByItk_3(img3D, itkDilate, img3D, factor, structuralElement);
128 
129  mitk::ImageReadAccessor accessor(img3D);
130  image->SetVolume(accessor.GetData(), t);
131  }
132  }
133  else
134  {
135  AccessByItk_3(image, itkDilate, image, factor, structuralElement);
136  }
137 
138  MITK_INFO << "Finished Dilate";
139 }
140 
142  int factor,
144 {
145  MITK_INFO << "Start Opening...";
146 
147  int timeSteps = static_cast<int>(image->GetTimeSteps());
148 
149  if (timeSteps > 1)
150  {
152  timeSelector->SetInput(image);
153 
154  for (int t = 0; t < timeSteps; ++t)
155  {
156  MITK_INFO << " Processing time step " << t;
157 
158  timeSelector->SetTimeNr(t);
159  timeSelector->Update();
160 
161  mitk::Image::Pointer img3D = timeSelector->GetOutput();
162  img3D->DisconnectPipeline();
163 
164  AccessByItk_3(img3D, itkOpening, img3D, factor, structuralElement);
165 
166  mitk::ImageReadAccessor accessor(img3D);
167  image->SetVolume(accessor.GetData(), t);
168  }
169  }
170  else
171  {
172  AccessByItk_3(image, itkOpening, image, factor, structuralElement);
173  }
174 
175  MITK_INFO << "Finished Opening";
176 }
177 
179 {
180  MITK_INFO << "Start FillHole...";
181 
182  int timeSteps = static_cast<int>(image->GetTimeSteps());
183 
184  if (timeSteps > 1)
185  {
187  timeSelector->SetInput(image);
188 
189  for (int t = 0; t < timeSteps; ++t)
190  {
191  MITK_INFO << " Processing time step " << t;
192 
193  timeSelector->SetTimeNr(t);
194  timeSelector->Update();
195 
196  mitk::Image::Pointer img3D = timeSelector->GetOutput();
197  img3D->DisconnectPipeline();
198 
199  AccessByItk_1(img3D, itkFillHoles, img3D);
200 
201  mitk::ImageReadAccessor accessor(img3D);
202  image->SetVolume(accessor.GetData(), t);
203  }
204  }
205  else
206  {
207  AccessByItk_1(image, itkFillHoles, image);
208  }
209 
210  MITK_INFO << "Finished FillHole";
211 }
212 
213 template <typename TPixel, unsigned int VDimension>
214 void mitk::MorphologicalOperations::itkClosing(
215  itk::Image<TPixel, VDimension> *sourceImage,
216  mitk::Image::Pointer &resultImage,
217  int factor,
219 {
220  typedef itk::Image<TPixel, VDimension> ImageType;
221  typedef itk::BinaryBallStructuringElement<TPixel, VDimension> BallType;
222  typedef itk::BinaryCrossStructuringElement<TPixel, VDimension> CrossType;
223  typedef typename itk::BinaryMorphologicalClosingImageFilter<ImageType, ImageType, BallType> BallClosingFilterType;
224  typedef typename itk::BinaryMorphologicalClosingImageFilter<ImageType, ImageType, CrossType> CrossClosingFilterType;
225 
226  if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital))
227  {
228  BallType ball = CreateStructuringElement<BallType>(structuralElementFlags, factor);
229 
231  closingFilter->SetKernel(ball);
232  closingFilter->SetInput(sourceImage);
233  closingFilter->SetForegroundValue(1);
234  closingFilter->UpdateLargestPossibleRegion();
235 
236  mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage);
237  }
238  else
239  {
240  CrossType cross = CreateStructuringElement<CrossType>(structuralElementFlags, factor);
241 
243  closingFilter->SetKernel(cross);
244  closingFilter->SetInput(sourceImage);
245  closingFilter->SetForegroundValue(1);
246  closingFilter->UpdateLargestPossibleRegion();
247 
248  mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage);
249  }
250 }
251 
252 template <typename TPixel, unsigned int VDimension>
253 void mitk::MorphologicalOperations::itkErode(
254  itk::Image<TPixel, VDimension> *sourceImage,
255  mitk::Image::Pointer &resultImage,
256  int factor,
258 {
259  typedef itk::Image<TPixel, VDimension> ImageType;
260  typedef itk::BinaryBallStructuringElement<TPixel, VDimension> BallType;
261  typedef itk::BinaryCrossStructuringElement<TPixel, VDimension> CrossType;
262  typedef typename itk::BinaryErodeImageFilter<ImageType, ImageType, BallType> BallErodeFilterType;
263  typedef typename itk::BinaryErodeImageFilter<ImageType, ImageType, CrossType> CrossErodeFilterType;
264 
265  if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital))
266  {
267  BallType ball = CreateStructuringElement<BallType>(structuralElementFlags, factor);
268 
270  erodeFilter->SetKernel(ball);
271  erodeFilter->SetInput(sourceImage);
272  erodeFilter->SetErodeValue(1);
273  erodeFilter->UpdateLargestPossibleRegion();
274 
275  mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage);
276  }
277  else
278  {
279  CrossType cross = CreateStructuringElement<CrossType>(structuralElementFlags, factor);
280 
282  erodeFilter->SetKernel(cross);
283  erodeFilter->SetInput(sourceImage);
284  erodeFilter->SetErodeValue(1);
285  erodeFilter->UpdateLargestPossibleRegion();
286 
287  mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage);
288  }
289 }
290 
291 template <typename TPixel, unsigned int VDimension>
292 void mitk::MorphologicalOperations::itkDilate(
293  itk::Image<TPixel, VDimension> *sourceImage,
294  mitk::Image::Pointer &resultImage,
295  int factor,
297 {
298  typedef itk::Image<TPixel, VDimension> ImageType;
299  typedef itk::BinaryBallStructuringElement<TPixel, VDimension> BallType;
300  typedef itk::BinaryCrossStructuringElement<TPixel, VDimension> CrossType;
301  typedef typename itk::BinaryDilateImageFilter<ImageType, ImageType, BallType> BallDilateFilterType;
302  typedef typename itk::BinaryDilateImageFilter<ImageType, ImageType, CrossType> CrossDilateFilterType;
303 
304  if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital))
305  {
306  BallType ball = CreateStructuringElement<BallType>(structuralElementFlags, factor);
307 
309  dilateFilter->SetKernel(ball);
310  dilateFilter->SetInput(sourceImage);
311  dilateFilter->SetDilateValue(1);
312  dilateFilter->UpdateLargestPossibleRegion();
313 
314  mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage);
315  }
316  else
317  {
318  CrossType cross = CreateStructuringElement<CrossType>(structuralElementFlags, factor);
319 
321  dilateFilter->SetKernel(cross);
322  dilateFilter->SetInput(sourceImage);
323  dilateFilter->SetDilateValue(1);
324  dilateFilter->UpdateLargestPossibleRegion();
325 
326  mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage);
327  }
328 }
329 
330 template <typename TPixel, unsigned int VDimension>
331 void mitk::MorphologicalOperations::itkOpening(
332  itk::Image<TPixel, VDimension> *sourceImage,
333  mitk::Image::Pointer &resultImage,
334  int factor,
336 {
337  typedef itk::Image<TPixel, VDimension> ImageType;
338  typedef itk::BinaryBallStructuringElement<TPixel, VDimension> BallType;
339  typedef itk::BinaryCrossStructuringElement<TPixel, VDimension> CrossType;
340  typedef typename itk::BinaryMorphologicalOpeningImageFilter<ImageType, ImageType, BallType> BallOpeningFiltertype;
341  typedef typename itk::BinaryMorphologicalOpeningImageFilter<ImageType, ImageType, CrossType> CrossOpeningFiltertype;
342 
343  if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital))
344  {
345  BallType ball = CreateStructuringElement<BallType>(structuralElementFlags, factor);
346 
348  openingFilter->SetKernel(ball);
349  openingFilter->SetInput(sourceImage);
350  openingFilter->SetForegroundValue(1);
351  openingFilter->SetBackgroundValue(0);
352  openingFilter->UpdateLargestPossibleRegion();
353 
354  mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage);
355  }
356  else
357  {
358  CrossType cross = CreateStructuringElement<CrossType>(structuralElementFlags, factor);
359 
361  openingFilter->SetKernel(cross);
362  openingFilter->SetInput(sourceImage);
363  openingFilter->SetForegroundValue(1);
364  openingFilter->SetBackgroundValue(0);
365  openingFilter->UpdateLargestPossibleRegion();
366 
367  mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage);
368  }
369 }
370 
371 template <typename TPixel, unsigned int VDimension>
372 void mitk::MorphologicalOperations::itkFillHoles(itk::Image<TPixel, VDimension> *sourceImage,
373  mitk::Image::Pointer &resultImage)
374 {
375  typedef itk::Image<TPixel, VDimension> ImageType;
376  typedef typename itk::BinaryFillholeImageFilter<ImageType> FillHoleFilterType;
377 
378  typename FillHoleFilterType::Pointer fillHoleFilter = FillHoleFilterType::New();
379  fillHoleFilter->SetInput(sourceImage);
380  fillHoleFilter->SetForegroundValue(1);
381  fillHoleFilter->UpdateLargestPossibleRegion();
382 
383  mitk::CastToMitkImage(fillHoleFilter->GetOutput(), resultImage);
384 }
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3)
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
const void * GetData() const
Gives const access to the data.
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
static void Closing(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
map::core::discrete::Elements< 3 >::InternalImageType ImageType
static void Opening(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:78
ImageReadAccessor class to get locked read access for a particular image part.
static void Dilate(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
static Pointer New()
static void FillHoles(mitk::Image::Pointer &image)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
static void Erode(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement)
Perform morphological operation on 2D, 3D or 3D+t segmentation.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.