diff --git a/Core/Code/DataManagement/mitkVector.h b/Core/Code/DataManagement/mitkVector.h index d523b7077f..295f9faa91 100644 --- a/Core/Code/DataManagement/mitkVector.h +++ b/Core/Code/DataManagement/mitkVector.h @@ -1,355 +1,436 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKVECTOR_H_HEADER_INCLUDED_C1EBD0AD #define MITKVECTOR_H_HEADER_INCLUDED_C1EBD0AD #include #include #include #include #include #include #include #include #include "mitkCommon.h" #ifndef DOXYGEN_SKIP namespace mitk { typedef float ScalarType; typedef itk::Matrix Matrix3D; typedef itk::Matrix Matrix4D; typedef vnl_matrix_fixed VnlMatrix3D; typedef itk::Transform Transform3D; typedef vnl_vector VnlVector; typedef vnl_vector_ref VnlVectorRef; typedef itk::Point Point2D; typedef itk::Point Point3D; typedef itk::Point Point4D; typedef itk::Point Point2I; typedef itk::Point Point3I; typedef itk::Point Point4I; typedef itk::Vector Vector2D; typedef itk::Vector Vector3D; typedef itk::Index<3> Index3D; typedef itk::ContinuousIndex ContinuousIndex3D; typedef vnl_quaternion Quaternion; //##Documentation //##@brief enumeration of the type a point can be enum PointSpecificationType { PTUNDEFINED = 0, PTSTART, PTCORNER, PTEDGE, PTEND }; typedef itk::NumericTraits ScalarTypeNumericTraits; MITK_CORE_EXPORT extern const ScalarType eps; MITK_CORE_EXPORT extern const ScalarType sqrteps; MITK_CORE_EXPORT extern const double large; template class VectorTraits { public: typedef T ValueType; }; template <> class VectorTraits { public: typedef ScalarType ValueType; }; template<> class VectorTraits { public: typedef double ValueType; }; template<> class VectorTraits< itk::Index<5> > { public: typedef itk::Index<5>::IndexValueType ValueType; }; template<> class VectorTraits< itk::Index<3> > { public: typedef itk::Index<3>::IndexValueType ValueType; }; template<> class VectorTraits< long int [3]> { public: typedef long int ValueType; }; template<> class VectorTraits< float [3]> { public: typedef float ValueType; }; template<> class VectorTraits< double [3]> { public: typedef double ValueType; }; template<> class VectorTraits< vnl_vector_fixed > { public: typedef ScalarType ValueType; }; template<> class VectorTraits< long unsigned int[3]> { public: typedef long unsigned int ValueType; }; template<> class VectorTraits< unsigned int *> { public: typedef unsigned int ValueType; }; template<> class VectorTraits< ScalarType[4] > { public: typedef ScalarType ValueType; }; template<> class VectorTraits< itk::Vector > { public: typedef float ValueType; }; template<> class VectorTraits< itk::Point > { public: typedef float ValueType; }; template<> class VectorTraits< itk::Point > { public: typedef float ValueType; }; template<> class VectorTraits< itk::Vector > { public: typedef double ValueType; }; template<> class VectorTraits< itk::Point > { public: typedef double ValueType; }; template<> class VectorTraits< itk::Vector > { public: typedef int ValueType; }; template<> class VectorTraits< itk::Point > { public: typedef int ValueType; }; template inline void itk2vtk(const Tin& in, Tout& out) { out[0]=(typename VectorTraits::ValueType)(in[0]); out[1]=(typename VectorTraits::ValueType)(in[1]); out[2]=(typename VectorTraits::ValueType)(in[2]); } template inline void vtk2itk(const Tin& in, Tout& out) { out[0]=(typename VectorTraits::ValueType)(in[0]); out[1]=(typename VectorTraits::ValueType)(in[1]); out[2]=(typename VectorTraits::ValueType)(in[2]); } template inline void FillVector3D(Tout& out, ScalarType x, ScalarType y, ScalarType z) { out[0] = (typename VectorTraits::ValueType)x; out[1] = (typename VectorTraits::ValueType)y; out[2] = (typename VectorTraits::ValueType)z; } template inline void FillVector4D(Tout& out, ScalarType x, ScalarType y, ScalarType z, ScalarType t) { out[0] = (typename VectorTraits::ValueType)x; out[1] = (typename VectorTraits::ValueType)y; out[2] = (typename VectorTraits::ValueType)z; out[3] = (typename VectorTraits::ValueType)t; } template inline void vnl2vtk(const vnl_vector& in, Tout *out) { unsigned int i; for(i=0; i inline void vtk2vnl(const Tin *in, vnl_vector& out) { unsigned int i; for(i=0; i inline void vtk2vnlref(const Tin *in, vnl_vector_ref& out) { unsigned int i; for(i=0; i inline void vnl2vtk(const vnl_vector_fixed& in, Tout *out) { unsigned int i; for(i=0; i inline void vtk2vnl(const Tin *in, vnl_vector_fixed& out) { unsigned int i; for(i=0; i itk::Vector operator+(const itk::Vector &vector, const itk::Point &point) { itk::Vector sub; for( unsigned int i=0; i inline itk::Vector& operator+=(itk::Vector &vector, const itk::Point &point) { for( unsigned int i=0; i itk::Vector operator-(const itk::Vector &vector, const itk::Point &point) { itk::Vector sub; for( unsigned int i=0; i inline itk::Vector& operator-=(itk::Vector &vector, const itk::Point &point) { for( unsigned int i=0; i +inline bool MatrixEqualRMS(const vnl_matrix_fixed& matrix1,const vnl_matrix_fixed& matrix2,mitk::ScalarType epsilon=mitk::eps) +{ + if ( (matrix1.rows() == matrix2.rows()) && (matrix1.cols() == matrix2.cols()) ) + { + vnl_matrix_fixed differenceMatrix = matrix1-matrix2; + if (differenceMatrix.rms() +inline bool MatrixEqualRMS(const itk::Matrix& matrix1,const itk::Matrix& matrix2,mitk::ScalarType epsilon=mitk::eps) +{ + return mitk::MatrixEqualRMS(matrix1.GetVnlMatrix(),matrix2.GetVnlMatrix(),epsilon); +} + +/*! +\brief Check for element-wise matrix equality with a user defined accuracy. +\param matrix1 first vnl matrix +\param matrix2 second vnl matrix +\epsilon user defined accuracy bounds +*/ +template +inline bool MatrixEqualElementWise(const vnl_matrix_fixed& matrix1,const vnl_matrix_fixed& matrix2,mitk::ScalarType epsilon=mitk::eps) +{ + if ( (matrix1.rows() == matrix2.rows()) && (matrix1.cols() == matrix2.cols()) ) + { + for( unsigned int r=0; repsilon) + { + return false; + } + } + } + return true; + } + else + { + return false; + } +} + +/*! +\brief Check for element-wise matrix equality with a user defined accuracy. +\param matrix1 first itk matrix +\param matrix2 second itk matrix +\epsilon user defined accuracy bounds +*/ +template +inline bool MatrixEqualElementWise(const itk::Matrix& matrix1,const itk::Matrix& matrix2,mitk::ScalarType epsilon=mitk::eps) +{ + return mitk::MatrixEqualElementWise(matrix1.GetVnlMatrix(),matrix2.GetVnlMatrix(),epsilon); +} + template - inline bool Equal(const itk::Vector& vector1, const itk::Vector& vector2) +inline bool Equal(const itk::Vector& vector1, const itk::Vector& vector2) { typename itk::Vector::VectorType diff = vector1-vector2; return diff.GetSquaredNorm() < mitk::eps; } template inline bool Equal(const itk::Point& vector1, const itk::Point& vector2) { typename itk::Point::VectorType diff = vector1-vector2; return diff.GetSquaredNorm() < mitk::eps; } inline bool Equal(const mitk::VnlVector& vector1, const mitk::VnlVector& vector2) { mitk::VnlVector diff = vector1-vector2; return diff.squared_magnitude() < mitk::eps; } inline bool Equal(double scalar1, double scalar2) { return fabs(scalar1-scalar2) < mitk::eps; } template inline bool Equal(const vnl_vector_fixed & vector1, const vnl_vector_fixed& vector2) { vnl_vector_fixed diff = vector1-vector2; return diff.squared_magnitude() < mitk::eps; } template inline void TransferMatrix(const itk::Matrix& in, itk::Matrix& out) { for (unsigned int i = 0; i < in.RowDimensions; ++i) for (unsigned int j = 0; j < in.ColumnDimensions; ++j) out[i][j] = in[i][j]; } } // namespace mitk #endif //DOXYGEN_SKIP /* * This part of the code has been shifted here to avoid compiler clashes * caused by including before the declaration of * the Equal() methods above. This problem occurs when using MSVC and is * probably related to a compiler bug. */ #include namespace mitk { typedef itk::AffineGeometryFrame::TransformType AffineTransform3D; } #define mitkSetConstReferenceMacro(name,type) \ virtual void Set##name (const type & _arg) \ { \ itkDebugMacro("setting " << #name " to " << _arg ); \ if (this->m_##name != _arg) \ { \ this->m_##name = _arg; \ this->Modified(); \ } \ } #define mitkSetVectorMacro(name,type) \ mitkSetConstReferenceMacro(name,type) #define mitkGetVectorMacro(name,type) \ itkGetConstReferenceMacro(name,type) #endif /* MITKVECTOR_H_HEADER_INCLUDED_C1EBD0AD */ diff --git a/Core/Code/Testing/files.cmake b/Core/Code/Testing/files.cmake index f4d4aea409..0fae44fb29 100644 --- a/Core/Code/Testing/files.cmake +++ b/Core/Code/Testing/files.cmake @@ -1,91 +1,92 @@ # tests with no extra command line parameter SET(MODULE_TESTS mitkCoreObjectFactoryTest.cpp mitkPointSetWriterTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkEnumerationPropertyTest.cpp mitkEventTest.cpp mitkFocusManagerTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkGlobalInteractionTest.cpp mitkImageDataItemTest.cpp #mitkImageMapper2DTest.cpp mitkImageGeneratorTest.cpp mitkBaseDataTest.cpp #mitkImageToItkTest.cpp mitkInteractorTest.cpp mitkITKThreadingTest.cpp # mitkLevelWindowManagerTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp #mitkPipelineSmartPointerCorrectnessTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetTest.cpp mitkPointSetInteractorTest.cpp mitkPropertyListTest.cpp #mitkRegistrationBaseTest.cpp #mitkSegmentationInterpolationTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkStateMachineTest.cpp mitkStateTest.cpp mitkSurfaceTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeSlicedGeometryTest.cpp mitkTransitionTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp #mitkAbstractTransformGeometryTest.cpp #mitkPicFileIOTest.cpp mitkStepperTest.cpp itkTotalVariationDenoisingImageFilterTest.cpp mitkRenderingManagerTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp + mitkVectorTest.cpp ) # test with image filename as an extra command line parameter SET(MODULE_IMAGE_TESTS mitkSurfaceVtkWriterTest.cpp mitkPicFileWriterTest.cpp #mitkImageSliceSelectorTest.cpp mitkImageTimeSelectorTest.cpp mitkPicFileReaderTest.cpp # mitkVtkPropRendererTest.cpp mitkDataNodeFactoryTest.cpp #mitkSTLFileReaderTest.cpp ) # list of images for which the tests are run SET(MODULE_TESTIMAGES US4DCyl.pic.gz Pic3D.pic.gz Pic2DplusT.pic.gz BallBinary30x30x30.pic.gz binary.stl ball.stl ) SET(MODULE_CUSTOM_TESTS #mitkLabeledImageToSurfaceFilterTest.cpp #mitkExternalToolsTest.cpp mitkDataStorageTest.cpp mitkDataNodeTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkEventMapperTest.cpp mitkNodeDependentPointSetInteractorTest.cpp mitkStateMachineFactoryTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp mitkImageWriterTest.cpp ) diff --git a/Core/Code/Testing/mitkVectorTest.cpp b/Core/Code/Testing/mitkVectorTest.cpp new file mode 100644 index 0000000000..b4f15e05e6 --- /dev/null +++ b/Core/Code/Testing/mitkVectorTest.cpp @@ -0,0 +1,126 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include +#include + +int mitkVectorTest(int /*argc*/, char* /*argv*/[]) +{ + MITK_TEST_BEGIN("mitkVector"); + // test itk vector equality methods + itk::Vector itkVector_1; + itkVector_1[0] = 4.6; + itkVector_1[1] = 9.76543; + itkVector_1[2] = 746.09; + + itk::Vector itkVector_2; + itk::Vector itkVector_3; + for (int i=0; i<3; i++) + { + itkVector_2[i] = itkVector_1[i] - sqrt(mitk::eps/3); + itkVector_3[i] = itkVector_1[i] - sqrt(mitk::eps/3.1); + } + + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkVector_1,itkVector_1), "Test vector equality using the same vector with mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(itkVector_1,itkVector_2), "Test vector equality using different vectors with an element-wise difference greater than mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkVector_1,itkVector_3), "Test vector equality using different vectors with an element-wise difference less than mitk::eps"); + // test itk point equality methods + itk::Point itkPoint_1; + itk::Point itkPoint_2; + itk::Point itkPoint_3; + for (int i=0; i<3; i++) + { + itkPoint_1[i] = itkVector_1[i]; + itkPoint_2[i] = itkVector_2[i]; + itkPoint_3[i] = itkVector_3[i]; + } + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkPoint_1,itkPoint_1), "Test point equality using the same point with mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(itkPoint_1,itkPoint_2), "Test point equality using different points with an element-wise difference greater than mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkPoint_1,itkPoint_3), "Test point equality using different points with an element-wise difference less than mitk::eps"); + // test mitk vnl vector equality methods + mitk::VnlVector mitk_vnl_vector_1(3); + mitk::VnlVector mitk_vnl_vector_2(3); + mitk::VnlVector mitk_vnl_vector_3(3); + for (int i=0; i<3; i++) + { + mitk_vnl_vector_1.put(i,itkVector_1[i]); + mitk_vnl_vector_2.put(i,itkVector_2[i]); + mitk_vnl_vector_3.put(i,itkVector_3[i]); + } + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(mitk_vnl_vector_1,mitk_vnl_vector_1), "Test mitk vnl vector equality using the same mitk vnl vector with mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(mitk_vnl_vector_1,mitk_vnl_vector_2), "Test mitk vnl vector equality using different mitk vnl vectors with an element-wise difference greater than mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(mitk_vnl_vector_1,mitk_vnl_vector_3), "Test mitk vnl vector equality using different mitk vnl vectors with an element-wise difference less than mitk::eps"); + // test vnl_vector equality method + vnl_vector_fixed vnlVector_1; + vnlVector_1[3] = 56.98; + vnlVector_1[4] = 22.32; + vnlVector_1[5] = 1.00; + vnlVector_1[6] = 119.02; + vnl_vector_fixed vnlVector_2; + vnl_vector_fixed vnlVector_3; + for (int i=0; i<7; i++) + { + if (i<3) + { + vnlVector_1.put(i,itkVector_1[i]); + } + vnlVector_2[i] = vnlVector_1[i]- sqrt(mitk::eps/6.9); + vnlVector_3[i] = vnlVector_1[i]- sqrt(mitk::eps/7.1); + } + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vnlVector_1,vnlVector_1), "Test vnl vector equality using the same vnl vector with mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(vnlVector_1,vnlVector_2), "Test vnl vector equality using different vnl vectors with an element-wise difference greater than mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vnlVector_1,vnlVector_3), "Test vnl vector equality using different vnl vectors with an element-wise difference less than mitk::eps"); + + // test scalar equality method + double scalar1 = 0.5689; + double scalar2 = scalar1 + mitk::eps; + double scalar3 = scalar1 + mitk::eps*0.95; + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(scalar1,scalar1), "Test scalar equality using the same scalar with mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(scalar1,scalar2), "Test scalar equality using the different scalars with a difference greater than mitk::eps"); + MITK_TEST_CONDITION_REQUIRED(mitk::Equal(scalar1,scalar3), "Test scalar equality using the different scalars with a difference less than mitk::eps"); + + // test matrix equality methods + vnl_matrix_fixed vnlMatrix3x3_1; + vnlMatrix3x3_1(0,0) = 1.1; + vnlMatrix3x3_1(0,1) = 0.4; + vnlMatrix3x3_1(0,2) = 5.3; + vnlMatrix3x3_1(1,0) = 2.7; + vnlMatrix3x3_1(1,1) = 3578.56418; + vnlMatrix3x3_1(1,2) = 123.56; + vnlMatrix3x3_1(2,0) = 546.89; + vnlMatrix3x3_1(2,1) = 0.0001; + vnlMatrix3x3_1(2,2) = 1.0; + vnl_matrix_fixed vnlMatrix3x3_2; + vnlMatrix3x3_2(0,0) = 1.1000009; + vnlMatrix3x3_2(0,1) = 0.4000009; + vnlMatrix3x3_2(0,2) = 5.3000009; + vnlMatrix3x3_2(1,0) = 2.7000009; + vnlMatrix3x3_2(1,1) = 3578.5641809; + vnlMatrix3x3_2(1,2) = 123.5600009; + vnlMatrix3x3_2(2,0) = 546.8900009; + vnlMatrix3x3_2(2,1) = 0.0001009; + vnlMatrix3x3_2(2,2) = 1.0000009; + + mitk::ScalarType epsilon = 0.000001; + MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(vnlMatrix3x3_1,vnlMatrix3x3_1,0.0),"Test for matrix equality with given epsilon=0.0 and exactly the same matrix elements"); + MITK_TEST_CONDITION_REQUIRED(!mitk::MatrixEqualElementWise(vnlMatrix3x3_1,vnlMatrix3x3_2,0.0),"Test for matrix equality with given epsilon=0.0 and slightly different matrix elements"); + MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(vnlMatrix3x3_1,vnlMatrix3x3_2,epsilon),"Test for matrix equality with given epsilon and slightly different matrix elements"); + MITK_TEST_CONDITION_REQUIRED(!mitk::MatrixEqualRMS(vnlMatrix3x3_1,vnlMatrix3x3_2,0.0),"Test for matrix equality with given epsilon=0.0 and slightly different matrix elements"); + MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualRMS(vnlMatrix3x3_1,vnlMatrix3x3_2,epsilon),"Test for matrix equality with given epsilon and slightly different matrix elements"); + + MITK_TEST_END(); +}