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 "itkExpNegativeImageFilter.h"
20 #include "itkExpNegativeImageAdaptor.h"
21 #include "itkSubtractImageFilter.h"
22 
23 
itkExpNegativeImageFilterAndAdaptorTest(int,char * [])24 int itkExpNegativeImageFilterAndAdaptorTest(int, char* [] )
25 {
26 
27   // Define the dimension of the images
28   constexpr unsigned int ImageDimension = 3;
29 
30   // Declare the types of the images
31   using InputImageType = itk::Image<float, ImageDimension>;
32   using OutputImageType = itk::Image<float, ImageDimension>;
33 
34   // Declare Iterator types apropriated for each image
35   using InputIteratorType = itk::ImageRegionIteratorWithIndex<InputImageType>;
36   using OutputIteratorType = itk::ImageRegionIteratorWithIndex<OutputImageType>;
37 
38   // Declare the type of the index to access images
39   using IndexType = itk::Index<ImageDimension>;
40 
41   // Declare the type of the size
42   using SizeType = itk::Size<ImageDimension>;
43 
44   // Declare the type of the Region
45   using RegionType = itk::ImageRegion<ImageDimension>;
46 
47   // Create two images
48   InputImageType::Pointer inputImage  = InputImageType::New();
49 
50   // Define their size, and start index
51   SizeType size;
52   size[0] = 2;
53   size[1] = 2;
54   size[2] = 2;
55 
56   IndexType start;
57   start[0] = 0;
58   start[1] = 0;
59   start[2] = 0;
60 
61   RegionType region;
62   region.SetIndex( start );
63   region.SetSize( size );
64 
65   // Initialize Image A
66   inputImage->SetLargestPossibleRegion( region );
67   inputImage->SetBufferedRegion( region );
68   inputImage->SetRequestedRegion( region );
69   inputImage->Allocate();
70   // Create one iterator for the Input Image (this is a light object)
71   InputIteratorType it( inputImage, inputImage->GetBufferedRegion() );
72 
73   // Initialize the content of Image A
74   const double value = itk::Math::pi / 6.0;
75   std::cout << "Content of the Input " << std::endl;
76   it.GoToBegin();
77   while( !it.IsAtEnd() )
78     {
79     it.Set( value );
80     std::cout << it.Get() << std::endl;
81     ++it;
82     }
83 
84   // Declare the type for the ExpNegative filter
85   using FilterType = itk::ExpNegativeImageFilter< InputImageType,
86                                OutputImageType  >;
87 
88 
89   // Create an ADD Filter
90   FilterType::Pointer filter = FilterType::New();
91 
92 
93   // Connect the input images
94   filter->SetInput( inputImage );
95 
96   // Get the Smart Pointer to the Filter Output
97   OutputImageType::Pointer outputImage = filter->GetOutput();
98 
99 
100   // Execute the filter
101   filter->Update();
102   filter->SetFunctor(filter->GetFunctor());
103 
104   // Create an iterator for going through the image output
105   OutputIteratorType ot(outputImage, outputImage->GetRequestedRegion());
106 
107   //  Check the content of the result image
108   std::cout << "Verification of the output " << std::endl;
109   const OutputImageType::PixelType epsilon = 1e-6;
110   ot.GoToBegin();
111   it.GoToBegin();
112   while( !ot.IsAtEnd() )
113     {
114     std::cout <<  ot.Get() << " = ";
115     const InputImageType::PixelType  input  = it.Get();
116     const OutputImageType::PixelType output = ot.Get();
117     const OutputImageType::PixelType exponential  = std::exp( - input);
118     std::cout <<  exponential  << std::endl;
119     if( std::fabs( exponential - output ) > epsilon )
120       {
121       std::cerr << "Error in itkExpNegativeImageFilterTest " << std::endl;
122       std::cerr << " std::exp( - " << input << ") = " << exponential << std::endl;
123       std::cerr << " differs from " << output;
124       std::cerr << " by more than " << epsilon << std::endl;
125       return EXIT_FAILURE;
126       }
127     ++ot;
128     ++it;
129     }
130 
131 
132   //---------------------------------------
133   // This section tests for ExpNegativeImageAdaptor
134   //---------------------------------------
135 
136   using AdaptorType = itk::ExpNegativeImageAdaptor<InputImageType,
137                           OutputImageType::PixelType>;
138 
139   AdaptorType::Pointer expAdaptor = AdaptorType::New();
140 
141   expAdaptor->SetImage( inputImage );
142 
143   using DiffFilterType = itk::SubtractImageFilter<
144                         OutputImageType,
145                         AdaptorType,
146                         OutputImageType   >;
147 
148   DiffFilterType::Pointer diffFilter = DiffFilterType::New();
149 
150   diffFilter->SetInput1( outputImage );
151   diffFilter->SetInput2( expAdaptor  );
152 
153   diffFilter->Update();
154 
155   // Get the Smart Pointer to the Diff filter Output
156   OutputImageType::Pointer diffImage = diffFilter->GetOutput();
157 
158   //  Check the content of the diff image
159   std::cout << "Comparing the results with those of an Adaptor" << std::endl;
160   std::cout << "Verification of the output " << std::endl;
161 
162   // Create an iterator for going through the image output
163   OutputIteratorType dt(diffImage, diffImage->GetRequestedRegion());
164 
165   dt.GoToBegin();
166   while( !dt.IsAtEnd() )
167     {
168     std::cout <<  dt.Get() << std::endl;
169     const OutputImageType::PixelType diff = dt.Get();
170     if( std::fabs( diff ) > epsilon )
171       {
172       std::cerr << "Error in itkExpNegativeImageFilterTest " << std::endl;
173       std::cerr << "Comparing results with Adaptors" << std::endl;
174       std::cerr << " difference = " << diff << std::endl;
175       std::cerr << " differs from 0 ";
176       std::cerr << " by more than " << epsilon << std::endl;
177       return EXIT_FAILURE;
178       }
179     ++dt;
180     }
181 
182 
183   return EXIT_SUCCESS;
184 }
185