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