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
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.