PageRenderTime 274ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/Modules/Registration/Common/test/itkCenteredTransformInitializerTest.cxx

https://github.com/chrismullins/ITK
C++ | 392 lines | 279 code | 81 blank | 32 comment | 11 complexity | cf75383b04b809c2f72d4e147aef1e28 MD5 | raw file
  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. #include "itkVersorRigid3DTransform.h"
  19. #include "itkCenteredTransformInitializer.h"
  20. #include "itkImageRegionIterator.h"
  21. namespace
  22. {
  23. const unsigned int Dimension = 3;
  24. // This function assumes that the center of mass of both images is the
  25. // geometrical center.
  26. template< typename TFixedImage, typename TMovingImage >
  27. bool RunTest(
  28. itk::SmartPointer< TFixedImage > fixedImage,
  29. itk::SmartPointer< TMovingImage > movingImage
  30. )
  31. {
  32. typedef TFixedImage FixedImageType;
  33. typedef TMovingImage MovingImageType;
  34. bool pass = true;
  35. // Transform Type
  36. typedef itk::VersorRigid3DTransform< double > TransformType;
  37. // calculate image centers
  38. TransformType::InputPointType fixedCenter;
  39. TransformType::InputPointType movingCenter;
  40. typedef itk::ContinuousIndex< double, Dimension > ContinuousIndexType;
  41. const typename FixedImageType::RegionType & fixedRegion = fixedImage->GetLargestPossibleRegion();
  42. const typename FixedImageType::SizeType & fixedSize = fixedRegion.GetSize();
  43. const typename FixedImageType::IndexType & fixedIndex = fixedRegion.GetIndex();
  44. ContinuousIndexType fixedCenterIndex;
  45. for ( unsigned int i=0; i<Dimension; i++ )
  46. {
  47. assert( 0 < fixedSize[i] );
  48. fixedCenterIndex[i] = static_cast< double >( fixedIndex[i] ) +
  49. static_cast< double >( fixedSize[i] - 1 ) / 2.0;
  50. }
  51. fixedImage->TransformContinuousIndexToPhysicalPoint( fixedCenterIndex, fixedCenter );
  52. const typename MovingImageType::RegionType & movingRegion = movingImage->GetLargestPossibleRegion();
  53. const typename MovingImageType::SizeType & movingSize = movingRegion.GetSize();
  54. const typename MovingImageType::IndexType & movingIndex = movingRegion.GetIndex();
  55. ContinuousIndexType movingCenterIndex;
  56. for ( unsigned int i=0; i<Dimension; i++ )
  57. {
  58. assert( 0 < movingSize[i] );
  59. movingCenterIndex[i] = static_cast< double >( movingIndex[i] ) +
  60. static_cast< double >( movingSize[i] - 1 ) / 2.0;
  61. }
  62. movingImage->TransformContinuousIndexToPhysicalPoint( movingCenterIndex, movingCenter );
  63. TransformType::InputVectorType relativeCenter = movingCenter - fixedCenter;
  64. TransformType::Pointer transform = TransformType::New();
  65. typedef itk::CenteredTransformInitializer<
  66. TransformType,
  67. FixedImageType,
  68. MovingImageType >
  69. InitializerType;
  70. typename InitializerType::Pointer initializer = InitializerType::New();
  71. initializer->SetFixedImage( fixedImage );
  72. initializer->SetMovingImage( movingImage );
  73. initializer->SetTransform( transform );
  74. transform->SetIdentity();
  75. initializer->GeometryOn();
  76. initializer->InitializeTransform();
  77. std::cout << std::endl << std::endl;
  78. std::cout << "Testing Geometric Mode " << std::endl;
  79. //transform->Print( std::cout );
  80. const TransformType::InputPointType & center1 = transform->GetCenter();
  81. const TransformType::OutputVectorType & translation1 = transform->GetTranslation();
  82. const TransformType::OffsetType & offset1 = transform->GetOffset();
  83. const double tolerance = 1e-3;
  84. // Verfications for the Geometry Mode
  85. for(unsigned int k=0; k < Dimension; k++ )
  86. {
  87. if( std::fabs( center1[k] - fixedCenter[k] ) > tolerance )
  88. {
  89. std::cerr << "Center differs from expected value" << std::endl;
  90. std::cerr << "It should be " << fixedCenter << std::endl;
  91. std::cerr << "but it is " << center1 << std::endl;
  92. pass = false;
  93. break;
  94. }
  95. if( std::fabs( translation1[k] - relativeCenter[k] ) > tolerance )
  96. {
  97. std::cerr << "Translation differs from expected value" << std::endl;
  98. std::cerr << "It should be " << relativeCenter << std::endl;
  99. std::cerr << "but it is " << translation1 << std::endl;
  100. pass = false;
  101. break;
  102. }
  103. if( std::fabs( offset1[k] - relativeCenter[k] ) > tolerance )
  104. {
  105. std::cerr << "Offset differs from expected value" << std::endl;
  106. std::cerr << "It should be " << relativeCenter << std::endl;
  107. std::cerr << "but it is " << offset1 << std::endl;
  108. pass = false;
  109. break;
  110. }
  111. }
  112. transform->SetIdentity();
  113. initializer->MomentsOn();
  114. initializer->InitializeTransform();
  115. std::cout << std::endl << std::endl;
  116. std::cout << "Testing Moments Mode " << std::endl;
  117. //transform->Print( std::cout );
  118. const TransformType::InputPointType & center2 = transform->GetCenter();
  119. const TransformType::OutputVectorType & translation2 = transform->GetTranslation();
  120. const TransformType::OffsetType & offset2 = transform->GetOffset();
  121. // Verfications for the Moments Mode
  122. for(unsigned int k=0; k < Dimension; k++ )
  123. {
  124. if( std::fabs( center2[k] - fixedCenter[k] ) > tolerance )
  125. {
  126. std::cerr << "Center differs from expected value" << std::endl;
  127. std::cerr << "It should be " << fixedCenter << std::endl;
  128. std::cerr << "but it is " << center2 << std::endl;
  129. pass = false;
  130. break;
  131. }
  132. if( std::fabs( translation2[k] - relativeCenter[k] ) > tolerance )
  133. {
  134. std::cerr << "Translation differs from expected value" << std::endl;
  135. std::cerr << "It should be " << relativeCenter << std::endl;
  136. std::cerr << "but it is " << translation2 << std::endl;
  137. pass = false;
  138. break;
  139. }
  140. if( std::fabs( offset2[k] - relativeCenter[k] ) > tolerance )
  141. {
  142. std::cerr << "Offset differs from expected value" << std::endl;
  143. std::cerr << "It should be " << relativeCenter << std::endl;
  144. std::cerr << "but it is " << offset2 << std::endl;
  145. pass = false;
  146. break;
  147. }
  148. }
  149. return pass;
  150. }
  151. template< typename TImage >
  152. void PopulateImage( itk::SmartPointer< TImage > image )
  153. {
  154. image->Allocate();
  155. image->FillBuffer( 0 );
  156. typedef TImage ImageType;
  157. typedef typename ImageType::RegionType RegionType;
  158. typedef typename ImageType::SizeType SizeType;
  159. typedef typename ImageType::IndexType IndexType;
  160. const RegionType & region = image->GetLargestPossibleRegion();
  161. const SizeType & size = region.GetSize();
  162. const IndexType & index = region.GetIndex();
  163. RegionType internalRegion;
  164. SizeType internalSize;
  165. IndexType internalIndex;
  166. const unsigned int border = 20;
  167. assert( 2 * border < size[0] );
  168. assert( 2 * border < size[1] );
  169. assert( 2 * border < size[2] );
  170. internalIndex[0] = index[0] + border;
  171. internalIndex[1] = index[1] + border;
  172. internalIndex[2] = index[2] + border;
  173. internalSize[0] = size[0] - 2 * border;
  174. internalSize[1] = size[1] - 2 * border;
  175. internalSize[2] = size[2] - 2 * border;
  176. internalRegion.SetSize( internalSize );
  177. internalRegion.SetIndex( internalIndex );
  178. typedef itk::ImageRegionIterator< ImageType > Iterator;
  179. Iterator it( image, internalRegion );
  180. it.GoToBegin();
  181. while( !it.IsAtEnd() )
  182. {
  183. it.Set( 200 );
  184. ++it;
  185. }
  186. }
  187. } // namespace
  188. /**
  189. * This program tests the use of the CenteredTransformInitializer class
  190. *
  191. *
  192. */
  193. int itkCenteredTransformInitializerTest(int , char* [] )
  194. {
  195. bool pass = true;
  196. std::cout << std::endl << std::endl;
  197. std::cout << "Running tests with itk::Image" << std::endl;
  198. {
  199. // Create Images
  200. typedef itk::Image<unsigned char, Dimension> FixedImageType;
  201. typedef itk::Image<unsigned char, Dimension> MovingImageType;
  202. typedef FixedImageType::SizeType SizeType;
  203. typedef FixedImageType::SpacingType SpacingType;
  204. typedef FixedImageType::PointType PointType;
  205. typedef FixedImageType::IndexType IndexType;
  206. typedef FixedImageType::RegionType RegionType;
  207. SizeType size;
  208. size[0] = 100;
  209. size[1] = 100;
  210. size[2] = 60;
  211. PointType fixedOrigin;
  212. fixedOrigin[0] = 0.0;
  213. fixedOrigin[1] = 0.0;
  214. fixedOrigin[2] = 0.0;
  215. PointType movingOrigin;
  216. movingOrigin[0] = 29.0;
  217. movingOrigin[1] = 17.0;
  218. movingOrigin[2] = 13.0;
  219. SpacingType spacing;
  220. spacing[0] = 1.5;
  221. spacing[1] = 1.5;
  222. spacing[2] = 2.5;
  223. IndexType index;
  224. index[0] = 0;
  225. index[1] = 0;
  226. index[2] = 0;
  227. RegionType region;
  228. region.SetSize( size );
  229. region.SetIndex( index );
  230. FixedImageType::Pointer fixedImage = FixedImageType::New();
  231. MovingImageType::Pointer movingImage = MovingImageType::New();
  232. fixedImage->SetRegions( region );
  233. fixedImage->SetSpacing( spacing );
  234. fixedImage->SetOrigin( fixedOrigin );
  235. movingImage->SetRegions( region );
  236. movingImage->SetSpacing( spacing );
  237. movingImage->SetOrigin( movingOrigin );
  238. PopulateImage( fixedImage );
  239. PopulateImage( movingImage );
  240. pass &= RunTest( fixedImage, movingImage );
  241. }
  242. std::cout << std::endl << std::endl;
  243. std::cout << "Running tests with itk::Image" << std::endl;
  244. {
  245. // Create Images
  246. typedef itk::Image<unsigned char, Dimension> FixedImageType;
  247. typedef itk::Image<unsigned char, Dimension> MovingImageType;
  248. typedef FixedImageType::SizeType SizeType;
  249. typedef FixedImageType::SpacingType SpacingType;
  250. typedef FixedImageType::PointType PointType;
  251. typedef FixedImageType::IndexType IndexType;
  252. typedef FixedImageType::RegionType RegionType;
  253. typedef FixedImageType::DirectionType DirectionType;
  254. SizeType size;
  255. size[0] = 100;
  256. size[1] = 100;
  257. size[2] = 60;
  258. PointType fixedOrigin;
  259. fixedOrigin[0] = 0.0;
  260. fixedOrigin[1] = 0.0;
  261. fixedOrigin[2] = 0.0;
  262. PointType movingOrigin;
  263. movingOrigin[0] = 29.0;
  264. movingOrigin[1] = 17.0;
  265. movingOrigin[2] = 13.0;
  266. SpacingType spacing;
  267. spacing[0] = 1.5;
  268. spacing[1] = 1.5;
  269. spacing[2] = 2.5;
  270. IndexType fixedIndex;
  271. fixedIndex[0] = 0;
  272. fixedIndex[1] = 0;
  273. fixedIndex[2] = 0;
  274. IndexType movingIndex;
  275. movingIndex[0] = 10;
  276. movingIndex[1] = 20;
  277. movingIndex[2] = 30;
  278. RegionType fixedRegion;
  279. fixedRegion.SetSize( size );
  280. fixedRegion.SetIndex( fixedIndex );
  281. RegionType movingRegion;
  282. movingRegion.SetSize( size );
  283. movingRegion.SetIndex( movingIndex );
  284. typedef itk::Versor< itk::SpacePrecisionType > VersorType;
  285. VersorType x; x.SetRotationAroundX( 0.5 );
  286. VersorType y; y.SetRotationAroundY( 1.0 );
  287. VersorType z; z.SetRotationAroundZ( 1.5 );
  288. DirectionType fixedDirection = (x*y*z).GetMatrix();
  289. DirectionType movingDirection = (z*y*x).GetMatrix();
  290. FixedImageType::Pointer fixedImage = FixedImageType::New();
  291. MovingImageType::Pointer movingImage = MovingImageType::New();
  292. fixedImage->SetRegions( fixedRegion );
  293. fixedImage->SetSpacing( spacing );
  294. fixedImage->SetOrigin( fixedOrigin );
  295. fixedImage->SetDirection( fixedDirection );
  296. movingImage->SetRegions( movingRegion );
  297. movingImage->SetSpacing( spacing );
  298. movingImage->SetOrigin( movingOrigin );
  299. movingImage->SetDirection( movingDirection );
  300. PopulateImage( fixedImage );
  301. PopulateImage( movingImage );
  302. pass &= RunTest( fixedImage, movingImage );
  303. }
  304. if( !pass )
  305. {
  306. std::cout << "Test FAILED." << std::endl;
  307. return EXIT_FAILURE;
  308. }
  309. std::cout << "Test PASSED." << std::endl;
  310. return EXIT_SUCCESS;
  311. }