diff --git a/CMakeExternals/ITK.cmake b/CMakeExternals/ITK.cmake index bca84c6025..e79c9bf399 100644 --- a/CMakeExternals/ITK.cmake +++ b/CMakeExternals/ITK.cmake @@ -1,84 +1,85 @@ #----------------------------------------------------------------------------- # ITK #----------------------------------------------------------------------------- # Sanity checks if(DEFINED ITK_DIR AND NOT EXISTS ${ITK_DIR}) message(FATAL_ERROR "ITK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj ITK) set(proj_DEPENDENCIES GDCM) if(MITK_USE_OpenCV) list(APPEND proj_DEPENDENCIES OpenCV) endif() if(MITK_USE_HDF5) list(APPEND proj_DEPENDENCIES HDF5) endif() set(ITK_DEPENDS ${proj}) if(NOT DEFINED ITK_DIR) set(additional_cmake_args ) if(MINGW) set(additional_cmake_args -DCMAKE_USE_WIN32_THREADS:BOOL=ON -DCMAKE_USE_PTHREADS:BOOL=OFF) endif() list(APPEND additional_cmake_args -DUSE_WRAP_ITK:BOOL=OFF ) if(MITK_USE_OpenCV) list(APPEND additional_cmake_args -DModule_ITKVideoBridgeOpenCV:BOOL=ON -DOpenCV_DIR:PATH=${OpenCV_DIR} ) endif() # Keep the behaviour of ITK 4.3 which by default turned on ITK Review # see MITK bug #17338 list(APPEND additional_cmake_args -DModule_ITKReview:BOOL=ON # for 4.7, the OpenJPEG is needed by review but the variable must be set -DModule_ITKOpenJPEG:BOOL=ON ) if(CTEST_USE_LAUNCHERS) list(APPEND additional_cmake_args "-DCMAKE_PROJECT_${proj}_INCLUDE:FILEPATH=${CMAKE_ROOT}/Modules/CTestUseLaunchers.cmake" ) endif() ExternalProject_Add(${proj} LIST_SEPARATOR ${sep} - URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/InsightToolkit-4.9.0.tar.xz - URL_MD5 0ce83c0f3c08f8ee992675fca4401572 + URL /home/neher/Downloads/ITK-4.11.0.zip + #URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/InsightToolkit-4.9.0.tar.xz + #URL_MD5 0ce83c0f3c08f8ee992675fca4401572 # work with external GDCM - PATCH_COMMAND ${PATCH_COMMAND} -N -p1 -i ${CMAKE_CURRENT_LIST_DIR}/ITK-4.9.0.patch CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${additional_cmake_args} -DBUILD_EXAMPLES:BOOL=OFF -DITK_USE_SYSTEM_GDCM:BOOL=ON -DGDCM_DIR:PATH=${GDCM_DIR} CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) set(ITK_DIR ${ep_prefix}) + mitkFunctionInstallExternalCMakeProject(${proj}) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() diff --git a/Modules/Core/test/mitkGeometry3DTest.cpp b/Modules/Core/test/mitkGeometry3DTest.cpp index 57df27330d..2c44503816 100644 --- a/Modules/Core/test/mitkGeometry3DTest.cpp +++ b/Modules/Core/test/mitkGeometry3DTest.cpp @@ -1,626 +1,626 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGeometry3D.h" #include -#include +#include #include "mitkInteractionConst.h" #include "mitkRotationOperation.h" #include #include #include "mitkTestingMacros.h" #include #include bool testGetAxisVectorVariants(mitk::Geometry3D *geometry) { int direction; for (direction = 0; direction < 3; ++direction) { mitk::Vector3D frontToBack(0.); switch (direction) { case 0: frontToBack = geometry->GetCornerPoint(false, false, false) - geometry->GetCornerPoint(true, false, false); break; // 7-3 case 1: frontToBack = geometry->GetCornerPoint(false, false, false) - geometry->GetCornerPoint(false, true, false); break; // 7-5 case 2: frontToBack = geometry->GetCornerPoint(false, false, false) - geometry->GetCornerPoint(false, false, true); break; // 7-2 } std::cout << "Testing GetAxisVector(int) vs GetAxisVector(bool, bool, bool): "; if (mitk::Equal(geometry->GetAxisVector(direction), frontToBack) == false) { std::cout << "[FAILED]" << std::endl; return false; } std::cout << "[PASSED]" << std::endl; } return true; } bool testGetAxisVectorExtent(mitk::Geometry3D *geometry) { int direction; for (direction = 0; direction < 3; ++direction) { if (mitk::Equal(geometry->GetAxisVector(direction).GetNorm(), geometry->GetExtentInMM(direction)) == false) { std::cout << "[FAILED]" << std::endl; return false; } std::cout << "[PASSED]" << std::endl; } return true; } // a part of the test requires axis-parallel coordinates int testIndexAndWorldConsistency(mitk::Geometry3D *geometry3d) { MITK_TEST_OUTPUT(<< "Testing consistency of index and world coordinate systems: "); mitk::Point3D origin = geometry3d->GetOrigin(); mitk::Point3D dummy; MITK_TEST_OUTPUT(<< " Testing index->world->index conversion consistency"); geometry3d->WorldToIndex(origin, dummy); geometry3d->IndexToWorld(dummy, dummy); MITK_TEST_CONDITION_REQUIRED(dummy == origin, ""); MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin, mitk::Point3D)==(0,0,0)"); mitk::Point3D globalOrigin; mitk::FillVector3D(globalOrigin, 0, 0, 0); mitk::Point3D originContinuousIndex; geometry3d->WorldToIndex(origin, originContinuousIndex); MITK_TEST_CONDITION_REQUIRED(originContinuousIndex == globalOrigin, ""); MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin, itk::Index)==(0,0,0)"); itk::Index<3> itkindex; geometry3d->WorldToIndex(origin, itkindex); itk::Index<3> globalOriginIndex; mitk::vtk2itk(globalOrigin, globalOriginIndex); MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, ""); MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin-0.5*spacing, itk::Index)==(0,0,0)"); mitk::Vector3D halfSpacingStep = geometry3d->GetSpacing() * 0.5; mitk::Matrix3D rotation; mitk::Point3D originOffCenter = origin - halfSpacingStep; geometry3d->WorldToIndex(originOffCenter, itkindex); MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, ""); MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)"); originOffCenter = origin + halfSpacingStep; originOffCenter -= 0.0001; geometry3d->WorldToIndex(originOffCenter, itkindex); MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, ""); MITK_TEST_OUTPUT(<< " Testing WorldToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)"); originOffCenter = origin + halfSpacingStep; itk::Index<3> global111; mitk::FillVector3D(global111, 1, 1, 1); geometry3d->WorldToIndex(originOffCenter, itkindex); MITK_TEST_CONDITION_REQUIRED(itkindex == global111, ""); MITK_TEST_OUTPUT(<< " Testing WorldToIndex(GetCenter())==BoundingBox.GetCenter: "); mitk::Point3D center = geometry3d->GetCenter(); mitk::Point3D centerContIndex; geometry3d->WorldToIndex(center, centerContIndex); mitk::BoundingBox::ConstPointer boundingBox = geometry3d->GetBoundingBox(); mitk::BoundingBox::PointType centerBounds = boundingBox->GetCenter(); // itk assumes corner based geometry. If our geometry is center based (imageGoe == true), everything needs to be // shifted if (geometry3d->GetImageGeometry()) { centerBounds[0] -= 0.5; centerBounds[1] -= 0.5; centerBounds[2] -= 0.5; } MITK_TEST_CONDITION_REQUIRED(mitk::Equal(centerContIndex, centerBounds), ""); MITK_TEST_OUTPUT(<< " Testing GetCenter()==IndexToWorld(BoundingBox.GetCenter): "); center = geometry3d->GetCenter(); mitk::Point3D centerBoundsInWorldCoords; geometry3d->IndexToWorld(centerBounds, centerBoundsInWorldCoords); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(center, centerBoundsInWorldCoords), ""); return EXIT_SUCCESS; } int testIndexAndWorldConsistencyForVectors(mitk::Geometry3D *geometry3d) { MITK_TEST_OUTPUT(<< "Testing consistency of index and world coordinate systems for vectors: "); mitk::Vector3D xAxisMM = geometry3d->GetAxisVector(0); mitk::Vector3D xAxisContinuousIndex; mitk::Vector3D xAxisContinuousIndexDeprecated; mitk::Point3D p, pIndex, origin; origin = geometry3d->GetOrigin(); p[0] = xAxisMM[0]; p[1] = xAxisMM[1]; p[2] = xAxisMM[2]; geometry3d->WorldToIndex(p, pIndex); geometry3d->WorldToIndex(xAxisMM, xAxisContinuousIndexDeprecated); geometry3d->WorldToIndex(xAxisMM, xAxisContinuousIndex); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == pIndex[0], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == pIndex[1], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == pIndex[2], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == xAxisContinuousIndexDeprecated[0], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == xAxisContinuousIndexDeprecated[1], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == xAxisContinuousIndexDeprecated[2], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[0] == pIndex[0], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[1] == pIndex[1], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[2] == pIndex[2], ""); geometry3d->IndexToWorld(xAxisContinuousIndex, xAxisContinuousIndex); geometry3d->IndexToWorld(xAxisContinuousIndexDeprecated, xAxisContinuousIndexDeprecated); geometry3d->IndexToWorld(pIndex, p); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex == xAxisMM, ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == p[0], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == p[1], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == p[2], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated == xAxisMM, ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[0] == p[0], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[1] == p[1], ""); MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[2] == p[2], ""); return EXIT_SUCCESS; } int testIndexAndWorldConsistencyForIndex(mitk::Geometry3D *geometry3d) { MITK_TEST_OUTPUT(<< "Testing consistency of index and world coordinate systems: "); // creating testing data itk::Index<4> itkIndex4, itkIndex4b; itk::Index<3> itkIndex3, itkIndex3b; itk::Index<2> itkIndex2, itkIndex2b; itk::Index<3> mitkIndex, mitkIndexb; itkIndex4[0] = itkIndex4[1] = itkIndex4[2] = itkIndex4[3] = 4; itkIndex3[0] = itkIndex3[1] = itkIndex3[2] = 6; itkIndex2[0] = itkIndex2[1] = 2; mitkIndex[0] = mitkIndex[1] = mitkIndex[2] = 13; // check for constistency mitk::Point3D point; geometry3d->IndexToWorld(itkIndex2, point); geometry3d->WorldToIndex(point, itkIndex2b); MITK_TEST_CONDITION_REQUIRED(((itkIndex2b[0] == itkIndex2[0]) && (itkIndex2b[1] == itkIndex2[1])), "Testing itk::index<2> for IndexToWorld/WorldToIndex consistency"); geometry3d->IndexToWorld(itkIndex3, point); geometry3d->WorldToIndex(point, itkIndex3b); MITK_TEST_CONDITION_REQUIRED( ((itkIndex3b[0] == itkIndex3[0]) && (itkIndex3b[1] == itkIndex3[1]) && (itkIndex3b[2] == itkIndex3[2])), "Testing itk::index<3> for IndexToWorld/WorldToIndex consistency"); geometry3d->IndexToWorld(itkIndex4, point); geometry3d->WorldToIndex(point, itkIndex4b); MITK_TEST_CONDITION_REQUIRED(((itkIndex4b[0] == itkIndex4[0]) && (itkIndex4b[1] == itkIndex4[1]) && (itkIndex4b[2] == itkIndex4[2]) && (itkIndex4b[3] == 0)), "Testing itk::index<3> for IndexToWorld/WorldToIndex consistency"); geometry3d->IndexToWorld(mitkIndex, point); geometry3d->WorldToIndex(point, mitkIndexb); MITK_TEST_CONDITION_REQUIRED( ((mitkIndexb[0] == mitkIndex[0]) && (mitkIndexb[1] == mitkIndex[1]) && (mitkIndexb[2] == mitkIndex[2])), "Testing mitk::Index for IndexToWorld/WorldToIndex consistency"); return EXIT_SUCCESS; } #include int testItkImageIsCenterBased() { MITK_TEST_OUTPUT(<< "Testing whether itk::Image coordinates are center-based."); typedef itk::Image ItkIntImage3D; ItkIntImage3D::Pointer itkintimage = ItkIntImage3D::New(); ItkIntImage3D::SizeType size; size.Fill(10); mitk::Point3D origin; mitk::FillVector3D(origin, 2, 3, 7); itkintimage->Initialize(); itkintimage->SetRegions(size); itkintimage->SetOrigin(origin); std::cout << "[PASSED]" << std::endl; MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToContinuousIndex(origin)==(0,0,0)"); mitk::Point3D globalOrigin; mitk::FillVector3D(globalOrigin, 0, 0, 0); itk::ContinuousIndex originContinuousIndex; itkintimage->TransformPhysicalPointToContinuousIndex(origin, originContinuousIndex); MITK_TEST_CONDITION_REQUIRED(originContinuousIndex == globalOrigin, ""); MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToIndex(origin)==(0,0,0)"); itk::Index<3> itkindex; itkintimage->TransformPhysicalPointToIndex(origin, itkindex); itk::Index<3> globalOriginIndex; mitk::vtk2itk(globalOrigin, globalOriginIndex); MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, ""); MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToIndex(origin-0.5*spacing)==(0,0,0)"); mitk::Vector3D halfSpacingStep = itkintimage->GetSpacing() * 0.5; mitk::Matrix3D rotation; mitk::Point3D originOffCenter = origin - halfSpacingStep; itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex); MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, ""); MITK_TEST_OUTPUT( << " Testing itk::Image::TransformPhysicalPointToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)"); originOffCenter = origin + halfSpacingStep; originOffCenter -= 0.0001; itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex); MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, ""); MITK_TEST_OUTPUT(<< " Testing itk::Image::TransformPhysicalPointToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)"); originOffCenter = origin + halfSpacingStep; itk::Index<3> global111; mitk::FillVector3D(global111, 1, 1, 1); itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex); MITK_TEST_CONDITION_REQUIRED(itkindex == global111, ""); MITK_TEST_OUTPUT(<< "=> Yes, itk::Image coordinates are center-based."); return EXIT_SUCCESS; } int testGeometry3D(bool imageGeometry) { // Build up a new image Geometry mitk::Geometry3D::Pointer geometry3d = mitk::Geometry3D::New(); float bounds[] = {-10.0, 17.0, -12.0, 188.0, 13.0, 211.0}; MITK_TEST_OUTPUT(<< "Initializing"); geometry3d->Initialize(); MITK_TEST_OUTPUT(<< "Setting ImageGeometry to " << imageGeometry); geometry3d->SetImageGeometry(imageGeometry); MITK_TEST_OUTPUT(<< "Setting bounds by SetFloatBounds(): " << bounds); geometry3d->SetFloatBounds(bounds); MITK_TEST_OUTPUT(<< "Testing AxisVectors"); if (testGetAxisVectorVariants(geometry3d) == false) return EXIT_FAILURE; if (testGetAxisVectorExtent(geometry3d) == false) return EXIT_FAILURE; MITK_TEST_OUTPUT(<< "Creating an AffineTransform3D transform"); mitk::AffineTransform3D::MatrixType matrix; matrix.SetIdentity(); matrix(1, 1) = 2; mitk::AffineTransform3D::Pointer transform; transform = mitk::AffineTransform3D::New(); transform->SetMatrix(matrix); MITK_TEST_OUTPUT(<< "Testing a SetIndexToWorldTransform"); geometry3d->SetIndexToWorldTransform(transform); MITK_TEST_OUTPUT(<< "Testing correctness of value returned by GetSpacing"); const mitk::Vector3D &spacing1 = geometry3d->GetSpacing(); mitk::Vector3D expectedSpacing; expectedSpacing.Fill(1.0); expectedSpacing[1] = 2; if (mitk::Equal(spacing1, expectedSpacing) == false) { MITK_TEST_OUTPUT(<< " [FAILED]"); return EXIT_FAILURE; } MITK_TEST_OUTPUT(<< "Testing a Compose(transform)"); geometry3d->Compose(transform); MITK_TEST_OUTPUT(<< "Testing correctness of value returned by GetSpacing"); const mitk::Vector3D &spacing2 = geometry3d->GetSpacing(); expectedSpacing[1] = 4; if (mitk::Equal(spacing2, expectedSpacing) == false) { MITK_TEST_OUTPUT(<< " [FAILED]"); return EXIT_FAILURE; } MITK_TEST_OUTPUT(<< "Testing correctness of SetSpacing"); mitk::Vector3D newspacing; mitk::FillVector3D(newspacing, 1.5, 2.5, 3.5); geometry3d->SetSpacing(newspacing); const mitk::Vector3D &spacing3 = geometry3d->GetSpacing(); if (mitk::Equal(spacing3, newspacing) == false) { MITK_TEST_OUTPUT(<< " [FAILED]"); return EXIT_FAILURE; } // Seperate Test function for Index and World consistency testIndexAndWorldConsistency(geometry3d); testIndexAndWorldConsistencyForVectors(geometry3d); testIndexAndWorldConsistencyForIndex(geometry3d); MITK_TEST_OUTPUT(<< "Testing a rotation of the geometry"); double angle = 35.0; mitk::Vector3D rotationVector; mitk::FillVector3D(rotationVector, 1, 0, 0); mitk::Point3D center = geometry3d->GetCenter(); auto op = new mitk::RotationOperation(mitk::OpROTATE, center, rotationVector, angle); geometry3d->ExecuteOperation(op); MITK_TEST_OUTPUT(<< "Testing mitk::GetRotation() and success of rotation"); mitk::Matrix3D rotation; mitk::GetRotation(geometry3d, rotation); mitk::Vector3D voxelStep = rotation * newspacing; mitk::Vector3D voxelStepIndex; geometry3d->WorldToIndex(voxelStep, voxelStepIndex); mitk::Vector3D expectedVoxelStepIndex; expectedVoxelStepIndex.Fill(1); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(voxelStepIndex, expectedVoxelStepIndex), ""); delete op; std::cout << "[PASSED]" << std::endl; MITK_TEST_OUTPUT(<< "Testing that ImageGeometry is still " << imageGeometry); MITK_TEST_CONDITION_REQUIRED(geometry3d->GetImageGeometry() == imageGeometry, ""); // Test if the translate function moves the origin correctly. mitk::Point3D oldOrigin = geometry3d->GetOrigin(); // use some random values for translation mitk::Vector3D translationVector; translationVector.SetElement(0, 17.5f); translationVector.SetElement(1, -32.3f); translationVector.SetElement(2, 4.0f); // compute ground truth mitk::Point3D tmpResult = geometry3d->GetOrigin() + translationVector; geometry3d->Translate(translationVector); MITK_TEST_CONDITION(mitk::Equal(geometry3d->GetOrigin(), tmpResult), "Testing if origin was translated."); translationVector *= -1; // vice versa geometry3d->Translate(translationVector); MITK_TEST_CONDITION(mitk::Equal(geometry3d->GetOrigin(), oldOrigin), "Testing if the translation could be done vice versa."); return EXIT_SUCCESS; } int testGeometryAfterCasting() { // Epsilon. Allowed difference for rotationvalue float eps = 0.0001; // Cast ITK and MITK images and see if geometry stays typedef itk::Image Image2DType; typedef itk::Image Image3DType; // Create 3D ITK Image from Scratch, cast to 3D MITK image, compare Geometries Image3DType::Pointer image3DItk = Image3DType::New(); Image3DType::RegionType myRegion; Image3DType::SizeType mySize; Image3DType::IndexType myIndex; Image3DType::SpacingType mySpacing; Image3DType::DirectionType myDirection, rotMatrixX, rotMatrixY, rotMatrixZ; mySpacing[0] = 31; mySpacing[1] = 0.1; mySpacing[2] = 2.9; myIndex[0] = -15; myIndex[1] = 15; myIndex[2] = 12; mySize[0] = 10; mySize[1] = 2; mySize[2] = 555; myRegion.SetSize(mySize); myRegion.SetIndex(myIndex); image3DItk->SetSpacing(mySpacing); image3DItk->SetRegions(myRegion); image3DItk->Allocate(); image3DItk->FillBuffer(0); myDirection.SetIdentity(); rotMatrixX.SetIdentity(); rotMatrixY.SetIdentity(); rotMatrixZ.SetIdentity(); mitk::Image::Pointer mitkImage; // direction [row] [coloum] MITK_TEST_OUTPUT(<< "Casting a rotated 3D ITK Image to a MITK Image and check if Geometry is still same"); for (double rotX = 0; rotX < (itk::Math::pi * 2); rotX += 0.4) { // Set Rotation X rotMatrixX[1][1] = cos(rotX); rotMatrixX[1][2] = -sin(rotX); rotMatrixX[2][1] = sin(rotX); rotMatrixX[2][2] = cos(rotX); for (double rotY = 0; rotY < (itk::Math::pi * 2); rotY += 0.33) { // Set Rotation Y rotMatrixY[0][0] = cos(rotY); rotMatrixY[0][2] = sin(rotY); rotMatrixY[2][0] = -sin(rotY); rotMatrixY[2][2] = cos(rotY); for (double rotZ = 0; rotZ < (itk::Math::pi * 2); rotZ += 0.5) { // Set Rotation Z rotMatrixZ[0][0] = cos(rotZ); rotMatrixZ[0][1] = -sin(rotZ); rotMatrixZ[1][0] = sin(rotZ); rotMatrixZ[1][1] = cos(rotZ); // Multiply matrizes myDirection = myDirection * rotMatrixX * rotMatrixY * rotMatrixZ; image3DItk->SetDirection(myDirection); mitk::CastToMitkImage(image3DItk, mitkImage); const mitk::AffineTransform3D::MatrixType &matrix = mitkImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix(); for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { double mitkValue = matrix[row][col] / mitkImage->GetGeometry()->GetSpacing()[col]; double itkValue = myDirection[row][col]; double diff = mitkValue - itkValue; // if you decrease this value, you can see that there might be QUITE high inaccuracy!!! if (diff > eps) // need to check, how exact it SHOULD be .. since it is NOT EXACT! { std::cout << "Had a difference of : " << diff; std::cout << "Error: Casting altered Geometry!"; std::cout << "ITK Matrix:\n" << myDirection; std::cout << "Mitk Matrix (With Spacing):\n" << matrix; std::cout << "Mitk Spacing: " << mitkImage->GetGeometry()->GetSpacing(); MITK_TEST_CONDITION_REQUIRED(false == true, ""); return false; } } } } } } // Create 2D ITK Image from Scratch, cast to 2D MITK image, compare Geometries Image2DType::Pointer image2DItk = Image2DType::New(); Image2DType::RegionType myRegion2D; Image2DType::SizeType mySize2D; Image2DType::IndexType myIndex2D; Image2DType::SpacingType mySpacing2D; Image2DType::DirectionType myDirection2D, rotMatrix; mySpacing2D[0] = 31; mySpacing2D[1] = 0.1; myIndex2D[0] = -15; myIndex2D[1] = 15; mySize2D[0] = 10; mySize2D[1] = 2; myRegion2D.SetSize(mySize2D); myRegion2D.SetIndex(myIndex2D); image2DItk->SetSpacing(mySpacing2D); image2DItk->SetRegions(myRegion2D); image2DItk->Allocate(); image2DItk->FillBuffer(0); myDirection2D.SetIdentity(); rotMatrix.SetIdentity(); // direction [row] [coloum] MITK_TEST_OUTPUT(<< "Casting a rotated 2D ITK Image to a MITK Image and check if Geometry is still same"); for (double rotTheta = 0; rotTheta < (itk::Math::pi * 2); rotTheta += 0.1) { // Set Rotation rotMatrix[0][0] = cos(rotTheta); rotMatrix[0][1] = -sin(rotTheta); rotMatrix[1][0] = sin(rotTheta); rotMatrix[1][1] = cos(rotTheta); // Multiply matrizes myDirection2D = myDirection2D * rotMatrix; image2DItk->SetDirection(myDirection2D); mitk::CastToMitkImage(image2DItk, mitkImage); const mitk::AffineTransform3D::MatrixType &matrix = mitkImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix(); // Compare MITK and ITK matrix for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { double mitkValue = matrix[row][col] / mitkImage->GetGeometry()->GetSpacing()[col]; if ((row == 2) && (col == row)) { if (mitkValue != 1) { MITK_TEST_OUTPUT(<< "After casting a 2D ITK to 3D MITK images, MITK matrix values for 0|2, 1|2, 2|0, 2|1 " "MUST be 0 and value for 2|2 must be 1"); return false; } } else if ((row == 2) || (col == 2)) { if (mitkValue != 0) { MITK_TEST_OUTPUT(<< "After casting a 2D ITK to 3D MITK images, MITK matrix values for 0|2, 1|2, 2|0, 2|1 " "MUST be 0 and value for 2|2 must be 1"); return false; } } else { double itkValue = myDirection2D[row][col]; double diff = mitkValue - itkValue; // if you decrease this value, you can see that there might be QUITE high inaccuracy!!! if (diff > eps) // need to check, how exact it SHOULD be .. since it is NOT EXACT! { std::cout << "Had a difference of : " << diff; std::cout << "Error: Casting altered Geometry!"; std::cout << "ITK Matrix:\n" << myDirection2D; std::cout << "Mitk Matrix (With Spacing):\n" << matrix; std::cout << "Mitk Spacing: " << mitkImage->GetGeometry()->GetSpacing(); MITK_TEST_CONDITION_REQUIRED(false == true, ""); return false; } } } } } // THIS WAS TESTED: // 2D ITK -> 2D MITK, // 3D ITK -> 3D MITK, // Still need to test: 2D MITK Image with ADDITIONAL INFORMATION IN MATRIX -> 2D ITK // 1. Possibility: 3x3 MITK matrix can be converted without loss into 2x2 ITK matrix // 2. Possibility: 3x3 MITK matrix can only be converted with loss into 2x2 ITK matrix // .. before implementing this, we wait for further development in geometry classes (e.g. Geoemtry3D::SetRotation(..)) return EXIT_SUCCESS; } int mitkGeometry3DTest(int /*argc*/, char * /*argv*/ []) { MITK_TEST_BEGIN(mitkGeometry3DTest); int result; MITK_TEST_CONDITION_REQUIRED((result = testItkImageIsCenterBased()) == EXIT_SUCCESS, ""); MITK_TEST_OUTPUT(<< "Running main part of test with ImageGeometry = false"); MITK_TEST_CONDITION_REQUIRED((result = testGeometry3D(false)) == EXIT_SUCCESS, ""); MITK_TEST_OUTPUT(<< "Running main part of test with ImageGeometry = true"); MITK_TEST_CONDITION_REQUIRED((result = testGeometry3D(true)) == EXIT_SUCCESS, ""); MITK_TEST_OUTPUT(<< "Running test to see if Casting MITK to ITK and the other way around destroys geometry"); MITK_TEST_CONDITION_REQUIRED((result = testGeometryAfterCasting()) == EXIT_SUCCESS, ""); MITK_TEST_END(); return EXIT_SUCCESS; } diff --git a/Modules/Core/test/mitkPlaneGeometryTest.cpp b/Modules/Core/test/mitkPlaneGeometryTest.cpp index f1ee6e0b5e..54f5955626 100644 --- a/Modules/Core/test/mitkPlaneGeometryTest.cpp +++ b/Modules/Core/test/mitkPlaneGeometryTest.cpp @@ -1,1078 +1,1078 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkAffineTransform3D.h" #include "mitkBaseGeometry.h" #include "mitkGeometry3D.h" #include "mitkInteractionConst.h" #include "mitkLine.h" #include "mitkPlaneGeometry.h" #include "mitkRotationOperation.h" #include "mitkSlicedGeometry3D.h" #include "mitkThinPlateSplineCurvedGeometry.h" #include #include #include -#include +#include #include #include static const mitk::ScalarType testEps = 1E-9; // the epsilon used in this test == at least float precision. class mitkPlaneGeometryTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPlaneGeometryTestSuite); MITK_TEST(TestInitializeStandardPlane); MITK_TEST(TestProjectPointOntoPlane); MITK_TEST(TestPlaneGeometryCloning); MITK_TEST(TestInheritance); MITK_TEST(TestSetExtendInMM); MITK_TEST(TestRotate); MITK_TEST(TestClone); MITK_TEST(TestPlaneComparison); MITK_TEST(TestAxialInitialization); MITK_TEST(TestFrontalInitialization); MITK_TEST(TestSaggitalInitialization); MITK_TEST(TestLefthandedCoordinateSystem); // Currently commented out, see See bug 15990 // MITK_TEST(testPlaneGeometryInitializeOrder); MITK_TEST(TestIntersectionPoint); MITK_TEST(TestCase1210); CPPUNIT_TEST_SUITE_END(); private: // private test members that are initialized by setUp() mitk::PlaneGeometry::Pointer planegeometry; mitk::Point3D origin; mitk::Vector3D right, bottom, normal, spacing; mitk::ScalarType width, height; mitk::ScalarType widthInMM, heightInMM, thicknessInMM; public: void setUp() override { planegeometry = mitk::PlaneGeometry::New(); width = 100; widthInMM = width; height = 200; heightInMM = height; thicknessInMM = 1.0; mitk::FillVector3D(origin, 4.5, 7.3, 11.2); mitk::FillVector3D(right, widthInMM, 0, 0); mitk::FillVector3D(bottom, 0, heightInMM, 0); mitk::FillVector3D(normal, 0, 0, thicknessInMM); mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM); planegeometry->InitializeStandardPlane(right, bottom); planegeometry->SetOrigin(origin); planegeometry->SetSpacing(spacing); } void tearDown() override {} // This test verifies inheritance behaviour, this test will fail if the behaviour changes in the future void TestInheritance() { mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); mitk::Geometry3D::Pointer g3d = dynamic_cast(plane.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Planegeometry should not be castable to Geometry 3D", g3d.IsNull()); mitk::BaseGeometry::Pointer base = dynamic_cast(plane.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Planegeometry should be castable to BaseGeometry", base.IsNotNull()); g3d = mitk::Geometry3D::New(); base = dynamic_cast(g3d.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Geometry3D should be castable to BaseGeometry", base.IsNotNull()); mitk::SlicedGeometry3D::Pointer sliced = mitk::SlicedGeometry3D::New(); g3d = dynamic_cast(sliced.GetPointer()); CPPUNIT_ASSERT_MESSAGE("SlicedGeometry3D should not be castable to Geometry3D", g3d.IsNull()); mitk::ThinPlateSplineCurvedGeometry::Pointer thin = mitk::ThinPlateSplineCurvedGeometry::New(); plane = dynamic_cast(thin.GetPointer()); CPPUNIT_ASSERT_MESSAGE("AbstractTransformGeometry should be castable to PlaneGeometry", plane.IsNotNull()); plane = mitk::PlaneGeometry::New(); mitk::AbstractTransformGeometry::Pointer atg = dynamic_cast(plane.GetPointer()); CPPUNIT_ASSERT_MESSAGE("PlaneGeometry should not be castable to AbstractTransofrmGeometry", atg.IsNull()); } void TestLefthandedCoordinateSystem() { /** * @brief This method tests InitializeStandardPlane() and IndexToWorld() * with a left-handed coordinate orientation or indexToWorldMatrix. * * Of course this test does not use standard Parameters, which are right-handed. * See also discussion of bug #11477: http://bugs.mitk.org/show_bug.cgi?id=11477 */ planegeometry = mitk::PlaneGeometry::New(); width = 100; widthInMM = 5; height = 200; heightInMM = 3; thicknessInMM = 1.0; mitk::FillVector3D(right, widthInMM, 0, 0); mitk::FillVector3D(bottom, 0, heightInMM, 0); // This one negative sign results in lefthanded coordinate orientation and det(matrix) < 0. mitk::FillVector3D(normal, 0, 0, -thicknessInMM); mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType matrix; mitk::AffineTransform3D::MatrixType::InternalMatrixType &vnl_matrix = matrix.GetVnlMatrix(); vnl_matrix.set_column(0, right); vnl_matrix.set_column(1, bottom); vnl_matrix.set_column(2, normal); // making sure that we didn't screw up this special test case or else fail deadly: assert(vnl_determinant(vnl_matrix) < 0.0); transform->SetIdentity(); transform->SetMatrix(matrix); planegeometry->InitializeStandardPlane(width, height, transform); // Crux of the matter. CPPUNIT_ASSERT_MESSAGE( "Testing if IndexToWorldMatrix is correct after InitializeStandardPlane( width, height, transform ) ", mitk::MatrixEqualElementWise(planegeometry->GetIndexToWorldTransform()->GetMatrix(), matrix)); mitk::Point3D p_index; p_index[0] = 10.; p_index[1] = 10.; p_index[2] = 0.; mitk::Point3D p_world; mitk::Point3D p_expectedResult; p_expectedResult[0] = 50.; p_expectedResult[1] = 30.; p_expectedResult[2] = 0.; ((mitk::BaseGeometry::Pointer)planegeometry)->IndexToWorld(p_index, p_world); // Crux of the matter. CPPUNIT_ASSERT_MESSAGE("Testing if IndexToWorld(a,b) function works correctly with lefthanded matrix ", mitk::Equal(p_world, p_expectedResult, testEps)); } // See bug 1210 // Test does not use standard Parameters void TestCase1210() { mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); mitk::Point3D origin; mitk::Vector3D right, down, spacing; mitk::FillVector3D(origin, 4.5, 7.3, 11.2); mitk::FillVector3D(right, 1.015625, 1.015625, 1.1999969482421875); mitk::FillVector3D(down, 1.4012984643248170709237295832899161312802619418765e-45, 0, 0); mitk::FillVector3D(spacing, 0, 1.4713633875410579244699160624544119378442750389703e-43, 9.2806360452222355258639080851310540729807238879469e-32); std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = NULL): " << std::endl; CPPUNIT_ASSERT_NO_THROW(planegeometry->InitializeStandardPlane(right, down, &spacing)); /* std::cout << "Testing width, height and thickness (in units): "; if((mitk::Equal(planegeometry->GetExtent(0),width)==false) || (mitk::Equal(planegeometry->GetExtent(1),height)==false) || (mitk::Equal(planegeometry->GetExtent(2),1)==false) ) { std::cout<<"[FAILED]"<GetExtentInMM(0),widthInMM)==false) || (mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) || (mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false) ) { std::cout<<"[FAILED]"< 0. * */ // Test does not use standard Parameters void TestIntersectionPoint() { // init plane with its parameter mitk::PlaneGeometry::Pointer myPlaneGeometry = mitk::PlaneGeometry::New(); mitk::Point3D origin; origin[0] = 0.0; origin[1] = 2.0; origin[2] = 0.0; mitk::Vector3D normal; normal[0] = 0.0; normal[1] = 1.0; normal[2] = 0.0; myPlaneGeometry->InitializePlane(origin, normal); // generate points and line for intersection testing // point distance of given line > 1 mitk::Point3D pointP1; pointP1[0] = 2.0; pointP1[1] = 1.0; pointP1[2] = 0.0; mitk::Point3D pointP2; pointP2[0] = 2.0; pointP2[1] = 4.0; pointP2[2] = 0.0; mitk::Vector3D lineDirection; lineDirection[0] = pointP2[0] - pointP1[0]; lineDirection[1] = pointP2[1] - pointP1[1]; lineDirection[2] = pointP2[2] - pointP1[2]; mitk::Line3D xingline(pointP1, lineDirection); mitk::Point3D calcXingPoint; myPlaneGeometry->IntersectionPoint(xingline, calcXingPoint); // point distance of given line < 1 mitk::Point3D pointP3; pointP3[0] = 2.0; pointP3[1] = 2.2; pointP3[2] = 0.0; mitk::Point3D pointP4; pointP4[0] = 2.0; pointP4[1] = 1.7; pointP4[2] = 0.0; mitk::Vector3D lineDirection2; lineDirection2[0] = pointP4[0] - pointP3[0]; lineDirection2[1] = pointP4[1] - pointP3[1]; lineDirection2[2] = pointP4[2] - pointP3[2]; mitk::Line3D xingline2(pointP3, lineDirection2); mitk::Point3D calcXingPoint2; myPlaneGeometry->IntersectionPoint(xingline2, calcXingPoint2); // intersection points must be the same CPPUNIT_ASSERT_MESSAGE("Failed to calculate Intersection Point", calcXingPoint == calcXingPoint2); } /** * @brief This method tests method ProjectPointOntoPlane. * * See also bug #3409. */ // Test does not use standard Parameters void TestProjectPointOntoPlane() { mitk::PlaneGeometry::Pointer myPlaneGeometry = mitk::PlaneGeometry::New(); // create normal mitk::Vector3D normal; normal[0] = 0.0; normal[1] = 0.0; normal[2] = 1.0; // create origin mitk::Point3D origin; origin[0] = -27.582859; origin[1] = 50; origin[2] = 200.27742; // initialize plane geometry myPlaneGeometry->InitializePlane(origin, normal); // output to descripe the test std::cout << "Testing PlaneGeometry according to bug #3409" << std::endl; std::cout << "Our normal is: " << normal << std::endl; std::cout << "So ALL projected points should have exactly the same z-value!" << std::endl; // create a number of points mitk::Point3D myPoints[5]; myPoints[0][0] = -27.582859; myPoints[0][1] = 50.00; myPoints[0][2] = 200.27742; myPoints[1][0] = -26.58662; myPoints[1][1] = 50.00; myPoints[1][2] = 200.19026; myPoints[2][0] = -26.58662; myPoints[2][1] = 50.00; myPoints[2][2] = 200.33124; myPoints[3][0] = 104.58662; myPoints[3][1] = 452.12313; myPoints[3][2] = 866.41236; myPoints[4][0] = -207.58662; myPoints[4][1] = 312.00; myPoints[4][2] = -300.12346; // project points onto plane mitk::Point3D myProjectedPoints[5]; for (unsigned int i = 0; i < 5; ++i) { myProjectedPoints[i] = myPlaneGeometry->ProjectPointOntoPlane(myPoints[i]); } // compare z-values with z-value of plane (should be equal) bool allPointsOnPlane = true; for (auto &myProjectedPoint : myProjectedPoints) { if (fabs(myProjectedPoint[2] - origin[2]) > mitk::sqrteps) { allPointsOnPlane = false; } } CPPUNIT_ASSERT_MESSAGE("All points lie not on the same plane", allPointsOnPlane); } void TestPlaneGeometryCloning() { mitk::PlaneGeometry::Pointer geometry2D = createPlaneGeometry(); try { mitk::PlaneGeometry::Pointer clone = geometry2D->Clone(); itk::Matrix matrix = clone->GetIndexToWorldTransform()->GetMatrix(); CPPUNIT_ASSERT_MESSAGE("Test if matrix element exists...", matrix[0][0] == 31); double origin = geometry2D->GetOrigin()[0]; CPPUNIT_ASSERT_MESSAGE("First Point of origin as expected...", mitk::Equal(origin, 8)); double spacing = geometry2D->GetSpacing()[0]; CPPUNIT_ASSERT_MESSAGE("First Point of spacing as expected...", mitk::Equal(spacing, 31)); } catch (...) { CPPUNIT_FAIL("Error during access on a member of cloned geometry"); } // direction [row] [coloum] MITK_TEST_OUTPUT(<< "Casting a rotated 2D ITK Image to a MITK Image and check if Geometry is still same"); } void TestPlaneGeometryInitializeOrder() { mitk::Vector3D mySpacing; mySpacing[0] = 31; mySpacing[1] = 0.1; mySpacing[2] = 5.4; mitk::Point3D myOrigin; myOrigin[0] = 8; myOrigin[1] = 9; myOrigin[2] = 10; mitk::AffineTransform3D::Pointer myTransform = mitk::AffineTransform3D::New(); itk::Matrix transMatrix; transMatrix.Fill(0); transMatrix[0][0] = 1; transMatrix[1][1] = 2; transMatrix[2][2] = 4; myTransform->SetMatrix(transMatrix); mitk::PlaneGeometry::Pointer geometry2D1 = mitk::PlaneGeometry::New(); geometry2D1->SetIndexToWorldTransform(myTransform); geometry2D1->SetSpacing(mySpacing); geometry2D1->SetOrigin(myOrigin); mitk::PlaneGeometry::Pointer geometry2D2 = mitk::PlaneGeometry::New(); geometry2D2->SetSpacing(mySpacing); geometry2D2->SetOrigin(myOrigin); geometry2D2->SetIndexToWorldTransform(myTransform); mitk::PlaneGeometry::Pointer geometry2D3 = mitk::PlaneGeometry::New(); geometry2D3->SetIndexToWorldTransform(myTransform); geometry2D3->SetSpacing(mySpacing); geometry2D3->SetOrigin(myOrigin); geometry2D3->SetIndexToWorldTransform(myTransform); CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 1 matches that of Geometry 2.", mitk::Equal(geometry2D1->GetOrigin(), geometry2D2->GetOrigin())); CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 1 match those of Geometry 3.", mitk::Equal(geometry2D1->GetOrigin(), geometry2D3->GetOrigin())); CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 2 match those of Geometry 3.", mitk::Equal(geometry2D2->GetOrigin(), geometry2D3->GetOrigin())); CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 1 match those of Geometry 2.", mitk::Equal(geometry2D1->GetSpacing(), geometry2D2->GetSpacing())); CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 1 match those of Geometry 3.", mitk::Equal(geometry2D1->GetSpacing(), geometry2D3->GetSpacing())); CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 2 match those of Geometry 3.", mitk::Equal(geometry2D2->GetSpacing(), geometry2D3->GetSpacing())); CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 1 match those of Geometry 2.", compareMatrix(geometry2D1->GetIndexToWorldTransform()->GetMatrix(), geometry2D2->GetIndexToWorldTransform()->GetMatrix())); CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 1 match those of Geometry 3.", compareMatrix(geometry2D1->GetIndexToWorldTransform()->GetMatrix(), geometry2D3->GetIndexToWorldTransform()->GetMatrix())); CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 2 match those of Geometry 3.", compareMatrix(geometry2D2->GetIndexToWorldTransform()->GetMatrix(), geometry2D3->GetIndexToWorldTransform()->GetMatrix())); } void TestInitializeStandardPlane() { CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: width", mitk::Equal(planegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: height", mitk::Equal(planegeometry->GetExtent(1), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: depth", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: width in mm", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: heght in mm", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: depth in mm", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorRight", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorBottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorNormal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); mitk::Vector3D spacing; thicknessInMM = 1.5; normal.Normalize(); normal *= thicknessInMM; mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM); planegeometry->InitializeStandardPlane(right.GetVnlVector(), bottom.GetVnlVector(), &spacing); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: width", mitk::Equal(planegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: height", mitk::Equal(planegeometry->GetExtent(1), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: depth", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: width in mm", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: height in mm", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: depth in mm", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorRight", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorBottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorNormal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); ; } void TestSetExtendInMM() { normal.Normalize(); normal *= thicknessInMM; planegeometry->SetExtentInMM(2, thicknessInMM); CPPUNIT_ASSERT_MESSAGE("Testing SetExtentInMM(2, ...), querying by GetExtentInMM(2): ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing SetExtentInMM(2, ...), querying by GetAxisVector(2) and comparing to normal: ", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); planegeometry->SetOrigin(origin); CPPUNIT_ASSERT_MESSAGE("Testing SetOrigin", mitk::Equal(planegeometry->GetOrigin(), origin, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Right", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Bottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Normal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom); } void TestRotate() { // Changing the IndexToWorldTransform to a rotated version by SetIndexToWorldTransform() (keep origin): mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New(); mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix; vnlmatrix = planegeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix(); mitk::VnlVector axis(3); mitk::FillVector3D(axis, 1.0, 1.0, 1.0); axis.normalize(); vnl_quaternion rotation(axis, 0.223); vnlmatrix = rotation.rotation_matrix_transpose() * vnlmatrix; mitk::Matrix3D matrix; matrix = vnlmatrix; transform->SetMatrix(matrix); transform->SetOffset(planegeometry->GetIndexToWorldTransform()->GetOffset()); right.SetVnlVector(rotation.rotation_matrix_transpose() * right.GetVnlVector()); bottom.SetVnlVector(rotation.rotation_matrix_transpose() * bottom.GetVnlVector()); normal.SetVnlVector(rotation.rotation_matrix_transpose() * normal.GetVnlVector()); planegeometry->SetIndexToWorldTransform(transform); // The origin changed,because m_Origin=m_IndexToWorldTransform->GetOffset()+GetAxisVector(2)*0.5 // and the AxisVector changes due to the rotation. In other words: the rotation was done around // the corner of the box, not around the planes origin. Now change it to a rotation around // the origin, simply by re-setting the origin to the original one: planegeometry->SetOrigin(origin); CPPUNIT_ASSERT_MESSAGE("Testing whether SetIndexToWorldTransform kept origin: ", mitk::Equal(planegeometry->GetOrigin(), origin, testEps)); mitk::Point2D point; point[0] = 4; point[1] = 3; mitk::Point2D dummy; planegeometry->WorldToIndex(point, dummy); planegeometry->IndexToWorld(dummy, dummy); CPPUNIT_ASSERT_MESSAGE("Testing consistency of index and world coordinates.", dummy == point); CPPUNIT_ASSERT_MESSAGE("Testing width of rotated version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height of rotated version: ", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness of rotated version: ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: right ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: bottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: normal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ", mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(), planegeometry->GetExtentInMM(0), testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ", mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(), planegeometry->GetExtentInMM(1), testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ", mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(), planegeometry->GetExtentInMM(2), testEps)); mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom); width *= 2; height *= 3; planegeometry->SetSizeInUnits(width, height); CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ", mitk::Equal(planegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ", mitk::Equal(planegeometry->GetExtent(1), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of version with changed size in units: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of version with changed size in units: ", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of version with changed size in units: ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: right ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: bottom", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: normal", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ", mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(), planegeometry->GetExtentInMM(0), testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ", mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(), planegeometry->GetExtentInMM(1), testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ", mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(), planegeometry->GetExtentInMM(2), testEps)); mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom); } void TestClone() { mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast(planegeometry->Clone().GetPointer()); // Cave: Statement below is negated! CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ", !((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount() != 1))); CPPUNIT_ASSERT_MESSAGE("Testing origin of cloned version: ", mitk::Equal(clonedplanegeometry->GetOrigin(), origin, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtent(1), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing extent (in units) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of cloned version: ", mitk::Equal(clonedplanegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: right", mitk::Equal(clonedplanegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: bottom", mitk::Equal(clonedplanegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: normal", mitk::Equal(clonedplanegeometry->GetAxisVector(2), normal, testEps)); mappingTests2D(clonedplanegeometry, width, height, widthInMM, heightInMM, origin, right, bottom); } void TestSaggitalInitialization() { mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0); mitk::PlaneGeometry::Pointer clonedplanegeometry = planegeometry->Clone(); // Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Sagittal, zPosition = 0, frontside=true): planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Sagittal); mitk::Vector3D newright, newbottom, newnormal; mitk::ScalarType newthicknessInMM; newright = bottom; newthicknessInMM = widthInMM / width * 1.0; // extent in normal direction is 1; newnormal = right; newnormal.Normalize(); newnormal *= newthicknessInMM; newbottom = normal; newbottom.Normalize(); newbottom *= thicknessInMM; CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of sagitally initialized version:", mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps)); // ok, corner was fine, so we can dare to believe the origin is ok. origin = planegeometry->GetOrigin(); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps)); mappingTests2D(planegeometry, height, 1, heightInMM, thicknessInMM, origin, newright, newbottom); // set origin back to the one of the axial slice: origin = clonedplanegeometry->GetOrigin(); // Testing backside initialization: InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition // = 0, frontside=false, rotated=true): planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Axial, 0, false, true); mitk::Point3D backsideorigin; backsideorigin = origin + clonedplanegeometry->GetAxisVector(1); //+clonedplanegeometry->GetAxisVector(2); CPPUNIT_ASSERT_MESSAGE("Testing origin of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetOrigin(), backsideorigin, testEps)); mitk::Point3D backsidecornerpoint0; backsidecornerpoint0 = cornerpoint0 + clonedplanegeometry->GetAxisVector(1); //+clonedplanegeometry->GetAxisVector(2); CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of sagitally initialized version: ", mitk::Equal(planegeometry->GetCornerPoint(0), backsidecornerpoint0, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version " "(should be same as in mm due to unit spacing, except for thickness, which is always 1): ", mitk::Equal(planegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version " "(should be same as in mm due to unit spacing, except for thickness, which is always 1): ", mitk::Equal(planegeometry->GetExtent(1), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version " "(should be same as in mm due to unit spacing, except for thickness, which is always 1): ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), -bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); // T22254: Flipped sign mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, backsideorigin, right, -bottom); } void TestFrontalInitialization() { mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0); mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast(planegeometry->Clone().GetPointer()); //-------- mitk::Vector3D newright, newbottom, newnormal; mitk::ScalarType newthicknessInMM; // Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Frontal, zPosition = 0, frontside=true) planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Frontal); newright = right; newbottom = normal; newbottom.Normalize(); newbottom *= thicknessInMM; newthicknessInMM = heightInMM / height * 1.0 /*extent in normal direction is 1*/; newnormal = -bottom; newnormal.Normalize(); newnormal *= newthicknessInMM; CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of frontally initialized version: ", mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps)); // ok, corner was fine, so we can dare to believe the origin is ok. origin = planegeometry->GetOrigin(); CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness (in units) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), -newnormal, testEps)); // T22254: Flipped sign mappingTests2D(planegeometry, width, 1, widthInMM, thicknessInMM, origin, newright, newbottom); // Changing plane to in-plane unit spacing using SetSizeInUnits: planegeometry->SetSizeInUnits(planegeometry->GetExtentInMM(0), planegeometry->GetExtentInMM(1)); CPPUNIT_ASSERT_MESSAGE("Testing origin of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetOrigin(), origin, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), -newnormal, testEps)); // T22254: Flipped sign mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom); // Changing plane to unit spacing also in normal direction using SetExtentInMM(2, 1.0): planegeometry->SetExtentInMM(2, 1.0); newnormal.Normalize(); CPPUNIT_ASSERT_MESSAGE("Testing origin of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetOrigin(), origin, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE( "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), 1.0, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), -newnormal, testEps)); // T22254: Flipped sign mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom); } void TestAxialInitialization() { mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0); // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane' mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast(planegeometry->Clone().GetPointer()); CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ", !((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount() != 1))); std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition = 0, " "frontside=true): " << std::endl; planegeometry->InitializeStandardPlane(clonedplanegeometry); CPPUNIT_ASSERT_MESSAGE("Testing origin of axially initialized version: ", mitk::Equal(planegeometry->GetOrigin(), origin)); CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of axially initialized version: ", mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0)); CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of axially initialized version (should be same as in mm due to " "unit spacing, except for thickness, which is always 1): ", mitk::Equal(planegeometry->GetExtent(0), width, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of axially initialized version (should be same as in mm due to " "unit spacing, except for thickness, which is always 1): ", mitk::Equal(planegeometry->GetExtent(1), height, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness (in units) of axially initialized version (should be same as in mm due " "to unit spacing, except for thickness, which is always 1): ", mitk::Equal(planegeometry->GetExtent(2), 1, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of axially initialized version: ", mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(0), right, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps)); CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ", mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom); } void TestPlaneComparison() { // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane' mitk::PlaneGeometry::Pointer clonedplanegeometry2 = dynamic_cast(planegeometry->Clone().GetPointer()); CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ", !((clonedplanegeometry2.IsNull()) || (clonedplanegeometry2->GetReferenceCount() != 1))); CPPUNIT_ASSERT_MESSAGE("Testing wheter original and clone are at the same position", clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer())); CPPUNIT_ASSERT_MESSAGE(" Asserting that origin is on the plane cloned plane:", clonedplanegeometry2->IsOnPlane(origin)); mitk::VnlVector newaxis(3); mitk::FillVector3D(newaxis, 1.0, 1.0, 1.0); newaxis.normalize(); vnl_quaternion rotation2(newaxis, 0.0); mitk::Vector3D clonednormal = clonedplanegeometry2->GetNormal(); mitk::Point3D clonedorigin = clonedplanegeometry2->GetOrigin(); auto planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), 180.0); clonedplanegeometry2->ExecuteOperation(planerot); CPPUNIT_ASSERT_MESSAGE(" Asserting that a flipped plane is still on the original plane: ", clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer())); clonedorigin += clonednormal; clonedplanegeometry2->SetOrigin(clonedorigin); CPPUNIT_ASSERT_MESSAGE("Testing if the translated (cloned, flipped) plane is parallel to its origin plane: ", clonedplanegeometry2->IsParallel(planegeometry)); delete planerot; planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), 0.5); clonedplanegeometry2->ExecuteOperation(planerot); CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as not paralell [rotation +0.5 degree] : ", !clonedplanegeometry2->IsParallel(planegeometry)); delete planerot; planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), -1.0); clonedplanegeometry2->ExecuteOperation(planerot); CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as not paralell [rotation -0.5 degree] : ", !clonedplanegeometry2->IsParallel(planegeometry)); delete planerot; planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), 360.5); clonedplanegeometry2->ExecuteOperation(planerot); CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as paralell [rotation 360 degree] : ", clonedplanegeometry2->IsParallel(planegeometry)); } private: // helper Methods for the Tests mitk::PlaneGeometry::Pointer createPlaneGeometry() { mitk::Vector3D mySpacing; mySpacing[0] = 31; mySpacing[1] = 0.1; mySpacing[2] = 5.4; mitk::Point3D myOrigin; myOrigin[0] = 8; myOrigin[1] = 9; myOrigin[2] = 10; mitk::AffineTransform3D::Pointer myTransform = mitk::AffineTransform3D::New(); itk::Matrix transMatrix; transMatrix.Fill(0); transMatrix[0][0] = 1; transMatrix[1][1] = 2; transMatrix[2][2] = 4; myTransform->SetMatrix(transMatrix); mitk::PlaneGeometry::Pointer geometry2D = mitk::PlaneGeometry::New(); geometry2D->SetIndexToWorldTransform(myTransform); geometry2D->SetSpacing(mySpacing); geometry2D->SetOrigin(myOrigin); return geometry2D; } bool compareMatrix(itk::Matrix left, itk::Matrix right) { bool equal = true; for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) equal &= mitk::Equal(left[i][j], right[i][j]); return equal; } /** * This function tests for correct mapping and is called several times from other tests **/ void mappingTests2D(const mitk::PlaneGeometry *planegeometry, const mitk::ScalarType &width, const mitk::ScalarType &height, const mitk::ScalarType &widthInMM, const mitk::ScalarType &heightInMM, const mitk::Point3D &origin, const mitk::Vector3D &right, const mitk::Vector3D &bottom) { std::cout << "Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected: "; mitk::Point2D pt2d_mm; mitk::Point3D pt3d_mm, expected_pt3d_mm; pt2d_mm[0] = widthInMM / 2.3; pt2d_mm[1] = heightInMM / 2.5; expected_pt3d_mm = origin + right * (pt2d_mm[0] / right.GetNorm()) + bottom * (pt2d_mm[1] / bottom.GetNorm()); planegeometry->Map(pt2d_mm, pt3d_mm); CPPUNIT_ASSERT_MESSAGE( "Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected", mitk::Equal(pt3d_mm, expected_pt3d_mm, testEps)); std::cout << "Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected: "; mitk::Point2D testpt2d_mm; planegeometry->Map(pt3d_mm, testpt2d_mm); std::cout << std::setprecision(12) << "Expected pt2d_mm " << pt2d_mm << std::endl; std::cout << std::setprecision(12) << "Result testpt2d_mm " << testpt2d_mm << std::endl; std::cout << std::setprecision(12) << "10*mitk::eps " << 10 * mitk::eps << std::endl; // This eps is temporarily set to 10*mitk::eps. See bug #15037 for details. CPPUNIT_ASSERT_MESSAGE("Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected", mitk::Equal(pt2d_mm, testpt2d_mm, 10 * mitk::eps)); std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: "; mitk::Point2D pt2d_units; pt2d_units[0] = width / 2.0; pt2d_units[1] = height / 2.0; pt2d_mm[0] = widthInMM / 2.0; pt2d_mm[1] = heightInMM / 2.0; planegeometry->IndexToWorld(pt2d_units, testpt2d_mm); std::cout << std::setprecision(12) << "Expected pt2d_mm " << pt2d_mm << std::endl; std::cout << std::setprecision(12) << "Result testpt2d_mm " << testpt2d_mm << std::endl; std::cout << std::setprecision(12) << "10*mitk::eps " << 10 * mitk::eps << std::endl; // This eps is temporarily set to 10*mitk::eps. See bug #15037 for details. CPPUNIT_ASSERT_MESSAGE("Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ", mitk::Equal(pt2d_mm, testpt2d_mm, 10 * mitk::eps)); std::cout << "Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected: "; mitk::Point2D testpt2d_units; planegeometry->WorldToIndex(pt2d_mm, testpt2d_units); std::cout << std::setprecision(12) << "Expected pt2d_units " << pt2d_units << std::endl; std::cout << std::setprecision(12) << "Result testpt2d_units " << testpt2d_units << std::endl; std::cout << std::setprecision(12) << "10*mitk::eps " << 10 * mitk::eps << std::endl; // This eps is temporarily set to 10*mitk::eps. See bug #15037 for details. CPPUNIT_ASSERT_MESSAGE("Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected:", mitk::Equal(pt2d_units, testpt2d_units, 10 * mitk::eps)); } }; MITK_TEST_SUITE_REGISTRATION(mitkPlaneGeometry) diff --git a/Modules/Core/test/mitkSlicedGeometry3DTest.cpp b/Modules/Core/test/mitkSlicedGeometry3DTest.cpp index 0a06d1db10..9e532acfd5 100644 --- a/Modules/Core/test/mitkSlicedGeometry3DTest.cpp +++ b/Modules/Core/test/mitkSlicedGeometry3DTest.cpp @@ -1,184 +1,184 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkImage.h" #include "mitkPlaneGeometry.h" #include "mitkSlicedGeometry3D.h" #include "mitkTestingMacros.h" #include -#include +#include #include #include static const mitk::ScalarType slicedGeometryEps = 1e-9; // Set epsilon to float precision for this test static mitk::PlaneGeometry::Pointer createPlaneGeometry() { auto planeGeometry = mitk::PlaneGeometry::New(); planeGeometry->Initialize(); return planeGeometry; } static mitk::SlicedGeometry3D::Pointer createSlicedGeometry(const mitk::Point3D &origin, const mitk::Vector3D &spacing, int numberOfSlices) { auto slicedGeometry = mitk::SlicedGeometry3D::New(); slicedGeometry->InitializeSlicedGeometry(static_cast(numberOfSlices)); slicedGeometry->SetOrigin(origin); slicedGeometry->SetSpacing(spacing); for (unsigned int i = 0; i < numberOfSlices; ++i) { auto planeGeometry = createPlaneGeometry(); slicedGeometry->SetPlaneGeometry(planeGeometry, i); } return slicedGeometry; } static mitk::SlicedGeometry3D::Pointer createEvenlySpacedSlicedGeometry(mitk::PlaneGeometry::Pointer planeGeometry, mitk::ScalarType spacing, int numberOfSlices) { auto slicedGeometry = mitk::SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(planeGeometry, spacing, numberOfSlices); return slicedGeometry; } template static T createArray(mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z) { T array; mitk::FillVector3D(array, x, y, z); return array; } static mitk::Point3D createPoint(mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z) { return createArray(x, y, z); } static mitk::Vector3D createVector(mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z) { return createArray(x, y, z); } static mitk::VnlVector createVnlVector(mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z) { mitk::VnlVector vector(3); mitk::FillVector3D(vector, x, y, z); return vector; } void mitkSlicedGeometry3D_ChangeImageGeometryConsideringOriginOffset_Test() { MITK_TEST_OUTPUT(<< "====== mitkSlicedGeometry3D_ChangeImageGeometryConsideringOriginOffset_Test() ======"); auto origin = createPoint(91.3, -13.3, 0); auto spacing = createVector(1.0, 0.9, 0.3); auto numberOfSlices = 5; auto slicedGeometry = createSlicedGeometry(origin, spacing, numberOfSlices); MITK_TEST_OUTPUT(<< "SlicedGeometry3D isn't an image geometry by default"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetImageGeometry() == false, ""); MITK_TEST_OUTPUT(<< "First and last PlaneGeometry in SlicedGeometry3D are not image geometries"); auto firstPlaneGeometry = slicedGeometry->GetPlaneGeometry(0); auto lastPlaneGeometry = slicedGeometry->GetPlaneGeometry(numberOfSlices - 1); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetImageGeometry() == false, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetImageGeometry() == false, ""); auto originOfSlicedGeometry = slicedGeometry->GetOrigin(); auto originOfFirstPlaneGeometry = firstPlaneGeometry->GetOrigin(); auto originOfLastPlaneGeometry = lastPlaneGeometry->GetOrigin(); auto firstCornerPointOfSlicedGeometry = slicedGeometry->GetCornerPoint(0); auto secondCornerPointOfFirstPlaneGeometry = firstPlaneGeometry->GetCornerPoint(1); auto thirdCornerPointOfLastPlaneGeometry = lastPlaneGeometry->GetCornerPoint(2); MITK_TEST_OUTPUT(<< "Calling SlicedGeometry3D::ChangeImageGeometryConsideringOriginOffset(true)"); slicedGeometry->ChangeImageGeometryConsideringOriginOffset(true); MITK_TEST_OUTPUT(<< "SlicedGeometry3D is an image geometry"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetImageGeometry() == true, ""); MITK_TEST_OUTPUT(<< "First and last PlaneGeometry in SlicedGeometry3D are image geometries"); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetImageGeometry() == true, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetImageGeometry() == true, ""); MITK_TEST_OUTPUT(<< "Corner points of geometries didn't change"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetCornerPoint(0) == firstCornerPointOfSlicedGeometry, ""); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetCornerPoint(1) == secondCornerPointOfFirstPlaneGeometry, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetCornerPoint(2) == thirdCornerPointOfLastPlaneGeometry, ""); MITK_TEST_OUTPUT(<< "Offsets were added to geometry origins"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetOrigin() == originOfSlicedGeometry + slicedGeometry->GetSpacing() * 0.5, ""); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetOrigin() == originOfFirstPlaneGeometry + firstPlaneGeometry->GetSpacing() * 0.5, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetOrigin() == originOfLastPlaneGeometry + lastPlaneGeometry->GetSpacing() * 0.5, ""); MITK_TEST_OUTPUT(<< "Calling SlicedGeometry3D::ChangeImageGeometryConsideringOriginOffset(false)"); slicedGeometry->ChangeImageGeometryConsideringOriginOffset(false); MITK_TEST_OUTPUT(<< "SlicedGeometry3D isn't an image geometry anymore"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetImageGeometry() == false, ""); MITK_TEST_OUTPUT(<< "First and last PlaneGeometry in SlicedGeometry3D are no image geometries anymore"); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetImageGeometry() == false, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetImageGeometry() == false, ""); MITK_TEST_OUTPUT(<< "Corner points of geometries didn't change"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetCornerPoint(0) == firstCornerPointOfSlicedGeometry, ""); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetCornerPoint(1) == secondCornerPointOfFirstPlaneGeometry, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetCornerPoint(2) == thirdCornerPointOfLastPlaneGeometry, ""); MITK_TEST_OUTPUT(<< "Offsets were subtracted from geometry origins"); MITK_TEST_CONDITION_REQUIRED(slicedGeometry->GetOrigin() == originOfSlicedGeometry, ""); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry->GetOrigin() == originOfFirstPlaneGeometry, ""); MITK_TEST_CONDITION_REQUIRED(lastPlaneGeometry->GetOrigin() == originOfLastPlaneGeometry, ""); } int mitkSlicedGeometry3DTest(int, char *[]) { mitk::ScalarType width = 100.0; mitk::ScalarType widthInMM = width; mitk::ScalarType height = 200.0; mitk::ScalarType heightInMM = height; mitk::ScalarType thicknessInMM = 3.0; auto right = createVector(widthInMM, 0.0, 0.0); auto bottom = createVector(0.0, heightInMM, 0.0); auto normal = createVector(0.0, 0.0, thicknessInMM); auto spacing = createVector(1.0, 1.0, thicknessInMM); auto planeGeometry = mitk::PlaneGeometry::New(); planeGeometry->InitializeStandardPlane(right, bottom, &spacing); auto numberOfSlices = 5; auto slicedGeometry = createEvenlySpacedSlicedGeometry(planeGeometry, thicknessInMM, numberOfSlices); auto firstPlaneGeometry = slicedGeometry->GetPlaneGeometry(0); MITK_TEST_OUTPUT(<< "Check if first PlaneGeometry of evenly spaced SlicedGeometry is valid"); MITK_TEST_CONDITION_REQUIRED(firstPlaneGeometry != nullptr, ""); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(firstPlaneGeometry->GetAxisVector(0), planeGeometry->GetAxisVector(0), slicedGeometryEps), ""); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(firstPlaneGeometry->GetAxisVector(1), planeGeometry->GetAxisVector(1), slicedGeometryEps), ""); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(firstPlaneGeometry->GetAxisVector(2), planeGeometry->GetAxisVector(2), slicedGeometryEps), ""); auto lastPlaneGeometry = slicedGeometry->GetPlaneGeometry(numberOfSlices - 1); auto expectedOriginOfLastSlice = createPoint(0.0, 0.0, thicknessInMM * (numberOfSlices - 1)); MITK_TEST_OUTPUT(<< "Check if origin of last PlaneGeometry is at expected location"); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(lastPlaneGeometry->GetOrigin(), expectedOriginOfLastSlice, slicedGeometryEps), ""); mitkSlicedGeometry3D_ChangeImageGeometryConsideringOriginOffset_Test(); std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } diff --git a/Modules/Core/test/mitkVectorTest.cpp b/Modules/Core/test/mitkVectorTest.cpp index 8e7794e5ba..3b0ec9ebbf 100644 --- a/Modules/Core/test/mitkVectorTest.cpp +++ b/Modules/Core/test/mitkVectorTest.cpp @@ -1,171 +1,171 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include -#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] - mitk::eps * 1.1; itkVector_3[i] = itkVector_1[i] - mitk::eps * 0.9; } MITK_TEST_CONDITION(mitk::Equal(itkVector_1, itkVector_1), "Test vector equality using the same vector with mitk::eps"); MITK_TEST_CONDITION( !mitk::Equal(itkVector_1, itkVector_2), "Test vector equality using different vectors with an element-wise difference greater than mitk::eps"); MITK_TEST_CONDITION(mitk::Equal(itkVector_1, itkVector_2, mitk::eps * 1.2), "Vectors are equal for higher epsilon tolerance ( 1.2 * mitk::eps )"); MITK_TEST_CONDITION( 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(mitk::Equal(itkPoint_1, itkPoint_1), "Test point equality using the same point with mitk::eps"); MITK_TEST_CONDITION( !mitk::Equal(itkPoint_1, itkPoint_2), "Test point equality using different points with an element-wise difference greater than mitk::eps"); MITK_TEST_CONDITION(mitk::Equal(itkPoint_1, itkPoint_2, mitk::eps * 1.2), "Points are equal for higher epsilon tolerance ( 1.2 * mitk::eps )"); MITK_TEST_CONDITION(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_1[i]); } MITK_TEST_CONDITION(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(!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(mitk::Equal(mitk_vnl_vector_1, mitk_vnl_vector_2, mitk::eps * 1.2), "Vnl vectors are equal for higher epsilon tolerance ( 1.2 * mitk::eps )"); MITK_TEST_CONDITION(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 typedef mitk::ScalarType VnlValueType; vnl_vector_fixed vnlVector_1; vnlVector_1[3] = 56.98; vnlVector_1[4] = 22.32; vnlVector_1[5] = 1.00; vnlVector_1[6] = 746.09; 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] - mitk::eps * 1.1f; vnlVector_3[i] = vnlVector_1[i] - mitk::eps * 0.9f; } MITK_TEST_CONDITION((mitk::Equal(vnlVector_1, vnlVector_1)), "vnl_fixed : v_1 == v_1 "); // the v_2 is constructed so that the equality test fails for mitk::eps, the norm of the difference between the // vectors is 7 * eps/6.9 MITK_TEST_CONDITION(!(mitk::Equal(vnlVector_1, vnlVector_2)), "vnl_fixed : v_1 != v_2 with mitk::eps "); // increase the epsilon value used for testing equality - should now pass ( 1.2 * mitk::eps > 7 * mitk::eps/6.9 ) MITK_TEST_CONDITION((mitk::Equal(vnlVector_1, vnlVector_2, mitk::eps * 1.2f)), "vnl_fixed : v_1 == v_2 with eps = 1.2 * mitk::eps "); MITK_TEST_CONDITION((mitk::Equal(vnlVector_1, vnlVector_3, mitk::eps)), "vnl_fixed : v_1 == v_3 with eps = 0.8 * mitk::eps "); MITK_TEST_CONDITION(!(mitk::Equal(vnlVector_1, vnlVector_3, mitk::eps * 0.8f)), "vnl_fixed : v_1 != v_3 with eps = 0.8 * mitk::eps "); // test scalar equality method mitk::ScalarType scalar1 = 0.5689; mitk::ScalarType scalar2 = scalar1 + mitk::eps * 1.01; mitk::ScalarType scalar3 = scalar1; mitk::ScalarType scalar4 = scalar1 + mitk::eps * 0.95; MITK_TEST_CONDITION(mitk::Equal(scalar1, scalar1), "Test scalar equality using the same scalar with mitk::eps"); MITK_TEST_CONDITION(!mitk::Equal(scalar1, scalar2), "Test scalar equality using the different scalars with a difference greater than mitk::eps"); MITK_TEST_CONDITION(mitk::Equal(scalar1, scalar3), "Test scalar equality using the different scalars with a difference equal to mitk::eps"); MITK_TEST_CONDITION(mitk::Equal(scalar1, scalar4), "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(mitk::MatrixEqualElementWise(vnlMatrix3x3_1, vnlMatrix3x3_1, mitk::eps), "Test for matrix equality with given epsilon=mitk::eps and exactly the same matrix elements"); MITK_TEST_CONDITION(!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(mitk::MatrixEqualElementWise(vnlMatrix3x3_1, vnlMatrix3x3_2, epsilon), "Test for matrix equality with given epsilon and slightly different matrix elements"); MITK_TEST_CONDITION(!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(mitk::MatrixEqualRMS(vnlMatrix3x3_1, vnlMatrix3x3_2, epsilon), "Test for matrix equality with given epsilon and slightly different matrix elements"); MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/Registration/mitkPyramidImageRegistrationMethod.h b/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/Registration/mitkPyramidImageRegistrationMethod.h index f8709320fd..2ca89703d7 100644 --- a/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/Registration/mitkPyramidImageRegistrationMethod.h +++ b/Modules/DiffusionImaging/DiffusionCore/include/Algorithms/Registration/mitkPyramidImageRegistrationMethod.h @@ -1,341 +1,341 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKPYRAMIDIMAGEREGISTRATION_H #define MITKPYRAMIDIMAGEREGISTRATION_H #include #include #include "itkImageMaskSpatialObject.h" #include "itkNotImageFilter.h" #include #include #include "mitkImage.h" #include "mitkBaseProcess.h" #include "mitkPyramidRegistrationMethodHelper.h" #include #include "mitkImageToItk.h" #include "mitkImageCast.h" #include "mitkImageCaster.h" #include "mitkITKImageImport.h" #include "mitkIOUtil.h" namespace mitk { /** * @brief The PyramidImageRegistration class implements a multi-scale registration method * * The PyramidImageRegistration class is suitable for aligning (f.e.) brain MR images. The method offers two * transform types * - Rigid: optimizing translation and rotation only and * - Affine ( default ): with scaling in addition ( 12 DOF ) * * The error metric is internally chosen based on the selected task type : \sa SetCrossModalityOn * * It uses * - MattesMutualInformation for CrossModality=on ( default ) and * - NormalizedCorrelation for CrossModality=off. */ class MITKDIFFUSIONCORE_EXPORT PyramidImageRegistrationMethod : public itk::Object { public: /** Typedefs */ mitkClassMacroItkParent(PyramidImageRegistrationMethod, itk::Object) /** Smart pointer support */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) typedef itk::OptimizerParameters ParametersType; /** Typedef for the transformation matrix, corresponds to the InternalMatrixType from ITK transforms */ typedef vnl_matrix_fixed< double, 3, 3> TransformMatrixType; typedef itk::AffineTransform< double > AffineTransformType; typedef itk::Euler3DTransform< double > RigidTransformType; /** Registration is between modalities - will take MattesMutualInformation as error metric */ void SetCrossModalityOn() { m_CrossModalityRegistration = true; } /** Registration is between modalities - will take NormalizedCorrelation as error metric */ void SetCrossModalityOff() { m_CrossModalityRegistration = false; } /** Turn the cross-modality on/off */ void SetCrossModality(bool flag) { if( flag ) this->SetCrossModalityOn(); else this->SetCrossModalityOff(); } /** Controll the verbosity of the registration output * * for true, each iteration step of the optimizer is watched and passed to the std::cout */ void SetVerbose(bool flag) { if( flag ) this->SetVerboseOn(); else this->SetVerboseOff(); } /** Turn verbosity on, \sa SetVerbose */ void SetVerboseOn() { m_Verbose = true; } /** Turn verbosity off, \sa SetVerbose */ void SetVerboseOff() { m_Verbose = false; } /** A rigid ( 6dof : translation + rotation ) transform is optimized */ void SetTransformToRigid() { m_UseAffineTransform = false; } /** An affine ( 12dof : Rigid + scale + skew ) transform is optimized */ void SetTransformToAffine() { m_UseAffineTransform = true; } /** Input image, the reference one */ void SetFixedImage( mitk::Image::Pointer ); /** Input image, the one to be transformed */ void SetMovingImage( mitk::Image::Pointer ); /** Fixed image mask, excludes the masked voxels from the registration metric*/ void SetFixedImageMask( mitk::Image::Pointer mask); /** \brief Use the itk::CenteredVersorTransformInitializer to perform initialization step for the registration * * The initializer takes the geometries and their features to perform an initialization for the successive registration */ void SetInitializeByGeometry(bool flag) { m_InitializeByGeometry = flag; } void Update(); /** * @brief Get the number of parameters optimized ( 12 or 6 ) * * @return number of paramters */ unsigned int GetNumberOfParameters() { unsigned int retValue = 12; if(!m_UseAffineTransform) retValue = 6; return retValue; } /** * @brief Copies the estimated parameters to the given array * @param paramArray, target array for copy, make sure to allocate enough space */ void GetParameters( double* paramArray) { if( m_EstimatedParameters == NULL ) { mitkThrow() << "No parameters were estimated yet, call Update() first."; } unsigned int dim = 12; if( !m_UseAffineTransform ) dim = 6; for( unsigned int i=0; i * * It returns identity if the internal parameters are not-yet allocated ( i.e. the filter did not run yet ) * * @return \sa TransformMatrixType */ TransformMatrixType GetLastRotationMatrix(); protected: PyramidImageRegistrationMethod(); ~PyramidImageRegistrationMethod(); /** Fixed image, used as reference for registration */ mitk::Image::Pointer m_FixedImage; /** Moving image, will be transformed */ mitk::Image::Pointer m_MovingImage; mitk::Image::Pointer m_FixedImageMask; bool m_CrossModalityRegistration; bool m_UseAffineTransform; bool m_UseWindowedSincInterpolator; bool m_UseNearestNeighborInterpolator; bool m_UseMask; double* m_EstimatedParameters; ParametersType m_InitialParameters; /** Control the verbosity of the regsitistration output */ bool m_Verbose; bool m_InitializeByGeometry; /** * @brief The method takes two itk::Images and performs a multi-scale registration on them * * Can be accessed by the AccessTwoImagesFixedDimensionByItk macro. * * @note Currently the access is currently reduced only for short and float ( the only types occuring with mitk::DiffusionImage ) and * hence the method is accessed by means of the \sa AccessTwoImagesFixedDimensionTypeSubsetByItk macro. */ template void RegisterTwoImagesV4(itk::Image* itkImage1, itk::Image* itkImage2); /** * @brief ResampleMitkImage applies the functionality of an the itk::ResampleImageFilter to the given * mitk::Image. * * The API of the function is conform to the interface of \sa AccessByItk_1 macros. */ template< typename TPixel, unsigned int VDimension> void ResampleMitkImage( itk::Image* itkImage, mitk::Image::Pointer& outputImage ); }; } // end namespace #endif // MITKPYRAMIDIMAGEREGISTRATION_H diff --git a/Modules/Segmentation/Algorithms/itkConnectedAdaptiveThresholdImageFilter.txx b/Modules/Segmentation/Algorithms/itkConnectedAdaptiveThresholdImageFilter.txx index 28face6748..6d740e27f0 100644 --- a/Modules/Segmentation/Algorithms/itkConnectedAdaptiveThresholdImageFilter.txx +++ b/Modules/Segmentation/Algorithms/itkConnectedAdaptiveThresholdImageFilter.txx @@ -1,297 +1,300 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _itkConnectedAdaptiveThresholdImageFilter_txx #define _itkConnectedAdaptiveThresholdImageFilter_txx #include "itkAdaptiveThresholdIterator.h" #include "itkBinaryThresholdImageFunction.h" #include "itkConnectedAdaptiveThresholdImageFilter.h" #include "itkMinimumMaximumImageFilter.h" #include "itkThresholdImageFilter.h" namespace itk { /** * Constructor */ template ConnectedAdaptiveThresholdImageFilter::ConnectedAdaptiveThresholdImageFilter() : m_FineDetectionMode(false) { } template void ConnectedAdaptiveThresholdImageFilter::GenerateData() { typename ConnectedAdaptiveThresholdImageFilter::InputImageConstPointer inputImage = this->GetInput(); typename ConnectedAdaptiveThresholdImageFilter::OutputImagePointer outputImage = this->GetOutput(); typename Superclass::InputPixelObjectType::Pointer lowerThreshold = this->GetLowerInput(); typename Superclass::InputPixelObjectType::Pointer upperThreshold = this->GetUpperInput(); // kommt drauf, wie wir hier die Pipeline aufbauen - Superclass::m_Lower = lowerThreshold->Get(); - Superclass::m_Upper = upperThreshold->Get(); + this->SetLower(lowerThreshold->Get()); + this->SetUpper(upperThreshold->Get()); typedef BinaryThresholdImageFunction FunctionType; typedef AdaptiveThresholdIterator IteratorType; - int initValue = IteratorType::CalculateInitializeValue((int)Superclass::m_Lower, (int)Superclass::m_Upper); + int initValue = IteratorType::CalculateInitializeValue((int)(this->GetLower()), (int)(this->GetUpper())); // Initialize the output according to the segmentation (fine or raw) if (m_FineDetectionMode) { outputImage = this->m_OutoutImageMaskFineSegmentation; } typename ConnectedAdaptiveThresholdImageFilter::OutputImageRegionType region = outputImage->GetRequestedRegion(); outputImage->SetBufferedRegion(region); outputImage->Allocate(); if (!m_FineDetectionMode) { // only initalize the output image if we are using the raw segmentation mode outputImage->FillBuffer((typename ConnectedAdaptiveThresholdImageFilter::OutputImagePixelType)initValue); } typename FunctionType::Pointer function = FunctionType::New(); function->SetInputImage(inputImage); + typename Superclass::SeedContainerType seeds; + seeds = this->GetSeeds(); + // pass parameters needed for region growing to iterator - IteratorType it(outputImage, function, this->m_Seeds); + IteratorType it(outputImage, function, seeds); it.SetFineDetectionMode(m_FineDetectionMode); it.SetExpansionDirection(m_GrowingDirectionIsUpwards); - it.SetMinTH((int)Superclass::m_Lower); - it.SetMaxTH((int)Superclass::m_Upper); + it.SetMinTH((int)(this->GetLower())); + it.SetMaxTH((int)(this->GetUpper())); it.GoToBegin(); this->m_SeedpointValue = it.GetSeedPointValue(); - if (Superclass::m_Lower > this->m_SeedpointValue || this->m_SeedpointValue > Superclass::m_Upper) + if ((this->GetLower()) > this->m_SeedpointValue || this->m_SeedpointValue > (this->GetUpper())) { // set m_SegmentationCancelled to true, so if it doesn't reach the point where it is set back to false // we can asssume that there was an error this->m_SegmentationCancelled = true; return; } // iterate through image until while (!it.IsAtEnd()) { // make iterator go one step further (calls method DoFloodStep()) ++it; } this->m_DetectedLeakagePoint = it.GetLeakagePoint(); this->m_SegmentationCancelled = false; } template TOutputImage *itk::ConnectedAdaptiveThresholdImageFilter::GetResultImage() { return m_OutoutImageMaskFineSegmentation; } template typename ConnectedAdaptiveThresholdImageFilter::IndexType itk::ConnectedAdaptiveThresholdImageFilter::CorrectSeedPointPosition( unsigned int sizeOfVolume, int lowerTh, int upperTh) { typename ConnectedAdaptiveThresholdImageFilter::InputImageConstPointer inputImage = this->GetInput(); typedef typename TInputImage::IndexType IndexType; IndexType itkIntelligentSeedIndex; int seedPixelValue = inputImage->GetPixel(m_SeedPointIndex); // set new seed index to the voxel with the darkest value and shortest distance to original seed if (seedPixelValue > upperTh || seedPixelValue < lowerTh) { // MITK_INFO << "seed pixel value [BEFORE] = " << seedPixelValue; // ToDo crop region itk::Index<3> workindex; for (int i = 0; i < 3; i++) { workindex[i] = m_SeedPointIndex[i] - sizeOfVolume / 2; if (workindex[i] < 0) workindex[i] = 0; } itk::Size<3> worksize; for (int i = 0; i < 3; i++) { worksize[i] = sizeOfVolume; } itk::ImageRegion<3> workregion(workindex, worksize); itk::ImageRegionIterator regionIt(const_cast(inputImage.GetPointer()), workregion); // int darkestGrayValue=seedPixelValue; int currentGrayValue; float distance = (float)(sizeOfVolume / 2); float relativeDistance = 1; // between 0 and 1 mitk::Vector3D seedVector, currentVector; mitk::FillVector3D(seedVector, m_SeedPointIndex[0], m_SeedPointIndex[1], m_SeedPointIndex[2]); currentVector = seedVector; float costValue = 0; // beware, Depending on seeking upper or lower value... for (regionIt.GoToBegin(); !regionIt.IsAtEnd(); ++regionIt) { // get current gray value currentGrayValue = regionIt.Value(); // get current seed index m_SeedPointIndex = regionIt.GetIndex(); // fill current vector mitk::FillVector3D(currentVector, m_SeedPointIndex[0], m_SeedPointIndex[1], m_SeedPointIndex[2]); // calculate distance from original seed to new seed mitk::Vector3D distVector = currentVector - seedVector; distance = fabs(distVector.GetSquaredNorm()); relativeDistance = distance / (sizeOfVolume / 2); // calculate "cost function" float currentCostValue = (1 - relativeDistance) * currentGrayValue; if (currentCostValue < costValue && currentGrayValue < upperTh) { itkIntelligentSeedIndex = regionIt.GetIndex(); costValue = currentCostValue; // MITK_INFO <<"cost value="<< costValue; // MITK_INFO <<"darkest and closest Voxel ="<< currentGrayValue; // MITK_INFO <<"m_UPPER="<< upperTh; } } // MITK_INFO<< "seed pixel value [AFTER] =" << inputImage->GetPixel(itkIntelligentSeedIndex) <<"\n"; } else { // no correction of the seed point is needed, just pass the original seed itkIntelligentSeedIndex = m_SeedPointIndex; } return itkIntelligentSeedIndex; } template void itk::ConnectedAdaptiveThresholdImageFilter::CropMask(unsigned int croppingSize) { // initialize center point of the working region itk::Index<3> workindex; for (int i = 0; i < 3; i++) { workindex[i] = m_SeedPointIndex[i] - croppingSize / 2; if (workindex[i] < 0) workindex[i] = 0; } // initialize working volume itk::Size<3> worksize; for (int i = 0; i < 3; i++) { worksize[i] = croppingSize; } // set working region itk::ImageRegion<3> workregion(workindex, worksize); // check if the entire region is inside the image if (!(m_OutoutImageMaskFineSegmentation->GetLargestPossibleRegion().IsInside(workregion))) { // if not then crop to the intersection of the image (gemeinsame Schnittmenge Bild und workingRegion) if (!(workregion.Crop(m_OutoutImageMaskFineSegmentation->GetLargestPossibleRegion()))) { MITK_ERROR << "Cropping working region failed!"; return; } } // initialize region iterator itk::ImageRegionIterator regionIt(m_OutoutImageMaskFineSegmentation, workregion); for (regionIt.GoToBegin(); !regionIt.IsAtEnd(); ++regionIt) { // and set all voxel inside the working region to zero regionIt.Set(0); } } template unsigned int itk::ConnectedAdaptiveThresholdImageFilter::AdjustIteratorMask() { typedef itk::ThresholdImageFilter ThresholdFilterType; typedef itk::MinimumMaximumImageFilter MaxFilterType; typename ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New(); typename MaxFilterType::Pointer maxFilter = MaxFilterType::New(); unsigned int maxValue; if (!m_DiscardLastPreview) { // get the biggest value of the image maxFilter->SetInput(m_OutoutImageMaskFineSegmentation); maxFilter->UpdateLargestPossibleRegion(); maxValue = maxFilter->GetMaximum(); } else { // use the last biggest value in the preview. This was set in SetParameterForFineSegmentation(...adjLowerTh...) [] maxValue = m_AdjLowerTh; } // set all values upper to zero (thresouldOutside uses < and > NOT <= and >=) thresholdFilter->SetInput(m_OutoutImageMaskFineSegmentation); thresholdFilter->SetOutsideValue(0); thresholdFilter->ThresholdOutside(m_AdjLowerTh, maxValue); thresholdFilter->UpdateLargestPossibleRegion(); // set all values in between lower and upper (>=lower && <=upper) to the highest value in the image thresholdFilter->SetInput(thresholdFilter->GetOutput()); thresholdFilter->SetOutsideValue(maxValue); thresholdFilter->ThresholdOutside(0, m_AdjLowerTh - 1); thresholdFilter->UpdateLargestPossibleRegion(); m_OutoutImageMaskFineSegmentation = thresholdFilter->GetOutput(); return maxValue; } template void itk::ConnectedAdaptiveThresholdImageFilter::SetParameterForFineSegmentation( TOutputImage *iteratorMaskForFineSegmentation, unsigned int adjLowerTh, unsigned int adjUpperTh, itk::Index<3> seedPoint, bool discardLeafSegmentation) { // just to make sure we´re in the right mode and the mask exsits if (m_FineDetectionMode && iteratorMaskForFineSegmentation) { m_OutoutImageMaskFineSegmentation = iteratorMaskForFineSegmentation; m_AdjLowerTh = adjLowerTh; m_AdjUpperTh = adjUpperTh; // still needed? m_SeedPointIndex = seedPoint; m_DiscardLastPreview = discardLeafSegmentation; } else { if (!m_FineDetectionMode) { MITK_ERROR << "Fine-detection-segmentation mode not set!"; } else { MITK_ERROR << "Iterator-mask-image not set!"; } } } } // end namespace itk #endif