Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
mitkImageDimensionConverterTest.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 // mitk includes
14 #include "mitkTestingConfig.h"
16 #include <mitkIOUtil.h>
17 #include <mitkImage.h>
18 #include <mitkImageCast.h>
19 #include <mitkImageDataItem.h>
21 #include <mitkInteractionConst.h>
22 #include <mitkPlaneOperation.h>
23 #include <mitkRotationOperation.h>
24 #include <mitkTestingMacros.h>
25 
26 // itk includes
27 #include <itkImage.h>
28 #include <itkMersenneTwisterRandomVariateGenerator.h>
29 
30 // stl includes
31 #include <fstream>
32 
33 // vtk includes
34 #include <vtkImageData.h>
35 
36 int mitkImageDimensionConverterTest(int /*argc*/, char * /*argv*/ [])
37 {
39 
40  // Define an epsilon which is the allowed error
41  float eps = 0.00001;
42 
43  // Define helper variables
44  float error = 0;
45  bool matrixIsEqual = true;
46  std::stringstream sstream;
48 
50  // Create 2D Image with a 3D rotation from scratch.
51  typedef itk::Image<double, 2> ImageType;
52  ImageType::Pointer itkImage = ImageType::New();
53  ImageType::RegionType myRegion;
54  ImageType::SizeType mySize;
55  ImageType::IndexType myIndex;
56  ImageType::SpacingType mySpacing;
57  mySpacing[0] = 1;
58  mySpacing[1] = 1;
59  myIndex[0] = 0;
60  myIndex[1] = 0;
61  mySize[0] = 50;
62  mySize[1] = 50;
63  myRegion.SetSize(mySize);
64  myRegion.SetIndex(myIndex);
65  itkImage->SetSpacing(mySpacing);
66  itkImage->SetRegions(myRegion);
67  itkImage->Allocate();
68  itkImage->FillBuffer(50);
69 
70  mitk::Image::Pointer mitkImage2D;
71  mitk::CastToMitkImage(itkImage, mitkImage2D);
72 
73  // rotate
74  mitk::Point3D p;
75  p[0] = 1;
76  p[1] = 3;
77  p[2] = 5;
79  v[0] = 0.3;
80  v[1] = 1;
81  v[2] = 0.1;
83  mitkImage2D->GetGeometry()->ExecuteOperation(&op);
84 
85  // Save original Geometry infos
86  mitk::Vector3D Original_col0, Original_col1, Original_col2;
87  Original_col0.SetVnlVector(
88  mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
89  Original_col1.SetVnlVector(
90  mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
91  Original_col2.SetVnlVector(
92  mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
93  MITK_INFO << "Rotated Matrix: " << Original_col0 << " " << Original_col1 << " " << Original_col2;
94 
95  mitk::Point3D Original_Origin = mitkImage2D->GetGeometry()->GetOrigin();
96  mitk::Vector3D Original_Spacing = mitkImage2D->GetGeometry()->GetSpacing();
97 
98  MITK_TEST_CONDITION_REQUIRED(mitkImage2D->GetDimension() == 2, "Created Image is Dimension 2");
99 
101  // mitkImage2D is now a 2D image with 3D Geometry information.
102  // Save it without conversion and load it again. It should have an identitiy matrix
103  sstream.clear();
104  sstream << MITK_TEST_OUTPUT_DIR << ""
105  << "/rotatedImage2D.nrrd";
106  mitk::IOUtil::Save(mitkImage2D, sstream.str());
107 
108  mitk::Image::Pointer imageLoaded2D = mitk::IOUtil::Load<mitk::Image>(sstream.str());
109 
110  // check if image can be loaded
111  MITK_TEST_CONDITION_REQUIRED(imageLoaded2D.IsNotNull(), "Loading saved 2D Image");
112 
113  MITK_TEST_CONDITION_REQUIRED(imageLoaded2D->GetDimension() == 2, "Loaded Image is Dimension 2");
114 
115  // check if spacing is ok
116  mitk::Vector3D Loaded2D_Spacing = imageLoaded2D->GetGeometry()->GetSpacing();
117 
118  error = std::fabs(Loaded2D_Spacing[0] - Original_Spacing[0]) + std::fabs(Loaded2D_Spacing[1] - Original_Spacing[1]) +
119  std::fabs(Loaded2D_Spacing[2] - 1);
120 
121  MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Spacing");
122 
123  // Check origin
124  mitk::Point3D Loaded2D_Origin = imageLoaded2D->GetGeometry()->GetOrigin();
125 
126  error = std::fabs(Loaded2D_Origin[0] - Original_Origin[0]) + std::fabs(Loaded2D_Origin[1] - Original_Origin[1]) +
127  std::fabs(Loaded2D_Origin[2] - 0);
128 
129  MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Origin");
130 
131  // Check matrix
132  mitk::Vector3D Loaded2D_col0, Loaded2D_col1, Loaded2D_col2;
133  Loaded2D_col0.SetVnlVector(
134  imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
135  Loaded2D_col1.SetVnlVector(
136  imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
137  Loaded2D_col2.SetVnlVector(
138  imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
139 
140  if ((std::fabs(1 - Loaded2D_col0[0]) > eps) || (std::fabs(0 - Loaded2D_col0[1]) > eps) ||
141  (std::fabs(0 - Loaded2D_col0[2]) > eps) || (std::fabs(0 - Loaded2D_col1[0]) > eps) ||
142  (std::fabs(1 - Loaded2D_col1[1]) > eps) || (std::fabs(0 - Loaded2D_col1[2]) > eps) ||
143  (std::fabs(0 - Loaded2D_col2[0]) > eps) || (std::fabs(0 - Loaded2D_col2[1]) > eps) ||
144  (std::fabs(1 - Loaded2D_col2[2]) > eps))
145  {
146  matrixIsEqual = false;
147  }
148  else
149  matrixIsEqual = true;
150 
151  MITK_TEST_CONDITION_REQUIRED(matrixIsEqual, "Compare Geometry: Matrix");
152 
154  // mitkImage2D is a 2D image with 3D Geometry information.
155  // Convert it with filter to a 3D image and check if everything went well
156  convertFilter->SetInput(mitkImage2D);
157  convertFilter->Update();
158  mitk::Image::Pointer mitkImage3D = convertFilter->GetOutput();
159 
160  MITK_TEST_CONDITION_REQUIRED(mitkImage3D->GetDimension() == 3, "Converted Image is Dimension 3");
161 
162  // check if geometry is still same
163  mitk::Vector3D Converted_Spacing = mitkImage3D->GetGeometry()->GetSpacing();
164 
165  error = std::fabs(Converted_Spacing[0] - Original_Spacing[0]) +
166  std::fabs(Converted_Spacing[1] - Original_Spacing[1]) + std::fabs(Converted_Spacing[2] - Original_Spacing[2]);
167 
168  MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Spacing");
169 
170  mitk::Point3D Converted_Origin = mitkImage3D->GetGeometry()->GetOrigin();
171 
172  error = std::fabs(Converted_Origin[0] - Original_Origin[0]) + std::fabs(Converted_Origin[1] - Original_Origin[1]) +
173  std::fabs(Converted_Origin[2] - Original_Origin[2]);
174 
175  MITK_INFO << Converted_Origin << " and " << Original_Origin;
176  MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Origin");
177 
178  mitk::Vector3D Converted_col0, Converted_col1, Converted_col2;
179  Converted_col0.SetVnlVector(
180  mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
181  Converted_col1.SetVnlVector(
182  mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
183  Converted_col2.SetVnlVector(
184  mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
185 
186  if ((std::fabs(Original_col0[0] - Converted_col0[0]) > eps) ||
187  (std::fabs(Original_col0[1] - Converted_col0[1]) > eps) ||
188  (std::fabs(Original_col0[2] - Converted_col0[2]) > eps) ||
189  (std::fabs(Original_col1[0] - Converted_col1[0]) > eps) ||
190  (std::fabs(Original_col1[1] - Converted_col1[1]) > eps) ||
191  (std::fabs(Original_col1[2] - Converted_col1[2]) > eps) ||
192  (std::fabs(Original_col2[0] - Converted_col2[0]) > eps) ||
193  (std::fabs(Original_col2[1] - Converted_col2[1]) > eps) ||
194  (std::fabs(Original_col2[2] - Converted_col2[2]) > eps))
195  {
196  MITK_INFO << "Oh No! Original Image Matrix and Converted Image Matrix are different!";
197  MITK_INFO << "original Image:" << Original_col0 << " " << Original_col1 << " " << Original_col2;
198  MITK_INFO << "converted Image:" << Converted_col0 << " " << Converted_col1 << " " << Converted_col2;
199  matrixIsEqual = false;
200  }
201  else
202  matrixIsEqual = true;
203 
204  MITK_TEST_CONDITION_REQUIRED(matrixIsEqual, "Compare Geometry: Matrix");
205 
207  // So far it seems good! now try to save and load the file
208 
209  std::stringstream sstream2;
210  sstream2 << MITK_TEST_OUTPUT_DIR << ""
211  << "/rotatedImage.nrrd";
212  mitk::IOUtil::Save(mitkImage3D, sstream2.str());
213  mitk::Image::Pointer imageLoaded = mitk::IOUtil::Load<mitk::Image>(sstream2.str());
214 
215  // check if image can be loaded
216  MITK_TEST_CONDITION_REQUIRED(imageLoaded.IsNotNull(), "Loading saved Image");
217 
218  // check if loaded image is still what it should be:
219  MITK_TEST_CONDITION_REQUIRED(imageLoaded->GetDimension() == 3, "Loaded Image is Dimension 3");
220 
221  // check if geometry is still same
222  mitk::Vector3D Loaded_Spacing = imageLoaded->GetGeometry()->GetSpacing();
223  error = std::fabs(Loaded_Spacing[0] - Original_Spacing[0]) + std::fabs(Loaded_Spacing[1] - Original_Spacing[1]) +
224  std::fabs(Loaded_Spacing[2] - Original_Spacing[2]);
225 
226  MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Spacing");
227 
228  mitk::Point3D Loaded_Origin = imageLoaded->GetGeometry()->GetOrigin();
229  error = std::fabs(Loaded_Origin[0] - Original_Origin[0]) + std::fabs(Loaded_Origin[1] - Original_Origin[1]) +
230  std::fabs(Loaded_Origin[2] - Original_Origin[2]);
231  MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Origin");
232 
233  mitk::Vector3D Loaded_col0, Loaded_col1, Loaded_col2;
234  Loaded_col0.SetVnlVector(
235  imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0));
236  Loaded_col1.SetVnlVector(
237  imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1));
238  Loaded_col2.SetVnlVector(
239  imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2));
240 
241  if ((std::fabs(Original_col0[0] - Loaded_col0[0]) > eps) || (std::fabs(Original_col0[1] - Loaded_col0[1]) > eps) ||
242  (std::fabs(Original_col0[2] - Loaded_col0[2]) > eps) || (std::fabs(Original_col1[0] - Loaded_col1[0]) > eps) ||
243  (std::fabs(Original_col1[1] - Loaded_col1[1]) > eps) || (std::fabs(Original_col1[2] - Loaded_col1[2]) > eps) ||
244  (std::fabs(Original_col2[0] - Loaded_col2[0]) > eps) || (std::fabs(Original_col2[1] - Loaded_col2[1]) > eps) ||
245  (std::fabs(Original_col2[2] - Loaded_col2[2]) > eps))
246  {
247  MITK_INFO << "Oh No! Original Image Matrix and Converted Image Matrix are different!";
248  MITK_INFO << "original Image:" << Original_col0 << " " << Original_col1 << " " << Original_col2;
249  MITK_INFO << "converted Image:" << Loaded_col0 << " " << Loaded_col1 << " " << Loaded_col2;
250  matrixIsEqual = false;
251  }
252  else
253  matrixIsEqual = true;
254 
255  MITK_TEST_CONDITION_REQUIRED(matrixIsEqual, "Compare Geometry: Matrix");
256 
257  return 0;
258 
259  MITK_TEST_END();
260 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
itk::Image< unsigned char, 3 > ImageType
#define MITK_TEST_CONDITION_REQUIRED(COND, MSG)
section GeneralTestsDeprecatedOldTestingStyle Deprecated macros All tests with MITK_TEST_BEGIN()
Constants for most interaction classes, due to the generic StateMachines.
#define MITK_TEST_OUTPUT_DIR
int mitkImageDimensionConverterTest(int, char *[])
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:74
static void Save(const mitk::BaseData *data, const std::string &path, bool setPathProperty=false)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:774
MITKCORE_EXPORT const ScalarType eps
and MITK_TEST_END()
Operation, that holds everything necessary for an rotation operation on mitk::BaseData.