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 // Disable warning for long symbol names in this file only
19 
20 /*
21 * This is a test file for the itkImageSpatialObject class.
22 * The suported pixel types does not include itkRGBPixel, itkRGBAPixel, etc...
23 * So far it only allows to manage images of simple types like unsigned short,
24 * unsigned int, or itk::Vector<...>.
25 */
26 
27 
28 #include "itkImageRegionIterator.h"
29 
30 #include "itkImageSpatialObject.h"
31 #include "itkLinearInterpolateImageFunction.h"
32 
33 
itkImageSpatialObjectTest(int,char * [])34 int itkImageSpatialObjectTest(int, char* [])
35 {
36   #define NDimensions 3
37 
38   using ScalarType = double;
39   using Pixel = unsigned short;
40   using ImageType = itk::Image<Pixel,NDimensions>;
41   using ImageSpatialObject = itk::ImageSpatialObject<NDimensions,Pixel>;
42   using Iterator = itk::ImageRegionIterator<ImageType>;
43   using PointType = itk::Point<ScalarType,NDimensions>;
44 
45   ImageType::Pointer image = ImageType::New();
46   ImageType::SizeType size = {{ 10, 10, 10 }};
47   ImageType::IndexType index = {{ 0, 0, 0 }};
48   ImageType::RegionType region;
49   ImageType::PointType origin;
50   origin.Fill(5);
51 
52   region.SetSize(size);
53   region.SetIndex(index);
54   image->SetOrigin(origin);
55   image->SetLargestPossibleRegion(region);
56   image->SetBufferedRegion(region);
57   image->SetRequestedRegion(region);
58   image->Allocate();
59 
60   Iterator it(image,region);
61   Pixel p =0;
62 
63   for(; !it.IsAtEnd(); ++it, ++p)
64     {
65     it.Set(p);
66     }
67   it.GoToBegin();
68 
69   ImageSpatialObject::Pointer imageSO = ImageSpatialObject::New();
70   imageSO->Print(std::cout);
71 
72   imageSO->SetImage(image);
73   imageSO->Update();
74 
75   ImageSpatialObject::TransformType::OffsetType offset;
76   offset.Fill(5);
77 
78   imageSO->GetModifiableObjectToParentTransform()->SetOffset(offset);
79   imageSO->Update();
80 
81   PointType q;
82   PointType r;
83   double returnedValue;
84   double expectedValue;
85 
86   r.Fill(9);
87   q.Fill(15);
88 
89   std::cout << "Bounding Box = "
90     << imageSO->GetMyBoundingBoxInWorldSpace()->GetBounds() << std::endl;
91   std::cout<<"IsInside()...";
92   if( imageSO->IsInsideInWorldSpace(r) || !imageSO->IsInsideInWorldSpace(q) )
93     {
94     std::cout<<"[FAILED]"<<std::endl;
95     return EXIT_FAILURE;
96     }
97   else
98     {
99     std::cout<<"[PASSED]"<<std::endl;
100     }
101 
102   q.Fill(15.1);
103   expectedValue = 555;
104 
105   try
106     {
107     imageSO->ValueAtInWorldSpace(q, returnedValue);
108     }
109   catch( itk::ExceptionObject & )
110     {
111     throw;
112     }
113 
114   std::cout<<"ValueAt()...";
115   if( itk::Math::NotAlmostEquals( returnedValue, expectedValue ) )
116     {
117     std::cout << "Expected: " << expectedValue << " returned: "
118       << returnedValue << std::endl;
119     std::cout <<"[FAILED]: " << std::endl;
120     return EXIT_FAILURE;
121     }
122   else
123     {
124     std::cout<<"[PASSED]"<<std::endl;
125     }
126 
127   ImageSpatialObject::DerivativeVectorType derivative;
128   ImageSpatialObject::DerivativeVectorType expectedDerivative;
129   Pixel expectedPixel;
130 
131   imageSO->DerivativeAtInWorldSpace(q, 1, derivative);
132   expectedPixel = 1;
133   expectedDerivative[0]=expectedPixel;
134   expectedPixel = 10;
135   expectedDerivative[1]=expectedPixel;
136   expectedPixel = 100;
137   expectedDerivative[2]=expectedPixel;
138   std::cout<<"DerivativeAt()...";
139   if( derivative != expectedDerivative )
140     {
141     std::cout<<"[FAILED]"<<std::endl;
142     return EXIT_FAILURE;
143     }
144   else
145     {
146     std::cout<<"[PASSED]"<<std::endl;
147     }
148 
149   // Now testing the ValueAt() with an interpolator
150   using InterpolatorType = itk::LinearInterpolateImageFunction<ImageType>;
151   InterpolatorType::Pointer interpolator = InterpolatorType::New();
152   imageSO->SetInterpolator(interpolator);
153   expectedValue = 566.1;
154 
155   try
156     {
157     imageSO->ValueAtInWorldSpace(q, returnedValue);
158     }
159   catch( itk::ExceptionObject & )
160     {
161     throw;
162     }
163 
164   std::cout<<"ValueAt() with interpolator...";
165   if( std::fabs(returnedValue-expectedValue)>0.001 )
166     {
167     std::cout << "Expected: " << expectedValue << " returned: "
168       << returnedValue << std::endl;
169     return EXIT_FAILURE;
170     }
171   else
172     {
173     std::cout<<"[PASSED]"<<std::endl;
174     }
175 
176 
177   imageSO->DerivativeAtInWorldSpace(q, 1, derivative);
178   expectedDerivative[0]=1;
179   expectedDerivative[1]=10;
180   expectedDerivative[2]=100;
181   std::cout<<"DerivativeAt() with interpolator ...";
182   if(  std::fabs(derivative[0]-expectedDerivative[0])>0.00001
183     || std::fabs(derivative[1]-expectedDerivative[1])>0.00001
184     || std::fabs(derivative[2]-expectedDerivative[2])>0.00001
185     )
186     {
187     std::cout << "Expected: " << derivative << " returned: "
188       << expectedDerivative << std::endl;
189     std::cout<<"[FAILED]"<<std::endl;
190     return EXIT_FAILURE;
191     }
192   else
193     {
194     std::cout<<"[PASSED]"<<std::endl;
195     }
196 
197   imageSO->Print(std::cout);
198 
199   return EXIT_SUCCESS;
200 }
201