Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkGeometry3DTest.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkGeometry3D.h"
18 
19 #include <vnl/vnl_quaternion.h>
20 #include <vnl/vnl_quaternion.txx>
21 
22 #include "mitkInteractionConst.h"
23 #include "mitkRotationOperation.h"
24 #include <mitkImageCast.h>
25 #include <mitkMatrixConvert.h>
26 
27 #include "mitkTestingMacros.h"
28 #include <fstream>
29 #include <mitkNumericTypes.h>
30 
32 {
33  int direction;
34  for (direction = 0; direction < 3; ++direction)
35  {
36  mitk::Vector3D frontToBack(0.);
37  switch (direction)
38  {
39  case 0:
40  frontToBack = geometry->GetCornerPoint(false, false, false) - geometry->GetCornerPoint(true, false, false);
41  break; // 7-3
42  case 1:
43  frontToBack = geometry->GetCornerPoint(false, false, false) - geometry->GetCornerPoint(false, true, false);
44  break; // 7-5
45  case 2:
46  frontToBack = geometry->GetCornerPoint(false, false, false) - geometry->GetCornerPoint(false, false, true);
47  break; // 7-2
48  }
49  std::cout << "Testing GetAxisVector(int) vs GetAxisVector(bool, bool, bool): ";
50  if (mitk::Equal(geometry->GetAxisVector(direction), frontToBack) == false)
51  {
52  std::cout << "[FAILED]" << std::endl;
53  return false;
54  }
55  std::cout << "[PASSED]" << std::endl;
56  }
57  return true;
58 }
59 
61 {
62  int direction;
63  for (direction = 0; direction < 3; ++direction)
64  {
65  if (mitk::Equal(geometry->GetAxisVector(direction).GetNorm(), geometry->GetExtentInMM(direction)) == false)
66  {
67  std::cout << "[FAILED]" << std::endl;
68  return false;
69  }
70  std::cout << "[PASSED]" << std::endl;
71  }
72  return true;
73 }
74 
75 // a part of the test requires axis-parallel coordinates
77 {
78  MITK_TEST_OUTPUT(<< "Testing consistency of index and world coordinate systems: ");
79  mitk::Point3D origin = geometry3d->GetOrigin();
80  mitk::Point3D dummy;
81 
82  MITK_TEST_OUTPUT(<< " Testing index->world->index conversion consistency");
83  geometry3d->WorldToIndex(origin, dummy);
84  geometry3d->IndexToWorld(dummy, dummy);
85  MITK_TEST_CONDITION_REQUIRED(dummy == origin, "");
86 
87  MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin, mitk::Point3D)==(0,0,0)");
88  mitk::Point3D globalOrigin;
89  mitk::FillVector3D(globalOrigin, 0, 0, 0);
90 
91  mitk::Point3D originContinuousIndex;
92  geometry3d->WorldToIndex(origin, originContinuousIndex);
93  MITK_TEST_CONDITION_REQUIRED(originContinuousIndex == globalOrigin, "");
94 
95  MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin, itk::Index)==(0,0,0)");
96  itk::Index<3> itkindex;
97  geometry3d->WorldToIndex(origin, itkindex);
98  itk::Index<3> globalOriginIndex;
99  mitk::vtk2itk(globalOrigin, globalOriginIndex);
100  MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
101 
102  MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin-0.5*spacing, itk::Index)==(0,0,0)");
103  mitk::Vector3D halfSpacingStep = geometry3d->GetSpacing() * 0.5;
105  mitk::Point3D originOffCenter = origin - halfSpacingStep;
106  geometry3d->WorldToIndex(originOffCenter, itkindex);
107  MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
108 
109  MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)");
110  originOffCenter = origin + halfSpacingStep;
111  originOffCenter -= 0.0001;
112  geometry3d->WorldToIndex(originOffCenter, itkindex);
113  MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
114 
115  MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)");
116  originOffCenter = origin + halfSpacingStep;
117  itk::Index<3> global111;
118  mitk::FillVector3D(global111, 1, 1, 1);
119  geometry3d->WorldToIndex(originOffCenter, itkindex);
120  MITK_TEST_CONDITION_REQUIRED(itkindex == global111, "");
121 
122  MITK_TEST_OUTPUT(<< " Testing WorldToIndex(GetCenter())==BoundingBox.GetCenter: ");
123  mitk::Point3D center = geometry3d->GetCenter();
124  mitk::Point3D centerContIndex;
125  geometry3d->WorldToIndex(center, centerContIndex);
126  mitk::BoundingBox::ConstPointer boundingBox = geometry3d->GetBoundingBox();
127  mitk::BoundingBox::PointType centerBounds = boundingBox->GetCenter();
128  // itk assumes corner based geometry. If our geometry is center based (imageGoe == true), everything needs to be
129  // shifted
130  if (geometry3d->GetImageGeometry())
131  {
132  centerBounds[0] -= 0.5;
133  centerBounds[1] -= 0.5;
134  centerBounds[2] -= 0.5;
135  }
136  MITK_TEST_CONDITION_REQUIRED(mitk::Equal(centerContIndex, centerBounds), "");
137 
138  MITK_TEST_OUTPUT(<< " Testing GetCenter()==IndexToWorld(BoundingBox.GetCenter): ");
139  center = geometry3d->GetCenter();
140  mitk::Point3D centerBoundsInWorldCoords;
141  geometry3d->IndexToWorld(centerBounds, centerBoundsInWorldCoords);
142  MITK_TEST_CONDITION_REQUIRED(mitk::Equal(center, centerBoundsInWorldCoords), "");
143 
144  return EXIT_SUCCESS;
145 }
146 
148 {
149  MITK_TEST_OUTPUT(<< "Testing consistency of index and world coordinate systems for vectors: ");
150  mitk::Vector3D xAxisMM = geometry3d->GetAxisVector(0);
151  mitk::Vector3D xAxisContinuousIndex;
152  mitk::Vector3D xAxisContinuousIndexDeprecated;
153 
154  mitk::Point3D p, pIndex, origin;
155  origin = geometry3d->GetOrigin();
156  p[0] = xAxisMM[0];
157  p[1] = xAxisMM[1];
158  p[2] = xAxisMM[2];
159 
160  geometry3d->WorldToIndex(p, pIndex);
161 
162  geometry3d->WorldToIndex(xAxisMM, xAxisContinuousIndexDeprecated);
163  geometry3d->WorldToIndex(xAxisMM, xAxisContinuousIndex);
164  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == pIndex[0], "");
165  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == pIndex[1], "");
166  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == pIndex[2], "");
167 
168  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == xAxisContinuousIndexDeprecated[0], "");
169  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == xAxisContinuousIndexDeprecated[1], "");
170  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == xAxisContinuousIndexDeprecated[2], "");
171 
172  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[0] == pIndex[0], "");
173  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[1] == pIndex[1], "");
174  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[2] == pIndex[2], "");
175 
176  geometry3d->IndexToWorld(xAxisContinuousIndex, xAxisContinuousIndex);
177  geometry3d->IndexToWorld(xAxisContinuousIndexDeprecated, xAxisContinuousIndexDeprecated);
178  geometry3d->IndexToWorld(pIndex, p);
179 
180  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex == xAxisMM, "");
181  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == p[0], "");
182  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == p[1], "");
183  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == p[2], "");
184 
185  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated == xAxisMM, "");
186  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[0] == p[0], "");
187  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[1] == p[1], "");
188  MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[2] == p[2], "");
189 
190  return EXIT_SUCCESS;
191 }
192 
194 {
195  MITK_TEST_OUTPUT(<< "Testing consistency of index and world coordinate systems: ");
196 
197  // creating testing data
198  itk::Index<4> itkIndex4, itkIndex4b;
199  itk::Index<3> itkIndex3, itkIndex3b;
200  itk::Index<2> itkIndex2, itkIndex2b;
201  itk::Index<3> mitkIndex, mitkIndexb;
202 
203  itkIndex4[0] = itkIndex4[1] = itkIndex4[2] = itkIndex4[3] = 4;
204  itkIndex3[0] = itkIndex3[1] = itkIndex3[2] = 6;
205  itkIndex2[0] = itkIndex2[1] = 2;
206  mitkIndex[0] = mitkIndex[1] = mitkIndex[2] = 13;
207 
208  // check for constistency
209  mitk::Point3D point;
210  geometry3d->IndexToWorld(itkIndex2, point);
211  geometry3d->WorldToIndex(point, itkIndex2b);
212 
213  MITK_TEST_CONDITION_REQUIRED(((itkIndex2b[0] == itkIndex2[0]) && (itkIndex2b[1] == itkIndex2[1])),
214  "Testing itk::index<2> for IndexToWorld/WorldToIndex consistency");
215 
216  geometry3d->IndexToWorld(itkIndex3, point);
217  geometry3d->WorldToIndex(point, itkIndex3b);
218 
220  ((itkIndex3b[0] == itkIndex3[0]) && (itkIndex3b[1] == itkIndex3[1]) && (itkIndex3b[2] == itkIndex3[2])),
221  "Testing itk::index<3> for IndexToWorld/WorldToIndex consistency");
222 
223  geometry3d->IndexToWorld(itkIndex4, point);
224  geometry3d->WorldToIndex(point, itkIndex4b);
225 
226  MITK_TEST_CONDITION_REQUIRED(((itkIndex4b[0] == itkIndex4[0]) && (itkIndex4b[1] == itkIndex4[1]) &&
227  (itkIndex4b[2] == itkIndex4[2]) && (itkIndex4b[3] == 0)),
228  "Testing itk::index<3> for IndexToWorld/WorldToIndex consistency");
229 
230  geometry3d->IndexToWorld(mitkIndex, point);
231  geometry3d->WorldToIndex(point, mitkIndexb);
232 
234  ((mitkIndexb[0] == mitkIndex[0]) && (mitkIndexb[1] == mitkIndex[1]) && (mitkIndexb[2] == mitkIndex[2])),
235  "Testing mitk::Index for IndexToWorld/WorldToIndex consistency");
236 
237  return EXIT_SUCCESS;
238 }
239 
240 #include <itkImage.h>
241 
243 {
244  MITK_TEST_OUTPUT(<< "Testing whether itk::Image coordinates are center-based.");
245  typedef itk::Image<int, 3> ItkIntImage3D;
247  ItkIntImage3D::SizeType size;
248  size.Fill(10);
249  mitk::Point3D origin;
250  mitk::FillVector3D(origin, 2, 3, 7);
251  itkintimage->Initialize();
252  itkintimage->SetRegions(size);
253  itkintimage->SetOrigin(origin);
254  std::cout << "[PASSED]" << std::endl;
255 
256  MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToContinuousIndex(origin)==(0,0,0)");
257  mitk::Point3D globalOrigin;
258  mitk::FillVector3D(globalOrigin, 0, 0, 0);
259 
260  itk::ContinuousIndex<mitk::ScalarType, 3> originContinuousIndex;
261  itkintimage->TransformPhysicalPointToContinuousIndex(origin, originContinuousIndex);
262  MITK_TEST_CONDITION_REQUIRED(originContinuousIndex == globalOrigin, "");
263 
264  MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToIndex(origin)==(0,0,0)");
265  itk::Index<3> itkindex;
266  itkintimage->TransformPhysicalPointToIndex(origin, itkindex);
267  itk::Index<3> globalOriginIndex;
268  mitk::vtk2itk(globalOrigin, globalOriginIndex);
269  MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
270 
271  MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToIndex(origin-0.5*spacing)==(0,0,0)");
272  mitk::Vector3D halfSpacingStep = itkintimage->GetSpacing() * 0.5;
274  mitk::Point3D originOffCenter = origin - halfSpacingStep;
275  itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex);
276  MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
277 
279  << " Testing itk::Image::TransformPhysicalPointToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)");
280  originOffCenter = origin + halfSpacingStep;
281  originOffCenter -= 0.0001;
282  itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex);
283  MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
284 
285  MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)");
286  originOffCenter = origin + halfSpacingStep;
287  itk::Index<3> global111;
288  mitk::FillVector3D(global111, 1, 1, 1);
289  itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex);
290  MITK_TEST_CONDITION_REQUIRED(itkindex == global111, "");
291 
292  MITK_TEST_OUTPUT(<< "=> Yes, itk::Image coordinates are center-based.");
293 
294  return EXIT_SUCCESS;
295 }
296 
297 int testGeometry3D(bool imageGeometry)
298 {
299  // Build up a new image Geometry
301  float bounds[] = {-10.0, 17.0, -12.0, 188.0, 13.0, 211.0};
302 
303  MITK_TEST_OUTPUT(<< "Initializing");
304  geometry3d->Initialize();
305 
306  MITK_TEST_OUTPUT(<< "Setting ImageGeometry to " << imageGeometry);
307  geometry3d->SetImageGeometry(imageGeometry);
308 
309  MITK_TEST_OUTPUT(<< "Setting bounds by SetFloatBounds(): " << bounds);
310  geometry3d->SetFloatBounds(bounds);
311 
312  MITK_TEST_OUTPUT(<< "Testing AxisVectors");
313  if (testGetAxisVectorVariants(geometry3d) == false)
314  return EXIT_FAILURE;
315 
316  if (testGetAxisVectorExtent(geometry3d) == false)
317  return EXIT_FAILURE;
318 
319  MITK_TEST_OUTPUT(<< "Creating an AffineTransform3D transform");
320  mitk::AffineTransform3D::MatrixType matrix;
321  matrix.SetIdentity();
322  matrix(1, 1) = 2;
324  transform = mitk::AffineTransform3D::New();
325  transform->SetMatrix(matrix);
326 
327  MITK_TEST_OUTPUT(<< "Testing a SetIndexToWorldTransform");
328  geometry3d->SetIndexToWorldTransform(transform);
329 
330  MITK_TEST_OUTPUT(<< "Testing correctness of value returned by GetSpacing");
331  const mitk::Vector3D &spacing1 = geometry3d->GetSpacing();
332  mitk::Vector3D expectedSpacing;
333  expectedSpacing.Fill(1.0);
334  expectedSpacing[1] = 2;
335  if (mitk::Equal(spacing1, expectedSpacing) == false)
336  {
337  MITK_TEST_OUTPUT(<< " [FAILED]");
338  return EXIT_FAILURE;
339  }
340 
341  MITK_TEST_OUTPUT(<< "Testing a Compose(transform)");
342  geometry3d->Compose(transform);
343 
344  MITK_TEST_OUTPUT(<< "Testing correctness of value returned by GetSpacing");
345  const mitk::Vector3D &spacing2 = geometry3d->GetSpacing();
346  expectedSpacing[1] = 4;
347  if (mitk::Equal(spacing2, expectedSpacing) == false)
348  {
349  MITK_TEST_OUTPUT(<< " [FAILED]");
350  return EXIT_FAILURE;
351  }
352 
353  MITK_TEST_OUTPUT(<< "Testing correctness of SetSpacing");
354  mitk::Vector3D newspacing;
355  mitk::FillVector3D(newspacing, 1.5, 2.5, 3.5);
356  geometry3d->SetSpacing(newspacing);
357  const mitk::Vector3D &spacing3 = geometry3d->GetSpacing();
358  if (mitk::Equal(spacing3, newspacing) == false)
359  {
360  MITK_TEST_OUTPUT(<< " [FAILED]");
361  return EXIT_FAILURE;
362  }
363 
364  // Seperate Test function for Index and World consistency
365  testIndexAndWorldConsistency(geometry3d);
368 
369  MITK_TEST_OUTPUT(<< "Testing a rotation of the geometry");
370  double angle = 35.0;
371  mitk::Vector3D rotationVector;
372  mitk::FillVector3D(rotationVector, 1, 0, 0);
373  mitk::Point3D center = geometry3d->GetCenter();
374  auto op = new mitk::RotationOperation(mitk::OpROTATE, center, rotationVector, angle);
375  geometry3d->ExecuteOperation(op);
376 
377  MITK_TEST_OUTPUT(<< "Testing mitk::GetRotation() and success of rotation");
379  mitk::GetRotation(geometry3d, rotation);
380  mitk::Vector3D voxelStep = rotation * newspacing;
381  mitk::Vector3D voxelStepIndex;
382  geometry3d->WorldToIndex(voxelStep, voxelStepIndex);
383  mitk::Vector3D expectedVoxelStepIndex;
384  expectedVoxelStepIndex.Fill(1);
385  MITK_TEST_CONDITION_REQUIRED(mitk::Equal(voxelStepIndex, expectedVoxelStepIndex), "");
386  delete op;
387  std::cout << "[PASSED]" << std::endl;
388 
389  MITK_TEST_OUTPUT(<< "Testing that ImageGeometry is still " << imageGeometry);
390  MITK_TEST_CONDITION_REQUIRED(geometry3d->GetImageGeometry() == imageGeometry, "");
391 
392  // Test if the translate function moves the origin correctly.
393  mitk::Point3D oldOrigin = geometry3d->GetOrigin();
394 
395  // use some random values for translation
396  mitk::Vector3D translationVector;
397  translationVector.SetElement(0, 17.5f);
398  translationVector.SetElement(1, -32.3f);
399  translationVector.SetElement(2, 4.0f);
400  // compute ground truth
401  mitk::Point3D tmpResult = geometry3d->GetOrigin() + translationVector;
402  geometry3d->Translate(translationVector);
403  MITK_TEST_CONDITION(mitk::Equal(geometry3d->GetOrigin(), tmpResult), "Testing if origin was translated.");
404 
405  translationVector *= -1; // vice versa
406  geometry3d->Translate(translationVector);
407 
408  MITK_TEST_CONDITION(mitk::Equal(geometry3d->GetOrigin(), oldOrigin),
409  "Testing if the translation could be done vice versa.");
410 
411  return EXIT_SUCCESS;
412 }
413 
415 {
416  // Epsilon. Allowed difference for rotationvalue
417  float eps = 0.0001;
418 
419  // Cast ITK and MITK images and see if geometry stays
420  typedef itk::Image<double, 2> Image2DType;
421  typedef itk::Image<double, 3> Image3DType;
422 
423  // Create 3D ITK Image from Scratch, cast to 3D MITK image, compare Geometries
424  Image3DType::Pointer image3DItk = Image3DType::New();
425  Image3DType::RegionType myRegion;
426  Image3DType::SizeType mySize;
427  Image3DType::IndexType myIndex;
428  Image3DType::SpacingType mySpacing;
429  Image3DType::DirectionType myDirection, rotMatrixX, rotMatrixY, rotMatrixZ;
430  mySpacing[0] = 31;
431  mySpacing[1] = 0.1;
432  mySpacing[2] = 2.9;
433  myIndex[0] = -15;
434  myIndex[1] = 15;
435  myIndex[2] = 12;
436  mySize[0] = 10;
437  mySize[1] = 2;
438  mySize[2] = 555;
439  myRegion.SetSize(mySize);
440  myRegion.SetIndex(myIndex);
441  image3DItk->SetSpacing(mySpacing);
442  image3DItk->SetRegions(myRegion);
443  image3DItk->Allocate();
444  image3DItk->FillBuffer(0);
445 
446  myDirection.SetIdentity();
447  rotMatrixX.SetIdentity();
448  rotMatrixY.SetIdentity();
449  rotMatrixZ.SetIdentity();
450 
451  mitk::Image::Pointer mitkImage;
452 
453  // direction [row] [coloum]
454  MITK_TEST_OUTPUT(<< "Casting a rotated 3D ITK Image to a MITK Image and check if Geometry is still same");
455  for (double rotX = 0; rotX < (itk::Math::pi * 2); rotX += 0.4)
456  {
457  // Set Rotation X
458  rotMatrixX[1][1] = cos(rotX);
459  rotMatrixX[1][2] = -sin(rotX);
460  rotMatrixX[2][1] = sin(rotX);
461  rotMatrixX[2][2] = cos(rotX);
462 
463  for (double rotY = 0; rotY < (itk::Math::pi * 2); rotY += 0.33)
464  {
465  // Set Rotation Y
466  rotMatrixY[0][0] = cos(rotY);
467  rotMatrixY[0][2] = sin(rotY);
468  rotMatrixY[2][0] = -sin(rotY);
469  rotMatrixY[2][2] = cos(rotY);
470 
471  for (double rotZ = 0; rotZ < (itk::Math::pi * 2); rotZ += 0.5)
472  {
473  // Set Rotation Z
474  rotMatrixZ[0][0] = cos(rotZ);
475  rotMatrixZ[0][1] = -sin(rotZ);
476  rotMatrixZ[1][0] = sin(rotZ);
477  rotMatrixZ[1][1] = cos(rotZ);
478 
479  // Multiply matrizes
480  myDirection = myDirection * rotMatrixX * rotMatrixY * rotMatrixZ;
481  image3DItk->SetDirection(myDirection);
482  mitk::CastToMitkImage(image3DItk, mitkImage);
483  const mitk::AffineTransform3D::MatrixType &matrix =
484  mitkImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix();
485 
486  for (int row = 0; row < 3; row++)
487  {
488  for (int col = 0; col < 3; col++)
489  {
490  double mitkValue = matrix[row][col] / mitkImage->GetGeometry()->GetSpacing()[col];
491  double itkValue = myDirection[row][col];
492  double diff = mitkValue - itkValue;
493  // if you decrease this value, you can see that there might be QUITE high inaccuracy!!!
494  if (diff > eps) // need to check, how exact it SHOULD be .. since it is NOT EXACT!
495  {
496  std::cout << "Had a difference of : " << diff;
497  std::cout << "Error: Casting altered Geometry!";
498  std::cout << "ITK Matrix:\n" << myDirection;
499  std::cout << "Mitk Matrix (With Spacing):\n" << matrix;
500  std::cout << "Mitk Spacing: " << mitkImage->GetGeometry()->GetSpacing();
501  MITK_TEST_CONDITION_REQUIRED(false == true, "");
502  return false;
503  }
504  }
505  }
506  }
507  }
508  }
509 
510  // Create 2D ITK Image from Scratch, cast to 2D MITK image, compare Geometries
511  Image2DType::Pointer image2DItk = Image2DType::New();
512  Image2DType::RegionType myRegion2D;
513  Image2DType::SizeType mySize2D;
514  Image2DType::IndexType myIndex2D;
515  Image2DType::SpacingType mySpacing2D;
516  Image2DType::DirectionType myDirection2D, rotMatrix;
517  mySpacing2D[0] = 31;
518  mySpacing2D[1] = 0.1;
519  myIndex2D[0] = -15;
520  myIndex2D[1] = 15;
521  mySize2D[0] = 10;
522  mySize2D[1] = 2;
523  myRegion2D.SetSize(mySize2D);
524  myRegion2D.SetIndex(myIndex2D);
525  image2DItk->SetSpacing(mySpacing2D);
526  image2DItk->SetRegions(myRegion2D);
527  image2DItk->Allocate();
528  image2DItk->FillBuffer(0);
529 
530  myDirection2D.SetIdentity();
531  rotMatrix.SetIdentity();
532 
533  // direction [row] [coloum]
534  MITK_TEST_OUTPUT(<< "Casting a rotated 2D ITK Image to a MITK Image and check if Geometry is still same");
535  for (double rotTheta = 0; rotTheta < (itk::Math::pi * 2); rotTheta += 0.1)
536  {
537  // Set Rotation
538  rotMatrix[0][0] = cos(rotTheta);
539  rotMatrix[0][1] = -sin(rotTheta);
540  rotMatrix[1][0] = sin(rotTheta);
541  rotMatrix[1][1] = cos(rotTheta);
542 
543  // Multiply matrizes
544  myDirection2D = myDirection2D * rotMatrix;
545  image2DItk->SetDirection(myDirection2D);
546  mitk::CastToMitkImage(image2DItk, mitkImage);
547  const mitk::AffineTransform3D::MatrixType &matrix =
548  mitkImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix();
549 
550  // Compare MITK and ITK matrix
551  for (int row = 0; row < 3; row++)
552  {
553  for (int col = 0; col < 3; col++)
554  {
555  double mitkValue = matrix[row][col] / mitkImage->GetGeometry()->GetSpacing()[col];
556  if ((row == 2) && (col == row))
557  {
558  if (mitkValue != 1)
559  {
560  MITK_TEST_OUTPUT(<< "After casting a 2D ITK to 3D MITK images, MITK matrix values for 0|2, 1|2, 2|0, 2|1 "
561  "MUST be 0 and value for 2|2 must be 1");
562  return false;
563  }
564  }
565  else if ((row == 2) || (col == 2))
566  {
567  if (mitkValue != 0)
568  {
569  MITK_TEST_OUTPUT(<< "After casting a 2D ITK to 3D MITK images, MITK matrix values for 0|2, 1|2, 2|0, 2|1 "
570  "MUST be 0 and value for 2|2 must be 1");
571  return false;
572  }
573  }
574  else
575  {
576  double itkValue = myDirection2D[row][col];
577  double diff = mitkValue - itkValue;
578  // if you decrease this value, you can see that there might be QUITE high inaccuracy!!!
579  if (diff > eps) // need to check, how exact it SHOULD be .. since it is NOT EXACT!
580  {
581  std::cout << "Had a difference of : " << diff;
582  std::cout << "Error: Casting altered Geometry!";
583  std::cout << "ITK Matrix:\n" << myDirection2D;
584  std::cout << "Mitk Matrix (With Spacing):\n" << matrix;
585  std::cout << "Mitk Spacing: " << mitkImage->GetGeometry()->GetSpacing();
586  MITK_TEST_CONDITION_REQUIRED(false == true, "");
587  return false;
588  }
589  }
590  }
591  }
592  }
593 
594  // THIS WAS TESTED:
595  // 2D ITK -> 2D MITK,
596  // 3D ITK -> 3D MITK,
597 
598  // Still need to test: 2D MITK Image with ADDITIONAL INFORMATION IN MATRIX -> 2D ITK
599  // 1. Possibility: 3x3 MITK matrix can be converted without loss into 2x2 ITK matrix
600  // 2. Possibility: 3x3 MITK matrix can only be converted with loss into 2x2 ITK matrix
601  // .. before implementing this, we wait for further development in geometry classes (e.g. Geoemtry3D::SetRotation(..))
602 
603  return EXIT_SUCCESS;
604 }
605 
606 int mitkGeometry3DTest(int /*argc*/, char * /*argv*/ [])
607 {
609 
610  int result;
611 
612  MITK_TEST_CONDITION_REQUIRED((result = testItkImageIsCenterBased()) == EXIT_SUCCESS, "");
613 
614  MITK_TEST_OUTPUT(<< "Running main part of test with ImageGeometry = false");
615  MITK_TEST_CONDITION_REQUIRED((result = testGeometry3D(false)) == EXIT_SUCCESS, "");
616 
617  MITK_TEST_OUTPUT(<< "Running main part of test with ImageGeometry = true");
618  MITK_TEST_CONDITION_REQUIRED((result = testGeometry3D(true)) == EXIT_SUCCESS, "");
619 
620  MITK_TEST_OUTPUT(<< "Running test to see if Casting MITK to ITK and the other way around destroys geometry");
621  MITK_TEST_CONDITION_REQUIRED((result = testGeometryAfterCasting()) == EXIT_SUCCESS, "");
622 
623  MITK_TEST_END();
624 
625  return EXIT_SUCCESS;
626 }
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
bool testGetAxisVectorVariants(mitk::Geometry3D *geometry)
mitk::Point3D PointType
itk::SmartPointer< Self > Pointer
Standard implementation of BaseGeometry.
void GetRotation(const mitk::BaseGeometry *geometry, TMatrixType &itkmatrix)
int mitkGeometry3DTest(int, char *[])
#define MITK_TEST_CONDITION_REQUIRED(COND, MSG)
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
section GeneralTestsDeprecatedOldTestingStyle Deprecated macros All tests with MITK_TEST_BEGIN()
static Pointer New()
Constants for most interaction classes, due to the generic StateMachines.
int testIndexAndWorldConsistencyForVectors(mitk::Geometry3D *geometry3d)
static Matrix3D rotation
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:110
itk::SmartPointer< const Self > ConstPointer
int testItkImageIsCenterBased()
int testGeometry3D(bool imageGeometry)
#define MITK_TEST_OUTPUT(x)
Output some text.
Vector3D GetAxisVector(unsigned int direction) const
Get vector along bounding-box in the specified direction in mm.
#define MITK_TEST_CONDITION(COND, MSG)
void vtk2itk(const Tin &in, Tout &out)
bool testGetAxisVectorExtent(mitk::Geometry3D *geometry)
Point3D GetCenter() const
Get the center of the bounding-box in mm.
Point3D GetCornerPoint(int id) const
Get the position of the corner number id (in world coordinates)
int testIndexAndWorldConsistencyForIndex(mitk::Geometry3D *geometry3d)
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:78
void IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
Convert (continuous or discrete) index coordinates of a vector vec_units to world coordinates (in mm)...
MITKCORE_EXPORT const ScalarType eps
int testIndexAndWorldConsistency(mitk::Geometry3D *geometry3d)
and MITK_TEST_END()
Operation, that holds everything necessary for an rotation operation on mitk::BaseData.
ScalarType GetExtentInMM(int direction) const
Get the extent of the bounding-box in the specified direction in mm.
virtual bool GetImageGeometry() const
Is this an ImageGeometry?
int testGeometryAfterCasting()
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
virtual const BoundingBoxType * GetBoundingBox()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.