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