DGtal  1.2.0
testITKImage.cpp
Go to the documentation of this file.
1 
31 #include <iostream>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/kernel/SpaceND.h"
34 #include "DGtal/kernel/domains/HyperRectDomain.h"
35 #include "DGtal/images/ImageContainerByITKImage.h"
36 #include <boost/foreach.hpp>
37 
38 //specific itk method
39 #if defined(__GNUG__)
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
42 #endif
43 #if defined(__clang__)
44 #pragma clang diagnostic push
45 #pragma clang diagnostic ignored "-Wdocumentation"
46 #endif
47 #include <itkExtractImageFilter.h>
48 #if defined(__clang__)
49 #pragma clang diagnostic pop
50 #endif
51 #if defined(__GNUG__)
52 #pragma GCC diagnostic pop
53 #endif
54 
56 
57 using namespace std;
58 using namespace DGtal;
59 
61 // Functions for testing class ITKImage.
63 
68 {
69  unsigned int nbok = 0;
70  unsigned int nb = 0;
71 
72  trace.beginBlock ( "ITK Image init..." );
73 
74  typedef DGtal::int32_t Integer;
75  typedef SpaceND<3, Integer > Space3Type;
77  typedef Domain::Point Point;
78 
80 
81  const Integer t[ ] = { 1, 1, 1};
82  const Integer t2[ ] = { 5, 5, 5};
83  const Integer t3[ ] = { 2, 2, 2};
84  Point lowerBound ( t );
85  Point upperBound ( t2 );
86  Point c ( t3 );
87  Integer val;
88 
89  Image myImage ( Domain(lowerBound, upperBound) );
90 
91  trace.info() << myImage << std::endl;
92  trace.info() << "getvalue= " << myImage(c) << endl;
93  trace.info() << "set value 23 " << endl;
94  myImage.setValue( c, 23);
95 
96  val = myImage(c);
97 
98  if (val == 23)
99  nbok++;
100  trace.info() << "getvalue= " << val << endl;
101  nb++;
102 
103  //Iterator test
104  trace.info() << "Simple Iterator=";
105  for (Image::ConstIterator it = myImage.begin(), itend = myImage.end();
106  it != itend;
107  ++it)
108  trace.warning() << myImage(it) << " ";
109  trace.info() << endl;
110 
111  //We rewrite the image
112  int nbVal = 0;
113  for (Image::Iterator it = myImage.begin(), itend = myImage.end();
114  it != itend;
115  ++it)
116  myImage.setValue(it, nbVal++);
117 
118  trace.info() << "Set Iterator=";
119  for (Image::ConstIterator it = myImage.begin(), itend = myImage.end();
120  it != itend;
121  ++it)
122  trace.warning() << myImage(it) << " ";
123  trace.info() << endl;
124 
125  auto & container = myImage.container();
126  (void)container;
127 
128 
129  trace.info() << "(" << nbok << "/" << nb << ") "
130  << "true == true" << std::endl;
131  trace.endBlock();
132 
133  return nbok == nb;
134 }
135 
137 {
138  unsigned int nbok = 0;
139  unsigned int nb = 0;
140 
141  trace.beginBlock ( "Test the use of a pure ITK method..." );
142 
143  typedef DGtal::int32_t Integer;
146  typedef Domain::Point Point;
147 
148 
150 
151  Point lowerBound ( 0, 0 );
152  Point upperBound ( 9, 9);
153  Domain domain(lowerBound, upperBound);
154 
155  Image myImage(domain);
156  trace.info() << myImage << std::endl;
157 
158  //We fill the image
159  Integer nbVal = 0;
160  for (Image::Iterator it = myImage.begin(), itend = myImage.end();
161  it != itend;
162  ++it)
163  myImage.setValue(it, nbVal++);
164 
165  trace.info() << "Input image=";
166  for (Image::ConstIterator it = myImage.begin(), itend = myImage.end();
167  it != itend;
168  ++it)
169  trace.warning() << myImage(it) << " ";
170  trace.info() << endl;
171 
172 
173  // We define a cropFilter
174  typedef itk::ExtractImageFilter< Image::ITKImage, Image::ITKImage > CropFilter;
175 
176  // Crop filter region
177  Image::ITKImage::SizeType size;
178  size[0] = 5;
179  size[1] = 5;
180 
181  Image::ITKImage::IndexType index;
182  index[0] = 2;
183  index[1] = 2;
184 
185  Image::ITKImage::RegionType regionToExtract(index,size);
186 
187  // Crop filter process
188  CropFilter::Pointer cropFilter = CropFilter::New();
189  cropFilter->SetInput( myImage.getITKImagePointer() );
190  cropFilter->SetExtractionRegion( regionToExtract );
191  cropFilter->Update();
192 
193  // Pointer to the filter output
194  Image::ITKImagePointer handleOut = cropFilter->GetOutput();
195  Image myImageOut ( handleOut );
196 
197 
198  trace.info() << "Output image=";
199 
200  for (Image::ConstIterator it = myImageOut.begin(), itend = myImageOut.end();
201  it != itend;
202  ++it)
203  {
204  nbok += (it.Value() == (it.GetIndex()[1]*10 + it.GetIndex()[0]));
205  nb++;
206  trace.warning() << it.Value() << "(" << (it.GetIndex()[1]*10 + it.GetIndex()[0]) << ")" << " ";
207  }
208  trace.info() << endl;
209 
210  trace.info() << "(" << nbok << "/" << nb << ") " << "true == true" << std::endl;
211  trace.endBlock();
212 
213  return nbok == 25 && nb == 25;
214 }
215 
217 {
218  trace.beginBlock ( "ITK Image With Metadata init..." );
219 
220  unsigned int nbok = 0;
221  unsigned int nb = 0;
222 
223  typedef DGtal::int32_t Integer;
224  typedef SpaceND<3, Integer > Space3Type;
226  typedef Domain::Point Point;
227 
229 
230  // REMEMBER: Origin in ITK is the physical position of the index {0,0,...}
231  // even when that zero-index is not included in the LargestPossibleRegion of the image.
232  const Integer t[ ] = { 1, 1, 1};
233  const Integer t2[ ] = { 5, 5, 5};
234  const Integer t3[ ] = { 2, 2, 2};
235  Point lowerBound ( t );
236  Point upperBound ( t2 );
237  Point c ( t3 );
238  Integer val;
239 
240  Image myImage ( Domain(lowerBound, upperBound) );
241  // Fill the image
242  int nbVal = 0;
243  for (Image::Iterator it = myImage.begin(), itend = myImage.end();
244  it != itend; ++it) {
245  myImage.setValue(it, nbVal++);
246  }
247  // Change the default metadata (physical properties) of an itk_image.
248  auto itk_image = myImage.getITKImagePointer();
249  Image::ITKImage::PointType origin;
250  origin.Fill(10.0);
251  Image::ITKImage::SpacingType spacing;
252  spacing.Fill(2.0);
253  Image::ITKImage::DirectionType direction;
254  direction.SetIdentity();
255  itk_image->SetOrigin(origin);
256  itk_image->SetSpacing(spacing);
257  itk_image->SetDirection(direction);
258 
259  // Check that the value of index points is not affected by a change of metadata.
260  val = myImage.operator()(lowerBound);
261  nbok += (val == 0); nb++;
262  trace.info() << "Index: " << lowerBound << ". Value: " << val << ". Expected: " << 0 << std::endl;
263  val = myImage.operator()(upperBound);
264  nbok += (val == 124); nb++;
265  trace.info() << "Index: " << upperBound << ". Value: " << val << ". Expected: " << 124 << std::endl;
266  val = myImage.operator()(c);
267  nbok += (val == 31); nb++;
268  trace.info() << "Index: " << c << ". Value: " << val << ". Expected: " << 31 << std::endl;
269 
270  Image::PhysicalPoint physical_point;
271  Image::PhysicalPoint expected_physical_point;
272  Image::Point index_point;
273 
274  // when shiftDomain is zero, index points (ITK) and domain points (DGtal) are equal
275  index_point = myImage.getIndexFromDomainPoint(lowerBound);
276  nbok += (index_point == lowerBound); nb++;
277  physical_point = myImage.getPhysicalPointFromDomainPoint(index_point);
278  expected_physical_point = myImage.getLowerBoundAsPhysicalPoint();
279  nbok += (physical_point[0] == 12.0); nb++;
280  nbok += (physical_point == expected_physical_point); nb++;
281  trace.info() << "Index: " << index_point << ". PhysicalPoint: " << physical_point << ". Expected: " << expected_physical_point << std::endl;
282 
283  index_point = myImage.getIndexFromDomainPoint(upperBound);
284  nbok += (index_point == upperBound); nb++;
285  physical_point = myImage.getPhysicalPointFromDomainPoint(index_point);
286  expected_physical_point = myImage.getUpperBoundAsPhysicalPoint();
287  nbok += (physical_point[0] == 20.0); nb++;
288  nbok += (physical_point == expected_physical_point); nb++;
289  trace.info() << "Index: " << index_point << ". PhysicalPoint: " << physical_point << ". Expected: " << expected_physical_point << std::endl;
290 
291  auto index_back = myImage.getDomainPointFromPhysicalPoint(physical_point);
292  nbok += (index_back == upperBound); nb++;
293  trace.info() << "PhysicalPoint: " << physical_point << ". Index (back): " << index_back << ". Expected: " << upperBound << std::endl;
294 
295  trace.endBlock();
296 
297  return nbok == 10 && nb == 10;
298 }
299 
301 {
302  trace.beginBlock ( "ITK Image With ShiftDomain init..." );
303 
304  unsigned int nbok = 0;
305  unsigned int nb = 0;
306 
307  typedef DGtal::int32_t Integer;
308  typedef SpaceND<3, Integer > Space3Type;
310  typedef Domain::Point Point;
311 
313 
314  const Integer t[ ] = { 1, 1, 1};
315  const Integer t2[ ] = { 5, 5, 5};
316  const Integer t3[ ] = { 2, 2, 2};
317  Point lowerBound ( t );
318  Point upperBound ( t2 );
319  Point c ( t3 );
320  Integer val;
321 
322  Image myImage ( Domain(lowerBound, upperBound) );
323 
324  // Fill the image
325  int nbVal = 0;
326  for (Image::Iterator it = myImage.begin(), itend = myImage.end();
327  it != itend; ++it) {
328  myImage.setValue(it, nbVal++);
329  }
330 
331  // Change the default metadata (physical properties) of an itk_image.
332  auto itk_image = myImage.getITKImagePointer();
333  Image::ITKImage::PointType origin;
334  origin.Fill(10.0);
335  Image::ITKImage::SpacingType spacing;
336  spacing.Fill(2.0);
337  Image::ITKImage::DirectionType direction;
338  direction.SetIdentity();
339  itk_image->SetOrigin(origin);
340  itk_image->SetSpacing(spacing);
341  itk_image->SetDirection(direction);
342 
343 
344  // Apply a domainShift
345  const Integer sd[ ] = { -20, -20, -20};
346  Point domainShift(sd);
347  myImage.updateDomain(domainShift);
348  Point new_lowerBound = myImage.domain().lowerBound();
349  Point new_upperBound = myImage.domain().upperBound();
350  nbok += ( new_lowerBound == lowerBound + domainShift); nb++;
351  trace.info() << "lowerBound: " << new_lowerBound << ". Expected: " << lowerBound + domainShift << std::endl;
352  nbok += ( new_upperBound == upperBound + domainShift); nb++;
353  trace.info() << "upperBound: " << new_upperBound << ". Expected: " << upperBound + domainShift << std::endl;
354 
355  // Check that the shifted domain points to the correct indices of the image.
356  val = myImage.operator()(new_lowerBound);
357  // It should have the same value than lowerBound had before applying the domainShift
358  nbok += (val == 0); nb++;
359  trace.info() << "Index: " << new_lowerBound << ". Value: " << val << ". Expected: " << 0 << std::endl;
360  val = myImage.operator()(new_upperBound);
361  nbok += (val == 124); nb++;
362  trace.info() << "Index: " << new_upperBound << ". Value: " << val << ". Expected: " << 124 << std::endl;
363  val = myImage.operator()(myImage.getDomainPointFromIndex(c));
364  nbok += (val == 31); nb++;
365  trace.info() << "Index: " << c << ". Value: " << val << ". Expected: " << 31 << std::endl;
366 
367  Image::PhysicalPoint physical_point;
368  Image::PhysicalPoint expected_physical_point;
369  Image::Point index_point;
370  Image::Point domain_point;
371 
372  index_point = lowerBound;
373  domain_point = new_lowerBound;
374  physical_point = myImage.getPhysicalPointFromDomainPoint(domain_point);
375  expected_physical_point = Image::PhysicalPoint(12.0, 12.0, 12.0);
376  nbok += (physical_point == expected_physical_point); nb++;
377  trace.info() << "Domain: " << domain_point <<
378  ". Index: " << index_point <<
379  ". PhysicalPoint: " << physical_point <<
380  ". Expected: " << expected_physical_point << std::endl;
381 
382  index_point = myImage.getIndexFromDomainPoint(new_lowerBound);
383  nbok += ( index_point == lowerBound ); nb++;
384  trace.info() << "index_point: " << index_point << ". Expected: " << lowerBound << std::endl;
385  physical_point = myImage.getPhysicalPointFromDomainPoint(new_lowerBound);
386  expected_physical_point = myImage.getLowerBoundAsPhysicalPoint();
387  nbok += (physical_point[0] == 12.0); nb++;
388  nbok += (physical_point == expected_physical_point); nb++;
389  trace.info() << "Domain: " << new_lowerBound <<
390  ". Index: " << index_point <<
391  ". PhysicalPoint: " << physical_point <<
392  ". Expected: " << expected_physical_point << std::endl;
393 
394  index_point = upperBound;
395  domain_point = new_upperBound;
396  physical_point = myImage.getPhysicalPointFromDomainPoint(domain_point);
397  expected_physical_point = myImage.getUpperBoundAsPhysicalPoint();
398  nbok += (physical_point[0] == 20.0); nb++;
399  nbok += (physical_point == expected_physical_point); nb++;
400  trace.info() << "Domain: " << new_lowerBound <<
401  ". Index: " << index_point <<
402  ". PhysicalPoint: " << physical_point <<
403  ". Expected: " << expected_physical_point << std::endl;
404 
405  return nbok == 11 && nb == 11;
406 }
407 
409 // Standard services - public :
410 
411 int main( int argc, char** argv )
412 {
413  trace.beginBlock ( "Testing class ITKImage" );
414  trace.info() << "Args:";
415  for ( int i = 0; i < argc; ++i )
416  trace.info() << " " << argv[ i ];
417  trace.info() << endl;
418 
419  bool res = testITKImage() && testITKMethod() &&
421  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
422  trace.endBlock();
423  return res ? 0 : 1;
424 }
425 // //
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
Aim: implements a model of CImageContainer using a ITK Image.
Aim: implements association bewteen points lying in a digital domain and values.
Definition: Image.h:70
const Domain & domain() const
Definition: Image.h:192
void setValue(const Point &aPoint, const Value &aValue)
Definition: Image.h:247
void beginBlock(const std::string &keyword="")
std::ostream & emphase()
std::ostream & info()
std::ostream & warning()
double endBlock()
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:154
boost::int32_t int32_t
signed 32-bit integer.
Definition: BasicTypes.h:72
unsigned int index(DGtal::uint32_t n, unsigned int b)
Definition: testBits.cpp:44
MyPointD Point
Definition: testClone2.cpp:383
SpaceND< 2, int > Space2Type
bool testITKMethod()
int main(int argc, char **argv)
bool testITKImageWithShiftDomain()
bool testITKImage()
bool testITKImageWithMetadata()
Domain domain
ImageContainerBySTLVector< Domain, Value > Image
HyperRectDomain< Space > Domain