1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #include "itkWatershedImageFilter.h"
20 #include "itkWatershedEquivalenceRelabeler.h"
21 #include "itkWatershedBoundaryResolver.h"
22 #include "itkSimpleFilterWatcher.h"
23 #include "itkTestingMacros.h"
24 
25 
itkWatershedImageFilterTest(int,char * [])26 int itkWatershedImageFilterTest( int, char* [] )
27 {
28 
29   constexpr unsigned int Dimension = 2;
30 
31   using PixelType = float;
32   using ImageType2D = itk::Image< PixelType, Dimension >;
33   using LongImageType2D = itk::Image< itk::IdentifierType, Dimension >;
34 
35 
36   itk::ImageRegion< Dimension > region;
37 
38   itk::Size< Dimension > size;
39   size[0] = 314;
40   size[1] = 314;
41 
42   itk::Index< Dimension > origin;
43   origin[0] = 0;
44   origin[1] = 0;
45 
46   region.SetSize( size );
47   region.SetIndex( origin );
48 
49   ImageType2D::Pointer image2D = ImageType2D::New();
50   image2D->SetLargestPossibleRegion( region);
51   image2D->SetBufferedRegion( region );
52   image2D->SetRequestedRegion( region );
53   image2D->Allocate();
54 
55   LongImageType2D::Pointer longimage2D = LongImageType2D::New();
56   longimage2D->SetRegions( region );
57   longimage2D->Allocate( true ); // initialize buffer to zero
58 
59   itk::ImageRegionIterator< ImageType2D > it2D( image2D,
60     image2D->GetRequestedRegion() );
61 
62   for( float q = 0.00f; !it2D.IsAtEnd(); ++it2D )
63     {
64     it2D.Value() = std::sin( q );
65     q += 0.10f;
66     }
67 
68   // Test various objects associated to itk::WatershedImageFilter
69   //
70 
71   // Test EquivalenceRelabeler
72   itk::EquivalencyTable::Pointer table = itk::EquivalencyTable::New();
73 
74   itk::watershed::EquivalenceRelabeler<
75     LongImageType2D::PixelType, Dimension >::Pointer eq =
76     itk::watershed::EquivalenceRelabeler<
77     LongImageType2D::PixelType, Dimension >::New();
78   eq->SetInputImage( longimage2D );
79 
80   eq->SetEquivalencyTable( table );
81   TEST_SET_GET_VALUE( table, eq->GetEquivalencyTable() );
82 
83 
84   TRY_EXPECT_NO_EXCEPTION( eq->Update() );
85 
86   // Test WatershedMiniPipelineProgressCommand
87   // Forcing the execution of the const Execute method which is not normally called.
88   itk::WatershedMiniPipelineProgressCommand::Pointer wmppc =
89     itk::WatershedMiniPipelineProgressCommand::New();
90 
91   EXERCISE_BASIC_OBJECT_METHODS( wmppc, WatershedMiniPipelineProgressCommand,
92     Command );
93 
94   double count = 2.0;
95   wmppc->SetCount( count );
96   TEST_SET_GET_VALUE( count, wmppc->GetCount() );
97 
98   unsigned int numberOfFilters = 2;
99   wmppc->SetNumberOfFilters( numberOfFilters );
100   TEST_SET_GET_VALUE( numberOfFilters, wmppc->GetNumberOfFilters() );
101 
102   wmppc->SetFilter( eq );
103   TEST_SET_GET_VALUE( eq, wmppc->GetFilter() );
104 
105   const itk::ProcessObject *constp = eq.GetPointer();
106   wmppc->Execute( constp, itk::ProgressEvent() );
107   wmppc->Execute( eq, itk::ProgressEvent() );
108 
109   // Test watershed::BoundaryResolver
110   itk::watershed::BoundaryResolver< PixelType, Dimension >::Pointer br =
111     itk::watershed::BoundaryResolver< PixelType, Dimension >::New();
112   if( br.IsNull() )
113     {
114     std::cerr << "Test failed!" << std::endl;
115     std::cout << "Null itk::watershed::BoundaryResolver." << std::endl;
116     return EXIT_FAILURE;
117     }
118   itk::watershed::Boundary< PixelType, 1 >::Pointer boundaryA =
119     itk::watershed::Boundary< PixelType, 1 >::New();
120   if( boundaryA.IsNull() )
121     {
122     std::cerr << "Test failed!" << std::endl;
123     std::cout << "Null itk::watershed::Boundary." << std::endl;
124     return EXIT_FAILURE;
125     }
126   itk::watershed::Boundary< PixelType, 1 >::Pointer boundaryB =
127     itk::watershed::Boundary< PixelType, 1 >::New();
128   if( boundaryB.IsNull() )
129     {
130     std::cerr << "Test failed!" << std::endl;
131     std::cout << "Null itk::watershed::Boundary." << std::endl;
132     return EXIT_FAILURE;
133     }
134 
135 
136   itk::WatershedImageFilter< ImageType2D >::Pointer watershedFilter =
137     itk::WatershedImageFilter< ImageType2D >::New();
138 
139   EXERCISE_BASIC_OBJECT_METHODS( watershedFilter, WatershedImageFilter,
140     ImageToImageFilter );
141 
142   itk::SimpleFilterWatcher watchIt( watershedFilter, "WatershedImageFilter" );
143 
144   double threshold = .05;
145   watershedFilter->SetThreshold( threshold );
146   TEST_SET_GET_VALUE( threshold, watershedFilter->GetThreshold() );
147 
148   double level = 1.0;
149   watershedFilter->SetLevel( level );
150   TEST_SET_GET_VALUE( level, watershedFilter->GetLevel() );
151 
152   watershedFilter->SetInput( image2D );
153 
154   TRY_EXPECT_NO_EXCEPTION( watershedFilter->Update() );
155 
156 
157   std::cout << "Test finished." << std::endl;
158   return EXIT_SUCCESS;
159 }
160