Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.