/Modules/Core/Common/test/itkConstNeighborhoodIteratorWithOnlyIndexTest.cxx

https://github.com/chrismullins/ITK · C++ · 457 lines · 373 code · 58 blank · 26 comment · 94 complexity · 2ff966e20b3f241a668a15db3912a193 MD5 · raw file

  1. /*=========================================================================
  2. *
  3. * Copyright Insight Software Consortium
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License" << std::endl;
  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. #include "itkNeighborhoodIteratorTestCommon.hxx"
  19. #include "itkConstNeighborhoodIteratorWithOnlyIndex.h"
  20. template <typename TImage>
  21. typename TImage::Pointer itkConstNeighborhoodIteratorWithOnlyIndexTestGetTestImage(int d1, int d2, int d3, int d4)
  22. {
  23. itk::Size<4> sizeND;
  24. sizeND[0] = d1;
  25. sizeND[1] = d2;
  26. sizeND[2] = d3;
  27. sizeND[3] = d4;
  28. itk::Index<4> origND;
  29. origND.Fill(0);
  30. itk::ImageRegion<4> RegionND;
  31. RegionND.SetSize(sizeND);
  32. RegionND.SetIndex(origND);
  33. typename TImage::Pointer imageND = TImage::New();
  34. imageND->SetLargestPossibleRegion(RegionND);
  35. imageND->SetBufferedRegion(RegionND);
  36. imageND->SetRequestedRegion(RegionND);
  37. return imageND;
  38. }
  39. template< typename TImage >
  40. int itkConstNeighborhoodIteratorWithOnlyIndexTestRun()
  41. {
  42. typename TImage::Pointer img = itkConstNeighborhoodIteratorWithOnlyIndexTestGetTestImage<TImage>(10, 10, 5, 3);
  43. typedef TImage ImageType;
  44. typedef itk::ConstNeighborhoodIteratorWithOnlyIndex< ImageType > ConstNeighborhoodIteratorType;
  45. typedef typename ConstNeighborhoodIteratorType::IndexType IndexType;
  46. IndexType loc;
  47. loc[0] = 4; loc[1] = 4; loc[2] = 2; loc[3] = 1;
  48. typename ConstNeighborhoodIteratorType::RadiusType radius;
  49. radius[0] = radius[1] = radius[2] = radius[3] = 1;
  50. typename ConstNeighborhoodIteratorType::RegionType reg;
  51. typename ConstNeighborhoodIteratorType::SizeType sz;
  52. IndexType idx;
  53. idx[0] = idx[1] = idx[2] = 0; idx[3] = 1;
  54. sz[0] = sz[1] = 10; sz[2] = 5; sz[3] = 1;
  55. reg.SetIndex(idx);
  56. reg.SetSize(sz);
  57. std::cout << "Creating ConstNeighborhoodIterator" << std::endl;
  58. ConstNeighborhoodIteratorType it(radius, img, reg);
  59. std::cout << "Moving iterator using SetLocation() to loc: " << loc << std::endl;
  60. it.SetLocation(loc);
  61. it.Print(std::cout);
  62. if( it.GetIndex() != loc )
  63. {
  64. std::cerr << "Error with SetLocation." << std::endl;
  65. return EXIT_FAILURE;
  66. }
  67. std::cout << "Test GetIndex( NeighborhoodIndex )" << std::endl;
  68. if( it.GetIndex( it.GetCenterNeighborhoodIndex() ) != loc )
  69. {
  70. std::cerr << "Error getting index from center nhood index. Returned " << it.GetIndex( it.GetCenterNeighborhoodIndex() ) << std::endl;
  71. return EXIT_FAILURE;
  72. }
  73. IndexType truthIndex;
  74. for( unsigned int i=0; i < 4; i++ )
  75. {
  76. truthIndex[i] = loc[i] - radius[i];
  77. }
  78. if( it.GetIndex( 0 ) != truthIndex )
  79. {
  80. std::cerr << "Error getting index from nhood index 0. Returned " << it.GetIndex( 0 ) << std::endl;
  81. }
  82. std::cout << "Testing GoToBegin()" << std::endl;
  83. it.GoToBegin();
  84. it.Print(std::cout);
  85. if( it.GetIndex() != idx )
  86. {
  87. std::cerr << "Error with GoToBegin. Expected: " << idx << ", GetIndex: " << it.GetIndex() << std::endl;
  88. return EXIT_FAILURE;
  89. }
  90. std::cout << "Testing IsAtBegin()" << std::endl;
  91. std::cout << it.IsAtBegin() << std::endl;
  92. if( ! it.IsAtBegin() )
  93. {
  94. std::cerr << "Error with IsAtBegin." << std::endl;
  95. return EXIT_FAILURE;
  96. }
  97. std::cout << "Testing GoToEnd()" << std::endl;
  98. it.GoToEnd();
  99. it.Print(std::cout);
  100. std::cout << "Testing IsAtEnd()" << std::endl;
  101. std::cout << it.IsAtEnd() << std::endl;
  102. if( ! it.IsAtEnd() )
  103. {
  104. std::cerr << "Error with either IsAtEnd or GoToEnd." << std::endl;
  105. return EXIT_FAILURE;
  106. }
  107. std::cout << "Testing forward iteration" << std::endl;
  108. it.GoToBegin();
  109. IndexType index = it.GetIndex();
  110. ++it;
  111. if( it.GetIndex()[0] != index[0]+1 )
  112. {
  113. std::cerr << "Error with fwd iteration" << std::endl;
  114. return EXIT_FAILURE;
  115. }
  116. while (! it.IsAtEnd())
  117. {
  118. ++it;
  119. }
  120. // fwd iterate by a line
  121. it.GoToBegin();
  122. index = it.GetIndex();
  123. for( unsigned int i = 0; i < sz[0]; i++ )
  124. {
  125. ++it;
  126. }
  127. if( it.GetIndex()[0] != index[0] || it.GetIndex()[1] != index[1]+1 )
  128. {
  129. std::cerr << "Error with fwd iteration by one line." << std::endl;
  130. return EXIT_FAILURE;
  131. }
  132. // fwd iterate by a slice
  133. index = it.GetIndex();
  134. for( unsigned int i = 0; i < sz[0]*sz[1]; i++ )
  135. {
  136. ++it;
  137. }
  138. if( it.GetIndex()[0] != index[0] || it.GetIndex()[1] != index[1] || it.GetIndex()[2] != index[2] + 1 )
  139. {
  140. std::cerr << "Error with fwd iteration by one slice." << std::endl;
  141. return EXIT_FAILURE;
  142. }
  143. std::cout << "Testing reverse iteration" << std::endl;
  144. it.GoToEnd();
  145. index = it.GetIndex();
  146. --it;
  147. if( it.GetIndex()[3] != index[3]-1 )
  148. {
  149. std::cerr << "Error with reverse iteration" << std::endl;
  150. return EXIT_FAILURE;
  151. }
  152. index = it.GetIndex();
  153. for( unsigned int i = 0; i < sz[0]; i++ )
  154. {
  155. --it;
  156. }
  157. if( it.GetIndex()[0] != index[0] || it.GetIndex()[1] != index[1] - 1 )
  158. {
  159. std::cerr << "Error with reverse iteration by one line." << std::endl;
  160. return EXIT_FAILURE;
  161. }
  162. index = it.GetIndex();
  163. for( unsigned int i = 0; i < sz[0]*sz[1]; i++ )
  164. {
  165. --it;
  166. }
  167. if( it.GetIndex()[0] != index[0] || it.GetIndex()[1] != index[1] || it.GetIndex()[2] != index[2] - 1 )
  168. {
  169. std::cerr << "Error with reverse iteration by one slice." << std::endl;
  170. return EXIT_FAILURE;
  171. }
  172. std::cout << "Moving iterator using SetLocation()" << std::endl;
  173. it.SetLocation(loc);
  174. it.Print(std::cout);
  175. std::cout << "Testing GetIndex()" << std::endl;
  176. std::cout << it.GetIndex() << std::endl;
  177. std::cout << "Testing GetBoundingBoxAsImageRegion" << std::endl;
  178. std::cout << it.GetBoundingBoxAsImageRegion() << std::endl;
  179. ////
  180. std::cout << "Testing random access iteration" << std::endl;
  181. typename ImageType::Pointer ra_img = itkConstNeighborhoodIteratorWithOnlyIndexTestGetTestImage<TImage>(10, 10, 5, 3);
  182. loc[0] = 4; loc[1] = 4; loc[2] = 2; loc[3] = 1;
  183. radius[0] = radius[1] = radius[2] = radius[3] = 1;
  184. std::cout << "Creating ConstNeighborhoodIterator" << std::endl;
  185. ConstNeighborhoodIteratorType ra_it(radius, ra_img, ra_img->GetRequestedRegion());
  186. ConstNeighborhoodIteratorType copy_it;
  187. std::cout << "Test copying." << std::endl;
  188. copy_it = ra_it;
  189. if( copy_it != ra_it || ! (copy_it == ra_it) )
  190. {
  191. std::cerr << "Failure with copying or equality comparison." << std::endl;
  192. return EXIT_FAILURE;
  193. }
  194. if( ! (copy_it >= ra_it) || ! (copy_it <= ra_it) )
  195. {
  196. std::cerr << "Failure with copying or >= or <= comparison." << std::endl;
  197. return EXIT_FAILURE;
  198. }
  199. std::cout << "Testing random access" << std::endl;
  200. ra_it.SetLocation( loc );
  201. std::cout << "Adding [1, 1, 1, 1]" << std::endl;
  202. OffsetType a_off;
  203. a_off.Fill(1);
  204. ra_it += a_off;
  205. for( unsigned int i=0; i < 4; i++ )
  206. {
  207. IndexType ind = ra_it.GetIndex();
  208. if( ind[i] != loc[i] + 1 )
  209. {
  210. std::cerr << "Error with adding offset " << a_off << std::endl;
  211. return EXIT_FAILURE;
  212. }
  213. }
  214. std::cout << "Test iterator comparisons" << std::endl;
  215. if( ! (copy_it < ra_it) || ! (copy_it <= ra_it) )
  216. {
  217. std::cerr << "Error with < or <=." << std::endl;
  218. return EXIT_FAILURE;
  219. }
  220. if( ! (copy_it < ra_it) || ! (copy_it <= ra_it) )
  221. {
  222. std::cerr << "Error with < or <=." << std::endl;
  223. return EXIT_FAILURE;
  224. }
  225. std::cout << "Subtracting [1, 1, 1, 1]" << std::endl;
  226. ra_it -= a_off;
  227. for( unsigned int i=0; i < 4; i++ )
  228. {
  229. IndexType ind = ra_it.GetIndex();
  230. if( ind[i] != loc[i] )
  231. {
  232. std::cerr << "Error with substracting offset " << a_off << std::endl;
  233. return EXIT_FAILURE;
  234. }
  235. }
  236. copy_it = ra_it;
  237. std::cout << "Adding [0 0 0 2]" << std::endl;
  238. a_off.Fill(0);
  239. a_off[3] = 2;
  240. ra_it += a_off;
  241. IndexType truth = loc;
  242. truth += a_off;
  243. for( unsigned int i=0; i < 4; i++ )
  244. {
  245. IndexType ind = ra_it.GetIndex();
  246. if( ind[i] != truth[i] )
  247. {
  248. std::cerr << "Error with adding offset " << a_off << std::endl;
  249. return EXIT_FAILURE;
  250. }
  251. }
  252. if( ra_it < copy_it || ra_it <= copy_it || copy_it > ra_it || copy_it >= ra_it )
  253. {
  254. std::cerr << "Error with > or >= comparison after adding offset." << std::endl;
  255. return EXIT_FAILURE;
  256. }
  257. copy_it = ra_it;
  258. std::cout << "Adding [0 8 0 0]" << std::endl;
  259. a_off.Fill(0);
  260. a_off[1] = 8;
  261. ra_it += a_off;
  262. truth += a_off;
  263. for( unsigned int i=0; i < 4; i++ )
  264. {
  265. IndexType ind = ra_it.GetIndex();
  266. if( ind[i] != truth[i] )
  267. {
  268. std::cerr << "Error with adding offset " << a_off << std::endl;
  269. return EXIT_FAILURE;
  270. }
  271. }
  272. if( ra_it < copy_it || ra_it <= copy_it || copy_it > ra_it || copy_it >= ra_it )
  273. {
  274. std::cerr << "Error with comparison after adding offset " << a_off << std::endl;
  275. std::cerr << (ra_it < copy_it) << ", " << (ra_it <= copy_it) << ", " << (copy_it > ra_it) << ", " << (copy_it >= ra_it) << std::endl;
  276. return EXIT_FAILURE;
  277. }
  278. copy_it = ra_it;
  279. std::cout << "Adding [5 -3 2 -1]" << std::endl;
  280. a_off[0] = 5;
  281. a_off[1] = -3;
  282. a_off[2] = 2;
  283. a_off[3] = -1;
  284. ra_it += a_off;
  285. truth += a_off;
  286. for( unsigned int i=0; i < 4; i++ )
  287. {
  288. IndexType ind = ra_it.GetIndex();
  289. if( ind[i] != truth[i] )
  290. {
  291. std::cerr << "Error with adding offset " << a_off << std::endl;
  292. return EXIT_FAILURE;
  293. }
  294. }
  295. if( ra_it > copy_it || ra_it >= copy_it || copy_it < ra_it || copy_it <= ra_it )
  296. {
  297. std::cerr << "Error with comparison after adding offset." << std::endl;
  298. return EXIT_FAILURE;
  299. }
  300. //
  301. // Test IndexInBounds
  302. //
  303. std::cout << "Testing IndexInBounds" << std::endl;
  304. int dims[4] = {13,11,9,7};
  305. typename ImageType::Pointer iib_img = itkConstNeighborhoodIteratorWithOnlyIndexTestGetTestImage<TImage>(dims[0], dims[1], dims[2], dims[3]);
  306. radius[0] = 4;
  307. radius[1] = 3;
  308. radius[2] = 2;
  309. radius[3] = 1;
  310. std::cout << "Creating ConstNeighborhoodIterator" << std::endl;
  311. typedef ConstNeighborhoodIteratorType IteratorType;
  312. IteratorType iib_it(radius, iib_img, iib_img->GetRequestedRegion());
  313. typename IteratorType::OffsetType resultOffset;
  314. typename IteratorType::OffsetType internalIndex;
  315. typename IteratorType::IndexType centerLoc;
  316. centerLoc[0] = static_cast<typename IteratorType::IndexType::IndexValueType>(dims[0] / 2);
  317. centerLoc[1] = static_cast<typename IteratorType::IndexType::IndexValueType>(dims[1] / 2);
  318. centerLoc[2] = static_cast<typename IteratorType::IndexType::IndexValueType>(dims[2] / 2);
  319. centerLoc[3] = static_cast<typename IteratorType::IndexType::IndexValueType>(dims[3] / 2);
  320. iib_it.GoToBegin();
  321. bool inside = iib_it.IndexInBounds( 0, internalIndex, resultOffset );
  322. if( inside )
  323. {
  324. std::cerr << "IndexInBounds failed for index 0, expected false." << std::endl;
  325. return EXIT_FAILURE;
  326. }
  327. for( unsigned int n = 0; n < 4; n++ )
  328. {
  329. if( resultOffset[n] != static_cast<itk::OffsetValueType>( radius[n] ) )
  330. {
  331. std::cerr << "IndexInBounds failed. Expected resultOffset of " << radius << ", but got " << resultOffset << std::endl;
  332. return EXIT_FAILURE;
  333. }
  334. }
  335. inside = iib_it.IndexInBounds( iib_it.Size()-1, internalIndex, resultOffset );
  336. if( ! inside )
  337. {
  338. std::cerr << "IndexInBounds failed for index size-1, expected true." << std::endl;
  339. return EXIT_FAILURE;
  340. }
  341. for( unsigned int n = 0; n < 4; n++ )
  342. {
  343. if( resultOffset[n] != 0 )
  344. {
  345. std::cerr << "IndexInBounds failed. Expected resultOffset of 0, but got " << resultOffset << std::endl;
  346. return EXIT_FAILURE;
  347. }
  348. }
  349. // Test min boundary by dimension
  350. int result = EXIT_SUCCESS;
  351. for( unsigned int n = 0; n < 4; n++ )
  352. {
  353. typename IteratorType::IndexType boundaryLoc = centerLoc;
  354. boundaryLoc[n] = 0;
  355. iib_it.SetLocation( boundaryLoc );
  356. if( iib_it.IndexInBounds( 0, internalIndex, resultOffset ) )
  357. {
  358. std::cerr << "IndexInBounds failed for min boundaryLoc: " << boundaryLoc << " and dimension: " << n << ". Expected false." << std::endl;
  359. result = EXIT_FAILURE;
  360. }
  361. }
  362. // Test max boundary by dimension
  363. for( unsigned int n = 0; n < 4; n++ )
  364. {
  365. typename IteratorType::IndexType boundaryLoc = centerLoc;
  366. boundaryLoc[n] = dims[n]-1;
  367. iib_it.SetLocation( boundaryLoc );
  368. if( iib_it.IndexInBounds( iib_it.Size()-1, internalIndex, resultOffset ) )
  369. {
  370. std::cerr << "IndexInBounds failed for max boundaryLoc: " << boundaryLoc << " and dimension: " << n << ". Expected false." << std::endl;
  371. result = EXIT_FAILURE;
  372. }
  373. }
  374. // Test center
  375. iib_it.SetLocation( centerLoc );
  376. inside = iib_it.IndexInBounds( 0, internalIndex, resultOffset );
  377. if( ! inside )
  378. {
  379. std::cerr << "IndexInBounds failed for index 0, expected true." << std::endl;
  380. result = EXIT_FAILURE;
  381. }
  382. return result;
  383. }
  384. int itkConstNeighborhoodIteratorWithOnlyIndexTest(int, char* [] )
  385. {
  386. std::cout << "*** Testing with itk::Image" << std::endl << std::endl;
  387. if( itkConstNeighborhoodIteratorWithOnlyIndexTestRun< itk::Image<char,4> >() == EXIT_FAILURE )
  388. {
  389. std::cerr << "XXX Failed with itk::Image XXX" << std::endl;
  390. return EXIT_FAILURE;
  391. }
  392. std::cout << std::endl << std::endl << "*** Testing with itk::ImageBase" << std::endl << std::endl;
  393. if ( itkConstNeighborhoodIteratorWithOnlyIndexTestRun< itk::ImageBase<4> >() == EXIT_FAILURE )
  394. {
  395. std::cerr << "XXX Failed with itk::ImageBase XXX" << std::endl;
  396. return EXIT_FAILURE;
  397. }
  398. return EXIT_SUCCESS;
  399. }