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 <iostream>
20 #include "itkStreamingImageFilter.h"
21 #include "itkWrapPadImageFilter.h"
22 #include "itkVectorImage.h"
23 #include "itkMath.h"
24 
25 //
26 // Check that val represents the correct pixel value.  This routine
27 // allows the pad region to extend to twice the size of the input.
28 //
VerifyPixel(int row,int col,short val,float & expected)29 int VerifyPixel(int row, int col, short val, float & expected)
30 {
31   if (row < 0) row += 8;
32   if (row < 0) row += 8;
33   if (row > 7) row -= 8;
34   if (row > 7) row -= 8;
35   if (col < 0) col += 12;
36   if (col < 0) col += 12;
37   if (col > 11) col -= 12;
38   if (col > 11) col -= 12;
39   expected = 8*col+row;
40   return ( itk::Math::AlmostEquals( val, expected) );
41 }
42 
43 
itkWrapPadImageTest(int,char * [])44 int itkWrapPadImageTest(int, char* [] )
45 {
46   // type alias to simplify the syntax
47   using ShortImage = itk::Image< short, 2 >;
48   using FloatImage = itk::Image< float, 2 >;
49   using VectorImage = itk::VectorImage< short, 2 >;
50 
51   // Test the creation of an image with native type
52   ShortImage::Pointer    image = ShortImage::New();
53   ShortImage::IndexType  index = {{0, 0}};
54   ShortImage::SizeType   size = {{8, 12}};
55   ShortImage::RegionType region( index, size );
56   image->SetRegions( region );
57   image->Allocate();
58 
59   VectorImage::Pointer vectorImage = VectorImage::New();
60   vectorImage->SetRegions( region );
61   vectorImage->SetNumberOfComponentsPerPixel( 3 );
62   vectorImage->Allocate();
63 
64   itk::ImageRegionIterator< ShortImage > it( image, region );
65   itk::ImageRegionIterator< VectorImage > vit( vectorImage, region );
66 
67   ShortImage::PixelType i = 0;
68   for (; !it.IsAtEnd(); ++it, ++vit, ++i)
69     {
70     it.Set( i );
71     VectorImage::PixelType vectorPixel( 3 );
72     vectorPixel = i;
73     vectorPixel[1] = i+1;
74     vit.Set( vectorPixel );
75     }
76 
77   // Create a filter
78   using PadFilterType = itk::WrapPadImageFilter< ShortImage, FloatImage >;
79   PadFilterType::Pointer wrapPad = PadFilterType::New();
80   wrapPad->SetInput( image );
81 
82   itk::WrapPadImageFilter< VectorImage, VectorImage >::Pointer vectorWrapPad;
83   vectorWrapPad = itk::WrapPadImageFilter< VectorImage, VectorImage >::New();
84   vectorWrapPad->SetInput( vectorImage );
85 
86   ShortImage::SizeValueType upperBound[2] = { 0, 0};
87   ShortImage::SizeValueType lowerBound[2] = { 0, 0};
88 
89   wrapPad->SetPadLowerBound( lowerBound );
90   wrapPad->SetPadUpperBound( upperBound );
91   wrapPad->UpdateLargestPossibleRegion();
92 
93   vectorWrapPad->SetPadLowerBound( lowerBound );
94   vectorWrapPad->SetPadUpperBound( upperBound );
95   vectorWrapPad->UpdateLargestPossibleRegion();
96 
97   std::cout << wrapPad << std::endl;
98   std::cout << vectorWrapPad << std::endl;
99 
100   std::cout << "Input spacing: " << image->GetSpacing()[0] << ", "
101             << image->GetSpacing()[1] << std::endl;
102   std::cout << "Output spacing: " << wrapPad->GetOutput()->GetSpacing()[0]
103             << ", " << wrapPad->GetOutput()->GetSpacing()[1] << std::endl;
104 
105   ShortImage::RegionType requestedRegion;
106   bool passed;
107 
108   // CASE 1
109   lowerBound[0] = 1; lowerBound[1] = 3;
110   upperBound[0] = 2; upperBound[1] = 4;
111   wrapPad->SetPadLowerBound( lowerBound );
112   wrapPad->SetPadUpperBound( upperBound );
113   wrapPad->UpdateLargestPossibleRegion();
114 
115   vectorWrapPad->SetPadLowerBound( lowerBound );
116   vectorWrapPad->SetPadUpperBound( upperBound );
117   vectorWrapPad->UpdateLargestPossibleRegion();
118 
119   requestedRegion = wrapPad->GetOutput()->GetRequestedRegion();
120 
121   itk::ImageRegionIterator< FloatImage > itIn1( wrapPad->GetOutput(), requestedRegion );
122   itk::ImageRegionIterator< VectorImage > vitIn1( vectorWrapPad->GetOutput(), requestedRegion );
123 
124   passed = true;
125   size = requestedRegion.GetSize();
126   index = requestedRegion.GetIndex();
127   if ( ( index[0] != (0 - (long) lowerBound[0] ) )
128       || ( index[1] != (0 - (long) lowerBound[1] ) )
129       || ( size[0] != (8 + lowerBound[0] + upperBound[0] ) )
130       || ( size[1] != (12 + lowerBound[1] + upperBound[1] ) ) )
131     {
132     passed = false;
133     }
134   else
135     {
136     for (; !itIn1.IsAtEnd(); ++itIn1, ++vitIn1)
137       {
138       int row = itIn1.GetIndex()[0];
139       int column = itIn1.GetIndex()[1];
140       FloatImage::PixelType expected = 0.0f;
141 
142       if ( !VerifyPixel( row, column, static_cast<short>(itIn1.Get()), expected ) )
143         {
144         std::cout << "Error in wrapPad: index (" << row << ", " << column
145                   << "). Got " << itIn1.Get() << ", expected " << expected << std::endl;
146         passed = false;
147         }
148 
149       if ( !VerifyPixel( row, column, vitIn1.Get()[1] - 1, expected ) )
150         {
151         std::cout << "Error in vectorWrapPad: index (" << row << ", " << column
152                   << "). Got " << vitIn1.Get()[1] - 1 << ", expected " << expected << std::endl;
153         passed = false;
154         }
155       }
156     }
157 
158   if (passed)
159     {
160     std::cout << "WrapPadImageFilter case 1 passed." << std::endl;
161     }
162   else
163     {
164     std::cout << "WrapPadImageFilter case 1 failed." << std::endl;
165     return EXIT_FAILURE;
166     }
167 
168 
169   // CASE 2
170   lowerBound[0] = 10;
171   upperBound[1] = 15;
172   wrapPad->SetPadLowerBound( lowerBound );
173   wrapPad->SetPadUpperBound( upperBound );
174   vectorWrapPad->SetPadLowerBound( lowerBound );
175   vectorWrapPad->SetPadUpperBound( upperBound );
176 
177   if ((wrapPad->GetPadUpperBound()[0] != upperBound[0])
178       || (wrapPad->GetPadUpperBound()[1] != upperBound[1])
179       || (wrapPad->GetPadLowerBound()[0] != lowerBound[0])
180       || (wrapPad->GetPadLowerBound()[1] != lowerBound[1]))
181     {
182     passed = false;
183     }
184   else
185     {
186     wrapPad->UpdateLargestPossibleRegion();
187     vectorWrapPad->UpdateLargestPossibleRegion();
188     requestedRegion = wrapPad->GetOutput()->GetRequestedRegion();
189 
190     itk::ImageRegionIterator< FloatImage > itIn2( wrapPad->GetOutput(), requestedRegion );
191     itk::ImageRegionIterator< VectorImage > vitIn2( vectorWrapPad->GetOutput(), requestedRegion );
192 
193     passed = true;
194     size = requestedRegion.GetSize();
195     index = requestedRegion.GetIndex();
196     if ( ( index[0] != (0 - (long) lowerBound[0] ) )
197         || ( index[1] != (0 - (long) lowerBound[1] ) )
198         || ( size[0] != (8 + lowerBound[0] + upperBound[0] ) )
199         || ( size[1] != (12 + lowerBound[1] + upperBound[1] ) ) )
200       {
201       passed = false;
202       }
203     else
204       {
205       for (; !itIn2.IsAtEnd(); ++itIn2, ++vitIn2 )
206         {
207         int row = itIn2.GetIndex()[0];
208         int column = itIn2.GetIndex()[1];
209         FloatImage::PixelType expected = 0.0f;
210 
211         if ( !VerifyPixel( row, column, static_cast<short>(itIn2.Get()), expected ) )
212           {
213           std::cout << "Error in wrapPad: index (" << row << ", " << column
214                     << "). Got " << itIn2.Get() << ", expected " << expected << std::endl;
215           passed = false;
216           }
217 
218         if ( !VerifyPixel( row, column, vitIn2.Get()[1] - 1, expected ) )
219           {
220           std::cout << "Error in vectorWrapPad: index (" << row << ", " << column
221                     << "). Got " << vitIn2.Get()[1] - 1 << ", expected " << expected << std::endl;
222           passed = false;
223           }
224         }
225       }
226     }
227 
228   if ( passed )
229     {
230     std::cout << "WrapPadImageFilter case 2 passed." << std::endl;
231     }
232   else
233     {
234     std::cout << "WrapPadImageFilter case 2 failed." << std::endl;
235     return EXIT_FAILURE;
236     }
237 
238 
239   // CASE 3
240   lowerBound[1] = 16;
241   upperBound[0] = 9;
242   wrapPad->SetPadLowerBound( lowerBound );
243   wrapPad->SetPadUpperBound( upperBound );
244   vectorWrapPad->SetPadLowerBound( lowerBound );
245   vectorWrapPad->SetPadUpperBound( upperBound );
246 
247   // Create a stream
248   using StreamingFilter = itk::StreamingImageFilter< FloatImage, FloatImage >;
249   StreamingFilter::Pointer stream = StreamingFilter::New();
250   stream->SetInput( wrapPad->GetOutput() );
251   stream->SetNumberOfStreamDivisions( 3 );
252 
253   itk::StreamingImageFilter< VectorImage, VectorImage >::Pointer vectorStream =
254     itk::StreamingImageFilter< VectorImage, VectorImage >::New();
255   vectorStream->SetInput( vectorWrapPad->GetOutput() );
256   vectorStream->SetNumberOfStreamDivisions( 3 );
257 
258   if ( ( wrapPad->GetPadUpperBound()[0] != upperBound[0] )
259       || ( wrapPad->GetPadUpperBound()[1] != upperBound[1] )
260       || ( wrapPad->GetPadLowerBound()[0] != lowerBound[0] )
261       || ( wrapPad->GetPadLowerBound()[1] != lowerBound[1] ) )
262     {
263     passed = false;
264     }
265   else
266     {
267     stream->UpdateLargestPossibleRegion();
268     vectorStream->UpdateLargestPossibleRegion();
269     requestedRegion = stream->GetOutput()->GetRequestedRegion();
270 
271     itk::ImageRegionIterator< FloatImage > itIn3(stream->GetOutput(), requestedRegion);
272     itk::ImageRegionIterator< VectorImage > vitIn3(vectorStream->GetOutput(), requestedRegion);
273 
274     passed = true;
275     size = requestedRegion.GetSize();
276     index = requestedRegion.GetIndex();
277     if ( ( index[0] != (0 - (long) lowerBound[0] ) )
278         || ( index[1] != (0 - (long) lowerBound[1] ) )
279         || ( size[0] != (8 + lowerBound[0] + upperBound[0] ) )
280         || ( size[1] != (12 + lowerBound[1] + upperBound[1] ) ) )
281       {
282       passed = false;
283       }
284     else
285       {
286       for (; !itIn3.IsAtEnd(); ++itIn3, ++vitIn3 )
287         {
288         int row = itIn3.GetIndex()[0];
289         int column = itIn3.GetIndex()[1];
290         FloatImage::PixelType expected = 0.0f;
291 
292         if ( !VerifyPixel( row, column, static_cast<short>(itIn3.Get()), expected ) )
293           {
294           std::cout << "Error in wrapPad: index (" << row << ", " << column
295                     << "). Got " << itIn3.Get() << ", expected " << expected << std::endl;
296           passed = false;
297           }
298 
299         if ( !VerifyPixel( row, column, vitIn3.Get()[1] - 1, expected ) )
300           {
301           std::cout << "Error in vectorWrapPad: index (" << row << ", " << column
302                     << "). Got " << vitIn3.Get()[1] - 1 << ", expected " << expected << std::endl;
303           passed = false;
304           }
305         }
306       }
307     }
308 
309   if ( passed )
310     {
311     std::cout << "WrapPadImageFilter case 3 passed." << std::endl;
312     }
313   else
314     {
315     std::cout << "WrapPadImageFilter case 3 failed." << std::endl;
316     return EXIT_FAILURE;
317     }
318 
319   return EXIT_SUCCESS;
320 }
321