diff --git a/Examples/FirstSteps/NewModule/test/mitkExampleDataStructureReaderWriterTest.cpp b/Examples/FirstSteps/NewModule/test/mitkExampleDataStructureReaderWriterTest.cpp index 1a94fe9506..1f3b0f8a46 100644 --- a/Examples/FirstSteps/NewModule/test/mitkExampleDataStructureReaderWriterTest.cpp +++ b/Examples/FirstSteps/NewModule/test/mitkExampleDataStructureReaderWriterTest.cpp @@ -1,75 +1,75 @@ /*=================================================================== 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. ===================================================================*/ // Testing #include "mitkTestFixture.h" #include "mitkTestingMacros.h" // std includes #include // MITK includes #include "mitkExampleDataStructure.h" #include "mitkIOUtil.h" // VTK includes #include class mitkExampleDataStructureReaderWriterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkExampleDataStructureReaderWriterTestSuite); // Test saving/loading MITK_TEST(ReadWrite_ExampleData_SavedAndLoadedDataEqualToExample); CPPUNIT_TEST_SUITE_END(); private: mitk::ExampleDataStructure::Pointer m_Data; std::string m_DefaultDataString; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override { m_DefaultDataString = "This is the example data content\nAnd a second line\n"; m_Data = mitk::ExampleDataStructure::New(); m_Data->SetData(m_DefaultDataString); } void tearDown() override { m_DefaultDataString = ""; m_Data = nullptr; } void ReadWrite_ExampleData_SavedAndLoadedDataEqualToExample() { std::string path = mitk::IOUtil::GetTempPath() + "ExampleDataOutput.txt"; mitk::IOUtil::Save(m_Data, path); mitk::ExampleDataStructure::Pointer loadedData = - dynamic_cast(mitk::IOUtil::Load(path)[0].GetPointer()); + mitk::IOUtil::Load(path); itksys::SystemTools::RemoveFile(path); CPPUNIT_ASSERT_MESSAGE("Comparing created and loaded example data.", mitk::Equal(m_Data, loadedData, mitk::eps, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkExampleDataStructureReaderWriter) diff --git a/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp b/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp index 22b6e513e8..0be7a6bebc 100644 --- a/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp +++ b/Examples/Tutorial/ITKAndVTK/mitkWithITKAndVTK.cpp @@ -1,80 +1,80 @@ /*=================================================================== 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 #include #include #include #include #include /// /// Small application for demonstrating the interaction between MITK, /// ITK and VTK (not necessarily useful). /// int main(int /*argc*/, char **argv) { // MITK: Read a .pic.gz file, e.g. Core/Code/Testing/Data/Pic3D.pic.gz from // disk const char *filename = argv[1]; mitk::Image::Pointer mitkImage; try { - mitkImage = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitkImage = mitk::IOUtil::Load(filename); } catch (const std::exception &e) { MITK_WARN << "Could not open file " << filename; return EXIT_FAILURE; } // ITK: Image smoothing // Create ITK image, cast from MITK image typedef itk::Image ImageType; ImageType::Pointer itkImage = ImageType::New(); mitk::CastToItkImage(mitkImage, itkImage); typedef itk::DiscreteGaussianImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(itkImage); filter->SetVariance(2); filter->SetMaximumKernelWidth(5); filter->Update(); // run filter // reimport filtered image data mitk::CastToMitkImage(filter->GetOutput(), mitkImage); // VTK: Show result in renderwindow vtkImageViewer *viewer = vtkImageViewer::New(); vtkRenderWindowInteractor *renderWindowInteractor = vtkRenderWindowInteractor::New(); viewer->SetupInteractor(renderWindowInteractor); viewer->SetInputData(mitkImage->GetVtkImageData()); viewer->Render(); viewer->SetColorWindow(255); viewer->SetColorLevel(128); renderWindowInteractor->Start(); renderWindowInteractor->Delete(); viewer->Delete(); return EXIT_SUCCESS; } diff --git a/Modules/AlgorithmsExt/test/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp b/Modules/AlgorithmsExt/test/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp index 8aad1c4115..622346680e 100644 --- a/Modules/AlgorithmsExt/test/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp +++ b/Modules/AlgorithmsExt/test/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp @@ -1,170 +1,170 @@ /*=================================================================== 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 #include #include "mitkAnisotropicIterativeClosestPointRegistration.h" #include "mitkAnisotropicRegistrationCommon.h" #include "mitkCovarianceMatrixCalculator.h" /** * Test to verify the results of the A-ICP registration. * The test runs the standard A-ICP and the trimmed variant. */ class mitkAnisotropicIterativeClosestPointRegistrationTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkAnisotropicIterativeClosestPointRegistrationTestSuite); MITK_TEST(testAicpRegistration); MITK_TEST(testTrimmedAicpregistration); CPPUNIT_TEST_SUITE_END(); private: typedef itk::Matrix Matrix3x3; typedef itk::Vector Vector3; typedef std::vector CovarianceMatrixList; mitk::Surface::Pointer m_MovingSurface; mitk::Surface::Pointer m_FixedSurface; mitk::PointSet::Pointer m_TargetsMovingSurface; mitk::PointSet::Pointer m_TargetsFixedSurface; CovarianceMatrixList m_SigmasMovingSurface; CovarianceMatrixList m_SigmasFixedSurface; double m_FRENormalizationFactor; public: /** * @brief Setup Always call this method before each Test-case to ensure * correct and new intialization of the used members for a new test case. * (If the members are not used in a test, the method does not need to be called). */ void setUp() override { mitk::CovarianceMatrixCalculator::Pointer matrixCalculator = mitk::CovarianceMatrixCalculator::New(); - m_MovingSurface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/head_green.stl"))[0].GetPointer()); - m_FixedSurface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/head_red.stl"))[0].GetPointer()); + m_MovingSurface = mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/head_green.stl")); + m_FixedSurface = mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/head_red.stl")); - m_TargetsMovingSurface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/targets_head_green.mps"))[0].GetPointer()); - m_TargetsFixedSurface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/targets_head_red.mps"))[0].GetPointer()); + m_TargetsMovingSurface = mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/targets_head_green.mps")); + m_TargetsFixedSurface = mitk::IOUtil::Load(GetTestDataFilePath("AICPRegistration/targets_head_red.mps")); // compute covariance matrices matrixCalculator->SetInputSurface(m_MovingSurface); matrixCalculator->ComputeCovarianceMatrices(); m_SigmasMovingSurface = matrixCalculator->GetCovarianceMatrices(); const double meanVarX = matrixCalculator->GetMeanVariance(); matrixCalculator->SetInputSurface(m_FixedSurface); matrixCalculator->ComputeCovarianceMatrices(); m_SigmasFixedSurface = matrixCalculator->GetCovarianceMatrices(); const double meanVarY = matrixCalculator->GetMeanVariance(); m_FRENormalizationFactor = sqrt(meanVarX + meanVarY); } void tearDown() override { m_MovingSurface = nullptr; m_FixedSurface = nullptr; m_TargetsMovingSurface = nullptr; m_TargetsFixedSurface = nullptr; m_SigmasMovingSurface.clear(); m_SigmasFixedSurface.clear(); } void testAicpRegistration() { const double expFRE = 27.5799; const double expTRE = 1.68835; mitk::AnisotropicIterativeClosestPointRegistration::Pointer aICP = mitk::AnisotropicIterativeClosestPointRegistration::New(); // set up parameters aICP->SetMovingSurface(m_MovingSurface); aICP->SetFixedSurface(m_FixedSurface); aICP->SetCovarianceMatricesMovingSurface(m_SigmasMovingSurface); aICP->SetCovarianceMatricesFixedSurface(m_SigmasFixedSurface); aICP->SetFRENormalizationFactor(m_FRENormalizationFactor); aICP->SetThreshold(0.000001); // run the algorithm aICP->Update(); MITK_INFO << "FRE: Expected: " << expFRE << ", computed: " << aICP->GetFRE(); CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test FRE", mitk::Equal(aICP->GetFRE(), expFRE, 0.0001)); // compute the target registration Error const double tre = mitk::AnisotropicRegistrationCommon::ComputeTargetRegistrationError(m_TargetsMovingSurface.GetPointer(), m_TargetsFixedSurface.GetPointer(), aICP->GetRotation(), aICP->GetTranslation()); // MITK_INFO << "R:\n" << aICP->GetRotation() << "T: "<< aICP->GetTranslation(); MITK_INFO << "TRE: Expected: " << expTRE << ", computed: " << tre; CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test TRE", mitk::Equal(tre, expTRE, 0.00001)); } void testTrimmedAicpregistration() { const double expFRE = 4.8912; const double expTRE = 0.0484215; mitk::AnisotropicIterativeClosestPointRegistration::Pointer aICP = mitk::AnisotropicIterativeClosestPointRegistration::New(); // Swap X and Y for partial overlapping registration aICP->SetMovingSurface(m_MovingSurface); aICP->SetFixedSurface(m_FixedSurface); aICP->SetCovarianceMatricesMovingSurface(m_SigmasMovingSurface); aICP->SetCovarianceMatricesFixedSurface(m_SigmasFixedSurface); aICP->SetFRENormalizationFactor(m_FRENormalizationFactor); aICP->SetThreshold(0.000001); aICP->SetTrimmFactor(0.50); // run the algorithm aICP->Update(); MITK_INFO << "FRE: Expected: " << expFRE << ", computed: " << aICP->GetFRE(); CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test FRE", mitk::Equal(aICP->GetFRE(), expFRE, 0.01)); // compute the target registration Error const double tre = mitk::AnisotropicRegistrationCommon::ComputeTargetRegistrationError(m_TargetsMovingSurface.GetPointer(), m_TargetsFixedSurface.GetPointer(), aICP->GetRotation(), aICP->GetTranslation()); MITK_INFO << "TRE: Expected: " << expTRE << ", computed: " << tre; CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test TRE", mitk::Equal(tre, expTRE, 0.01)); } }; MITK_TEST_SUITE_REGISTRATION(mitkAnisotropicIterativeClosestPointRegistration) diff --git a/Modules/AlgorithmsExt/test/mitkCovarianceMatrixCalculatorTest.cpp b/Modules/AlgorithmsExt/test/mitkCovarianceMatrixCalculatorTest.cpp index 82a5ae8b36..597b0f64b4 100644 --- a/Modules/AlgorithmsExt/test/mitkCovarianceMatrixCalculatorTest.cpp +++ b/Modules/AlgorithmsExt/test/mitkCovarianceMatrixCalculatorTest.cpp @@ -1,110 +1,110 @@ /*=================================================================== 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 #include #include #include /** Test class to test the computation of covariance matrices * for the A-ICP algorithm. The test runs the CM_PCA method. */ class mitkCovarianceMatrixCalculatorTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkCovarianceMatrixCalculatorTestSuite); MITK_TEST(testCovarianceMatrixCalculation_CM_PCA); CPPUNIT_TEST_SUITE_END(); private: typedef itk::Matrix CovarianceMatrix; typedef std::vector CovarianceMatrixList; mitk::Surface::Pointer m_Surface; CovarianceMatrixList m_Reference; public: void setUp() override { - m_Surface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("RenderingTestData/Stanford_bunny.stl"))[0].GetPointer()); + m_Surface = mitk::IOUtil::Load(GetTestDataFilePath("RenderingTestData/Stanford_bunny.stl")); // saved results CovarianceMatrix m1, m2, m3; // set 3 reference results into the vector. The first in the array, one from // the middle and the last one m1[0][0] = 366.169; m1[1][0] = 39.5242; m1[2][0] = 102.368; m1[0][1] = 39.5242; m1[1][1] = 6.97979; m1[2][1] = 6.91726; m1[0][2] = 102.368; m1[1][2] = 6.91726; m1[2][2] = 389.481; m_Reference.push_back(m1); m2[0][0] = 107.999; m2[1][0] = 71.6708; m2[2][0] = -0.908269; m2[0][1] = 71.6708; m2[1][1] = 133.407; m2[2][1] = 40.8706; m2[0][2] = -0.908269; m2[1][2] = 40.8706; m2[2][2] = 25.1825; m_Reference.push_back(m2); m3[0][0] = 177.916; m3[1][0] = 4.92498; m3[2][0] = 5.86319; m3[0][1] = 4.92498; m3[1][1] = 0.214147; m3[2][1] = -1.98345; m3[0][2] = 5.86319; m3[1][2] = -1.98345; m3[2][2] = 232.092; m_Reference.push_back(m3); } void tearDown() override { m_Surface = nullptr; m_Reference.clear(); } void testCovarianceMatrixCalculation_CM_PCA() { mitk::CovarianceMatrixCalculator::Pointer matrixCalculator = mitk::CovarianceMatrixCalculator::New(); matrixCalculator->SetInputSurface(m_Surface); matrixCalculator->ComputeCovarianceMatrices(); CovarianceMatrixList result = matrixCalculator->GetCovarianceMatrices(); CPPUNIT_ASSERT_MESSAGE("mitkCovarianceMatrixCalculatorTestSuite test first matrix", mitk::MatrixEqualElementWise(result.at(0), m_Reference.at(0), 0.001)); CPPUNIT_ASSERT_MESSAGE("mitkCovarianceMatrixCalculatorTestSuite test middle matrix", mitk::MatrixEqualElementWise(result.at(result.size() / 2), m_Reference.at(1), 0.001)); CPPUNIT_ASSERT_MESSAGE("mitkCovarianceMatrixCalculatorTestSuite test last matrix", mitk::MatrixEqualElementWise(result.at((result.size() - 1)), m_Reference.at(2), 0.001)); } }; MITK_TEST_SUITE_REGISTRATION(mitkCovarianceMatrixCalculator) diff --git a/Modules/AlgorithmsExt/test/mitkImageToUnstructuredGridFilterTest.cpp b/Modules/AlgorithmsExt/test/mitkImageToUnstructuredGridFilterTest.cpp index 1dd3cabf93..3cc5b5a148 100644 --- a/Modules/AlgorithmsExt/test/mitkImageToUnstructuredGridFilterTest.cpp +++ b/Modules/AlgorithmsExt/test/mitkImageToUnstructuredGridFilterTest.cpp @@ -1,83 +1,83 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include class mitkImageToUnstructuredGridFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageToUnstructuredGridFilterTestSuite); MITK_TEST(testImageToUnstructuredGridFilterInitialization); MITK_TEST(testInput); MITK_TEST(testUnstructuredGridGeneration); MITK_TEST(testThreshold); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ mitk::Image::Pointer m_BallImage; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ - void setUp() override { m_BallImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30.nrrd"))[0].GetPointer()); } + void setUp() override { m_BallImage = mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30.nrrd")); } void testImageToUnstructuredGridFilterInitialization() { mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); CPPUNIT_ASSERT_MESSAGE("Testing instantiation of test object", testFilter.IsNotNull()); CPPUNIT_ASSERT_MESSAGE("Testing initialization of threshold member variable", testFilter->GetThreshold() == -0.1); } void testInput() { mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); testFilter->SetInput(m_BallImage); CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", testFilter->GetInput() == m_BallImage); } void testUnstructuredGridGeneration() { mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); testFilter->SetInput(m_BallImage); testFilter->Update(); CPPUNIT_ASSERT_MESSAGE("Testing UnstructuredGrid generation!", testFilter->GetOutput() != nullptr); } void testThreshold() { mitk::ImageToUnstructuredGridFilter::Pointer testFilter1 = mitk::ImageToUnstructuredGridFilter::New(); testFilter1->SetInput(m_BallImage); testFilter1->Update(); int numberOfPoints1 = testFilter1->GetNumberOfExtractedPoints(); mitk::ImageToUnstructuredGridFilter::Pointer testFilter2 = mitk::ImageToUnstructuredGridFilter::New(); testFilter2->SetInput(m_BallImage); testFilter2->SetThreshold(1.0); testFilter2->Update(); int numberOfPoints2 = testFilter2->GetNumberOfExtractedPoints(); CPPUNIT_ASSERT_MESSAGE("Testing Threshold", numberOfPoints1 > numberOfPoints2); } }; MITK_TEST_SUITE_REGISTRATION(mitkImageToUnstructuredGridFilter) diff --git a/Modules/AlgorithmsExt/test/mitkLabeledImageToSurfaceFilterTest.cpp b/Modules/AlgorithmsExt/test/mitkLabeledImageToSurfaceFilterTest.cpp index 03904ff1a5..32a45a6700 100644 --- a/Modules/AlgorithmsExt/test/mitkLabeledImageToSurfaceFilterTest.cpp +++ b/Modules/AlgorithmsExt/test/mitkLabeledImageToSurfaceFilterTest.cpp @@ -1,350 +1,350 @@ /*=================================================================== 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 "mitkLabeledImageToSurfaceFilter.h" #include "mitkReferenceCountWatcher.h" #include #include "mitkIOUtil.h" #include bool equals(const mitk::ScalarType &val1, const mitk::ScalarType &val2, mitk::ScalarType epsilon = mitk::eps) { return (std::fabs(val1 - val2) <= epsilon); } int mitkLabeledImageToSurfaceFilterTest(int argc, char *argv[]) { if (argc < 2) { std::cout << "no path to testing specified [FAILED]" << std::endl; return EXIT_FAILURE; } std::string fileIn = argv[1]; std::cout << "Eingabe Datei: " << fileIn << std::endl; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(fileIn)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(fileIn); if (image->GetPixelType() != mitk::PixelType(mitk::MakeScalarPixelType()) || image->GetPixelType() != mitk::PixelType(mitk::MakeScalarPixelType())) { std::cout << "file not a char or unsigned char image - test will not be applied [PASSED]" << std::endl; std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } std::cout << "Testing instantiation: "; mitk::LabeledImageToSurfaceFilter::Pointer filter = mitk::LabeledImageToSurfaceFilter::New(); if (filter.IsNull()) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Create surface with default settings: "; filter->SetInput(image); filter->Update(); if (filter->GetNumberOfOutputs() != 1) { std::cout << "Wrong number of outputs, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput() == nullptr) { std::cout << "Output is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput()->GetVtkPolyData() == nullptr) { std::cout << "PolyData of surface is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing index to label conversion: "; if (filter->GetLabelForNthOutput(0) != 257) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for label calculation: "; if (!equals(filter->GetVolumeForLabel(257), 14.328)) { std::cout << filter->GetVolumeForLabel(257) << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for index calculation: "; if (!equals(filter->GetVolumeForNthOutput(0), 14.328)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Create surface using optimised settings: "; filter->GenerateAllLabelsOn(); filter->SetGaussianStandardDeviation(1.5); filter->SetSmooth(true); // smooth wireframe filter->SetDecimate(mitk::ImageToSurfaceFilter::DecimatePro); filter->SetTargetReduction(0.8); if (filter->GetNumberOfOutputs() != 1) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Create surface for label 257: "; filter->GenerateAllLabelsOff(); filter->SetLabel(257); filter->Update(); if (filter->GetNumberOfOutputs() != 1) { std::cout << "Wrong number of outputs, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput() == nullptr) { std::cout << "Output is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput()->GetVtkPolyData() == nullptr) { std::cout << "PolyData of surface is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for label calculation: "; if (!equals(filter->GetVolumeForLabel(257), 14.328)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for index calculation: "; if (!equals(filter->GetVolumeForNthOutput(0), 14.328)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Create surface for multiple labels: "; filter->GenerateAllLabelsOn(); filter->SetBackgroundLabel(32000); filter->Update(); if (filter->GetNumberOfOutputs() != 2) { std::cout << "Wrong number of outputs, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput() == nullptr) { std::cout << "Output 0 is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput()->GetVtkPolyData() == nullptr) { std::cout << "PolyData of output 0 is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput(1) == nullptr) { std::cout << "Output 1 is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput(1)->GetVtkPolyData() == nullptr) { std::cout << "PolyData of output 1 is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for label calculation: "; if (!equals(filter->GetVolumeForLabel(257), 14.328)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else if (!equals(filter->GetVolumeForLabel(0), 12.672)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for index calculation: "; if (!equals(filter->GetVolumeForNthOutput(1), 14.328)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else if (!equals(filter->GetVolumeForNthOutput(0), 12.672)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } mitk::ReferenceCountWatcher::Pointer outputSurface1Watcher = new mitk::ReferenceCountWatcher(filter->GetOutput(1), "outputSurface1"); mitk::ReferenceCountWatcher::Pointer filterWatcher = new mitk::ReferenceCountWatcher(filter, "filter"); std::cout << "Create surface for background (label 0): " << std::flush; filter->GenerateAllLabelsOff(); filter->SetLabel(0); filter->SetBackgroundLabel(257); // mitk::Surface::Pointer surface = filter->GetOutput(1); // std::cout<< surface->GetReferenceCount() << std::endl; filter->Update(); // surface = nullptr; if (filter->GetNumberOfOutputs() != 1) { std::cout << "Wrong number of outputs, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput() == nullptr) { std::cout << "Output is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput()->GetVtkPolyData() == nullptr) { std::cout << "PolyData of surface is nullptr, [FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing reference count correctness of old output 1: " << std::flush; if (outputSurface1Watcher->GetReferenceCount() != 0) { std::cout << "outputSurface1Watcher->GetReferenceCount()==" << outputSurface1Watcher->GetReferenceCount() << "!=0, [FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing reference count correctness of filter: " << std::flush; if (filterWatcher->GetReferenceCount() != 2) { std::cout << "filterWatcher->GetReferenceCount()==" << outputSurface1Watcher->GetReferenceCount() << "!=2, [FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing index to label conversion: "; if (filter->GetLabelForNthOutput(0) != 0) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for label calculation: "; if (!equals(filter->GetVolumeForLabel(filter->GetLabel()), 12.672)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Testing volume for index calculation: "; if (!equals(filter->GetVolumeForNthOutput(0), 12.672)) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "Create surface for invalid label: "; filter->GenerateAllLabelsOff(); filter->SetLabel(1); filter->Update(); if (filter->GetNumberOfOutputs() != 1) { std::cout << "Number of outputs != 1, [FAILED]" << std::endl; return EXIT_FAILURE; } else if (filter->GetOutput()->GetVtkPolyData()->GetNumberOfPoints() != 0) { std::cout << "PolyData is not empty (" << filter->GetOutput()->GetVtkPolyData()->GetNumberOfPoints() << "), [FAILED]" << std::endl; return EXIT_FAILURE; } else { std::cout << "[PASSED]" << std::endl; } std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLMRUtilities/test/mitkGlobalFeaturesTest.cpp b/Modules/Classification/CLMRUtilities/test/mitkGlobalFeaturesTest.cpp index 1eeb39d459..1eaba76244 100644 --- a/Modules/Classification/CLMRUtilities/test/mitkGlobalFeaturesTest.cpp +++ b/Modules/Classification/CLMRUtilities/test/mitkGlobalFeaturesTest.cpp @@ -1,316 +1,316 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include #include #include #include #include template static mitk::Image::Pointer GenerateMaskImage(unsigned int dimX, unsigned int dimY, unsigned int dimZ, float spacingX = 1, float spacingY = 1, float spacingZ = 1) { typedef itk::Image< TPixelType, 3 > ImageType; typename ImageType::RegionType imageRegion; imageRegion.SetSize(0, dimX); imageRegion.SetSize(1, dimY); imageRegion.SetSize(2, dimZ); typename ImageType::SpacingType spacing; spacing[0] = spacingX; spacing[1] = spacingY; spacing[2] = spacingZ; mitk::Point3D origin; origin.Fill(0.0); itk::Matrix directionMatrix; directionMatrix.SetIdentity(); typename ImageType::Pointer image = ImageType::New(); image->SetSpacing( spacing ); image->SetOrigin( origin ); image->SetDirection( directionMatrix ); image->SetLargestPossibleRegion( imageRegion ); image->SetBufferedRegion( imageRegion ); image->SetRequestedRegion( imageRegion ); image->Allocate(); image->FillBuffer(1); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( image.GetPointer() ); mitkImage->SetVolume( image->GetBufferPointer() ); return mitkImage; } template static mitk::Image::Pointer GenerateGradientWithDimXImage(unsigned int dimX, unsigned int dimY, unsigned int dimZ, float spacingX = 1, float spacingY = 1, float spacingZ = 1) { typedef itk::Image< TPixelType, 3 > ImageType; typename ImageType::RegionType imageRegion; imageRegion.SetSize(0, dimX); imageRegion.SetSize(1, dimY); imageRegion.SetSize(2, dimZ); typename ImageType::SpacingType spacing; spacing[0] = spacingX; spacing[1] = spacingY; spacing[2] = spacingZ; mitk::Point3D origin; origin.Fill(0.0); itk::Matrix directionMatrix; directionMatrix.SetIdentity(); typename ImageType::Pointer image = ImageType::New(); image->SetSpacing( spacing ); image->SetOrigin( origin ); image->SetDirection( directionMatrix ); image->SetLargestPossibleRegion( imageRegion ); image->SetBufferedRegion( imageRegion ); image->SetRequestedRegion( imageRegion ); image->Allocate(); image->FillBuffer(0.0); typedef itk::ImageRegionIterator IteratorOutputType; IteratorOutputType it(image, imageRegion); it.GoToBegin(); TPixelType val = 0; while(!it.IsAtEnd()) { it.Set(val % dimX); val++; ++it; } mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( image.GetPointer() ); mitkImage->SetVolume( image->GetBufferPointer() ); return mitkImage; } class mitkGlobalFeaturesTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGlobalFeaturesTestSuite ); MITK_TEST(FirstOrder_SinglePoint); MITK_TEST(FirstOrder_QubicArea); //MITK_TEST(RunLenght_QubicArea); MITK_TEST(Coocurrence_QubicArea); //MITK_TEST(TestFirstOrderStatistic); // MITK_TEST(TestThreadedDecisionForest); CPPUNIT_TEST_SUITE_END(); private: typedef itk::Image ImageType; typedef itk::Image MaskType; mitk::Image::Pointer m_Image,m_Mask,m_Mask1; ImageType::Pointer m_ItkImage; MaskType::Pointer m_ItkMask,m_ItkMask1; mitk::Image::Pointer m_GradientImage, m_GradientMask; public: void setUp(void) { // Load Image Data - m_Image = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + m_Image = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); mitk::CastToItkImage(m_Image,m_ItkImage); // Create a single mask with only one pixel within the regions - mitk::Image::Pointer mask1 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + mitk::Image::Pointer mask1 = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); mitk::CastToItkImage(mask1,m_ItkMask); m_ItkMask->FillBuffer(0); MaskType::IndexType index; index[0]=88;index[1]=81;index[2]=13; m_ItkMask->SetPixel(index, 1); MITK_INFO << "Pixel Value: "<GetPixel(index); mitk::CastToMitkImage(m_ItkMask, m_Mask); // Create a mask with a covered region - mitk::Image::Pointer lmask1 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + mitk::Image::Pointer lmask1 = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); mitk::CastToItkImage(lmask1,m_ItkMask1); m_ItkMask1->FillBuffer(0); int range=2; for (int x = 88-range;x < 88+range+1;++x) { for (int y=81-range;y<81+range+1;++y) { for (int z=13-range;z<13+range+1;++z) { index[0] = x; index[1] = y; index[2] = z; //MITK_INFO << "Pixel: " <GetPixel(index); m_ItkMask1->SetPixel(index, 1); } } } mitk::CastToMitkImage(m_ItkMask1, m_Mask1); m_GradientImage=GenerateGradientWithDimXImage(5,5,5); m_GradientMask = GenerateMaskImage(5,5,5); } void FirstOrder_SinglePoint() { mitk::GIFFirstOrderStatistics::Pointer calculator = mitk::GIFFirstOrderStatistics::New(); calculator->SetHistogramSize(4096); calculator->SetUseCtRange(true); auto features = calculator->CalculateFeatures(m_Image, m_Mask); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The range of a single pixel should be 0",0.0, results["FirstOrder Range"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The uniformity of a single pixel should be 1",1.0, results["FirstOrder Uniformity"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The entropy of a single pixel should be 0",0.0, results["FirstOrder Entropy"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Root-Means-Square of a single pixel with (-352) should be 352",352.0, results["FirstOrder RMS"], 0.01); CPPUNIT_ASSERT_EQUAL_MESSAGE("The Kurtosis of a single pixel should be undefined",results["FirstOrder Kurtosis"]==results["FirstOrder Kurtosis"], false); CPPUNIT_ASSERT_EQUAL_MESSAGE("The Skewness of a single pixel should be undefined",results["FirstOrder Skewness"]==results["FirstOrder Skewness"], false); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean absolute deviation of a single pixel with (-352) should be 0",0, results["FirstOrder Mean absolute deviation"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Covered image intensity range of a single pixel with (-352) should be 0",0, results["FirstOrder Covered Image Intensity Range"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Minimum of a single pixel with (-352) should be -352",-352, results["FirstOrder Minimum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Maximum of a single pixel with (-352) should be -352",-352, results["FirstOrder Maximum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean of a single pixel with (-352) should be -352",-352, results["FirstOrder Mean"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Variance (corrected) of a single pixel with (-352) should be 0",0, results["FirstOrder Variance"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Sum of a single pixel with (-352) should be -352",-352, results["FirstOrder Sum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Median of a single pixel with (-352) should be -352",-352, results["FirstOrder Median"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Standard deviation (corrected) of a single pixel with (-352) should be -352",0, results["FirstOrder Standard deviation"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The number of voxels of a single pixel should be 1",1, results["FirstOrder No. of Voxel"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Energy of a single pixel should be 352*352",352*352, results["FirstOrder Energy"], 0.0); // MITK_ASSERT_EQUAL(results["FirstOrder Range"]==0.0,true,"The range of a single pixel should be 0"); } void FirstOrder_QubicArea() { mitk::GIFFirstOrderStatistics::Pointer calculator = mitk::GIFFirstOrderStatistics::New(); calculator->SetHistogramSize(4096); calculator->SetUseCtRange(true); auto features = calculator->CalculateFeatures(m_Image, m_Mask1); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The range should be 981",981, results["FirstOrder Range"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Root-Means-Square of a single pixel with (-352) should be 352",402.895778, results["FirstOrder RMS"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Minimum of a single pixel with (-352) should be -352",-937, results["FirstOrder Minimum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Maximum of a single pixel with (-352) should be -352",44, results["FirstOrder Maximum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean of a single pixel with (-352) should be -352",-304.448, results["FirstOrder Mean"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Sum of a single pixel with (-352) should be -352",-38056, results["FirstOrder Sum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Median of a single pixel with (-352) should be -352",-202, results["FirstOrder Median"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The number of voxels of a single pixel should be 1",125, results["FirstOrder No. of Voxel"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Standard deviation (corrected) of a single pixel with (-352) should be -352",264.949066, results["FirstOrder Standard deviation"], 0.000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Energy of a single pixel should be 352*352",20290626, results["FirstOrder Energy"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The uniformity of a single pixel should be 1",0.0088960, results["FirstOrder Uniformity"], 0.0000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The entropy of a single pixel should be 0",-6.853784285, results["FirstOrder Entropy"], 0.000000005); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Variance (corrected) of a single pixel with (-352) should be 0",70198.0074, results["FirstOrder Variance"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Kurtosis of a single pixel should be 0",2.63480121, results["FirstOrder Kurtosis"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Skewness of a single pixel should be 0",-0.91817318, results["FirstOrder Skewness"], 0.00001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean absolute deviation of a single pixel with (-352) should be 0",219.348608, results["FirstOrder Mean absolute deviation"], 0.000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Covered image intensity range of a single pixel with (-352) should be 0",0.41149329, results["FirstOrder Covered Image Intensity Range"], 0.000001); } void RunLenght_QubicArea() { mitk::GIFGrayLevelRunLength::Pointer calculator = mitk::GIFGrayLevelRunLength::New(); //calculator->SetHistogramSize(4096); calculator->SetUseCtRange(true); calculator->SetRange(981); auto features = calculator->CalculateFeatures(m_Image, m_Mask1); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } } void Coocurrence_QubicArea() { /* * Expected Matrix: (Direction 0,0,1) * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 0 | 20 | 0 | 0 | 0 | * |------------------------| * | 0 | 0 | 20 | 0 | 0 | * |------------------------| * | 0 | 0 | 0 | 20 | 0 | * |------------------------| * | 0 | 0 | 0 | 0 | 20 | * |------------------------| * Expected Matrix: (Direction (1,0,0),(0,1,0)) * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| */ mitk::GIFCooccurenceMatrix::Pointer calculator = mitk::GIFCooccurenceMatrix::New(); //calculator->SetHistogramSize(4096); //calculator->SetUseCtRange(true); //calculator->SetRange(981); auto features = calculator->CalculateFeatures(m_GradientImage, m_GradientMask); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean energy value should be 0.2",0.2, results["co-occ. (1) Energy Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean entropy value should be 0.2",2.321928, results["co-occ. (1) Entropy Means"], 0.000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean contrast value should be 0.0",0, results["co-occ. (1) Contrast Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean dissimilarity value should be 0.0",0, results["co-occ. (1) Dissimilarity Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean homogenity1 value should be 1.0",1, results["co-occ. (1) Homogeneity1 Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean InverseDifferenceMoment value should be 1.0",1, results["co-occ. (1) InverseDifferenceMoment Means"], mitk::eps); } }; MITK_TEST_SUITE_REGISTRATION(mitkGlobalFeatures) \ No newline at end of file diff --git a/Modules/Classification/CLMRUtilities/test/mitkSmoothedClassProbabilitesTest.cpp b/Modules/Classification/CLMRUtilities/test/mitkSmoothedClassProbabilitesTest.cpp index c7f6a8535e..f1e695cb66 100644 --- a/Modules/Classification/CLMRUtilities/test/mitkSmoothedClassProbabilitesTest.cpp +++ b/Modules/Classification/CLMRUtilities/test/mitkSmoothedClassProbabilitesTest.cpp @@ -1,94 +1,94 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkSmoothedClassProbabilitesTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSmoothedClassProbabilitesTestSuite ); MITK_TEST(TrainSVMClassifier); // MITK_TEST(TestThreadedDecisionForest); CPPUNIT_TEST_SUITE_END(); private: typedef itk::Image ImageType; mitk::Image::Pointer p1,p2,p3,pmask; ImageType::Pointer i1,i2,i3,imask; public: void setUp(void) { // Load Image Data - p1 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-0_0.nrrd"))[0].GetPointer()); - p2 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-1_0.nrrd"))[0].GetPointer()); - p3 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-2_0.nrrd"))[0].GetPointer()); - pmask = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/mask.nrrd"))[0].GetPointer()); + p1 = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-0_0.nrrd")); + p2 = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-1_0.nrrd")); + p3 = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-2_0.nrrd")); + pmask = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/mask.nrrd")); mitk::CastToItkImage(p1,i1); mitk::CastToItkImage(p2,i2); mitk::CastToItkImage(p3,i3); mitk::CastToItkImage(pmask,imask); } void TrainSVMClassifier() { itk::SmoothedClassProbabilites::Pointer filter = itk::SmoothedClassProbabilites::New(); filter->SetInput(0,i1); filter->SetInput(1,i2); filter->SetInput(2,i3); filter->SetMaskImage(imask); filter->SetSigma(1.0); filter->Update(); mitk::Image::Pointer out; mitk::CastToMitkImage(filter->GetOutput(), out); mitk::IOUtil::Save(out, "/Users/jc/test.nrrd"); } void TestThreadedDecisionForest() { // m_LoadedDecisionForest->SetCollection(m_TrainDatacollection); // m_LoadedDecisionForest->SetModalities(m_Selected_items); // m_LoadedDecisionForest->SetMaskName("ClassMask"); // m_LoadedDecisionForest->SetResultMask("ResultMask"); // m_LoadedDecisionForest->SetResultProb("ResultProb"); // m_LoadedDecisionForest->TestThreaded(); // mitk::DataCollection::Pointer res_col = dynamic_cast(dynamic_cast(m_TrainDatacollection->GetData("Test-Study").GetPointer())->GetData("Test-Subject").GetPointer()); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultMask"),"/Users/jc/res_mask.nrrd"); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultProb_Class-0"),"/Users/jc/res_prob_0.nrrd"); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultProb_Class-1"),"/Users/jc/res_prob_1.nrrd"); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultProb_Class-2"),"/Users/jc/res_prob_2.nrrd"); } }; MITK_TEST_SUITE_REGISTRATION(mitkSmoothedClassProbabilites) diff --git a/Modules/Classification/CLMiniApps/CL2Dto3DImage.cpp b/Modules/Classification/CLMiniApps/CL2Dto3DImage.cpp index 66e1acaa53..b31b764144 100644 --- a/Modules/Classification/CLMiniApps/CL2Dto3DImage.cpp +++ b/Modules/Classification/CLMiniApps/CL2Dto3DImage.cpp @@ -1,59 +1,59 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include "mitkIOUtil.h" int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input file:", "Input file",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file",us::Any(),false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputName = us::any_cast(parsedArgs["input"]); std::string outputName = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(inputName); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputName); mitk::Convert2Dto3DImageFilter::Pointer multiFilter2 = mitk::Convert2Dto3DImageFilter::New(); multiFilter2->SetInput(image); multiFilter2->Update(); mitk::Image::Pointer image2 = multiFilter2->GetOutput(); mitk::IOUtil::Save(image2, outputName); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLBrainMask.cpp b/Modules/Classification/CLMiniApps/CLBrainMask.cpp index 77218a9374..fce9aa7ff1 100644 --- a/Modules/Classification/CLMiniApps/CLBrainMask.cpp +++ b/Modules/Classification/CLMiniApps/CLBrainMask.cpp @@ -1,104 +1,104 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" #include "itkImageRegionIterator.h" // MITK #include #include #include // ITK #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; template void Normalize(itk::Image* itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output) { typedef itk::Image ImageType; typedef itk::Image MaskType; typename ImageType::Pointer itkIm2 = ImageType::New(); typename MaskType::Pointer itkMask1 = MaskType::New(); mitk::CastToItkImage(im2, itkIm2); mitk::CastToItkImage(mask1, itkMask1); itk::ImageRegionIterator iterI1(itkImage, itkImage->GetLargestPossibleRegion()); itk::ImageRegionIterator iterI2(itkIm2, itkImage->GetLargestPossibleRegion()); itk::ImageRegionIterator iter(itkMask1, itkImage->GetLargestPossibleRegion()); while (! iter.IsAtEnd()) { unsigned char maskV = 0; if (iterI1.Value() > 0.0001 && iterI2.Value() > 0.00001) maskV = 1; iter.Set(maskV); ++iter; ++iterI1; ++iterI2; } mitk::Image::Pointer img = mitk::ImportItkImage(itkMask1); mitk::IOUtil::Save(img, output); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("image2", "i2", mitkCommandLineParser::InputImage, "Input Mask", "The median of the area covered by this mask will be set to 0", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "Input Mask", "The median of the area covered by this mask will be set to 1", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output Image", "Target file. The output statistic is appended to this file.", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("MR Normalization Tool"); parser.setDescription("Normalizes a MR image. Sets the Median of the tissue covered by mask 0 to 0 and the median of the area covered by mask 1 to 1."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(parsedArgs["image"].ToString())[0].GetPointer()); - mitk::Image::Pointer im2= dynamic_cast(mitk::IOUtil::Load(parsedArgs["image2"].ToString())[0].GetPointer()); - mitk::Image::Pointer mask = dynamic_cast(mitk::IOUtil::Load(parsedArgs["mask"].ToString())[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["image"].ToString()); + mitk::Image::Pointer im2= mitk::IOUtil::Load(parsedArgs["image2"].ToString()); + mitk::Image::Pointer mask = mitk::IOUtil::Load(parsedArgs["mask"].ToString()); AccessByItk_3(image, Normalize, im2, mask, parsedArgs["output"].ToString()); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLGlobalImageFeatures.cpp b/Modules/Classification/CLMiniApps/CLGlobalImageFeatures.cpp index ce665572a6..eadc6188f3 100644 --- a/Modules/Classification/CLMiniApps/CLGlobalImageFeatures.cpp +++ b/Modules/Classification/CLMiniApps/CLGlobalImageFeatures.cpp @@ -1,758 +1,758 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkResampleImageFilter.h" #include #include #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include "vtkRenderLargeImage.h" #include "vtkPNGWriter.h" typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned short, 3 > MaskImageType; template class punct_facet : public std::numpunct { public: punct_facet(charT sep) : m_Sep(sep) { } protected: charT do_decimal_point() const { return m_Sep; } private: charT m_Sep; }; template void ResampleImage(itk::Image* itkImage, float resolution, mitk::Image::Pointer& newImage) { typedef itk::Image ImageType; typedef itk::ResampleImageFilter ResampleFilterType; typename ResampleFilterType::Pointer resampler = ResampleFilterType::New(); auto spacing = itkImage->GetSpacing(); auto size = itkImage->GetLargestPossibleRegion().GetSize(); for (unsigned int i = 0; i < VImageDimension; ++i) { size[i] = size[i] / (1.0*resolution)*(1.0*spacing[i])+1.0; } spacing.Fill(resolution); resampler->SetInput(itkImage); resampler->SetSize(size); resampler->SetOutputSpacing(spacing); resampler->SetOutputOrigin(itkImage->GetOrigin()); resampler->SetOutputDirection(itkImage->GetDirection()); resampler->Update(); newImage->InitializeByItk(resampler->GetOutput()); mitk::GrabItkImageMemory(resampler->GetOutput(), newImage); } template static void CreateNoNaNMask(itk::Image* itkValue, mitk::Image::Pointer mask, mitk::Image::Pointer& newMask) { typedef itk::Image< TPixel, VImageDimension> LFloatImageType; typedef itk::Image< unsigned short, VImageDimension> LMaskImageType; typename LMaskImageType::Pointer itkMask = LMaskImageType::New(); mitk::CastToItkImage(mask, itkMask); typedef itk::ImageDuplicator< LMaskImageType > DuplicatorType; typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage(itkMask); duplicator->Update(); auto tmpMask = duplicator->GetOutput(); itk::ImageRegionIterator mask1Iter(itkMask, itkMask->GetLargestPossibleRegion()); itk::ImageRegionIterator mask2Iter(tmpMask, tmpMask->GetLargestPossibleRegion()); itk::ImageRegionIterator imageIter(itkValue, itkValue->GetLargestPossibleRegion()); while (!mask1Iter.IsAtEnd()) { mask2Iter.Set(0); if (mask1Iter.Value() > 0) { // Is not NaN if (imageIter.Value() == imageIter.Value()) { mask2Iter.Set(1); } } ++mask1Iter; ++mask2Iter; ++imageIter; } newMask->InitializeByItk(tmpMask); mitk::GrabItkImageMemory(tmpMask, newMask); } template static void ResampleMask(itk::Image* itkMoving, mitk::Image::Pointer ref, mitk::Image::Pointer& newMask) { typedef itk::Image< TPixel, VImageDimension> LMaskImageType; typedef itk::NearestNeighborInterpolateImageFunction< LMaskImageType> NearestNeighborInterpolateImageFunctionType; typedef itk::ResampleImageFilter ResampleFilterType; typename NearestNeighborInterpolateImageFunctionType::Pointer nn_interpolator = NearestNeighborInterpolateImageFunctionType::New(); typename LMaskImageType::Pointer itkRef = LMaskImageType::New(); mitk::CastToItkImage(ref, itkRef); typename ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage(itkRef); resampler->UseReferenceImageOn(); resampler->SetInterpolator(nn_interpolator); resampler->Update(); newMask->InitializeByItk(resampler->GetOutput()); mitk::GrabItkImageMemory(resampler->GetOutput(), newMask); } static void ExtractSlicesFromImages(mitk::Image::Pointer image, mitk::Image::Pointer mask, mitk::Image::Pointer maskNoNaN, mitk::Image::Pointer morphMask, int direction, std::vector &imageVector, std::vector &maskVector, std::vector &maskNoNaNVector, std::vector &morphMaskVector) { typedef itk::Image< double, 2 > FloatImage2DType; typedef itk::Image< unsigned short, 2 > MaskImage2DType; FloatImageType::Pointer itkFloat = FloatImageType::New(); MaskImageType::Pointer itkMask = MaskImageType::New(); MaskImageType::Pointer itkMaskNoNaN = MaskImageType::New(); MaskImageType::Pointer itkMorphMask = MaskImageType::New(); mitk::CastToItkImage(mask, itkMask); mitk::CastToItkImage(maskNoNaN, itkMaskNoNaN); mitk::CastToItkImage(image, itkFloat); mitk::CastToItkImage(morphMask, itkMorphMask); int idxA, idxB, idxC; switch (direction) { case 0: idxA = 1; idxB = 2; idxC = 0; break; case 1: idxA = 0; idxB = 2; idxC = 1; break; case 2: idxA = 0; idxB = 1; idxC = 2; break; default: idxA = 1; idxB = 2; idxC = 0; break; } auto imageSize = image->GetLargestPossibleRegion().GetSize(); FloatImageType::IndexType index3D; FloatImage2DType::IndexType index2D; FloatImage2DType::SpacingType spacing2D; spacing2D[0] = itkFloat->GetSpacing()[idxA]; spacing2D[1] = itkFloat->GetSpacing()[idxB]; for (unsigned int i = 0; i < imageSize[idxC]; ++i) { FloatImage2DType::RegionType region; FloatImage2DType::IndexType start; FloatImage2DType::SizeType size; start[0] = 0; start[1] = 0; size[0] = imageSize[idxA]; size[1] = imageSize[idxB]; region.SetIndex(start); region.SetSize(size); FloatImage2DType::Pointer image2D = FloatImage2DType::New(); image2D->SetRegions(region); image2D->Allocate(); MaskImage2DType::Pointer mask2D = MaskImage2DType::New(); mask2D->SetRegions(region); mask2D->Allocate(); MaskImage2DType::Pointer masnNoNaN2D = MaskImage2DType::New(); masnNoNaN2D->SetRegions(region); masnNoNaN2D->Allocate(); MaskImage2DType::Pointer morph2D = MaskImage2DType::New(); morph2D->SetRegions(region); morph2D->Allocate(); unsigned long voxelsInMask = 0; for (unsigned int a = 0; a < imageSize[idxA]; ++a) { for (unsigned int b = 0; b < imageSize[idxB]; ++b) { index3D[idxA] = a; index3D[idxB] = b; index3D[idxC] = i; index2D[0] = a; index2D[1] = b; image2D->SetPixel(index2D, itkFloat->GetPixel(index3D)); mask2D->SetPixel(index2D, itkMask->GetPixel(index3D)); masnNoNaN2D->SetPixel(index2D, itkMaskNoNaN->GetPixel(index3D)); morph2D->SetPixel(index2D, itkMorphMask->GetPixel(index3D)); voxelsInMask += (itkMask->GetPixel(index3D) > 0) ? 1 : 0; } } image2D->SetSpacing(spacing2D); mask2D->SetSpacing(spacing2D); masnNoNaN2D->SetSpacing(spacing2D); morph2D->SetSpacing(spacing2D); mitk::Image::Pointer tmpFloatImage = mitk::Image::New(); tmpFloatImage->InitializeByItk(image2D.GetPointer()); mitk::GrabItkImageMemory(image2D, tmpFloatImage); mitk::Image::Pointer tmpMaskImage = mitk::Image::New(); tmpMaskImage->InitializeByItk(mask2D.GetPointer()); mitk::GrabItkImageMemory(mask2D, tmpMaskImage); mitk::Image::Pointer tmpMaskNoNaNImage = mitk::Image::New(); tmpMaskNoNaNImage->InitializeByItk(masnNoNaN2D.GetPointer()); mitk::GrabItkImageMemory(masnNoNaN2D, tmpMaskNoNaNImage); mitk::Image::Pointer tmpMorphMaskImage = mitk::Image::New(); tmpMorphMaskImage->InitializeByItk(morph2D.GetPointer()); mitk::GrabItkImageMemory(morph2D, tmpMorphMaskImage); if (voxelsInMask > 0) { imageVector.push_back(tmpFloatImage); maskVector.push_back(tmpMaskImage); maskNoNaNVector.push_back(tmpMaskNoNaNImage); morphMaskVector.push_back(tmpMorphMaskImage); } } } static void SaveSliceOrImageAsPNG(mitk::Image::Pointer image, mitk::Image::Pointer mask, std::string path, int index) { // Create a Standalone Datastorage for the single purpose of saving screenshots.. mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); QmitkRenderWindow renderWindow; renderWindow.GetRenderer()->SetDataStorage(ds); auto nodeI = mitk::DataNode::New(); nodeI->SetData(image); auto nodeM = mitk::DataNode::New(); nodeM->SetData(mask); ds->Add(nodeI); ds->Add(nodeM); mitk::TimeGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); mitk::SliceNavigationController::Pointer sliceNaviController = renderWindow.GetSliceNavigationController(); unsigned int numberOfSteps = 1; if (sliceNaviController) { numberOfSteps = sliceNaviController->GetSlice()->GetSteps(); sliceNaviController->GetSlice()->SetPos(0); } renderWindow.show(); renderWindow.resize(256, 256); for (unsigned int currentStep = 0; currentStep < numberOfSteps; ++currentStep) { if (sliceNaviController) { sliceNaviController->GetSlice()->SetPos(currentStep); } renderWindow.GetRenderer()->PrepareRender(); vtkRenderWindow* renderWindow2 = renderWindow.GetVtkRenderWindow(); mitk::BaseRenderer* baserenderer = mitk::BaseRenderer::GetInstance(renderWindow2); auto vtkRender = baserenderer->GetVtkRenderer(); vtkRender->GetRenderWindow()->WaitForCompletion(); vtkRenderLargeImage* magnifier = vtkRenderLargeImage::New(); magnifier->SetInput(vtkRender); magnifier->SetMagnification(3.0); std::stringstream ss; ss << path << "_Idx-" << index << "_Step-"<> tmpImageName; auto fileWriter = vtkPNGWriter::New(); fileWriter->SetInputConnection(magnifier->GetOutputPort()); fileWriter->SetFileName(tmpImageName.c_str()); fileWriter->Write(); fileWriter->Delete(); } } int main(int argc, char* argv[]) { // Commented : Updated to a common interface, include, if possible, mask is type unsigned short, uses Quantification, Comments // Name follows standard scheme with Class Name::Feature Name // Commented 2: Updated to use automatic inclusion of list of parameters if required. mitk::GIFImageDescriptionFeatures::Pointer ipCalculator = mitk::GIFImageDescriptionFeatures::New(); // Commented 2, Tested mitk::GIFFirstOrderStatistics::Pointer firstOrderCalculator = mitk::GIFFirstOrderStatistics::New(); //Commented 2 mitk::GIFFirstOrderHistogramStatistics::Pointer firstOrderHistoCalculator = mitk::GIFFirstOrderHistogramStatistics::New(); // Commented 2, Tested mitk::GIFVolumetricStatistics::Pointer volCalculator = mitk::GIFVolumetricStatistics::New(); // Commented 2, Tested mitk::GIFVolumetricDensityStatistics::Pointer voldenCalculator = mitk::GIFVolumetricDensityStatistics::New(); // Commented 2, Tested mitk::GIFCooccurenceMatrix::Pointer coocCalculator = mitk::GIFCooccurenceMatrix::New(); // Commented 2, Will not be tested mitk::GIFCooccurenceMatrix2::Pointer cooc2Calculator = mitk::GIFCooccurenceMatrix2::New(); //Commented 2 mitk::GIFNeighbouringGreyLevelDependenceFeature::Pointer ngldCalculator = mitk::GIFNeighbouringGreyLevelDependenceFeature::New(); //Commented 2, Tested mitk::GIFGreyLevelRunLength::Pointer rlCalculator = mitk::GIFGreyLevelRunLength::New(); // Commented 2 mitk::GIFGreyLevelSizeZone::Pointer glszCalculator = mitk::GIFGreyLevelSizeZone::New(); // Commented 2, Tested mitk::GIFGreyLevelDistanceZone::Pointer gldzCalculator = mitk::GIFGreyLevelDistanceZone::New(); //Commented 2, Tested mitk::GIFLocalIntensity::Pointer lociCalculator = mitk::GIFLocalIntensity::New(); //Commented 2, Tested mitk::GIFIntensityVolumeHistogramFeatures::Pointer ivohCalculator = mitk::GIFIntensityVolumeHistogramFeatures::New(); // Commented 2 mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::Pointer ngtdCalculator = mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::New(); //Commented 2, Tested mitk::GIFCurvatureStatistic::Pointer curvCalculator = mitk::GIFCurvatureStatistic::New(); //Commented 2, Tested std::vector features; features.push_back(volCalculator.GetPointer()); features.push_back(voldenCalculator.GetPointer()); features.push_back(curvCalculator.GetPointer()); features.push_back(firstOrderCalculator.GetPointer()); features.push_back(firstOrderHistoCalculator.GetPointer()); features.push_back(ivohCalculator.GetPointer()); features.push_back(lociCalculator.GetPointer()); features.push_back(coocCalculator.GetPointer()); features.push_back(cooc2Calculator.GetPointer()); features.push_back(ngldCalculator.GetPointer()); features.push_back(rlCalculator.GetPointer()); features.push_back(glszCalculator.GetPointer()); features.push_back(gldzCalculator.GetPointer()); features.push_back(ipCalculator.GetPointer()); features.push_back(ngtdCalculator.GetPointer()); mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); mitk::cl::GlobalImageFeaturesParameter param; param.AddParameter(parser); parser.addArgument("--","-", mitkCommandLineParser::String, "---", "---", us::Any(),true); for (auto cFeature : features) { cFeature->AddArguments(parser); } parser.addArgument("--", "-", mitkCommandLineParser::String, "---", "---", us::Any(), true); parser.addArgument("description","d",mitkCommandLineParser::String,"Text","Description that is added to the output",us::Any()); parser.addArgument("direction", "dir", mitkCommandLineParser::String, "Int", "Allows to specify the direction for Cooc and RL. 0: All directions, 1: Only single direction (Test purpose), 2,3,4... Without dimension 0,1,2... ", us::Any()); parser.addArgument("slice-wise", "slice", mitkCommandLineParser::String, "Int", "Allows to specify if the image is processed slice-wise (number giving direction) ", us::Any()); parser.addArgument("output-mode", "omode", mitkCommandLineParser::Int, "Int", "Defines if the results of an image / slice are written in a single row (0 , default) or column (1)."); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Global Image Feature calculator"); parser.setDescription("Calculates different global statistics for a given segmentation / image combination"); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); param.ParseParameter(parsedArgs); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } //bool savePNGofSlices = true; //std::string folderForPNGOfSlices = "E:\\tmp\\bonekamp\\fig\\"; std::string version = "Version: 1.22"; MITK_INFO << version; std::ofstream log; if (param.useLogfile) { log.open(param.logfilePath, std::ios::app); log << version; log << "Image: " << param.imagePath; log << "Mask: " << param.maskPath; } if (param.useDecimalPoint) { std::cout.imbue(std::locale(std::cout.getloc(), new punct_facet(param.decimalPoint))); } mitk::Image::Pointer image; mitk::Image::Pointer mask; - mitk::Image::Pointer tmpImage = mitk::IOUtil::LoadImage(param.imagePath); - mitk::Image::Pointer tmpMask = mitk::IOUtil::LoadImage(param.maskPath); + mitk::Image::Pointer tmpImage = mitk::IOUtil::Load(param.imagePath); + mitk::Image::Pointer tmpMask = mitk::IOUtil::Load(param.maskPath); image = tmpImage; mask = tmpMask; mitk::Image::Pointer morphMask = mask; if (param.useMorphMask) { - morphMask = mitk::IOUtil::LoadImage(param.morphPath); + morphMask = mitk::IOUtil::Load(param.morphPath); } log << " Check for Dimensions -"; if ((image->GetDimension() != mask->GetDimension())) { MITK_INFO << "Dimension of image does not match. "; MITK_INFO << "Correct one image, may affect the result"; if (image->GetDimension() == 2) { mitk::Convert2Dto3DImageFilter::Pointer multiFilter2 = mitk::Convert2Dto3DImageFilter::New(); multiFilter2->SetInput(tmpImage); multiFilter2->Update(); image = multiFilter2->GetOutput(); } if (mask->GetDimension() == 2) { mitk::Convert2Dto3DImageFilter::Pointer multiFilter3 = mitk::Convert2Dto3DImageFilter::New(); multiFilter3->SetInput(tmpMask); multiFilter3->Update(); mask = multiFilter3->GetOutput(); } } int writeDirection = 0; if (parsedArgs.count("output-mode")) { writeDirection = us::any_cast(parsedArgs["output-mode"]); } log << " Check for Resolution -"; if (param.resampleToFixIsotropic) { mitk::Image::Pointer newImage = mitk::Image::New(); AccessByItk_2(image, ResampleImage, param.resampleResolution, newImage); image = newImage; } if ( ! mitk::Equal(mask->GetGeometry(0)->GetOrigin(), image->GetGeometry(0)->GetOrigin())) { MITK_INFO << "Not equal Origins"; if (param.ensureSameSpace) { MITK_INFO << "Warning!"; MITK_INFO << "The origin of the input image and the mask do not match. They are"; MITK_INFO << "now corrected. Please check to make sure that the images still match"; image->GetGeometry(0)->SetOrigin(mask->GetGeometry(0)->GetOrigin()); } else { return -1; } } log << " Resample if required -"; if (param.resampleMask) { mitk::Image::Pointer newMaskImage = mitk::Image::New(); AccessByItk_2(mask, ResampleMask, image, newMaskImage); mask = newMaskImage; } log << " Check for Equality -"; if ( ! mitk::Equal(mask->GetGeometry(0)->GetSpacing(), image->GetGeometry(0)->GetSpacing())) { MITK_INFO << "Not equal Sapcings"; if (param.ensureSameSpace) { MITK_INFO << "Warning!"; MITK_INFO << "The spacing of the mask was set to match the spacing of the input image."; MITK_INFO << "This might cause unintended spacing of the mask image"; image->GetGeometry(0)->SetSpacing(mask->GetGeometry(0)->GetSpacing()); } else { MITK_INFO << "The spacing of the mask and the input images is not equal."; MITK_INFO << "Terminating the programm. You may use the '-fi' option"; return -1; } } int direction = 0; if (parsedArgs.count("direction")) { direction = mitk::cl::splitDouble(parsedArgs["direction"].ToString(), ';')[0]; } MITK_INFO << "Start creating Mask without NaN"; mitk::Image::Pointer maskNoNaN = mitk::Image::New(); AccessByItk_2(image, CreateNoNaNMask, mask, maskNoNaN); //CreateNoNaNMask(mask, image, maskNoNaN); bool sliceWise = false; int sliceDirection = 0; unsigned int currentSlice = 0; bool imageToProcess = true; std::vector floatVector; std::vector maskVector; std::vector maskNoNaNVector; std::vector morphMaskVector; if ((parsedArgs.count("slice-wise")) && image->GetDimension() > 2) { MITK_INFO << "Enabled slice-wise"; sliceWise = true; sliceDirection = mitk::cl::splitDouble(parsedArgs["slice-wise"].ToString(), ';')[0]; MITK_INFO << sliceDirection; ExtractSlicesFromImages(image, mask, maskNoNaN, morphMask, sliceDirection, floatVector, maskVector, maskNoNaNVector, morphMaskVector); MITK_INFO << "Slice"; } log << " Configure features -"; for (auto cFeature : features) { if (param.defineGlobalMinimumIntensity) { cFeature->SetMinimumIntensity(param.globalMinimumIntensity); cFeature->SetUseMinimumIntensity(true); } if (param.defineGlobalMaximumIntensity) { cFeature->SetMaximumIntensity(param.globalMaximumIntensity); cFeature->SetUseMaximumIntensity(true); } if (param.defineGlobalNumberOfBins) { cFeature->SetBins(param.globalNumberOfBins); MITK_INFO << param.globalNumberOfBins; } cFeature->SetParameter(parsedArgs); cFeature->SetDirection(direction); cFeature->SetEncodeParameters(param.encodeParameter); } bool addDescription = parsedArgs.count("description"); mitk::cl::FeatureResultWritter writer(param.outputPath, writeDirection); if (param.useDecimalPoint) { writer.SetDecimalPoint(param.decimalPoint); } std::string description = ""; if (addDescription) { description = parsedArgs["description"].ToString(); } mitk::Image::Pointer cImage = image; mitk::Image::Pointer cMask = mask; mitk::Image::Pointer cMaskNoNaN = maskNoNaN; mitk::Image::Pointer cMorphMask = morphMask; if (param.useHeader) { writer.AddColumn("SoftwareVersion"); writer.AddColumn("Patient"); writer.AddColumn("Image"); writer.AddColumn("Segmentation"); } // Create a QTApplication and a Datastorage // This is necessary in order to save screenshots of // each image / slice. QApplication qtapplication(argc, argv); QmitkRegisterClasses(); std::vector allStats; log << " Begin Processing -"; while (imageToProcess) { if (sliceWise) { cImage = floatVector[currentSlice]; cMask = maskVector[currentSlice]; cMaskNoNaN = maskNoNaNVector[currentSlice]; cMorphMask = morphMaskVector[currentSlice]; imageToProcess = (floatVector.size()-1 > (currentSlice)) ? true : false ; } else { imageToProcess = false; } if (param.writePNGScreenshots) { SaveSliceOrImageAsPNG(cImage, cMask, param.pngScreenshotsPath, currentSlice); } if (param.writeAnalysisImage) { mitk::IOUtil::Save(cImage, param.anaylsisImagePath); } if (param.writeAnalysisMask) { mitk::IOUtil::Save(cMask, param.analysisMaskPath); } mitk::AbstractGlobalImageFeature::FeatureListType stats; for (auto cFeature : features) { log << " Calculating " << cFeature->GetFeatureClassName() << " -"; cFeature->SetMorphMask(cMorphMask); cFeature->CalculateFeaturesUsingParameters(cImage, cMask, cMaskNoNaN, stats); } for (std::size_t i = 0; i < stats.size(); ++i) { std::cout << stats[i].first << " - " << stats[i].second << std::endl; } writer.AddHeader(description, currentSlice, stats, param.useHeader, addDescription); if (true) { writer.AddSubjectInformation(MITK_REVISION); writer.AddSubjectInformation(param.imageFolder); writer.AddSubjectInformation(param.imageName); writer.AddSubjectInformation(param.maskName); } writer.AddResult(description, currentSlice, stats, param.useHeader, addDescription); allStats.push_back(stats); ++currentSlice; } log << " Process Slicewise -"; if (sliceWise) { mitk::AbstractGlobalImageFeature::FeatureListType statMean, statStd; for (std::size_t i = 0; i < allStats[0].size(); ++i) { auto cElement1 = allStats[0][i]; cElement1.first = "SliceWise Mean " + cElement1.first; cElement1.second = 0.0; auto cElement2 = allStats[0][i]; cElement2.first = "SliceWise Var. " + cElement2.first; cElement2.second = 0.0; statMean.push_back(cElement1); statStd.push_back(cElement2); } for (auto cStat : allStats) { for (std::size_t i = 0; i < cStat.size(); ++i) { statMean[i].second += cStat[i].second / (1.0*allStats.size()); } } for (auto cStat : allStats) { for (std::size_t i = 0; i < cStat.size(); ++i) { statStd[i].second += (cStat[i].second - statMean[i].second)*(cStat[i].second - statMean[i].second) / (1.0*allStats.size()); } } for (std::size_t i = 0; i < statMean.size(); ++i) { std::cout << statMean[i].first << " - " << statMean[i].second << std::endl; std::cout << statStd[i].first << " - " << statStd[i].second << std::endl; } if (true) { writer.AddSubjectInformation(MITK_REVISION); writer.AddSubjectInformation(param.imageFolder); writer.AddSubjectInformation(param.imageName); writer.AddSubjectInformation(param.maskName + " - Mean"); } writer.AddResult(description, currentSlice, statMean, param.useHeader, addDescription); if (true) { writer.AddSubjectInformation(MITK_REVISION); writer.AddSubjectInformation(param.imageFolder); writer.AddSubjectInformation(param.imageName); writer.AddSubjectInformation(param.maskName + " - Var."); } writer.AddResult(description, currentSlice, statStd, param.useHeader, addDescription); } if (param.useLogfile) { log << "Finished calculation" << std::endl; log.close(); } return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLImageConverter.cpp b/Modules/Classification/CLMiniApps/CLImageConverter.cpp index af36ca9dd8..de2ab03538 100644 --- a/Modules/Classification/CLMiniApps/CLImageConverter.cpp +++ b/Modules/Classification/CLMiniApps/CLImageConverter.cpp @@ -1,54 +1,54 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input file:", "Input file",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file",us::Any(),false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputName = us::any_cast(parsedArgs["input"]); std::string outputName = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(inputName)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputName); mitk::IOUtil::Save(image, outputName); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLImageCropper.cpp b/Modules/Classification/CLMiniApps/CLImageCropper.cpp index e0368a5c7d..99912e3369 100644 --- a/Modules/Classification/CLMiniApps/CLImageCropper.cpp +++ b/Modules/Classification/CLMiniApps/CLImageCropper.cpp @@ -1,66 +1,66 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include #include int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("reference", "r", mitkCommandLineParser::InputDirectory, "Input file:", "Input file",us::Any(),false); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input file:", "Input file",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file",us::Any(),false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string referenceName = us::any_cast(parsedArgs["reference"]); std::string inputName = us::any_cast(parsedArgs["input"]); std::string outputName = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer imageToCrop = dynamic_cast(mitk::IOUtil::Load(inputName)[0].GetPointer()); - mitk::Image::Pointer referenceImage = dynamic_cast(mitk::IOUtil::Load(referenceName)[0].GetPointer()); + mitk::Image::Pointer imageToCrop = mitk::IOUtil::Load(inputName); + mitk::Image::Pointer referenceImage = mitk::IOUtil::Load(referenceName); mitk::BoundingObjectCutter::Pointer cutter = mitk::BoundingObjectCutter::New(); mitk::BoundingObject::Pointer boundingObject = (mitk::Cuboid::New()).GetPointer(); boundingObject->FitGeometry(referenceImage->GetGeometry()); cutter->SetBoundingObject(boundingObject); cutter->SetInput(imageToCrop); cutter->Update(); mitk::IOUtil::Save(cutter->GetOutput(), outputName); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLImageTypeConverter.cpp b/Modules/Classification/CLMiniApps/CLImageTypeConverter.cpp index 41ab9734a5..aeeaf8325a 100644 --- a/Modules/Classification/CLMiniApps/CLImageTypeConverter.cpp +++ b/Modules/Classification/CLMiniApps/CLImageTypeConverter.cpp @@ -1,108 +1,108 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include #include #define CONVERT_IMAGE(TYPE, DIM) itk::Image::Pointer itkImage = itk::Image::New(); \ MITK_INFO << "Data Type for Conversion: "<< typeid(TYPE).name(); \ mitk::CastToItkImage(image, itkImage); \ mitk::CastToMitkImage(itkImage, outputImage) int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Image Type Converter"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input file:", "Input file",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file", us::Any(), false); parser.addArgument("type", "t", mitkCommandLineParser::OutputFile, "Type definition:", "Define Scalar data type: int, uint, short, ushort, char, uchar, float, double", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputName = us::any_cast(parsedArgs["input"]); std::string outputName = us::any_cast(parsedArgs["output"]); std::string type = us::any_cast(parsedArgs["type"]); - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(inputName); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputName); mitk::Image::Pointer outputImage = mitk::Image::New(); if (type.compare("int") == 0) { CONVERT_IMAGE(int, 3); } else if (type.compare("uint") == 0) { CONVERT_IMAGE(unsigned int, 3); } else if (type.compare("char") == 0) { CONVERT_IMAGE(char, 3); } else if (type.compare("uchar") == 0) { CONVERT_IMAGE(unsigned char, 3); } else if (type.compare("short") == 0) { CONVERT_IMAGE(short, 3); } else if (type.compare("ushort") == 0) { CONVERT_IMAGE(unsigned short, 3); } else if (type.compare("float") == 0) { CONVERT_IMAGE(float, 3); } else if (type.compare("double") == 0) { CONVERT_IMAGE(double, 3); } else if (type.compare("none") == 0) { MITK_INFO << " No conversion performed"; outputImage = image; } else { CONVERT_IMAGE(double, 3); } mitk::IOUtil::Save(outputImage, outputName); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLLungSegmentation.cpp b/Modules/Classification/CLMiniApps/CLLungSegmentation.cpp index 46b4e58737..b20ee2a468 100644 --- a/Modules/Classification/CLMiniApps/CLLungSegmentation.cpp +++ b/Modules/Classification/CLMiniApps/CLLungSegmentation.cpp @@ -1,176 +1,176 @@ /*=================================================================== 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 "mitkProperties.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include #include "mitkLabelSetImage.h" #include "mitkImageCast.h" #include "mitkImageTimeSelector.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include #include template void StartRegionGrowing(itk::Image* itkImage, mitk::Image::Pointer &result) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; typedef itk::ConnectedThresholdImageFilter RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); // convert world coordinates to image indices IndexType startIndex; IndexType seedIndex; IndexType bestSeedIndex; startIndex[0] = itkImage->GetLargestPossibleRegion().GetSize()[0]/2; startIndex[1] = itkImage->GetLargestPossibleRegion().GetSize()[1]/2; startIndex[2] = itkImage->GetLargestPossibleRegion().GetSize()[2]/2; auto region = itkImage->GetLargestPossibleRegion(); auto spacing = itkImage->GetSpacing(); spacing[0] = itkImage->GetSpacing()[0]; spacing[1] = itkImage->GetSpacing()[1]; spacing[2] = itkImage->GetSpacing()[2]; int minimumDistance = 50 * 50 * (spacing[0] + spacing[1] + spacing[2]); for (int x = -50; x < 50; ++x) { for (int y = -50; y < 50; ++y) { for (int z = -20; z < 20; ++z) { seedIndex[0] = startIndex[0] + x; seedIndex[1] = startIndex[1] + y; seedIndex[2] = startIndex[2] + z; if (region.IsInside(seedIndex)) { if (itkImage->GetPixel(seedIndex) > 0) { int newDistance = x*x*spacing[0] + y*y*spacing[1] + z*z*spacing[2]; if (newDistance < minimumDistance) { bestSeedIndex = seedIndex; minimumDistance = newDistance; } } } } } } seedIndex = bestSeedIndex; MITK_INFO << "Seedpoint: " << seedIndex; //perform region growing in desired segmented region regionGrower->SetInput(itkImage); regionGrower->AddSeed(seedIndex); regionGrower->SetLower(1); regionGrower->SetUpper(255); try { regionGrower->Update(); } catch (const itk::ExceptionObject&) { return; // can't work } catch (...) { return; } //Store result and preview mitk::CastToMitkImage(regionGrower->GetOutput(), result); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input folder:", "Input folder", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file",us::Any(),false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputFile = us::any_cast(parsedArgs["input"]); std::string outFileName = us::any_cast(parsedArgs["output"]); MITK_INFO << "Start Image Loading"; - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(inputFile); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputFile); MITK_INFO << "Loaded Image"; mitk::OtsuSegmentationFilter::Pointer otsuFilter = mitk::OtsuSegmentationFilter::New(); otsuFilter->SetNumberOfThresholds(2); otsuFilter->SetValleyEmphasis(false); otsuFilter->SetNumberOfBins(128); otsuFilter->SetInput(image); try { otsuFilter->Update(); } catch (...) { mitkThrow() << "itkOtsuFilter error (image dimension must be in {2, 3} and image must not be RGB)"; } MITK_INFO << "Calculated Otsu"; mitk::LabelSetImage::Pointer resultImage = mitk::LabelSetImage::New(); resultImage->InitializeByLabeledImage(otsuFilter->GetOutput()); mitk::Image::Pointer rawMask = resultImage->CreateLabelMask(1); mitk::Image::Pointer pickedMask; AccessByItk_1(rawMask, StartRegionGrowing, pickedMask); mitk::MorphologicalOperations::FillHoles(pickedMask); mitk::MorphologicalOperations::Closing(pickedMask, 5, mitk::MorphologicalOperations::StructuralElementType::Ball); mitk::MorphologicalOperations::FillHoles(pickedMask); mitk::IOUtil::Save(pickedMask, outFileName); return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLMiniApps/CLMRNormalization.cpp b/Modules/Classification/CLMiniApps/CLMRNormalization.cpp index 453523dbd7..a32f9d650d 100644 --- a/Modules/Classification/CLMiniApps/CLMRNormalization.cpp +++ b/Modules/Classification/CLMiniApps/CLMRNormalization.cpp @@ -1,165 +1,165 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" #include "itkImageRegionIterator.h" // MITK #include #include #include #include #include // ITK #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; int main(int argc, char* argv[]) { MITK_INFO << "Start"; mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("mode", "mode", mitkCommandLineParser::InputImage, "Normalisation mode", "1,2,3: Single Area normalization to Mean, Median, Mode, 4,5,6: Mean, Median, Mode of two regions. ", us::Any(), false); parser.addArgument("mask0", "m0", mitkCommandLineParser::InputImage, "Input Mask", "The median of the area covered by this mask will be set to 0", us::Any(), false); parser.addArgument("mask1", "m1", mitkCommandLineParser::InputImage, "Input Mask", "The median of the area covered by this mask will be set to 1", us::Any(), true); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output Image", "Target file. The output statistic is appended to this file.", us::Any(), false); parser.addArgument("ignore-outlier", "outlier", mitkCommandLineParser::Bool, "Ignore Outlier", "Ignores the highest and lowest 2% during calculation. Only on single mask normalization.", us::Any(), true); parser.addArgument("value", "v", mitkCommandLineParser::Float, "Target Value", "Target value, the target value (for example median) is set to this value.", us::Any(), true); parser.addArgument("width", "w", mitkCommandLineParser::Float, "Target Width", "Ignores the highest and lowest 2% during calculation. Only on single mask normalization.", us::Any(), true); parser.addArgument("float", "float", mitkCommandLineParser::Bool, "Target Width", "Ignores the highest and lowest 2% during calculation. Only on single mask normalization.", us::Any(), true); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("MR Normalization Tool"); parser.setDescription("Normalizes a MR image. Sets the Median of the tissue covered by mask 0 to 0 and the median of the area covered by mask 1 to 1."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } bool ignore_outlier = false; if (parsedArgs.count("ignore-outlier")) { ignore_outlier = us::any_cast(parsedArgs["ignore-outlier"]); } MITK_INFO << "Mode access"; int mode =std::stoi(us::any_cast(parsedArgs["mode"])); MITK_INFO << "Mode: " << mode; MITK_INFO << "Read images"; mitk::Image::Pointer mask1; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(parsedArgs["image"].ToString())[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["image"].ToString()); if (parsedArgs.count("float")) { typedef itk::Image ImageType; ImageType::Pointer img = ImageType::New(); mitk::CastToItkImage(image, img); mitk::CastToMitkImage(img, image); } - mitk::Image::Pointer mask0 = dynamic_cast(mitk::IOUtil::Load(parsedArgs["mask0"].ToString())[0].GetPointer()); + mitk::Image::Pointer mask0 = mitk::IOUtil::Load(parsedArgs["mask0"].ToString()); if (mode > 3) { - mask1 = dynamic_cast(mitk::IOUtil::Load(parsedArgs["mask1"].ToString())[0].GetPointer()); + mask1 = mitk::IOUtil::Load(parsedArgs["mask1"].ToString()); } mitk::MRNormLinearStatisticBasedFilter::Pointer oneRegion = mitk::MRNormLinearStatisticBasedFilter::New(); mitk::MRNormTwoRegionsBasedFilter::Pointer twoRegion = mitk::MRNormTwoRegionsBasedFilter::New(); mitk::Image::Pointer output; oneRegion->SetInput(image); oneRegion->SetMask(mask0); oneRegion->SetIgnoreOutlier(ignore_outlier); twoRegion->SetInput(image); twoRegion->SetMask1(mask0); twoRegion->SetMask2(mask1); if (parsedArgs.count("value")) { double target = us::any_cast(parsedArgs["value"]); oneRegion->SetTargetValue(target); } if (parsedArgs.count("width")) { double width = us::any_cast(parsedArgs["width"]); oneRegion->SetTargetValue(width); } switch (mode) { case 1: oneRegion->SetCenterMode(mitk::MRNormLinearStatisticBasedFilter::MEAN); oneRegion->Update(); output=oneRegion->GetOutput(); break; case 2: oneRegion->SetCenterMode(mitk::MRNormLinearStatisticBasedFilter::MEDIAN); oneRegion->Update(); output=oneRegion->GetOutput(); break; case 3: oneRegion->SetCenterMode(mitk::MRNormLinearStatisticBasedFilter::MODE); oneRegion->Update(); output=oneRegion->GetOutput(); break; case 4: twoRegion->SetArea1(mitk::MRNormTwoRegionsBasedFilter::MEAN); twoRegion->SetArea2(mitk::MRNormTwoRegionsBasedFilter::MEAN); twoRegion->Update(); output=twoRegion->GetOutput(); break; case 5: twoRegion->SetArea1(mitk::MRNormTwoRegionsBasedFilter::MEDIAN); twoRegion->SetArea2(mitk::MRNormTwoRegionsBasedFilter::MEDIAN); twoRegion->Update(); output=twoRegion->GetOutput(); break; case 6: twoRegion->SetArea1(mitk::MRNormTwoRegionsBasedFilter::MODE); twoRegion->SetArea2(mitk::MRNormTwoRegionsBasedFilter::MODE); twoRegion->Update(); output=twoRegion->GetOutput(); break; } mitk::IOUtil::Save(output, parsedArgs["output"].ToString()); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp b/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp index 58ff53861c..12be20f840 100644 --- a/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp +++ b/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp @@ -1,168 +1,168 @@ /*=================================================================== 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 "mitkProperties.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "mitkPreferenceListReaderOptionsFunctor.h" // MatchPoint #include #include #include #include #include #include #include #include #include #include #include #include // Qt #include #include #include //#include #include #include #include #include int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("moving", "m", mitkCommandLineParser::InputDirectory, "Input folder:", "Input folder", us::Any(), false); parser.addArgument("fixed", "f", mitkCommandLineParser::InputDirectory, "Input folder:", "Input folder", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file", us::Any(), false); parser.addArgument("reader", "r", mitkCommandLineParser::Int, "Reader ID", "Reader Name", us::Any(), false); parser.addArgument("interpolation", "interp", mitkCommandLineParser::Int, "Reader ID", "Reader Name", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); QFileInfo fi(argv[0]); map::deployment::DLLDirectoryBrowser::Pointer browser = map::deployment::DLLDirectoryBrowser::New(); browser->addDLLSearchLocation(QDir::homePath().toStdString()); browser->addDLLSearchLocation(QDir::currentPath().toStdString()); browser->addDLLSearchLocation(fi.canonicalPath().toStdString()); browser->update(); auto dllList = browser->getLibraryInfos(); int id = 0; std::cout << std::endl << " --- Algorithm List --- " << std::endl; for (auto info : dllList) { std::cout << "Algorithm ID " << id << ": " << info->getAlgorithmUID().getName() << std::endl; ++id; } std::cout << std::endl << " --- Interpolation List --- " << std::endl; std::cout << "Interpolation ID 0: Linear Interpolation " << std::endl; std::cout << "Interpolation ID 1: Nearest Neighbour" << std::endl; std::cout << "Interpolation ID 2: BSpline 3D" << std::endl << std::endl; mitk::ImageMappingInterpolator::Type interpolationMode = mitk::ImageMappingInterpolator::Linear; if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string movingFile = us::any_cast(parsedArgs["moving"]); std::string fixedFile = us::any_cast(parsedArgs["fixed"]); int selectedAlgorithm = us::any_cast(parsedArgs["reader"]); std::string outputPath = us::any_cast(parsedArgs["output"]); if (parsedArgs.count("interpolation")) { switch (us::any_cast(parsedArgs["interpolation"])) { case 0: interpolationMode = mitk::ImageMappingInterpolator::Linear; break; case 1: interpolationMode = mitk::ImageMappingInterpolator::NearestNeighbor; break; case 2: interpolationMode = mitk::ImageMappingInterpolator::BSpline_3; break; default: interpolationMode = mitk::ImageMappingInterpolator::Linear; } } - mitk::Image::Pointer movingImage = dynamic_cast(mitk::IOUtil::Load(movingFile)[0].GetPointer()); - mitk::Image::Pointer fixedImage = dynamic_cast(mitk::IOUtil::Load(fixedFile)[0].GetPointer()); + mitk::Image::Pointer movingImage = mitk::IOUtil::Load(movingFile); + mitk::Image::Pointer fixedImage = mitk::IOUtil::Load(fixedFile); auto dllInfo = dllList[selectedAlgorithm]; if (!dllInfo) { MITK_ERROR << "No valid algorithm is selected. Cannot load algorithm. ABORTING."; return -1; } ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( dllInfo->getLibraryFilePath()); ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); MITK_INFO << "Well...."; if (tempAlgorithm.IsNull()) { MITK_ERROR << "Error. Cannot load selected algorithm."; return -2; } mitk::MITKAlgorithmHelper helper(tempAlgorithm); helper.SetData(movingImage, fixedImage); auto registration = helper.GetRegistration(); MITK_INFO << "Well...."; mitk::Image::Pointer spResultData= mitk::ImageMappingHelper::map(movingImage, registration, false, // Use all Pixels 0.0, // Padding Value fixedImage->GetGeometry()->Clone().GetPointer(), // Ref. Geometry false, //!(this->m_allowUnregPixels), 0, // Error Value interpolationMode // Interpolator Type ); MITK_INFO << "Well...."; mitk::IOUtil::Save(spResultData, outputPath); return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLMiniApps/CLMultiForestPrediction.cpp b/Modules/Classification/CLMiniApps/CLMultiForestPrediction.cpp index bc42b2a075..2958e02732 100644 --- a/Modules/Classification/CLMiniApps/CLMultiForestPrediction.cpp +++ b/Modules/Classification/CLMiniApps/CLMultiForestPrediction.cpp @@ -1,251 +1,251 @@ /*=================================================================== 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 mitkForest_cpp #define mitkForest_cpp #include "time.h" #include #include #include #include #include #include #include #include #include #include #include // ----------------------- Forest Handling ---------------------- #include int main(int argc, char* argv[]) { MITK_INFO << "Starting MITK_Forest Mini-App"; ////////////////////////////////////////////////////////////////////////////// // Read Console Input Parameter ////////////////////////////////////////////////////////////////////////////// ConfigFileReader allConfig(argv[1]); bool readFile = true; std::stringstream ss; for (int i = 0; i < argc; ++i ) { MITK_INFO << "-----"<< argv[i]<<"------"; if (readFile) { if (argv[i][0] == '+') { readFile = false; continue; } else { try { allConfig.ReadFile(argv[i]); } catch (std::exception &e) { MITK_INFO << e.what(); } } } else { std::string input = argv[i]; std::replace(input.begin(), input.end(),'_',' '); ss << input << std::endl; } } allConfig.ReadStream(ss); try { ////////////////////////////////////////////////////////////////////////////// // General ////////////////////////////////////////////////////////////////////////////// int currentRun = allConfig.IntValue("General","Run",0); //int doTraining = allConfig.IntValue("General","Do Training",1); std::string forestPath = allConfig.Value("General","Forest Path"); std::string trainingCollectionPath = allConfig.Value("General","Patient Collection"); std::string testCollectionPath = allConfig.Value("General", "Patient Test Collection", trainingCollectionPath); ////////////////////////////////////////////////////////////////////////////// // Read Default Classification ////////////////////////////////////////////////////////////////////////////// std::vector trainPatients = allConfig.Vector("Training Group",currentRun); std::vector testPatients = allConfig.Vector("Test Group",currentRun); std::vector modalities = allConfig.Vector("Modalities", 0); std::vector outputFilter = allConfig.Vector("Output Filter", 0); std::string trainMask = allConfig.Value("Data","Training Mask"); std::string completeTrainMask = allConfig.Value("Data","Complete Training Mask"); std::string testMask = allConfig.Value("Data","Test Mask"); std::string resultMask = allConfig.Value("Data", "Result Mask"); std::string resultProb = allConfig.Value("Data", "Result Propability"); std::string outputFolder = allConfig.Value("General","Output Folder"); std::string writeDataFilePath = allConfig.Value("Forest","File to write data to"); ////////////////////////////////////////////////////////////////////////////// // Read Data Forest Parameter ////////////////////////////////////////////////////////////////////////////// int testSingleDataset = allConfig.IntValue("Data", "Test Single Dataset",0); std::string singleDatasetName = allConfig.Value("Data", "Single Dataset Name", "none"); std::vector forestVector = allConfig.Vector("Forests", 0); ////////////////////////////////////////////////////////////////////////////// // Read Statistic Parameter ////////////////////////////////////////////////////////////////////////////// std::string statisticFilePath = allConfig.Value("Evaluation", "Statistic output file"); std::string statisticShortFilePath = allConfig.Value("Evaluation", "Statistic short output file"); std::string statisticShortFileLabel = allConfig.Value("Evaluation", "Index for short file"); std::string statisticGoldStandard = allConfig.Value("Evaluation", "Gold Standard Name","GTV"); //bool statisticWithHeader = allConfig.IntValue("Evaluation", "Write header in short file",0); std::vector labelGroupA = allConfig.Vector("LabelsA",0); std::vector labelGroupB = allConfig.Vector("LabelsB",0); std::ofstream timingFile; timingFile.open((statisticFilePath + ".timing").c_str(), std::ios::app); timingFile << statisticShortFileLabel << ";"; std::time_t lastTimePoint; time(&lastTimePoint); ////////////////////////////////////////////////////////////////////////////// // Read Images ////////////////////////////////////////////////////////////////////////////// std::vector usedModalities; for (std::size_t i = 0; i < modalities.size(); ++i) { usedModalities.push_back(modalities[i]); } usedModalities.push_back(trainMask); usedModalities.push_back(completeTrainMask); usedModalities.push_back(testMask); usedModalities.push_back(statisticGoldStandard); // vtkSmartPointer colReader = vtkSmartPointer::New(); mitk::CollectionReader* colReader = new mitk::CollectionReader(); colReader->AddDataElementIds(trainPatients); colReader->SetDataItemNames(usedModalities); if (testSingleDataset > 0) { testPatients.clear(); testPatients.push_back(singleDatasetName); } colReader->ClearDataElementIds(); colReader->AddDataElementIds(testPatients); mitk::DataCollection::Pointer testCollection = colReader->LoadCollection(testCollectionPath); std::time_t now; time(&now); double seconds = std::difftime(now, lastTimePoint); timingFile << seconds << ";"; time(&lastTimePoint); mitk::VigraRandomForestClassifier::Pointer forest = mitk::VigraRandomForestClassifier::New(); MITK_INFO << "Convert Test data"; auto testDataX = mitk::DCUtilities::DC3dDToMatrixXd(testCollection, modalities, testMask); for (std::size_t i = 0; i < forestVector.size(); ++i) { - forest = dynamic_cast(mitk::IOUtil::Load(forestVector[i])[0].GetPointer()); + forest = mitk::IOUtil::Load(forestVector[i]); time(&now); seconds = std::difftime(now, lastTimePoint); MITK_INFO << "Duration for Training: " << seconds; timingFile << seconds << ";"; time(&lastTimePoint); MITK_INFO << "Predict Test Data"; auto testDataNewY = forest->Predict(testDataX); auto testDataNewProb = forest->GetPointWiseProbabilities(); auto maxClassValue = testDataNewProb.cols(); std::vector names; for (int j = 0; j < maxClassValue; ++j) { std::string name = resultProb + std::to_string(j); names.push_back(name); } mitk::DCUtilities::MatrixToDC3d(testDataNewY, testCollection, resultMask, testMask); mitk::DCUtilities::MatrixToDC3d(testDataNewProb, testCollection, names, testMask); MITK_INFO << "Converted predicted data"; time(&now); seconds = std::difftime(now, lastTimePoint); timingFile << seconds << ";"; time(&lastTimePoint); ////////////////////////////////////////////////////////////////////////////// // Save results to folder ////////////////////////////////////////////////////////////////////////////// MITK_INFO << "Write Result to HDD"; mitk::CollectionWriter::ExportCollectionToFolder(testCollection, outputFolder + "/result_collection.xml", outputFilter); MITK_INFO << "Calculate Statistic...."; ////////////////////////////////////////////////////////////////////////////// // Calculate and Print Statistic ////////////////////////////////////////////////////////////////////////////// std::ofstream statisticFile; statisticFile.open(statisticFilePath.c_str(), std::ios::app); std::ofstream sstatisticFile; sstatisticFile.open(statisticShortFilePath.c_str(), std::ios::app); mitk::CollectionStatistic stat; stat.SetCollection(testCollection); stat.SetClassCount(5); stat.SetGoldName(statisticGoldStandard); stat.SetTestName(resultMask); stat.SetMaskName(testMask); mitk::BinaryValueminusOneToIndexMapper mapper; stat.SetGroundTruthValueToIndexMapper(&mapper); stat.SetTestValueToIndexMapper(&mapper); stat.Update(); //stat.Print(statisticFile,sstatisticFile,statisticWithHeader, statisticShortFileLabel); stat.Print(statisticFile, sstatisticFile, true, statisticShortFileLabel + "_"+std::to_string(i)); statisticFile.close(); time(&now); seconds = std::difftime(now, lastTimePoint); timingFile << seconds << std::endl; time(&lastTimePoint); timingFile.close(); } } catch (std::string s) { MITK_INFO << s; return 0; } catch (char* s) { MITK_INFO << s; } return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLN4.cpp b/Modules/Classification/CLMiniApps/CLN4.cpp index f7a65eb60f..eb8373c0ef 100644 --- a/Modules/Classification/CLMiniApps/CLN4.cpp +++ b/Modules/Classification/CLMiniApps/CLN4.cpp @@ -1,121 +1,121 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include #include "mitkCommandLineParser.h" #include #include int main(int argc, char* argv[]) { typedef itk::Image MaskImageType; typedef itk::Image ImageType; typedef itk::N4BiasFieldCorrectionImageFilter < ImageType, MaskImageType, ImageType > FilterType; mitkCommandLineParser parser; parser.setTitle("N4 Bias Field Correction"); parser.setCategory("Classification Command Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input file:", "Input file", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::OutputFile, "Output file:", "Mask file", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file", us::Any(), false); parser.addArgument("number-of-controllpoints", "noc", mitkCommandLineParser::Int, "Parameter", "The noc for the point grid size defining the B-spline estimate (default 4)", us::Any(), true); parser.addArgument("number-of-fitting-levels", "nofl", mitkCommandLineParser::Int, "Parameter", "Number of fitting levels for the multi-scale approach (default 1)", us::Any(), true); parser.addArgument("number-of-histogram-bins", "nofl", mitkCommandLineParser::Int, "Parameter", "number of bins defining the log input intensity histogram (default 200)", us::Any(), true); parser.addArgument("spline-order", "so", mitkCommandLineParser::Int, "Parameter", "Define the spline order (default 3)", us::Any(), true); parser.addArgument("winer-filter-noise", "wfn", mitkCommandLineParser::Float, "Parameter", "Noise estimate defining the Wiener filter (default 0.01)", us::Any(), true); parser.addArgument("number-of-maximum-iterations", "nomi", mitkCommandLineParser::Int, "Parameter", "Spezifies the maximum number of iterations per run", us::Any(), true); // ToDo: Number Of Maximum Iterations durchschleifen std::map parsedArgs = parser.parseArguments(argc, argv); // Show a help message if (parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } MaskImageType::Pointer itkMsk = MaskImageType::New(); - mitk::Image::Pointer img = mitk::IOUtil::LoadImage(parsedArgs["mask"].ToString()); + mitk::Image::Pointer img = mitk::IOUtil::Load(parsedArgs["mask"].ToString()); mitk::CastToItkImage(img, itkMsk); ImageType::Pointer itkImage = ImageType::New(); - mitk::Image::Pointer img2 = mitk::IOUtil::LoadImage(parsedArgs["input"].ToString()); + mitk::Image::Pointer img2 = mitk::IOUtil::Load(parsedArgs["input"].ToString()); mitk::CastToItkImage(img2, itkImage); FilterType::Pointer filter = FilterType::New(); filter->SetInput(itkImage); filter->SetMaskImage(itkMsk); if (parsedArgs.count("number-of-controllpoints") > 0) { int variable = us::any_cast(parsedArgs["maximum-iterations"]); MITK_INFO << "Number of controll points: " << variable; filter->SetNumberOfControlPoints(variable); } if (parsedArgs.count("number-of-fitting-levels") > 0) { int variable = us::any_cast(parsedArgs["number-of-fitting-levels"]); MITK_INFO << "Number of fitting levels: " << variable; filter->SetNumberOfFittingLevels(variable); } if (parsedArgs.count("number-of-histogram-bins") > 0) { int variable = us::any_cast(parsedArgs["number-of-histogram-bins"]); MITK_INFO << "Number of histogram bins: " << variable; filter->SetNumberOfHistogramBins(variable); } if (parsedArgs.count("spline-order") > 0) { int variable = us::any_cast(parsedArgs["spline-order"]); MITK_INFO << "Spline Order " << variable; filter->SetSplineOrder(variable); } if (parsedArgs.count("winer-filter-noise") > 0) { float variable = us::any_cast(parsedArgs["winer-filter-noise"]); MITK_INFO << "Number of histogram bins: " << variable; filter->SetWienerFilterNoise(variable); } if (parsedArgs.count("number-of-maximum-iterations") > 0) { int variable = us::any_cast(parsedArgs["number-of-maximum-iterations"]); MITK_INFO << "Number of Maximum Iterations: " << variable; auto list = filter->GetMaximumNumberOfIterations(); list.Fill(variable); filter->SetMaximumNumberOfIterations(list); } filter->Update(); auto out = filter->GetOutput(); mitk::Image::Pointer outImg = mitk::Image::New(); mitk::CastToMitkImage(out, outImg); mitk::IOUtil::Save(outImg, parsedArgs["output"].ToString()); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLNrrdToPoly.cpp b/Modules/Classification/CLMiniApps/CLNrrdToPoly.cpp index b7eb90a499..4f49e3b8c7 100644 --- a/Modules/Classification/CLMiniApps/CLNrrdToPoly.cpp +++ b/Modules/Classification/CLMiniApps/CLNrrdToPoly.cpp @@ -1,78 +1,78 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" // VTK #include #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "Input Mask", "Mask Image that specifies the area over for the statistic, (Values = 1)", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output text file", "Target file. The output statistic is appended to this file.", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Segmentation to Mask"); parser.setDescription("Estimates a Mesh from a segmentation"); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } MITK_INFO << "Version: "<< 1.0; - mitk::Image::Pointer mask = mitk::IOUtil::LoadImage(parsedArgs["mask"].ToString()); + mitk::Image::Pointer mask = mitk::IOUtil::Load(parsedArgs["mask"].ToString()); vtkSmartPointer image = mask->GetVtkImageData(); image->SetOrigin(mask->GetGeometry()->GetOrigin()[0], mask->GetGeometry()->GetOrigin()[1], mask->GetGeometry()->GetOrigin()[2]); vtkSmartPointer mesher = vtkSmartPointer::New(); mesher->SetInputData(image); mitk::Surface::Pointer surf = mitk::Surface::New(); mesher->SetValue(0,0.5); mesher->Update(); surf->SetVtkPolyData(mesher->GetOutput()); mitk::IOUtil::Save(surf, parsedArgs["output"].ToString()); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLOverlayRoiCenterOfMass.cpp b/Modules/Classification/CLMiniApps/CLOverlayRoiCenterOfMass.cpp index d4f23bca8c..961d3b51ac 100644 --- a/Modules/Classification/CLMiniApps/CLOverlayRoiCenterOfMass.cpp +++ b/Modules/Classification/CLMiniApps/CLOverlayRoiCenterOfMass.cpp @@ -1,178 +1,178 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include "vtkRenderLargeImage.h" #include "vtkPNGWriter.h" #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; template static void FindMostSampleSlice(itk::Image* mask, int & selectedSlice) { int idx = VImageDimension - 1; int size = mask->GetLargestPossibleRegion().GetSize()[idx]; std::vector numberOfSamples; numberOfSamples.resize(size,0); itk::ImageRegionIteratorWithIndex > mask1Iter(mask, mask->GetLargestPossibleRegion()); while (!mask1Iter.IsAtEnd()) { if (mask1Iter.Value() > 0) { numberOfSamples[mask1Iter.GetIndex()[idx]]+=1; } ++mask1Iter; } selectedSlice = 0; for (std::size_t i = 0; i < numberOfSamples.size(); ++i) { if (numberOfSamples[selectedSlice] < numberOfSamples[i]) selectedSlice = i; } } static void SaveSliceOrImageAsPNG(mitk::Image::Pointer image, mitk::Image::Pointer mask, std::string path, int index) { // Create a Standalone Datastorage for the single purpose of saving screenshots.. mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); QmitkRenderWindow renderWindow; renderWindow.GetRenderer()->SetDataStorage(ds); auto nodeI = mitk::DataNode::New(); nodeI->SetData(image); auto nodeM = mitk::DataNode::New(); nodeM->SetData(mask); ds->Add(nodeI); ds->Add(nodeM); mitk::TimeGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews( mask->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::SliceNavigationController::Pointer sliceNaviController = renderWindow.GetSliceNavigationController(); sliceNaviController->SetViewDirection(mitk::SliceNavigationController::Axial); unsigned int numberOfSteps = 1; if (sliceNaviController) { numberOfSteps = sliceNaviController->GetSlice()->GetSteps(); sliceNaviController->GetSlice()->SetPos(numberOfSteps-index); } renderWindow.show(); renderWindow.resize(256, 256); //if (sliceNaviController) //{ // sliceNaviController->GetSlice()->SetPos(index); //} renderWindow.GetRenderer()->PrepareRender(); vtkRenderWindow* renderWindow2 = renderWindow.GetVtkRenderWindow(); mitk::BaseRenderer* baserenderer = mitk::BaseRenderer::GetInstance(renderWindow2); auto vtkRender = baserenderer->GetVtkRenderer(); vtkRender->GetRenderWindow()->WaitForCompletion(); vtkRenderLargeImage* magnifier = vtkRenderLargeImage::New(); magnifier->SetInput(vtkRender); magnifier->SetMagnification(3.0); std::stringstream ss; ss << path <<".png"; std::string tmpImageName; ss >> tmpImageName; auto fileWriter = vtkPNGWriter::New(); fileWriter->SetInputConnection(magnifier->GetOutputPort()); fileWriter->SetFileName(tmpImageName.c_str()); fileWriter->Write(); fileWriter->Delete(); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "", us::Any(),false); parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "Input Image", "", us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::InputImage, "Output Image", "", us::Any(),false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Image with Overlay Plotter"); parser.setDescription("Plots "); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); std::string imagePath = us::any_cast(parsedArgs["image"]); std::string maskPath = us::any_cast(parsedArgs["mask"]); std::string outputPath = us::any_cast(parsedArgs["output"]); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } std::string version = "Version: 1.0"; MITK_INFO << version; - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(imagePath); - mitk::Image::Pointer mask = mitk::IOUtil::LoadImage(maskPath); + mitk::Image::Pointer image = mitk::IOUtil::Load(imagePath); + mitk::Image::Pointer mask = mitk::IOUtil::Load(maskPath); // Create a QTApplication and a Datastorage // This is necessary in order to save screenshots of // each image / slice. QApplication qtapplication(argc, argv); QmitkRegisterClasses(); int currentSlice = 0; AccessByItk_1(mask, FindMostSampleSlice, currentSlice); SaveSliceOrImageAsPNG(image, mask, outputPath, currentSlice); return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLPlanarFigureToNrrd.cpp b/Modules/Classification/CLMiniApps/CLPlanarFigureToNrrd.cpp index df2a5c77f3..e87d3065f2 100644 --- a/Modules/Classification/CLMiniApps/CLPlanarFigureToNrrd.cpp +++ b/Modules/Classification/CLMiniApps/CLPlanarFigureToNrrd.cpp @@ -1,145 +1,145 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; struct MaskParameter { mitk::Image::Pointer mask; unsigned int axis; unsigned int slice; }; template < typename TPixel, unsigned int VImageDimension > void CreateNewMask(const itk::Image< TPixel, VImageDimension > *image, MaskParameter param, mitk::Image::Pointer &output) { int transform[3][2]; transform[0][0] = 1; transform[0][1] = 2; transform[1][0] = 0; transform[1][1] = 2; transform[2][0] = 0; transform[2][1] = 1; typedef itk::Image MaskType; typedef itk::Image Mask2DType; typename Mask2DType::Pointer mask = Mask2DType::New(); mitk::CastToItkImage(param.mask, mask); typename MaskType::Pointer mask3D = MaskType::New(); mask3D->SetRegions(image->GetLargestPossibleRegion()); mask3D->SetSpacing(image->GetSpacing()); mask3D->SetOrigin(image->GetOrigin()); mask3D->Allocate(); itk::ImageRegionIteratorWithIndex iter(mask3D, mask3D->GetLargestPossibleRegion()); while (!iter.IsAtEnd()) { auto index = iter.GetIndex(); iter.Set(0); if (index[param.axis] == param.slice) { Mask2DType::IndexType index2D; index2D[0] = index[transform[param.axis][0]]; index2D[1] = index[transform[param.axis][1]]; auto pixel = mask->GetPixel(index2D); iter.Set(pixel); } ++iter; } mitk::CastToMitkImage(mask3D, output); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("planar", "p", mitkCommandLineParser::InputDirectory, "Input Polydata", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("image", "i", mitkCommandLineParser::OutputDirectory, "Input Image", "Image which defines the dimensions of the Segmentation", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output file", "Output file. ", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Planar Data to Nrrd Segmentation"); parser.setDescription("Creates a Nrrd segmentation based on a 2d-vtk polydata."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } try { mitk::BaseData::Pointer data = mitk::IOUtil::Load(parsedArgs["planar"].ToString())[0]; mitk::PlanarFigure::Pointer planar = dynamic_cast(data.GetPointer()); - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(parsedArgs["image"].ToString())[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["image"].ToString()); mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetPlanarFigure(planar); pfMaskGen->SetTimeStep(0); pfMaskGen->SetInputImage(image); mitk::Image::Pointer mask = pfMaskGen->GetMask(); mitk::Image::Pointer refImage = pfMaskGen->GetReferenceImage(); unsigned int axis = pfMaskGen->GetPlanarFigureAxis(); unsigned int slice = pfMaskGen->GetPlanarFigureSlice(); //itk::Image::IndexType index; mitk::Image::Pointer fullMask; MaskParameter param; param.slice = slice; param.axis = axis; param.mask = mask; AccessByItk_2(image, CreateNewMask, param, fullMask); std::string saveAs = parsedArgs["output"].ToString(); MITK_INFO << "Save as: " << saveAs; mitk::IOUtil::Save(pfMaskGen->GetMask(), saveAs); mitk::IOUtil::Save(fullMask, saveAs); return 0; } catch (...) { return EXIT_FAILURE; } } #endif diff --git a/Modules/Classification/CLMiniApps/CLPointSetToSegmentation.cpp b/Modules/Classification/CLMiniApps/CLPointSetToSegmentation.cpp index 7e1acff682..7fef2f0b83 100644 --- a/Modules/Classification/CLMiniApps/CLPointSetToSegmentation.cpp +++ b/Modules/Classification/CLMiniApps/CLPointSetToSegmentation.cpp @@ -1,120 +1,120 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include #include #include #include "mitkCommandLineParser.h" typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned short, 3 > MaskImageType; int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("pointset", "p", mitkCommandLineParser::InputDirectory, "Input Polydata", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("image", "i", mitkCommandLineParser::OutputDirectory, "Input Image", "Image which defines the dimensions of the Segmentation", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output file", "Output files. Two files are create, a .nrrd image and a 3d-vtk.", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("2D-Polydata to Nrrd Segmentation"); parser.setDescription("Creates a Nrrd segmentation based on a 2d-vtk polydata."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } mitk::BaseData::Pointer data = mitk::IOUtil::Load(parsedArgs["pointset"].ToString())[0]; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(parsedArgs["image"].ToString())[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["image"].ToString()); //MITK_INFO << data; mitk::PointSet::Pointer points = dynamic_cast(data.GetPointer()); MaskImageType::Pointer mask = MaskImageType::New(); mitk::CastToItkImage(image, mask); double minX, minY, minZ; double maxX, maxY, maxZ; minX = minY = minZ = std::numeric_limits::max(); maxX = maxY = maxZ = std::numeric_limits::lowest(); for (auto iter = points->Begin(); iter != points->End(); ++iter) { minX = std::min(minX, iter.Value().GetElement(0)); minY = std::min(minY, iter.Value().GetElement(1)); minZ = std::min(minZ, iter.Value().GetElement(2)); maxX = std::max(maxX, iter.Value().GetElement(0)); maxY = std::max(maxY, iter.Value().GetElement(1)); maxZ = std::max(maxZ, iter.Value().GetElement(2)); } MaskImageType::PointType point; MaskImageType::IndexType iMin; MaskImageType::IndexType iMax; point[0] = minX; point[1] = minY; point[2] = minZ; mask->TransformPhysicalPointToIndex(point, iMin); point[0] = maxX; point[1] = maxY; point[2] = maxZ; mask->TransformPhysicalPointToIndex(point, iMax); itk::ImageRegionIteratorWithIndex iter(mask, mask->GetLargestPossibleRegion()); while (!iter.IsAtEnd()) { MaskImageType::IndexType index = iter.GetIndex(); if ((index[0] >= iMin[0]) && (index[1] >= iMin[1]) && (index[2] >= iMin[2]) && (index[0] <= iMax[0]) && (index[1] <= iMax[1]) && (index[2] <= iMax[2])) { iter.Set(1); } else { iter.Set(0); } ++iter; } mitk::Image::Pointer ergImage = mitk::Image::New(); mitk::CastToMitkImage(mask, ergImage); std::string saveAs = parsedArgs["output"].ToString(); MITK_INFO << "Save as: " << saveAs; mitk::IOUtil::Save(ergImage, saveAs); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLPolyToNrrd.cpp b/Modules/Classification/CLMiniApps/CLPolyToNrrd.cpp index 028d211666..6d1f1a08bf 100644 --- a/Modules/Classification/CLMiniApps/CLPolyToNrrd.cpp +++ b/Modules/Classification/CLMiniApps/CLPolyToNrrd.cpp @@ -1,108 +1,108 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("polydata", "p", mitkCommandLineParser::InputDirectory, "Input Polydata", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("image", "i", mitkCommandLineParser::OutputDirectory, "Input Image", "Image which defines the dimensions of the Segmentation", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output file", "Output files. Two files are create, a .nrrd image and a 3d-vtk.", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("2D-Polydata to Nrrd Segmentation"); parser.setDescription("Creates a Nrrd segmentation based on a 2d-vtk polydata."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } mitk::BaseData::Pointer data = mitk::IOUtil::Load(parsedArgs["polydata"].ToString())[0]; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(parsedArgs["image"].ToString())[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["image"].ToString()); //MITK_INFO << data; mitk::Surface::Pointer surf = dynamic_cast(data.GetPointer()); vtkSmartPointer circle = surf->GetVtkPolyData(); vtkSmartPointer extruder = vtkSmartPointer::New(); extruder->SetInputData(circle); image->GetGeometry()->GetSpacing()[2]; extruder->SetScaleFactor(1.); extruder->SetExtrusionTypeToNormalExtrusion(); extruder->SetVector(0, 0, image->GetGeometry()->GetSpacing()[2]); extruder->Update(); surf->SetVtkPolyData(extruder->GetOutput()); mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New(); surfaceToImageFilter->MakeOutputBinaryOn(); surfaceToImageFilter->SetInput(surf); surfaceToImageFilter->SetImage(image); surfaceToImageFilter->Update(); mitk::Image::Pointer resultImage = surfaceToImageFilter->GetOutput(); mitk::Convert2Dto3DImageFilter::Pointer multiFilter = mitk::Convert2Dto3DImageFilter::New(); multiFilter->SetInput(resultImage); multiFilter->Update(); resultImage = multiFilter->GetOutput(); std::string saveAs = parsedArgs["output"].ToString(); MITK_INFO << "Save as: " << saveAs; saveAs = saveAs + ".vtk"; mitk::IOUtil::Save(surf.GetPointer(),saveAs); saveAs = parsedArgs["output"].ToString(); MITK_INFO << "Save as: " << saveAs; saveAs = saveAs + ".nrrd"; mitk::IOUtil::Save(resultImage,saveAs); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLRandomSampling.cpp b/Modules/Classification/CLMiniApps/CLRandomSampling.cpp index fd8632de2a..055d031e6d 100644 --- a/Modules/Classification/CLMiniApps/CLRandomSampling.cpp +++ b/Modules/Classification/CLMiniApps/CLRandomSampling.cpp @@ -1,158 +1,158 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include static std::vector splitDouble(std::string str, char delimiter) { std::vector internal; std::stringstream ss(str); // Turn the string into a stream. std::string tok; double val; while (getline(ss, tok, delimiter)) { std::stringstream s2(tok); s2 >> val; internal.push_back(val); } return internal; } static std::vector splitUInt(std::string str, char delimiter) { std::vector internal; std::stringstream ss(str); // Turn the string into a stream. std::string tok; unsigned int val; while (getline(ss, tok, delimiter)) { std::stringstream s2(tok); s2 >> val; internal.push_back(val); } return internal; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Random Sampling"); parser.setCategory("Classification Command Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input file:", "Input file", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file", us::Any(), false); parser.addArgument("single-rate", "sr", mitkCommandLineParser::OutputFile, "Single Acceptance rate for all voxel", "Output file", us::Any(), true); parser.addArgument("class-rate", "cr", mitkCommandLineParser::OutputFile, "Class-dependend acceptance rate", "Output file", us::Any(), true); parser.addArgument("single-number", "sn", mitkCommandLineParser::OutputFile, "Single Number of Voxel for each class", "Output file", us::Any(), true); parser.addArgument("class-number", "cn", mitkCommandLineParser::OutputFile, "Class-dependedn number of voxels ", "Output file", us::Any(), true); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) return EXIT_FAILURE; // Show a help message if (parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } if (parsedArgs.count("single-rate") + parsedArgs.count("class-rate") + parsedArgs.count("single-number") + parsedArgs.count("class-number") < 1) { std::cout << "Please specify the sampling rate or number of voxels to be labeled" << std::endl << std::endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } if (parsedArgs.count("single-rate") + parsedArgs.count("class-rate") + parsedArgs.count("single-number") + parsedArgs.count("class-number") > 2) { std::cout << "Please specify only one way for the sampling rate or number of voxels to be labeled" << std::endl << std::endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputName = us::any_cast(parsedArgs["input"]); std::string outputName = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(inputName); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputName); mitk::RandomImageSampler::Pointer filter = mitk::RandomImageSampler::New(); filter->SetInput(image); if (parsedArgs.count("single-rate")) { filter->SetSamplingMode(mitk::RandomImageSamplerMode::SINGLE_ACCEPTANCE_RATE); auto rate = splitDouble(parsedArgs["single-rate"].ToString(), ';'); if (rate.size() != 1) { std::cout << "Please specify a single double value for single-rate, for example 0.3." << std::endl << std::endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } filter->SetAcceptanceRate(rate[0]); } else if (parsedArgs.count("class-rate")) { filter->SetSamplingMode(mitk::RandomImageSamplerMode::CLASS_DEPENDEND_ACCEPTANCE_RATE); auto rate = splitDouble(parsedArgs["class-rate"].ToString(), ';'); if (rate.size() < 2) { std::cout << "Please specify at least two, semicolon separated values for class-rate, for example '0.3;0.2' ." << std::endl << std::endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } filter->SetAcceptanceRateVector(rate); } else if (parsedArgs.count("single-number")) { filter->SetSamplingMode(mitk::RandomImageSamplerMode::SINGLE_NUMBER_OF_ACCEPTANCE); auto rate = splitUInt(parsedArgs["single-number"].ToString(), ';'); if (rate.size() != 1) { std::cout << "Please specify a single double value for single-number, for example 100." << std::endl << std::endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } filter->SetNumberOfSamples(rate[0]); } else if (parsedArgs.count("class-number")) { filter->SetSamplingMode(mitk::RandomImageSamplerMode::CLASS_DEPENDEND_NUMBER_OF_ACCEPTANCE); auto rate = splitUInt(parsedArgs["class-number"].ToString(), ';'); if (rate.size() < 2) { std::cout << "Please specify at least two, semicolon separated values for class-number, for example '100;200' ." << std::endl << std::endl; std::cout << parser.helpText(); return EXIT_SUCCESS; } filter->SetNumberOfSamplesVector(rate); } filter->Update(); mitk::IOUtil::Save(filter->GetOutput(), outputName); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLRemoveEmptyVoxels.cpp b/Modules/Classification/CLMiniApps/CLRemoveEmptyVoxels.cpp index 45d34b1ecf..d26096c42f 100644 --- a/Modules/Classification/CLMiniApps/CLRemoveEmptyVoxels.cpp +++ b/Modules/Classification/CLMiniApps/CLRemoveEmptyVoxels.cpp @@ -1,159 +1,159 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "mitkImageCast.h" #include #include #include "mitkImageGenerator.h" int main(int argc, char* argv[]) { typedef itk::Image ImageType; typedef itk::Image MaskImageType; typedef ImageType::Pointer ImagePointerType; typedef MaskImageType::Pointer MaskImagePointerType; typedef itk::ImageRegionConstIterator ConstIteratorType; typedef itk::ImageRegionConstIterator ConstMaskIteratorType; typedef itk::ImageRegionIterator IteratorType; typedef itk::ImageRegionIterator MaskIteratorType; mitkCommandLineParser parser; parser.setTitle("Remove empty voxels Sampling"); parser.setCategory("Classification Command Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("mask-input", "mi", mitkCommandLineParser::InputDirectory, "Input file:", "Input file", us::Any(), false); parser.addArgument("mask-output", "mo", mitkCommandLineParser::OutputFile, "Output file:", "Output file", us::Any(), false); for (int i = 0; i < 100; ++i) { std::stringstream s1; s1 << i; std::string number = s1.str(); parser.addArgument("input"+number, "i"+number, mitkCommandLineParser::OutputFile, "Input file", "input file", us::Any(), true); parser.addArgument("output" + number, "o" + number, mitkCommandLineParser::OutputFile, "Output File", "Output file", us::Any(), true); } std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) return EXIT_FAILURE; // Show a help message if (parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } // Load Mask Image and count number of non-zero voxels - mitk::Image::Pointer mask = mitk::IOUtil::LoadImage(parsedArgs["mask-input"].ToString()); + mitk::Image::Pointer mask = mitk::IOUtil::Load(parsedArgs["mask-input"].ToString()); MaskImagePointerType itkMask = MaskImageType::New(); mitk::CastToItkImage(mask, itkMask); ConstMaskIteratorType maskIter(itkMask, itkMask->GetLargestPossibleRegion()); std::size_t nonZero = 0; while (!maskIter.IsAtEnd()) { if (maskIter.Value() > 0) { ++nonZero; } ++maskIter; } maskIter.GoToBegin(); // Create new mask image auto mitkNewMask = mitk::ImageGenerator::GenerateGradientImage(nonZero, 1, 1, 1, 1, 1); MaskImagePointerType itkNewMask = MaskImageType::New(); mitk::CastToItkImage(mitkNewMask, itkNewMask); MaskIteratorType newMaskIter(itkNewMask, itkNewMask->GetLargestPossibleRegion()); // Read additional image std::vector mitkImagesVector; std::vector itkImageVector; std::vector itkOutputImageVector; std::vector inputIteratorVector; std::vector outputIteratorVector; for (int i = 0; i < 100; ++i) { std::stringstream s1; s1 << i; std::string number = s1.str(); if (parsedArgs.count("input" + number) < 1) break; if (parsedArgs.count("output" + number) < 1) break; - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(parsedArgs["input"+number].ToString()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["input"+number].ToString()); mitkImagesVector.push_back(image); ImagePointerType itkImage = ImageType::New(); mitk::CastToItkImage(image, itkImage); itkImageVector.push_back(itkImage); ConstIteratorType iter(itkImage, itkImage->GetLargestPossibleRegion()); inputIteratorVector.push_back(iter); auto mitkNewImage = mitk::ImageGenerator::GenerateGradientImage(nonZero, 1, 1, 1, 1, 1); ImagePointerType itkNewOutput = ImageType::New(); mitk::CastToItkImage(mitkNewImage, itkNewOutput); IteratorType outputIter(itkNewOutput, itkNewOutput->GetLargestPossibleRegion()); itkOutputImageVector.push_back(itkNewOutput); outputIteratorVector.push_back(outputIter); } // Convert non-zero voxels to the new images while (!maskIter.IsAtEnd()) { if (maskIter.Value() > 0) { newMaskIter.Set(maskIter.Value()); ++newMaskIter; for (std::size_t i = 0; i < outputIteratorVector.size(); ++i) { outputIteratorVector[i].Set(inputIteratorVector[i].Value()); ++(outputIteratorVector[i]); } } ++maskIter; for (std::size_t i = 0; i < inputIteratorVector.size(); ++i) { ++(inputIteratorVector[i]); } } // Save the new images for (std::size_t i = 0; i < outputIteratorVector.size(); ++i) { std::stringstream s1; s1 << i; std::string number = s1.str(); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitk::CastToMitkImage(itkOutputImageVector[i], mitkImage); mitk::IOUtil::Save(mitkImage, parsedArgs["output" + number].ToString()); } // Save the new mask { mitk::Image::Pointer mitkImage = mitk::Image::New(); mitk::CastToMitkImage(itkNewMask, mitkImage); mitk::IOUtil::Save(mitkImage, parsedArgs["mask-output"].ToString()); } return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLMiniApps/CLResampleImageToReference.cpp b/Modules/Classification/CLMiniApps/CLResampleImageToReference.cpp index e58acfba58..8449df4179 100644 --- a/Modules/Classification/CLMiniApps/CLResampleImageToReference.cpp +++ b/Modules/Classification/CLMiniApps/CLResampleImageToReference.cpp @@ -1,116 +1,116 @@ /*=================================================================== 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 mitkCLResampleImageToReference_cpp #define mitkCLResampleImageToReference_cpp #include "mitkCommandLineParser.h" #include #include #include #include #include #include // ITK #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" template void ResampleImageToReferenceFunction(itk::Image* itkReference, mitk::Image::Pointer moving, std::string ergPath) { typedef itk::Image InputImageType; // Identify Transform typedef itk::IdentityTransform T_Transform; typename T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, VImageDimension> WindowedSincInterpolatorType; typename WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); typedef itk::LinearInterpolateImageFunction< InputImageType> LinearInterpolateImageFunctionType; typename LinearInterpolateImageFunctionType::Pointer lin_interpolator = LinearInterpolateImageFunctionType::New(); typedef itk::NearestNeighborInterpolateImageFunction< InputImageType> NearestNeighborInterpolateImageFunctionType; typename NearestNeighborInterpolateImageFunctionType::Pointer nn_interpolator = NearestNeighborInterpolateImageFunctionType::New(); typename InputImageType::Pointer itkMoving = InputImageType::New(); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; typename ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); //if ( sincInterpol) // resampler->SetInterpolator(sinc_interpolator); //else resampler->SetInterpolator(lin_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory(resampler->GetOutput(), result); MITK_INFO << "writing result to: " << ergPath; mitk::IOUtil::Save(result, ergPath); //return result; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("fix", "f", mitkCommandLineParser::InputImage, "Input Image", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("moving", "m", mitkCommandLineParser::OutputFile, "Output text file", "Target file. The output statistic is appended to this file.", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Extension", "File extension. Default is .nii.gz", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Resample Image To Reference"); parser.setDescription("Resamples an image (moving) to an given image (fix) without additional registration."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } - mitk::Image::Pointer fix = mitk::IOUtil::LoadImage(parsedArgs["fix"].ToString()); - mitk::Image::Pointer moving = mitk::IOUtil::LoadImage(parsedArgs["moving"].ToString()); + mitk::Image::Pointer fix = mitk::IOUtil::Load(parsedArgs["fix"].ToString()); + mitk::Image::Pointer moving = mitk::IOUtil::Load(parsedArgs["moving"].ToString()); mitk::Image::Pointer erg = mitk::Image::New(); AccessByItk_2(fix, ResampleImageToReferenceFunction, moving, parsedArgs["output"].ToString()); } #endif diff --git a/Modules/Classification/CLMiniApps/CLScreenshot.cpp b/Modules/Classification/CLMiniApps/CLScreenshot.cpp index e16aa2156e..a44319310e 100644 --- a/Modules/Classification/CLMiniApps/CLScreenshot.cpp +++ b/Modules/Classification/CLMiniApps/CLScreenshot.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. ===================================================================*/ #ifndef mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include "vtkRenderLargeImage.h" #include "vtkPNGWriter.h" static void SaveSliceOrImageAsPNG(std::vector listOfOutputs, std::string path) { std::vector colorList; colorList.push_back(mitk::ColorProperty::New(0.9569, 0.16471, 0.25490)); // Red colorList.push_back(mitk::ColorProperty::New(1, 0.839, 0)); // Yellow colorList.push_back(mitk::ColorProperty::New(0, 0.6, 0.2)); // Green colorList.push_back(mitk::ColorProperty::New(0, 0.2784, 0.7255)); // BLue colorList.push_back(mitk::ColorProperty::New(1,0.3608,0)); // Orange colorList.push_back(mitk::ColorProperty::New(0.839215,0.141176,0.80784)); // Violett colorList.push_back(mitk::ColorProperty::New(0.1372,0.81568,0.7647)); // Turkis colorList.push_back(mitk::ColorProperty::New(0.61176,0.9568,0.16078)); // Bright Green colorList.push_back(mitk::ColorProperty::New(1,0.4274,0.16862)); // Dark Orange colorList.push_back(mitk::ColorProperty::New(0.88633,0.14901,0.64705)); // Pink // Create a Standalone Datastorage for the single purpose of saving screenshots.. mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); QmitkRenderWindow renderWindow; renderWindow.GetRenderer()->SetDataStorage(ds); int numberOfSegmentations = 0; bool isSegmentation = false; for (auto name : listOfOutputs) { - mitk::Image::Pointer tmpImage = mitk::IOUtil::LoadImage(name); + mitk::Image::Pointer tmpImage = mitk::IOUtil::Load(name); auto nodeI = mitk::DataNode::New(); nodeI->SetData(tmpImage); nodeI->GetPropertyValue("binary",isSegmentation); if (isSegmentation) { nodeI->SetProperty("color", colorList[numberOfSegmentations % colorList.size()]); nodeI->SetProperty("binaryimage.hoveringannotationcolor", colorList[numberOfSegmentations % colorList.size()]); nodeI->SetProperty("binaryimage.hoveringcolor", colorList[numberOfSegmentations % colorList.size()]); nodeI->SetProperty("binaryimage.selectedannotationcolor", colorList[numberOfSegmentations % colorList.size()]); nodeI->SetProperty("binaryimage.selectedcolor", colorList[numberOfSegmentations % colorList.size()]); numberOfSegmentations++; } ds->Add(nodeI); } mitk::TimeGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); mitk::SliceNavigationController::Pointer sliceNaviController = renderWindow.GetSliceNavigationController(); unsigned int numberOfSteps = 1; if (sliceNaviController) { numberOfSteps = sliceNaviController->GetSlice()->GetSteps(); sliceNaviController->GetSlice()->SetPos(0); } renderWindow.show(); renderWindow.resize(512, 512); for (unsigned int currentStep = 0; currentStep < numberOfSteps; ++currentStep) { if (sliceNaviController) { sliceNaviController->GetSlice()->SetPos(currentStep); } renderWindow.GetRenderer()->PrepareRender(); vtkRenderWindow* renderWindow2 = renderWindow.GetVtkRenderWindow(); mitk::BaseRenderer* baserenderer = mitk::BaseRenderer::GetInstance(renderWindow2); auto vtkRender = baserenderer->GetVtkRenderer(); vtkRender->GetRenderWindow()->WaitForCompletion(); vtkRenderLargeImage* magnifier = vtkRenderLargeImage::New(); magnifier->SetInput(vtkRender); magnifier->SetMagnification(3.0); std::stringstream ss; ss << path << "screenshot_step-"<> tmpImageName; auto fileWriter = vtkPNGWriter::New(); fileWriter->SetInputConnection(magnifier->GetOutputPort()); fileWriter->SetFileName(tmpImageName.c_str()); fileWriter->Write(); fileWriter->Delete(); } } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // Required Parameter parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to the input image files (Separated with semicolons)", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output text file", "Path to output file. The output statistic is appended to this file.", us::Any(), false); parser.addArgument("direction", "dir", mitkCommandLineParser::String, "Int", "Allows to specify the direction for Cooc and RL. 0: All directions, 1: Only single direction (Test purpose), 2,3,4... Without dimension 0,1,2... ", us::Any()); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Screenshot of a single image"); parser.setDescription(""); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } std::string version = "Version: 1.0"; MITK_INFO << version; //int direction = 0; if (parsedArgs.count("direction")) { MITK_INFO << "Warning: Option direction currently not supported"; // direction = mitk::cl::splitDouble(parsedArgs["direction"].ToString(), ';')[0]; } auto listOfFiles = mitk::cl::splitString(parsedArgs["image"].ToString(), ';'); // Create a QTApplication and a Datastorage // This is necessary in order to save screenshots of // each image / slice. QApplication qtapplication(argc, argv); QmitkRegisterClasses(); SaveSliceOrImageAsPNG(listOfFiles, parsedArgs["output"].ToString()); return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLSkullMask.cpp b/Modules/Classification/CLMiniApps/CLSkullMask.cpp index 04e3d4dce2..587157a680 100644 --- a/Modules/Classification/CLMiniApps/CLSkullMask.cpp +++ b/Modules/Classification/CLMiniApps/CLSkullMask.cpp @@ -1,198 +1,198 @@ /*=================================================================== 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 mitkCLPolyToNrrd_cpp #define mitkCLPolyToNrrd_cpp #include "time.h" #include #include #include #include "mitkCommandLineParser.h" #include "itkImageRegionIterator.h" // MITK #include #include #include // ITK #include #include typedef itk::Image< double, 3 > FloatImageType; typedef itk::Image< unsigned char, 3 > MaskImageType; template static void DetectSkull(itk::Image* itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output) { typedef itk::Image ImageType; typedef itk::Image MaskType; typename ImageType::Pointer itkIm2 = ImageType::New(); typename MaskType::Pointer itkMask1 = MaskType::New(); mitk::CastToItkImage(im2, itkIm2); mitk::CastToItkImage(mask1, itkMask1); itk::ImageRegionIterator iterI1(itkImage, itkImage->GetLargestPossibleRegion()); itk::ImageRegionIterator iterI2(itkIm2, itkImage->GetLargestPossibleRegion()); itk::ImageRegionIterator iter(itkMask1, itkImage->GetLargestPossibleRegion()); while (! iter.IsAtEnd()) { unsigned char maskV = 0; if (iterI1.Value() > 0.0001 && iterI2.Value() > 0.00001) maskV = 1; iter.Set(maskV); ++iter; ++iterI1; ++iterI2; } mitk::Image::Pointer img = mitk::ImportItkImage(itkMask1); mitk::IOUtil::Save(img, output); } int main(int argc, char* argv[]) { typedef itk::Image ImageType; typedef itk::Image MaskType; mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("image", "i", mitkCommandLineParser::StringList, "Input Image", "Path to the input images. Mask covers area of all images", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "Input Mask", "The median of the area covered by this mask will be set to 1", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("MR Normalization Tool"); parser.setDescription("Normalizes a MR image. Sets the Median of the tissue covered by mask 0 to 0 and the median of the area covered by mask 1 to 1."); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } us::Any listAny = parsedArgs["image"]; auto inputImageList = us::any_cast(listAny); std::vector imageList; for (std::size_t i = 0; i < inputImageList.size(); ++i) { - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(inputImageList[i])[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputImageList[i]); ImageType::Pointer itkImage = ImageType::New(); mitk::CastToItkImage(image, itkImage); imageList.push_back(itkImage); } - mitk::Image::Pointer mitkMask = dynamic_cast(mitk::IOUtil::Load(inputImageList[0])[0].GetPointer()); + mitk::Image::Pointer mitkMask = mitk::IOUtil::Load(inputImageList[0]); MaskType::Pointer mask = MaskType::New(); mitk::CastToItkImage(mitkMask, mask); itk::ImageRegionIterator maskIter(mask, mask->GetLargestPossibleRegion()); while (!maskIter.IsAtEnd()) { maskIter.Set(0); ++maskIter; } std::vector listOfIndexes; listOfIndexes.reserve(1000); // Find Start Location for the case that one corner is "blocked" by content. Works only on the first image! ImageType::IndexType tmpIndex; ImageType::IndexType startIndex; startIndex.Fill(0); for (unsigned char i = 0; i < 8; ++i) { tmpIndex.Fill(0); if ((i & 1) > 0) tmpIndex[0] = mask->GetLargestPossibleRegion().GetSize(0)-1; if ((i & 2) > 0) tmpIndex[1] = mask->GetLargestPossibleRegion().GetSize(1)-1; if ((i & 4) > 0) tmpIndex[2] = mask->GetLargestPossibleRegion().GetSize(2)-1; MITK_INFO << tmpIndex; if (imageList[0]->GetPixel(tmpIndex) < imageList[0]->GetPixel(startIndex)) { startIndex = tmpIndex; } } listOfIndexes.push_back(tmpIndex); while (listOfIndexes.size() > 0) { ImageType::IndexType currentIndex = listOfIndexes.back(); listOfIndexes.pop_back(); if (!(mask->GetLargestPossibleRegion().IsInside(currentIndex))) { continue; } if (mask->GetPixel(currentIndex) == 0) { mask->SetPixel(currentIndex, 1); double minimum = std::numeric_limits::max(); for (std::size_t i = 0; i < imageList.size(); ++i) { minimum = std::min(minimum, imageList[i]->GetPixel(currentIndex)); } if (minimum < 35) { mask->SetPixel(currentIndex, 2); tmpIndex = currentIndex; tmpIndex[0] += 1; listOfIndexes.push_back(tmpIndex); tmpIndex[0] -= 2; listOfIndexes.push_back(tmpIndex); tmpIndex[0] += 1; tmpIndex[1] += 1; listOfIndexes.push_back(tmpIndex); tmpIndex[1] -= 2; listOfIndexes.push_back(tmpIndex); tmpIndex[1] += 1; tmpIndex[2] += 1; listOfIndexes.push_back(tmpIndex); tmpIndex[2] -= 2; listOfIndexes.push_back(tmpIndex); } } } MITK_INFO << "Im here"; maskIter.GoToBegin(); while (!maskIter.IsAtEnd()) { if (maskIter.Get() == 2) maskIter.Set(0); else maskIter.Set(1); ++maskIter; } mitk::Image::Pointer ergMask = mitk::ImportItkImage(mask); std::string maskPath = parsedArgs["mask"].ToString(); mitk::IOUtil::Save(ergMask, maskPath); //AccessByItk_3(image, Normalize, im2, mask, parsedArgs["output"].ToString()); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLStaple.cpp b/Modules/Classification/CLMiniApps/CLStaple.cpp index bc559f5593..49e17ac471 100644 --- a/Modules/Classification/CLMiniApps/CLStaple.cpp +++ b/Modules/Classification/CLMiniApps/CLStaple.cpp @@ -1,46 +1,46 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include #include int main(int argc, char* argv[]) { typedef itk::Image MaskImageType; typedef itk::Image ImageType; typedef itk::STAPLEImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetForegroundValue(2); for (int i = 2; i < argc; ++i) { MITK_INFO << argv[i]; MaskImageType::Pointer itkImg = MaskImageType::New(); - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(argv[i])[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(argv[i]); mitk::CastToItkImage(img,itkImg); filter->SetInput(i-2, itkImg); } filter->Update(); auto out = filter->GetOutput(); mitk::Image::Pointer outImg = mitk::Image::New(); mitk::CastToMitkImage(out, outImg); mitk::IOUtil::Save(outImg, argv[1]); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/CLSurWeighting.cpp b/Modules/Classification/CLMiniApps/CLSurWeighting.cpp index 325a0bf3df..6e8ad725ab 100644 --- a/Modules/Classification/CLMiniApps/CLSurWeighting.cpp +++ b/Modules/Classification/CLMiniApps/CLSurWeighting.cpp @@ -1,73 +1,73 @@ /*=================================================================== 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 mitkForest_cpp #define mitkForest_cpp #include "time.h" #include #include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { MITK_INFO << "Argc " << argc; ////////////////////////////////////////////////////////////////////////////// // Read Images ////////////////////////////////////////////////////////////////////////////// mitk::DataCollection::Pointer col = mitk::DataCollection::New(); MITK_INFO << "Arg 2 " << argv[2]; - mitk::Image::Pointer sur=dynamic_cast(mitk::IOUtil::Load(argv[2])[0].GetPointer()); + mitk::Image::Pointer sur=mitk::IOUtil::Load(argv[2]); col->AddData(sur.GetPointer(),"sur"); MITK_INFO << "Arg 3 " << argv[3]; - mitk::Image::Pointer mask=dynamic_cast(mitk::IOUtil::Load(argv[3])[0].GetPointer()); + mitk::Image::Pointer mask=mitk::IOUtil::Load(argv[3]); col->AddData(mask.GetPointer(),"mask"); std::vector modalities; for (int i = 4; i < argc; ++i) { MITK_INFO << "Img " << argv[i]; std::stringstream ss; ss << i; modalities.push_back(ss.str()); - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(argv[i])[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(argv[i]); col->AddData(img.GetPointer(),ss.str()); } mitk::LRDensityEstimation est; est.SetCollection(col); est.SetTrainMask("sur"); est.SetTestMask("mask"); est.SetModalities(modalities); est.SetWeightName("weight"); est.Update(); mitk::Image::Pointer w= col->GetMitkImage("weight"); mitk::IOUtil::Save(w,argv[1]); return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLVoxelClassification.cpp b/Modules/Classification/CLMiniApps/CLVoxelClassification.cpp index 1a29727ccb..94eed48ec4 100644 --- a/Modules/Classification/CLMiniApps/CLVoxelClassification.cpp +++ b/Modules/Classification/CLMiniApps/CLVoxelClassification.cpp @@ -1,480 +1,480 @@ /*=================================================================== 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 mitkForest_cpp #define mitkForest_cpp #include "time.h" #include #include #include #include #include #include #include #include #include #include #include // ----------------------- Forest Handling ---------------------- //#include #include //#include //#include //#include //#include // ----------------------- Point weighting ---------------------- //#include //#include //#include #include //#include //#include //#include //#include int main(int argc, char* argv[]) { MITK_INFO << "Starting MITK_Forest Mini-App"; ////////////////////////////////////////////////////////////////////////////// // Read Console Input Parameter ////////////////////////////////////////////////////////////////////////////// ConfigFileReader allConfig(argv[1]); bool readFile = true; std::stringstream ss; for (int i = 0; i < argc; ++i ) { MITK_INFO << "-----"<< argv[i]<<"------"; if (readFile) { if (argv[i][0] == '+') { readFile = false; continue; } else { try { allConfig.ReadFile(argv[i]); } catch (std::exception &e) { MITK_INFO << e.what(); } } } else { std::string input = argv[i]; std::replace(input.begin(), input.end(),'_',' '); ss << input << std::endl; } } allConfig.ReadStream(ss); try { ////////////////////////////////////////////////////////////////////////////// // General ////////////////////////////////////////////////////////////////////////////// int currentRun = allConfig.IntValue("General","Run",0); int doTraining = allConfig.IntValue("General","Do Training",1); std::string forestPath = allConfig.Value("General","Forest Path"); std::string trainingCollectionPath = allConfig.Value("General","Patient Collection"); std::string testCollectionPath = allConfig.Value("General", "Patient Test Collection", trainingCollectionPath); ////////////////////////////////////////////////////////////////////////////// // Read Default Classification ////////////////////////////////////////////////////////////////////////////// std::vector trainPatients = allConfig.Vector("Training Group",currentRun); std::vector testPatients = allConfig.Vector("Test Group",currentRun); std::vector modalities = allConfig.Vector("Modalities", 0); std::vector outputFilter = allConfig.Vector("Output Filter", 0); std::string trainMask = allConfig.Value("Data","Training Mask"); std::string completeTrainMask = allConfig.Value("Data","Complete Training Mask"); std::string testMask = allConfig.Value("Data","Test Mask"); std::string resultMask = allConfig.Value("Data", "Result Mask"); std::string resultProb = allConfig.Value("Data", "Result Propability"); std::string outputFolder = allConfig.Value("General","Output Folder"); std::string writeDataFilePath = allConfig.Value("Forest","File to write data to"); ////////////////////////////////////////////////////////////////////////////// // Read Data Forest Parameter ////////////////////////////////////////////////////////////////////////////// int testSingleDataset = allConfig.IntValue("Data", "Test Single Dataset",0); std::string singleDatasetName = allConfig.Value("Data", "Single Dataset Name", "none"); int trainSingleDataset = allConfig.IntValue("Data", "Train Single Dataset", 0); std::string singleTrainDatasetName = allConfig.Value("Data", "Train Single Dataset Name", "none"); ////////////////////////////////////////////////////////////////////////////// // Read Forest Parameter ////////////////////////////////////////////////////////////////////////////// int minimumSplitNodeSize = allConfig.IntValue("Forest", "Minimum split node size",1); int numberOfTrees = allConfig.IntValue("Forest", "Number of Trees",255); double samplesPerTree = atof(allConfig.Value("Forest", "Samples per Tree").c_str()); if (samplesPerTree <= 0.0000001) { samplesPerTree = 1.0; } MITK_INFO << "Samples per Tree: " << samplesPerTree; int sampleWithReplacement = allConfig.IntValue("Forest", "Sample with replacement",1); double trainPrecision = atof(allConfig.Value("Forest", "Precision").c_str()); if (trainPrecision <= 0.0000000001) { trainPrecision = 0.0; } double weightLambda = atof(allConfig.Value("Forest", "Weight Lambda").c_str()); if (weightLambda <= 0.0000000001) { weightLambda = 0.0; } int maximumTreeDepth = allConfig.IntValue("Forest", "Maximum Tree Depth",10000); // TODO int randomSplit = allConfig.IntValue("Forest","Use RandomSplit",0); ////////////////////////////////////////////////////////////////////////////// // Read Statistic Parameter ////////////////////////////////////////////////////////////////////////////// std::string statisticFilePath = allConfig.Value("Evaluation", "Statistic output file"); std::string statisticShortFilePath = allConfig.Value("Evaluation", "Statistic short output file"); std::string statisticShortFileLabel = allConfig.Value("Evaluation", "Index for short file"); std::string statisticGoldStandard = allConfig.Value("Evaluation", "Gold Standard Name","GTV"); // TODO bool statisticWithHeader = allConfig.IntValue("Evaluation", "Write header in short file",0); std::vector labelGroupA = allConfig.Vector("LabelsA",0); std::vector labelGroupB = allConfig.Vector("LabelsB",0); ////////////////////////////////////////////////////////////////////////////// // Read Special Parameter ////////////////////////////////////////////////////////////////////////////// bool useWeightedPoints = allConfig.IntValue("Forest", "Use point-based weighting",0); // TODO bool writePointsToFile = allConfig.IntValue("Forest", "Write points to file",0); // TODO int importanceWeightAlgorithm = allConfig.IntValue("Forest","Importance weight Algorithm",0); std::string importanceWeightName = allConfig.Value("Forest","Importance weight name",""); std::ofstream timingFile; timingFile.open((statisticFilePath + ".timing").c_str(), std::ios::app); timingFile << statisticShortFileLabel << ";"; std::time_t lastTimePoint; time(&lastTimePoint); ////////////////////////////////////////////////////////////////////////////// // Read Images ////////////////////////////////////////////////////////////////////////////// std::vector usedModalities; for (std::size_t i = 0; i < modalities.size(); ++i) { usedModalities.push_back(modalities[i]); } usedModalities.push_back(trainMask); usedModalities.push_back(completeTrainMask); usedModalities.push_back(testMask); usedModalities.push_back(statisticGoldStandard); usedModalities.push_back(importanceWeightName); if (trainSingleDataset > 0) { trainPatients.clear(); trainPatients.push_back(singleTrainDatasetName); } mitk::CollectionReader* colReader = new mitk::CollectionReader(); colReader->AddDataElementIds(trainPatients); colReader->SetDataItemNames(usedModalities); //colReader->SetNames(usedModalities); mitk::DataCollection::Pointer trainCollection; if (doTraining) { trainCollection = colReader->LoadCollection(trainingCollectionPath); } if (testSingleDataset > 0) { testPatients.clear(); testPatients.push_back(singleDatasetName); } colReader->ClearDataElementIds(); colReader->AddDataElementIds(testPatients); mitk::DataCollection::Pointer testCollection = colReader->LoadCollection(testCollectionPath); std::time_t now; time(&now); double seconds = std::difftime(now, lastTimePoint); timingFile << seconds << ";"; time(&lastTimePoint); /* if (writePointsToFile) { MITK_INFO << "Use external weights..."; mitk::ExternalWeighting weightReader; weightReader.SetModalities(modalities); weightReader.SetTestCollection(testCollection); weightReader.SetTrainCollection(trainCollection); weightReader.SetTestMask(testMask); weightReader.SetTrainMask(trainMask); weightReader.SetWeightsName("weights"); weightReader.SetCorrectionFactor(1.0); weightReader.SetWeightFileName(writeDataFilePath); weightReader.WriteData(); return 0; }*/ ////////////////////////////////////////////////////////////////////////////// // If required do Training.... ////////////////////////////////////////////////////////////////////////////// //mitk::DecisionForest forest; mitk::VigraRandomForestClassifier::Pointer forest = mitk::VigraRandomForestClassifier::New(); forest->SetSamplesPerTree(samplesPerTree); forest->SetMinimumSplitNodeSize(minimumSplitNodeSize); forest->SetTreeCount(numberOfTrees); forest->UseSampleWithReplacement(sampleWithReplacement); forest->SetPrecision(trainPrecision); forest->SetMaximumTreeDepth(maximumTreeDepth); forest->SetWeightLambda(weightLambda); // TODO forest.UseRandomSplit(randomSplit); if (doTraining) { // 0 = LR-Estimation // 1 = KNN-Estimation // 2 = Kliep // 3 = Extern Image // 4 = Zadrozny // 5 = Spectral // 6 = uLSIF auto trainDataX = mitk::DCUtilities::DC3dDToMatrixXd(trainCollection, modalities, trainMask); auto trainDataY = mitk::DCUtilities::DC3dDToMatrixXi(trainCollection, trainMask, trainMask); if (useWeightedPoints) //if (false) { MITK_INFO << "Activated Point-based weighting..."; //forest.UseWeightedPoints(true); forest->UsePointWiseWeight(true); //forest.SetWeightName("calculated_weight"); /*if (importanceWeightAlgorithm == 1) { mitk::KNNDensityEstimation est; est.SetCollection(trainCollection); est.SetTrainMask(trainMask); est.SetTestMask(testMask); est.SetModalities(modalities); est.SetWeightName("calculated_weight"); est.Update(); } else if (importanceWeightAlgorithm == 2) { mitk::KliepDensityEstimation est; est.SetCollection(trainCollection); est.SetTrainMask(trainMask); est.SetTestMask(testMask); est.SetModalities(modalities); est.SetWeightName("calculated_weight"); est.Update(); } else if (importanceWeightAlgorithm == 3) { forest.SetWeightName(importanceWeightName); } else if (importanceWeightAlgorithm == 4) { mitk::ZadroznyWeighting est; est.SetCollection(trainCollection); est.SetTrainMask(trainMask); est.SetTestMask(testMask); est.SetModalities(modalities); est.SetWeightName("calculated_weight"); est.Update(); } else if (importanceWeightAlgorithm == 5) { mitk::SpectralDensityEstimation est; est.SetCollection(trainCollection); est.SetTrainMask(trainMask); est.SetTestMask(testMask); est.SetModalities(modalities); est.SetWeightName("calculated_weight"); est.Update(); } else if (importanceWeightAlgorithm == 6) { mitk::ULSIFDensityEstimation est; est.SetCollection(trainCollection); est.SetTrainMask(trainMask); est.SetTestMask(testMask); est.SetModalities(modalities); est.SetWeightName("calculated_weight"); est.Update(); } else*/ { mitk::LRDensityEstimation est; est.SetCollection(trainCollection); est.SetTrainMask(trainMask); est.SetTestMask(testMask); est.SetModalities(modalities); est.SetWeightName("calculated_weight"); est.Update(); } auto trainDataW = mitk::DCUtilities::DC3dDToMatrixXd(trainCollection, "calculated_weight", trainMask); forest->SetPointWiseWeight(trainDataW); forest->UsePointWiseWeight(true); } MITK_INFO << "Start training the forest"; forest->Train(trainDataX, trainDataY); MITK_INFO << "Save Forest"; mitk::IOUtil::Save(forest, forestPath); } else { - forest = dynamic_cast(mitk::IOUtil::Load(forestPath)[0].GetPointer());// TODO forest.Load(forestPath); + forest = mitk::IOUtil::Load(forestPath);// TODO forest.Load(forestPath); } time(&now); seconds = std::difftime(now, lastTimePoint); MITK_INFO << "Duration for Training: " << seconds; timingFile << seconds << ";"; time(&lastTimePoint); ////////////////////////////////////////////////////////////////////////////// // If required do Save Forest.... ////////////////////////////////////////////////////////////////////////////// //writer.// (forest); /* auto w = forest->GetTreeWeights(); w(0,0) = 10; forest->SetTreeWeights(w);*/ ////////////////////////////////////////////////////////////////////////////// // If required do test ////////////////////////////////////////////////////////////////////////////// MITK_INFO << "Convert Test data"; auto testDataX = mitk::DCUtilities::DC3dDToMatrixXd(testCollection,modalities, testMask); MITK_INFO << "Predict Test Data"; auto testDataNewY = forest->Predict(testDataX); auto testDataNewProb = forest->GetPointWiseProbabilities(); //MITK_INFO << testDataNewY; auto maxClassValue = testDataNewProb.cols(); std::vector names; for (int i = 0; i < maxClassValue; ++i) { std::string name = resultProb + std::to_string(i); MITK_INFO << name; names.push_back(name); } //names.push_back("prob-1"); //names.push_back("prob-2"); mitk::DCUtilities::MatrixToDC3d(testDataNewY, testCollection, resultMask, testMask); mitk::DCUtilities::MatrixToDC3d(testDataNewProb, testCollection, names, testMask); MITK_INFO << "Converted predicted data"; //forest.SetMaskName(testMask); //forest.SetCollection(testCollection); //forest.Test(); //forest.PrintTree(0); time(&now); seconds = std::difftime(now, lastTimePoint); timingFile << seconds << ";"; time(&lastTimePoint); ////////////////////////////////////////////////////////////////////////////// // Cost-based analysis ////////////////////////////////////////////////////////////////////////////// // TODO Reactivate //MITK_INFO << "Calculate Cost-based Statistic "; //mitk::CostingStatistic costStat; //costStat.SetCollection(testCollection); //costStat.SetCombinedA("combinedHealty"); //costStat.SetCombinedB("combinedTumor"); //costStat.SetCombinedLabel("combinedLabel"); //costStat.SetMaskName(testMask); ////std::vector labelHealthy; ////labelHealthy.push_back("result_prop_Class-0"); ////labelHealthy.push_back("result_prop_Class-4"); ////std::vector labelTumor; ////labelTumor.push_back("result_prop_Class-1"); ////labelTumor.push_back("result_prop_Class-2"); ////labelTumor.push_back("result_prop_Class-3"); //costStat.SetProbabilitiesA(labelGroupA); //costStat.SetProbabilitiesB(labelGroupB); //std::ofstream costStatisticFile; //costStatisticFile.open((statisticFilePath + ".cost").c_str(), std::ios::app); //std::ofstream lcostStatisticFile; //lcostStatisticFile.open((statisticFilePath + ".longcost").c_str(), std::ios::app); //costStat.WriteStatistic(lcostStatisticFile,costStatisticFile,2.5,statisticShortFileLabel); //costStatisticFile.close(); //costStat.CalculateClass(50); ////////////////////////////////////////////////////////////////////////////// // Save results to folder ////////////////////////////////////////////////////////////////////////////// ////std::vector outputFilter; //outputFilter.push_back(resultMask); //std::vector propNames = forest.GetListOfProbabilityNames(); //outputFilter.insert(outputFilter.begin(), propNames.begin(), propNames.end()); MITK_INFO << "Write Result to HDD"; mitk::CollectionWriter::ExportCollectionToFolder(testCollection, outputFolder + "/result_collection.xml", outputFilter); MITK_INFO << "Calculate Statistic...." ; ////////////////////////////////////////////////////////////////////////////// // Calculate and Print Statistic ////////////////////////////////////////////////////////////////////////////// std::ofstream statisticFile; statisticFile.open(statisticFilePath.c_str(), std::ios::app); std::ofstream sstatisticFile; sstatisticFile.open(statisticShortFilePath.c_str(), std::ios::app); mitk::CollectionStatistic stat; stat.SetCollection(testCollection); stat.SetClassCount(5); stat.SetGoldName(statisticGoldStandard); stat.SetTestName(resultMask); stat.SetMaskName(testMask); mitk::BinaryValueminusOneToIndexMapper mapper; stat.SetGroundTruthValueToIndexMapper(&mapper); stat.SetTestValueToIndexMapper(&mapper); stat.Update(); //stat.Print(statisticFile,sstatisticFile,statisticWithHeader, statisticShortFileLabel); stat.Print(statisticFile,sstatisticFile,true, statisticShortFileLabel); statisticFile.close(); time(&now); seconds = std::difftime(now, lastTimePoint); timingFile << seconds << std::endl; time(&lastTimePoint); timingFile.close(); } catch (std::string s) { MITK_INFO << s; return 0; } catch (char* s) { MITK_INFO << s; } return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLVoxelFeatures.cpp b/Modules/Classification/CLMiniApps/CLVoxelFeatures.cpp index ef6f66995c..853dfdc8d2 100644 --- a/Modules/Classification/CLMiniApps/CLVoxelFeatures.cpp +++ b/Modules/Classification/CLMiniApps/CLVoxelFeatures.cpp @@ -1,434 +1,434 @@ /*=================================================================== 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 mitkCLVoxeFeatures_cpp #define mitkCLVoxeFeatures_cpp #include "time.h" #include #include #include #include #include #include "mitkCommandLineParser.h" #include "itkDiscreteGaussianImageFilter.h" #include #include "itkHessianRecursiveGaussianImageFilter.h" #include "itkUnaryFunctorImageFilter.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include #include #include static std::vector splitDouble(std::string str, char delimiter) { std::vector internal; std::stringstream ss(str); // Turn the string into a stream. std::string tok; double val; while (std::getline(ss, tok, delimiter)) { std::stringstream s2(tok); s2 >> val; internal.push_back(val); } return internal; } namespace Functor { template class MatrixFirstEigenvalue { public: MatrixFirstEigenvalue() {} virtual ~MatrixFirstEigenvalue() {} int order; inline TOutput operator ()(const TInput& input) { double a,b,c; if (input[0] < 0.01 && input[1] < 0.01 &&input[2] < 0.01 &&input[3] < 0.01 &&input[4] < 0.01 &&input[5] < 0.01) return 0; vnl_symmetric_eigensystem_compute_eigenvals(input[0], input[1],input[2],input[3],input[4],input[5],a,b,c); switch (order) { case 0: return a; case 1: return b; case 2: return c; default: return a; } } bool operator !=(const MatrixFirstEigenvalue) const { return false; } bool operator ==(const MatrixFirstEigenvalue& other) const { return !(*this != other); } }; } template void GaussianFilter(itk::Image* itkImage, double variance, mitk::Image::Pointer &output) { typedef itk::Image ImageType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType > GaussFilterType; typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New(); gaussianFilter->SetInput( itkImage ); gaussianFilter->SetVariance(variance); gaussianFilter->Update(); mitk::CastToMitkImage(gaussianFilter->GetOutput(), output); } template void DifferenceOfGaussFilter(itk::Image* itkImage, double variance, mitk::Image::Pointer &output) { typedef itk::Image ImageType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType > GaussFilterType; typedef itk::SubtractImageFilter SubFilterType; typename GaussFilterType::Pointer gaussianFilter1 = GaussFilterType::New(); gaussianFilter1->SetInput( itkImage ); gaussianFilter1->SetVariance(variance); gaussianFilter1->Update(); typename GaussFilterType::Pointer gaussianFilter2 = GaussFilterType::New(); gaussianFilter2->SetInput( itkImage ); gaussianFilter2->SetVariance(variance*0.66*0.66); gaussianFilter2->Update(); typename SubFilterType::Pointer subFilter = SubFilterType::New(); subFilter->SetInput1(gaussianFilter1->GetOutput()); subFilter->SetInput2(gaussianFilter2->GetOutput()); subFilter->Update(); mitk::CastToMitkImage(subFilter->GetOutput(), output); } template void LaplacianOfGaussianFilter(itk::Image* itkImage, double variance, mitk::Image::Pointer &output) { typedef itk::Image ImageType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType > GaussFilterType; typedef itk::LaplacianRecursiveGaussianImageFilter LaplacianFilter; typename GaussFilterType::Pointer gaussianFilter = GaussFilterType::New(); gaussianFilter->SetInput( itkImage ); gaussianFilter->SetVariance(variance); gaussianFilter->Update(); typename LaplacianFilter::Pointer laplaceFilter = LaplacianFilter::New(); laplaceFilter->SetInput(gaussianFilter->GetOutput()); laplaceFilter->Update(); mitk::CastToMitkImage(laplaceFilter->GetOutput(), output); } template void HessianOfGaussianFilter(itk::Image* itkImage, double variance, std::vector &out) { typedef itk::Image ImageType; typedef itk::Image FloatImageType; typedef itk::HessianRecursiveGaussianImageFilter HessianFilterType; typedef typename HessianFilterType::OutputImageType VectorImageType; typedef Functor::MatrixFirstEigenvalue DeterminantFunctorType; typedef itk::UnaryFunctorImageFilter DetFilterType; typename HessianFilterType::Pointer hessianFilter = HessianFilterType::New(); hessianFilter->SetInput(itkImage); hessianFilter->SetSigma(std::sqrt(variance)); for (unsigned int i = 0; i < VImageDimension; ++i) { typename DetFilterType::Pointer detFilter = DetFilterType::New(); detFilter->SetInput(hessianFilter->GetOutput()); detFilter->GetFunctor().order = i; detFilter->Update(); mitk::CastToMitkImage(detFilter->GetOutput(), out[i]); } } template void LocalHistograms2(itk::Image* itkImage, std::vector &out, std::vector params) { typedef itk::Image ImageType; typedef itk::MultiHistogramFilter MultiHistogramType; double minimum = params[0]; double maximum = params[1]; int bins = std::round(params[2]); double offset = minimum; double delta = (maximum - minimum) / bins; typename MultiHistogramType::Pointer filter = MultiHistogramType::New(); filter->SetInput(itkImage); filter->SetOffset(offset); filter->SetDelta(delta); filter->SetBins(bins); filter->Update(); for (int i = 0; i < bins; ++i) { mitk::Image::Pointer img = mitk::Image::New(); mitk::CastToMitkImage(filter->GetOutput(i), img); out.push_back(img); } } template void LocalHistograms(itk::Image* itkImage, std::vector &out, double offset, double delta) { typedef itk::Image ImageType; typedef itk::MultiHistogramFilter MultiHistogramType; typename MultiHistogramType::Pointer filter = MultiHistogramType::New(); filter->SetInput(itkImage); filter->SetOffset(offset); filter->SetDelta(delta); filter->Update(); for (int i = 0; i < 11; ++i) { mitk::Image::Pointer img = mitk::Image::New(); mitk::CastToMitkImage(filter->GetOutput(i), img); out.push_back(img); } } template void localStatistic(itk::Image* itkImage, std::vector &out, int size) { typedef itk::Image ImageType; typedef itk::LocalStatisticFilter MultiHistogramType; typename MultiHistogramType::Pointer filter = MultiHistogramType::New(); filter->SetInput(itkImage); filter->SetSize(size); filter->Update(); for (int i = 0; i < 5; ++i) { mitk::Image::Pointer img = mitk::Image::New(); mitk::CastToMitkImage(filter->GetOutput(i), img); out.push_back(img); } } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("image", "i", mitkCommandLineParser::InputImage, "Input Image", "Path to the input VTK polydata", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output text file", "Target file. The output statistic is appended to this file.", us::Any(), false); parser.addArgument("extension", "e", mitkCommandLineParser::OutputFile, "Extension", "File extension. Default is .nii.gz", us::Any(), true); parser.addArgument("gaussian","g",mitkCommandLineParser::String, "Gaussian Filtering of the input images", "Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any()); parser.addArgument("difference-of-gaussian","dog",mitkCommandLineParser::String, "Difference of Gaussian Filtering of the input images", "Difference of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any()); parser.addArgument("laplace-of-gauss","log",mitkCommandLineParser::String, "Laplacian of Gaussian Filtering", "Laplacian of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any()); parser.addArgument("hessian-of-gauss","hog",mitkCommandLineParser::String, "Hessian of Gaussian Filtering", "Hessian of Gaussian Filter. Followed by the used variances seperated by ';' ",us::Any()); parser.addArgument("local-histogram", "lh", mitkCommandLineParser::String, "Local Histograms", "Calculate the local histogram based feature. Specify Offset and Delta, for exampel -3;0.6 ", us::Any()); parser.addArgument("local-histogram2", "lh2", mitkCommandLineParser::String, "Local Histograms", "Calculate the local histogram based feature. Specify Minimum;Maximum;Bins, for exampel -3;3;6 ", us::Any()); parser.addArgument("local-statistic", "ls", mitkCommandLineParser::String, "Local Histograms", "Calculate the local histogram based feature. Specify Offset and Delta, for exampel -3;0.6 ", us::Any()); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Global Image Feature calculator"); parser.setDescription("Calculates different global statistics for a given segmentation / image combination"); parser.setContributor("MBI"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { return EXIT_FAILURE; } if ( parsedArgs.count("help") || parsedArgs.count("h")) { return EXIT_SUCCESS; } - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(parsedArgs["image"].ToString())[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(parsedArgs["image"].ToString()); std::string filename=parsedArgs["output"].ToString(); std::string extension = ".nii.gz"; if (parsedArgs.count("extension")) { extension = parsedArgs["extension"].ToString(); } //////////////////////////////////////////////////////////////// // CAlculate Local Histogram //////////////////////////////////////////////////////////////// MITK_INFO << "Check for Local Histogram..."; if (parsedArgs.count("local-histogram")) { std::vector outs; auto ranges = splitDouble(parsedArgs["local-histogram"].ToString(), ';'); if (ranges.size() < 2) { MITK_INFO << "Missing Delta and Offset for Local Histogram"; } else { AccessByItk_3(image, LocalHistograms, outs, ranges[0], ranges[1]); for (std::size_t i = 0; i < outs.size(); ++i) { std::string name = filename + "-lh" + us::any_value_to_string(i)+extension; mitk::IOUtil::Save(outs[i], name); } } } //////////////////////////////////////////////////////////////// // CAlculate Local Histogram 2 //////////////////////////////////////////////////////////////// MITK_INFO << "Check for Local Histogram..."; if (parsedArgs.count("local-histogram2")) { std::vector outs; auto ranges = splitDouble(parsedArgs["local-histogram2"].ToString(), ';'); if (ranges.size() < 3) { MITK_INFO << "Missing Delta and Offset for Local Histogram"; } else { AccessByItk_2(image, LocalHistograms2, outs, ranges); for (std::size_t i = 0; i < outs.size(); ++i) { std::string name = filename + "-lh2" + us::any_value_to_string(i)+extension; mitk::IOUtil::Save(outs[i], name); } } } //////////////////////////////////////////////////////////////// // CAlculate Local Statistic //////////////////////////////////////////////////////////////// MITK_INFO << "Check for Local Histogram..."; if (parsedArgs.count("local-statistic")) { std::vector outs; auto ranges = splitDouble(parsedArgs["local-statistic"].ToString(), ';'); if (ranges.size() < 1) { MITK_INFO << "Missing Rage"; } else { for (std::size_t j = 0; j < ranges.size(); ++j) { AccessByItk_2(image, localStatistic, outs, ranges[j]); for (std::size_t i = 0; i < outs.size(); ++i) { std::string name = filename + "-lstat" + us::any_value_to_string(ranges[j])+ "_" +us::any_value_to_string(i)+extension; mitk::IOUtil::Save(outs[i], name); } outs.clear(); } } } //////////////////////////////////////////////////////////////// // CAlculate Gaussian Features //////////////////////////////////////////////////////////////// MITK_INFO << "Check for Gaussian..."; if (parsedArgs.count("gaussian")) { MITK_INFO << "Calculate Gaussian... " << parsedArgs["gaussian"].ToString(); auto ranges = splitDouble(parsedArgs["gaussian"].ToString(),';'); for (std::size_t i = 0; i < ranges.size(); ++i) { MITK_INFO << "Gaussian with sigma: " << ranges[i]; mitk::Image::Pointer output; AccessByItk_2(image, GaussianFilter, ranges[i], output); MITK_INFO << "Write output:"; std::string name = filename + "-gaussian-" + us::any_value_to_string(ranges[i]) + extension; mitk::IOUtil::Save(output, name); } } //////////////////////////////////////////////////////////////// // CAlculate Difference of Gaussian Features //////////////////////////////////////////////////////////////// MITK_INFO << "Check for DoG..."; if (parsedArgs.count("difference-of-gaussian")) { MITK_INFO << "Calculate Difference of Gaussian... " << parsedArgs["difference-of-gaussian"].ToString(); auto ranges = splitDouble(parsedArgs["difference-of-gaussian"].ToString(),';'); for (std::size_t i = 0; i < ranges.size(); ++i) { mitk::Image::Pointer output; AccessByItk_2(image, DifferenceOfGaussFilter, ranges[i], output); std::string name = filename + "-dog-" + us::any_value_to_string(ranges[i]) + extension; mitk::IOUtil::Save(output, name); } } MITK_INFO << "Check for LoG..."; //////////////////////////////////////////////////////////////// // CAlculate Laplacian Of Gauss Features //////////////////////////////////////////////////////////////// if (parsedArgs.count("laplace-of-gauss")) { MITK_INFO << "Calculate LoG... " << parsedArgs["laplace-of-gauss"].ToString(); auto ranges = splitDouble(parsedArgs["laplace-of-gauss"].ToString(),';'); for (std::size_t i = 0; i < ranges.size(); ++i) { mitk::Image::Pointer output; AccessByItk_2(image, LaplacianOfGaussianFilter, ranges[i], output); std::string name = filename + "-log-" + us::any_value_to_string(ranges[i]) + extension; mitk::IOUtil::Save(output, name); } } MITK_INFO << "Check for HoG..."; //////////////////////////////////////////////////////////////// // CAlculate Hessian Of Gauss Features //////////////////////////////////////////////////////////////// if (parsedArgs.count("hessian-of-gauss")) { MITK_INFO << "Calculate HoG... " << parsedArgs["hessian-of-gauss"].ToString(); auto ranges = splitDouble(parsedArgs["hessian-of-gauss"].ToString(),';'); for (std::size_t i = 0; i < ranges.size(); ++i) { std::vector outs; outs.push_back(mitk::Image::New()); outs.push_back(mitk::Image::New()); outs.push_back(mitk::Image::New()); AccessByItk_2(image, HessianOfGaussianFilter, ranges[i], outs); std::string name = filename + "-hog0-" + us::any_value_to_string(ranges[i]) + extension; mitk::IOUtil::Save(outs[0], name); name = filename + "-hog1-" + us::any_value_to_string(ranges[i]) + extension; mitk::IOUtil::Save(outs[1], name); name = filename + "-hog2-" + us::any_value_to_string(ranges[i]) + extension; mitk::IOUtil::Save(outs[2], name); } } return 0; } #endif diff --git a/Modules/Classification/CLMiniApps/CLWeighting.cpp b/Modules/Classification/CLMiniApps/CLWeighting.cpp index b47bcc67e3..98a873ccc6 100644 --- a/Modules/Classification/CLMiniApps/CLWeighting.cpp +++ b/Modules/Classification/CLMiniApps/CLWeighting.cpp @@ -1,217 +1,217 @@ /*=================================================================== 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 mitkForest_cpp #define mitkForest_cpp #include "time.h" #include #include #include "mitkCommandLineParser.h" #include #include #include //#include #include struct TrainingSet { vnl_matrix feature; vnl_vector label; double ratio; }; const vnl_matrix ReadMatrix(std::string path) { std::fstream file(path); std::vector > listOfRows; std::string line; while (std::getline(file, line)) { auto current_row = mitk::cl::splitDouble(line, ','); if (listOfRows.size() < 1) { listOfRows.push_back(current_row); } else if (current_row.size() == listOfRows[0].size()) { listOfRows.push_back(current_row); } } file.close(); vnl_matrix result(listOfRows.size(), listOfRows[0].size()); for (std::size_t i = 0; i < listOfRows.size(); ++i) { for (std::size_t j = 0; j < listOfRows[0].size(); ++j) { result(i, j) = listOfRows[i][j]; } } return result; } const TrainingSet ReadBothMatrix(std::string train, std::string test) { std::fstream file(train); std::vector > listOfRows; std::vector label; double trSamples = 0; double teSamples = 0; std::string line; while (std::getline(file, line)) { auto current_row = mitk::cl::splitDouble(line, ','); if (listOfRows.size() < 1) { listOfRows.push_back(current_row); label.push_back(0); trSamples += 1; } else if (current_row.size() == listOfRows[0].size()) { listOfRows.push_back(current_row); label.push_back(0); trSamples += 1; } } file.close(); std::fstream file2(test); while (std::getline(file2, line)) { auto current_row = mitk::cl::splitDouble(line, ','); if (listOfRows.size() < 1) { listOfRows.push_back(current_row); label.push_back(1); teSamples += 1; } else if (current_row.size() == listOfRows[0].size()) { listOfRows.push_back(current_row); label.push_back(1); teSamples += 1; } } file2.close(); vnl_matrix resultMatrix(listOfRows.size(), listOfRows[0].size()); vnl_vector resultLabel(listOfRows.size()); for (std::size_t i = 0; i < listOfRows.size(); ++i) { for (std::size_t j = 0; j < listOfRows[0].size(); ++j) { resultMatrix(i, j) = listOfRows[i][j]; } resultLabel(i) = label[i]; } TrainingSet set; set.feature = resultMatrix; set.label = resultLabel; set.ratio = trSamples / teSamples; return set; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("training", "t", mitkCommandLineParser::InputImage, "Input Image", "desc", us::Any(), false); parser.addArgument("prediction", "p", mitkCommandLineParser::InputImage, "Input Image", "desc", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::InputImage, "Normalisation mode", "desc", us::Any(), false); //parser.addArgument("algorithm", "a", mitkCommandLineParser::InputImage, "Input Mask", "desc", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Importance weighting algorithm"); parser.setDescription("Calculates the importance weighting of two input matrixes. "); parser.setContributor("MBI"); MITK_INFO << "Extracting Parameters...."; std::map parsedArgs = parser.parseArguments(argc, argv); std::string trainingPath = us::any_cast(parsedArgs["training"]); std::string predictionPath = us::any_cast(parsedArgs["prediction"]); std::string outputPath = us::any_cast(parsedArgs["output"]); //std::string algorithm = us::any_cast(parsedArgs["algorithm"]); MITK_INFO << "Reading Data..."; auto input = ReadBothMatrix(trainingPath, predictionPath); MITK_INFO << "Calculating Weights..."; mitk::GeneralizedLinearModel glm(input.feature, input.label); auto weights = glm.ExpMu(input.feature); MITK_INFO << "Writing Weights ..."; MITK_INFO << outputPath; std::ofstream file(outputPath); for (unsigned int i = 0; i < input.label.size(); ++i) { if (input.label(i) < 0.5) { file << (input.ratio * weights(i)) << std::endl; } } file.close(); ////////////////////////////////////////////////////////////////////////////// // Read Images ////////////////////////////////////////////////////////////////////////////// //mitk::DataCollection::Pointer col = mitk::DataCollection::New(); //MITK_INFO << "Arg 2 " << argv[2]; - //mitk::Image::Pointer sur=mitk::IOUtil::LoadImage(argv[2]); + //mitk::Image::Pointer sur=mitk::IOUtil::Load(argv[2]); //col->AddData(sur.GetPointer(),"sur"); //MITK_INFO << "Arg 3 " << argv[3]; - //mitk::Image::Pointer mask=mitk::IOUtil::LoadImage(argv[3]); + //mitk::Image::Pointer mask=mitk::IOUtil::Load(argv[3]); //col->AddData(mask.GetPointer(),"mask"); //std::vector modalities; //for (int i = 4; i < argc; ++i) //{ // MITK_INFO << "Img " << argv[i]; // std::stringstream ss; // ss << i; // modalities.push_back(ss.str()); - // mitk::Image::Pointer img = mitk::IOUtil::LoadImage(argv[i]); + // mitk::Image::Pointer img = mitk::IOUtil::Load(argv[i]); // col->AddData(img.GetPointer(),ss.str()); //} //mitk::LRDensityEstimation est; //est.SetCollection(col); //est.SetTrainMask("sur"); //est.SetTestMask("mask"); //est.SetModalities(modalities); //est.SetWeightName("weight"); //est.Update(); //mitk::Image::Pointer w= col->GetMitkImage("weight"); //mitk::IOUtil::SaveImage(w,argv[1]); return 0; } #endif \ No newline at end of file diff --git a/Modules/Classification/CLMiniApps/ManualSegmentationEvaluation.cpp b/Modules/Classification/CLMiniApps/ManualSegmentationEvaluation.cpp index e210dc9e6e..a20b0b4a53 100644 --- a/Modules/Classification/CLMiniApps/ManualSegmentationEvaluation.cpp +++ b/Modules/Classification/CLMiniApps/ManualSegmentationEvaluation.cpp @@ -1,364 +1,364 @@ /*=================================================================== 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 "mitkImage.h" #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include // ITK #include // MITK #include // Classification #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace mitk; std::vector m_FeatureImageVector; void ProcessFeatureImages(const mitk::Image::Pointer & raw_image, const mitk::Image::Pointer & brain_mask) { typedef itk::Image DoubleImageType; typedef itk::Image ShortImageType; typedef itk::ConstNeighborhoodIterator NeighborhoodType; // Neighborhood iterator to access image typedef itk::Functor::NeighborhoodFirstOrderStatistics FunctorType; typedef itk::NeighborhoodFunctorImageFilter FOSFilerType; m_FeatureImageVector.clear(); // RAW m_FeatureImageVector.push_back(raw_image); // GAUSS mitk::Image::Pointer smoothed; mitk::CLUtil::GaussianFilter(raw_image,smoothed,1); m_FeatureImageVector.push_back(smoothed); // Calculate Probability maps (parameters used from literatur) // CSF mitk::Image::Pointer csf_prob = mitk::Image::New(); mitk::CLUtil::ProbabilityMap(smoothed,13.9, 8.3,csf_prob); m_FeatureImageVector.push_back(csf_prob); // Lesion mitk::Image::Pointer les_prob = mitk::Image::New(); mitk::CLUtil::ProbabilityMap(smoothed,59, 11.6,les_prob); m_FeatureImageVector.push_back(les_prob); // Barin (GM/WM) mitk::Image::Pointer brain_prob = mitk::Image::New(); mitk::CLUtil::ProbabilityMap(smoothed,32, 5.6,brain_prob); m_FeatureImageVector.push_back(brain_prob); std::vector FOS_sizes; FOS_sizes.push_back(1); DoubleImageType::Pointer input; ShortImageType::Pointer mask; mitk::CastToItkImage(smoothed, input); mitk::CastToItkImage(brain_mask, mask); for(unsigned int i = 0 ; i < FOS_sizes.size(); i++) { FOSFilerType::Pointer filter = FOSFilerType::New(); filter->SetNeighborhoodSize(FOS_sizes[i]); filter->SetInput(input); filter->SetMask(mask); filter->Update(); FOSFilerType::DataObjectPointerArray array = filter->GetOutputs(); for( unsigned int i = 0; i < FunctorType::OutputCount; i++) { mitk::Image::Pointer featureimage; mitk::CastToMitkImage(dynamic_cast(array[i].GetPointer()),featureimage); m_FeatureImageVector.push_back(featureimage); // AddImageAsDataNode(featureimage,FunctorType::GetFeatureName(i))->SetVisibility(show_nodes); } } { itk::HessianMatrixEigenvalueImageFilter< DoubleImageType >::Pointer filter = itk::HessianMatrixEigenvalueImageFilter< DoubleImageType >::New(); filter->SetInput(input); filter->SetImageMask(mask); filter->SetSigma(3); filter->Update(); mitk::Image::Pointer o1,o2,o3; mitk::CastToMitkImage(filter->GetOutput(0),o1); mitk::CastToMitkImage(filter->GetOutput(1),o2); mitk::CastToMitkImage(filter->GetOutput(2),o3); m_FeatureImageVector.push_back(o1); m_FeatureImageVector.push_back(o2); m_FeatureImageVector.push_back(o3); } { itk::StructureTensorEigenvalueImageFilter< DoubleImageType >::Pointer filter = itk::StructureTensorEigenvalueImageFilter< DoubleImageType >::New(); filter->SetInput(input); filter->SetImageMask(mask); filter->SetInnerScale(1.5); filter->SetOuterScale(3); filter->Update(); mitk::Image::Pointer o1,o2,o3; mitk::CastToMitkImage(filter->GetOutput(0),o1); mitk::CastToMitkImage(filter->GetOutput(1),o2); mitk::CastToMitkImage(filter->GetOutput(2),o3); m_FeatureImageVector.push_back(o1); m_FeatureImageVector.push_back(o2); m_FeatureImageVector.push_back(o3); } { itk::LineHistogramBasedMassImageFilter< DoubleImageType >::Pointer filter = itk::LineHistogramBasedMassImageFilter< DoubleImageType >::New(); filter->SetInput(input); filter->SetImageMask(mask); filter->Update(); mitk::Image::Pointer o1; mitk::CastToMitkImage(filter->GetOutput(0),o1); m_FeatureImageVector.push_back(o1); } } std::vector PointSetToVector(const mitk::PointSet::Pointer & mps) { std::vector result; for(int i = 0 ; i < mps->GetSize(); i++) result.push_back(mps->GetPoint(i)); return result; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("inputdir", "i", mitkCommandLineParser::InputDirectory, "Input Directory", "Contains input feature files.", us::Any(), false); parser.addArgument("outputdir", "o", mitkCommandLineParser::OutputDirectory, "Output Directory", "Destination of output files.", us::Any(), false); parser.addArgument("mitkprojectdata", "d", mitkCommandLineParser::InputFile, "original class mask and raw image", "Orig. data.", us::Any(), false); parser.addArgument("csfmps", "csf", mitkCommandLineParser::InputFile, "CSF Pointset", ".", us::Any(), false); parser.addArgument("lesmps", "les", mitkCommandLineParser::InputFile, "LES Pointset", ".", us::Any(), false); parser.addArgument("bramps", "bra", mitkCommandLineParser::InputFile, "BRA Pointset", ".", us::Any(), false); // parser.addArgument("points", "p", mitkCommandLineParser::Int, "Ensure that p points are selected", ".", us::Any(), false); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Evaluationtool for Manual-Segmentation"); parser.setDescription("Uses Datacollection to calculate DICE scores for CSF LES BRA"); parser.setContributor("MBI"); // Params parsing std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inputdir = us::any_cast(parsedArgs["inputdir"]); std::string outputdir = us::any_cast(parsedArgs["outputdir"]); std::string mitkprojectdata = us::any_cast(parsedArgs["mitkprojectdata"]); std::string csf_mps_name = us::any_cast(parsedArgs["csfmps"]); std::string les_mps_name = us::any_cast(parsedArgs["lesmps"]); std::string bra_mps_name = us::any_cast(parsedArgs["bramps"]); mitk::Image::Pointer class_mask_sampled, raw_image, class_mask; mitk::PointSet::Pointer CSF_mps, LES_mps, BRA_mps; // Load from mitk-project auto so = mitk::IOUtil::Load(inputdir + "/" + mitkprojectdata); std::map map; mitk::CLUtil::CountVoxel(dynamic_cast(so[1].GetPointer()), map); raw_image = map.size() <= 7 ? dynamic_cast(so[0].GetPointer()) : dynamic_cast(so[1].GetPointer()); class_mask = map.size() <= 7 ? dynamic_cast(so[1].GetPointer()) : dynamic_cast(so[0].GetPointer()); - CSF_mps = dynamic_cast(mitk::IOUtil::Load(inputdir + "/" + csf_mps_name)[0].GetPointer()); - LES_mps = dynamic_cast(mitk::IOUtil::Load(inputdir + "/" + les_mps_name)[0].GetPointer()); - BRA_mps = dynamic_cast(mitk::IOUtil::Load(inputdir + "/" + bra_mps_name)[0].GetPointer()); + CSF_mps = mitk::IOUtil::Load(inputdir + "/" + csf_mps_name); + LES_mps = mitk::IOUtil::Load(inputdir + "/" + les_mps_name); + BRA_mps = mitk::IOUtil::Load(inputdir + "/" + bra_mps_name); unsigned int num_points = CSF_mps->GetSize() + LES_mps->GetSize() + BRA_mps->GetSize(); MITK_INFO << "Found #" << num_points << " points over all classes."; ProcessFeatureImages(raw_image, class_mask); std::map tmpMap; tmpMap[0] = 0; tmpMap[1] = 1; tmpMap[2] = 1; tmpMap[3] = 1; tmpMap[4] = 2; tmpMap[5] = 3; tmpMap[6] = 3; mitk::CLUtil::MergeLabels( class_mask, tmpMap); class_mask_sampled = class_mask->Clone(); itk::Image::Pointer itk_classmask_sampled; mitk::CastToItkImage(class_mask_sampled,itk_classmask_sampled); itk::ImageRegionIteratorWithIndex >::IndexType index; itk::ImageRegionIteratorWithIndex > iit(itk_classmask_sampled,itk_classmask_sampled->GetLargestPossibleRegion()); std::ofstream myfile; myfile.open (inputdir + "/results_3.csv"); Eigen::MatrixXd X_test; unsigned int count_test = 0; mitk::CLUtil::CountVoxel(class_mask, count_test); X_test = Eigen::MatrixXd(count_test, m_FeatureImageVector.size()); unsigned int pos = 0; for( const auto & image : m_FeatureImageVector) { X_test.col(pos) = mitk::CLUtil::Transform(image,class_mask); ++pos; } unsigned int runs = 20; for(unsigned int k = 0 ; k < runs; k++) { auto CSF_vec = PointSetToVector(CSF_mps); auto LES_vec = PointSetToVector(LES_mps); auto BRA_vec = PointSetToVector(BRA_mps); itk_classmask_sampled->FillBuffer(0); // initial draws std::random_shuffle(CSF_vec.begin(), CSF_vec.end()); class_mask->GetGeometry()->WorldToIndex(CSF_vec.back(),index); iit.SetIndex(index); iit.Set(1); CSF_vec.pop_back(); std::random_shuffle(LES_vec.begin(), LES_vec.end()); class_mask->GetGeometry()->WorldToIndex(LES_vec.back(),index); iit.SetIndex(index); iit.Set(2); LES_vec.pop_back(); std::random_shuffle(BRA_vec.begin(), BRA_vec.end()); class_mask->GetGeometry()->WorldToIndex(BRA_vec.back(),index); iit.SetIndex(index); iit.Set(3); BRA_vec.pop_back(); std::stringstream ss; while(!(CSF_vec.empty() && LES_vec.empty() && BRA_vec.empty())) { mitk::CastToMitkImage(itk_classmask_sampled, class_mask_sampled); // Train forest mitk::VigraRandomForestClassifier::Pointer classifier = mitk::VigraRandomForestClassifier::New(); classifier->SetTreeCount(40); classifier->SetSamplesPerTree(0.66); Eigen::MatrixXd X_train; unsigned int count_train = 0; mitk::CLUtil::CountVoxel(class_mask_sampled, count_train); X_train = Eigen::MatrixXd(count_train, m_FeatureImageVector.size() ); unsigned int pos = 0; for( const auto & image : m_FeatureImageVector) { X_train.col(pos) = mitk::CLUtil::Transform(image,class_mask_sampled); ++pos; } Eigen::MatrixXi Y = mitk::CLUtil::Transform(class_mask_sampled,class_mask_sampled); classifier->Train(X_train,Y); Eigen::MatrixXi Y_test = classifier->Predict(X_test); mitk::Image::Pointer result_mask = mitk::CLUtil::Transform(Y_test, class_mask); itk::Image::Pointer itk_result_mask, itk_class_mask; mitk::CastToItkImage(result_mask,itk_result_mask); mitk::CastToItkImage(class_mask, itk_class_mask); itk::LabelOverlapMeasuresImageFilter >::Pointer overlap_filter = itk::LabelOverlapMeasuresImageFilter >::New(); overlap_filter->SetInput(0,itk_result_mask); overlap_filter->SetInput(1,itk_class_mask); overlap_filter->Update(); MITK_INFO << "DICE (" << num_points - (CSF_vec.size() + LES_vec.size() + BRA_vec.size()) << "): " << overlap_filter->GetDiceCoefficient(); ss << overlap_filter->GetDiceCoefficient() <<","; // random class selection if(!CSF_vec.empty()) { std::random_shuffle(CSF_vec.begin(), CSF_vec.end()); class_mask->GetGeometry()->WorldToIndex(CSF_vec.back(),index); iit.SetIndex(index); iit.Set(1); CSF_vec.pop_back(); } if(!LES_vec.empty()) { std::random_shuffle(LES_vec.begin(), LES_vec.end()); class_mask->GetGeometry()->WorldToIndex(LES_vec.back(),index); iit.SetIndex(index); iit.Set(2); LES_vec.pop_back(); } if(!BRA_vec.empty()) { std::random_shuffle(BRA_vec.begin(), BRA_vec.end()); class_mask->GetGeometry()->WorldToIndex(BRA_vec.back(),index); iit.SetIndex(index); iit.Set(3); BRA_vec.pop_back(); } } myfile << ss.str() << "\n"; myfile.flush(); } myfile.close(); return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLMiniApps/RandomForestTraining.cpp b/Modules/Classification/CLMiniApps/RandomForestTraining.cpp index 6d20ae73e1..e818994033 100644 --- a/Modules/Classification/CLMiniApps/RandomForestTraining.cpp +++ b/Modules/Classification/CLMiniApps/RandomForestTraining.cpp @@ -1,152 +1,152 @@ /*=================================================================== 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 "mitkImage.h" #include #include "mitkCommandLineParser.h" #include #include #include #include #include // ITK #include // MITK #include // Classification #include #include #include #include #include using namespace mitk; /** * */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // required params parser.addArgument("inputdir", "i", mitkCommandLineParser::InputDirectory, "Input Directory", "Contains input feature files.", us::Any(), false); parser.addArgument("outputdir", "o", mitkCommandLineParser::OutputDirectory, "Output Directory", "Destination of output files.", us::Any(), false); parser.addArgument("classmask", "m", mitkCommandLineParser::InputFile, "Class mask image", "Contains several classes.", us::Any(), false); // optional params parser.addArgument("select", "s", mitkCommandLineParser::String, "Item selection", "Using Regular expression, seperated by space e.g.: '*.nrrd *.vtk *test*'",std::string("*.nrrd"),true); parser.addArgument("treecount", "tc", mitkCommandLineParser::Int, "Treecount", "Number of trees.",50,true); parser.addArgument("treedepth", "td", mitkCommandLineParser::Int, "Treedepth", "Maximal tree depth.",50,true); parser.addArgument("minsplitnodesize", "min", mitkCommandLineParser::Int, "Minimum split node size.", "Minimum split node size.",2,true); parser.addArgument("precision", "p", mitkCommandLineParser::Float, "Split precision.", "Precision.", mitk::eps,true); parser.addArgument("fraction", "f", mitkCommandLineParser::Float, "Fraction of samples per tree.", "Fraction of samples per tree.", 0.6f,true); parser.addArgument("replacment", "r", mitkCommandLineParser::Bool, "Sample with replacement.", "Sample with replacement.", true,true); // Miniapp Infos parser.setCategory("Classification Tools"); parser.setTitle("Random Forest Training"); parser.setDescription("Vigra RF impl."); parser.setContributor("MBI"); // Params parsing std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inputdir = us::any_cast(parsedArgs["inputdir"]); std::string outputdir = us::any_cast(parsedArgs["outputdir"]); std::string classmask = us::any_cast(parsedArgs["classmask"]); int treecount = parsedArgs.count("treecount") ? us::any_cast(parsedArgs["treecount"]) : 50; int treedepth = parsedArgs.count("treedepth") ? us::any_cast(parsedArgs["treedepth"]) : 50; int minsplitnodesize = parsedArgs.count("minsplitnodesize") ? us::any_cast(parsedArgs["minsplitnodesize"]) : 2; float precision = parsedArgs.count("precision") ? us::any_cast(parsedArgs["precision"]) : mitk::eps; float fraction = parsedArgs.count("fraction") ? us::any_cast(parsedArgs["fraction"]) : 0.6; bool withreplacement = parsedArgs.count("replacment") ? us::any_cast(parsedArgs["replacment"]) : true; std::string filt_select =/* parsedArgs.count("select") ? us::any_cast(parsedArgs["select"]) :*/ "*.nrrd"; QString filter(filt_select.c_str()); // **** in principle repeat this block to create a feature matrix X_all for all subjects (in dir) // Get nrrd filepath QDir dir(inputdir.c_str()); auto strl = dir.entryList(filter.split(" "),QDir::Files); // load class mask - mitk::Image::Pointer mask = dynamic_cast(mitk::IOUtil::Load(classmask)[0].GetPointer()); + mitk::Image::Pointer mask = mitk::IOUtil::Load(classmask); unsigned int num_samples = 0; mitk::CLUtil::CountVoxel(mask,num_samples); // initialize featurematrix [num_samples, num_featureimages] Eigen::MatrixXd X(num_samples, strl.size()); for(int i = 0 ; i < strl.size(); i++) { // load feature image - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(inputdir + strl[i].toStdString())[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(inputdir + strl[i].toStdString()); // transfom it into a [num_samples, 1] vector depending on the classmask Eigen::MatrixXd _x = mitk::CLUtil::Transform(img,mask); // replace i-th (empty) col with feature vector in _x X.block(0,i,num_samples,1) = _x; } // **** // transform classmask into the label-vector [num_samples, 1] Eigen::MatrixXi Y = mitk::CLUtil::Transform(mask,mask); mitk::VigraRandomForestClassifier::Pointer classifier = mitk::VigraRandomForestClassifier::New(); classifier->SetTreeCount(treecount); classifier->SetMaximumTreeDepth(treedepth); classifier->SetMinimumSplitNodeSize(minsplitnodesize); classifier->SetPrecision(precision); classifier->SetSamplesPerTree(fraction); classifier->UseSampleWithReplacement(withreplacement); classifier->PrintParameter(); classifier->Train(X,Y); MITK_INFO << classifier->IsEmpty(); // no metainformations are saved currently // only the raw vigra rf data mitk::IOUtil::Save(classifier, outputdir + "RandomForest.hdf5"); Eigen::MatrixXi Y_pred = classifier->Predict(X); Eigen::MatrixXd Probs = classifier->GetPointWiseProbabilities(); MITK_INFO << Y_pred.rows() << " " << Y_pred.cols(); MITK_INFO << Probs.rows() << " " << Probs.cols(); // mitk::Image::Pointer prediction = mitk::CLUtil::Transform(Y_pred,mask); mitk::Image::Pointer probs_1 = mitk::CLUtil::Transform(Probs.col(0),mask); mitk::Image::Pointer probs_2 = mitk::CLUtil::Transform(Probs.col(1),mask); mitk::Image::Pointer probs_3 = mitk::CLUtil::Transform(Probs.col(2),mask); mitk::IOUtil::Save(probs_1, outputdir + "probs_1.nrrd"); mitk::IOUtil::Save(probs_2, outputdir + "probs_2.nrrd"); mitk::IOUtil::Save(probs_3, outputdir + "probs_3.nrrd"); // mitk::IOUtil::Save(probs_2, outputdir + "test.nrrd"); return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLMiniApps/XRaxSimulationFromCT.cpp b/Modules/Classification/CLMiniApps/XRaxSimulationFromCT.cpp index 7286cb1881..0cdc98a1c1 100644 --- a/Modules/Classification/CLMiniApps/XRaxSimulationFromCT.cpp +++ b/Modules/Classification/CLMiniApps/XRaxSimulationFromCT.cpp @@ -1,226 +1,226 @@ /*=================================================================== 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 "mitkProperties.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "itkImageRegionIterator.h" // MITK #include #include #include struct Params { bool invert; float zeroValue; }; template void CreateXRay(itk::Image* itkImage, mitk::Image::Pointer mask1, std::string output, Params param) { typedef itk::Image ImageType; typedef itk::Image MaskType; typedef itk::Image NewImageType; typename MaskType::Pointer itkMask = MaskType::New(); mitk::CastToItkImage(mask1, itkMask); NewImageType::SpacingType newSpacing; auto spacing = itkImage->GetSpacing(); spacing[0] = itkImage->GetSpacing()[0]; spacing[1] = itkImage->GetSpacing()[1]; spacing[2] = itkImage->GetSpacing()[2]; spacing = itkImage->GetSpacing(); NewImageType::RegionType region1,region2,region3,region1m,region2m,region3m; NewImageType::IndexType start; start[0] = 0; start[1] = 0; NewImageType::SizeType size1, size2, size3; size1[0] = mask1->GetDimensions()[0]; size2[0] = mask1->GetDimensions()[0]; size3[0] = mask1->GetDimensions()[1]; size1[1] = mask1->GetDimensions()[1]; size2[1] = mask1->GetDimensions()[2]; size3[1] = mask1->GetDimensions()[2]; region1.SetSize(size1); region1m.SetSize(size1); region2.SetSize(size2); region2m.SetSize(size2); region3.SetSize(size3); region3m.SetSize(size3); region1.SetIndex(start); region1m.SetIndex(start); region2.SetIndex(start); region2m.SetIndex(start); region3.SetIndex(start); region3m.SetIndex(start); NewImageType::Pointer image1 = NewImageType::New(); image1->SetRegions(region1); image1->Allocate(); image1->FillBuffer(0); newSpacing[0] = spacing[0]; newSpacing[1] = spacing[1]; image1->SetSpacing(newSpacing); NewImageType::Pointer image2 = NewImageType::New(); image2->SetRegions(region2); image2->Allocate(); image2->FillBuffer(0); newSpacing[0] = spacing[0]; newSpacing[1] = spacing[2]; image2->SetSpacing(newSpacing); NewImageType::Pointer image3 = NewImageType::New(); image3->SetRegions(region3); image3->Allocate(); image3->FillBuffer(0); newSpacing[0] = spacing[1]; newSpacing[1] = spacing[2]; image3->SetSpacing(newSpacing); NewImageType::Pointer image1m = NewImageType::New(); image1m->SetRegions(region1m); image1m->Allocate(); image1m->FillBuffer(0); newSpacing[0] = spacing[0]; newSpacing[1] = spacing[1]; image1m->SetSpacing(newSpacing); NewImageType::Pointer image2m = NewImageType::New(); image2m->SetRegions(region2m); image2m->Allocate(); image2m->FillBuffer(0); newSpacing[0] = spacing[0]; newSpacing[1] = spacing[2]; image2m->SetSpacing(newSpacing); NewImageType::Pointer image3m = NewImageType::New(); image3m->SetRegions(region3m); image3m->Allocate(); image3m->FillBuffer(0); newSpacing[0] = spacing[1]; newSpacing[1] = spacing[2]; image3m->SetSpacing(newSpacing); for (unsigned int x = 0; x < mask1->GetDimensions()[0]; ++x) { for (unsigned int y = 0; y < mask1->GetDimensions()[1]; ++y) { for (unsigned int z = 0; z < mask1->GetDimensions()[2]; ++z) { NewImageType::IndexType newIndex; typename ImageType::IndexType index; index[0] = x; index[1] = y; index[2] = z; double pixel = itkImage->GetPixel(index)+1024; pixel = pixel / 1000.0; pixel = (pixel < 0)? 0 : pixel; newIndex[0] = x; newIndex[1] = y; image1->SetPixel(newIndex, image1->GetPixel(newIndex) + pixel); newIndex[0] = x; newIndex[1] = z; image2->SetPixel(newIndex, image2->GetPixel(newIndex) + pixel); newIndex[0] = y; newIndex[1] = z; image3->SetPixel(newIndex, image3->GetPixel(newIndex) + pixel); if (itkMask->GetPixel(index) > 0 && !param.invert) { pixel = param.zeroValue + 1024; pixel = pixel / 1000.0; } if (itkMask->GetPixel(index) < 1 && param.invert) { pixel = param.zeroValue + 1024; pixel = pixel / 1000.0; } pixel = (pixel < 0)? 0 : pixel; newIndex[0] = x; newIndex[1] = y; image1m->SetPixel(newIndex, image1m->GetPixel(newIndex) + pixel); newIndex[0] = x; newIndex[1] = z; image2m->SetPixel(newIndex, image2m->GetPixel(newIndex) + pixel); newIndex[0] = y; newIndex[1] = z; image3m->SetPixel(newIndex, image3m->GetPixel(newIndex) + pixel); } } } mitk::Image::Pointer img = mitk::ImportItkImage(image1); mitk::IOUtil::Save(img, output + "1.nrrd"); img = mitk::ImportItkImage(image2); mitk::IOUtil::Save(img, output + "2.nrrd"); img = mitk::ImportItkImage(image3); mitk::IOUtil::Save(img, output + "3.nrrd"); img = mitk::ImportItkImage(image1m); mitk::IOUtil::Save(img, output + "1m.nrrd"); img = mitk::ImportItkImage(image2m); mitk::IOUtil::Save(img, output + "2m.nrrd"); img = mitk::ImportItkImage(image3m); mitk::IOUtil::Save(img, output + "3m.nrrd"); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MBI"); parser.setArgumentPrefix("-","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input image:", "Input folder", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputDirectory, "Input mask:", "Input folder", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file:", "Output file", us::Any(), false); parser.addArgument("invert", "invert", mitkCommandLineParser::Bool, "Input mask:", "Input folder", us::Any()); parser.addArgument("zero_value", "zero", mitkCommandLineParser::Float, "Output file:", "Output file", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputImage = us::any_cast(parsedArgs["input"]); MITK_INFO << inputImage; std::string inputMask = us::any_cast(parsedArgs["mask"]); MITK_INFO << inputMask; Params param; param.invert = false; param.zeroValue = 0; if (parsedArgs.count("invert")) { param.invert = true; } if (parsedArgs.count("zero_value")) { param.zeroValue = us::any_cast(parsedArgs["zero_value"]); } - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(inputImage); - mitk::Image::Pointer mask = mitk::IOUtil::LoadImage(inputMask); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputImage); + mitk::Image::Pointer mask = mitk::IOUtil::Load(inputMask); AccessByItk_3(image, CreateXRay, mask, parsedArgs["output"].ToString(),param); //const mitk::Image::Pointer image = *imageIter; //mitk::IOUtil::SaveImage(image,outFileName); return EXIT_SUCCESS; } diff --git a/Modules/Classification/CLUtilities/test/mitkGIFCurvatureStatisticTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFCurvatureStatisticTest.cpp index 77d68c7123..e9c908dabc 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFCurvatureStatisticTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFCurvatureStatisticTest.cpp @@ -1,122 +1,122 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFCurvatureStatisticTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFCurvatureStatisticTestSuite); MITK_TEST(ImageDescription_PhantomTest); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest() { mitk::GIFCurvatureStatistic::Pointer featureCalculator = mitk::GIFCurvatureStatistic::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 44 features.", std::size_t(44), featureList.size()); // These values are obtained by a run of the filter. // The might be wrong! CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Minimum Mean Curvature with Large IBSI Phantom Image", -1.51, results["Curvature Feature::Minimum Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Maximum Mean Curvature with Large IBSI Phantom Image", 0.51, results["Curvature Feature::Maximum Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Mean Curvature with Large IBSI Phantom Image", 0.095, results["Curvature Feature::Mean Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Mean Curvature with Large IBSI Phantom Image", 0.45, results["Curvature Feature::Standard Deviation Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Mean Curvature with Large IBSI Phantom Image", -2.55, results["Curvature Feature::Skewness Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Positive Mean Curvature with Large IBSI Phantom Image", 0.30, results["Curvature Feature::Mean Positive Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Positive Mean Curvature with Large IBSI Phantom Image", 0.12, results["Curvature Feature::Standard Deviation Positive Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Positive Mean Curvature with Large IBSI Phantom Image", 0.60, results["Curvature Feature::Skewness Positive Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Negative Mean Curvature with Large IBSI Phantom Image", -0.955, results["Curvature Feature::Mean Negative Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Negative Mean Curvature with Large IBSI Phantom Image", 0.56, results["Curvature Feature::Standard Deviation Negative Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Negative Mean Curvature with Large IBSI Phantom Image", 0.09, results["Curvature Feature::Skewness Negative Mean Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Minimum Gaussian Curvature with Large IBSI Phantom Image", -0.211, results["Curvature Feature::Minimum Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Maximum Gaussian Curvature with Large IBSI Phantom Image", 1.81, results["Curvature Feature::Maximum Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Gaussian Curvature with Large IBSI Phantom Image", 0.14, results["Curvature Feature::Mean Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Gaussian Curvature with Large IBSI Phantom Image", 0.42, results["Curvature Feature::Standard Deviation Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Gaussian Curvature with Large IBSI Phantom Image", 3.51, results["Curvature Feature::Skewness Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Positive Gaussian Curvature with Large IBSI Phantom Image", 0.26, results["Curvature Feature::Mean Positive Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Positive Gaussian Curvature with Large IBSI Phantom Image", 0.53, results["Curvature Feature::Standard Deviation Positive Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Positive Gaussian Curvature with Large IBSI Phantom Image", 2.52, results["Curvature Feature::Skewness Positive Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Negative Gaussian Curvature with Large IBSI Phantom Image", -0.03, results["Curvature Feature::Mean Negative Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Negative Gaussian Curvature with Large IBSI Phantom Image", 0.055, results["Curvature Feature::Standard Deviation Negative Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Negative Gaussian Curvature with Large IBSI Phantom Image", -1.92, results["Curvature Feature::Skewness Negative Gaussian Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Minimum Minimum Curvature with Large IBSI Phantom Image", -2.19, results["Curvature Feature::Minimum Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Maximum Minimum Curvature with Large IBSI Phantom Image", 0.35, results["Curvature Feature::Maximum Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Minimum Curvature with Large IBSI Phantom Image", -0.11, results["Curvature Feature::Mean Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Minimum Curvature with Large IBSI Phantom Image", 0.573, results["Curvature Feature::Standard Deviation Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Minimum Curvature with Large IBSI Phantom Image", -2.742, results["Curvature Feature::Skewness Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Positive Minimum Curvature with Large IBSI Phantom Image", 0.161, results["Curvature Feature::Mean Positive Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Positive Minimum Curvature with Large IBSI Phantom Image", 0.165, results["Curvature Feature::Standard Deviation Positive Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Positive Minimum Curvature with Large IBSI Phantom Image", 0.108, results["Curvature Feature::Skewness Positive Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Negative Minimum Curvature with Large IBSI Phantom Image", -0.42, results["Curvature Feature::Mean Negative Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Negative Minimum Curvature with Large IBSI Phantom Image", 0.733, results["Curvature Feature::Standard Deviation Negative Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Negative Minimum Curvature with Large IBSI Phantom Image", -1.73, results["Curvature Feature::Skewness Negative Minimum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Minimum Maximum Curvature with Large IBSI Phantom Image", -0.83, results["Curvature Feature::Minimum Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Maximum Maximum Curvature with Large IBSI Phantom Image", 0.79, results["Curvature Feature::Maximum Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Maximum Curvature with Large IBSI Phantom Image", 0.30, results["Curvature Feature::Mean Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Maximum Curvature with Large IBSI Phantom Image", 0.369, results["Curvature Feature::Standard Deviation Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Maximum Curvature with Large IBSI Phantom Image", -1.617, results["Curvature Feature::Skewness Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Positive Maximum Curvature with Large IBSI Phantom Image", 0.419, results["Curvature Feature::Mean Positive Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Positive Maximum Curvature with Large IBSI Phantom Image", 0.217, results["Curvature Feature::Standard Deviation Positive Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Positive Maximum Curvature with Large IBSI Phantom Image", -0.958, results["Curvature Feature::Skewness Positive Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Mean Negative Maximum Curvature with Large IBSI Phantom Image", -0.44, results["Curvature Feature::Mean Negative Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Standard Deviation Negative Maximum Curvature with Large IBSI Phantom Image", 0.399, results["Curvature Feature::Standard Deviation Negative Maximum Curvature"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Curvature Feature::Skewness Negative Maximum Curvature with Large IBSI Phantom Image", 0.109, results["Curvature Feature::Skewness Negative Maximum Curvature"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFCurvatureStatistic ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFFirstOrderHistogramStatisticsTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFFirstOrderHistogramStatisticsTest.cpp index 4d02a4a9cc..ddbb9318c4 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFFirstOrderHistogramStatisticsTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFFirstOrderHistogramStatisticsTest.cpp @@ -1,127 +1,127 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFFirstOrderHistogramStatisticsTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFFirstOrderHistogramStatisticsTestSuite); MITK_TEST(ImageDescription_PhantomTest); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest() { mitk::GIFFirstOrderHistogramStatistics::Pointer featureCalculator = mitk::GIFFirstOrderHistogramStatistics::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 46 features.", std::size_t(46), featureList.size()); // These values are obtained by a run of the filter. // The might be wrong! CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Mean Value should be 2.15 with Large IBSI Phantom Image", 2.15, results["First Order Histogram::Mean Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Variance Value should be 3.05 with Large IBSI Phantom Image", 3.05, results["First Order Histogram::Variance Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Skewness Value should be 1.08 with Large IBSI Phantom Image", 1.08, results["First Order Histogram::Skewness Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Excess Kurtosis Value should be -0.355 with Large IBSI Phantom Image", -0.355, results["First Order Histogram::Excess Kurtosis Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Median Value should be 1 with Large IBSI Phantom Image", 1.0, results["First Order Histogram::Median Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Minimum Value should be 1 with Large IBSI Phantom Image", 1, results["First Order Histogram::Minimum Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Percentile 10 Value should be 0.648 with Large IBSI Phantom Image", 0.648, results["First Order Histogram::Percentile 10 Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Percentile 90 Value should be 4.475 with Large IBSI Phantom Image", 4.475, results["First Order Histogram::Percentile 90 Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Maximum Value should be 6 with Large IBSI Phantom Image", 6, results["First Order Histogram::Maximum Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Mode Value should be 1 with Large IBSI Phantom Image", 1, results["First Order Histogram::Mode Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Interquantile Range Value should be 2.9 with Large IBSI Phantom Image", 2.911, results["First Order Histogram::Interquantile Range Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Range Value should be 5 with Large IBSI Phantom Image", 5, results["First Order Histogram::Range Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Mean Absolute Deviation Value should be 1.55 with Large IBSI Phantom Image", 1.55, results["First Order Histogram::Mean Absolute Deviation Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Robust Mean Absolute Deviation Value should be 1.11 with Large IBSI Phantom Image", 1.11, results["First Order Histogram::Robust Mean Absolute Deviation Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Median Absolute Deviation Value should be 1.14 with Large IBSI Phantom Image", 1.14, results["First Order Histogram::Median Absolute Deviation Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Coefficient of Variation Value should be 0.812 with Large IBSI Phantom Image", 0.812, results["First Order Histogram::Coefficient of Variation Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Quantile coefficient of Dispersion Value should be 0.626 with Large IBSI Phantom Image", 0.626, results["First Order Histogram::Quantile coefficient of Dispersion Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Entropy Value should be 1.27 with Large IBSI Phantom Image", 1.27, results["First Order Histogram::Entropy Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Uniformity Value should be 0.512 with Large IBSI Phantom Image", 0.512, results["First Order Histogram::Uniformity Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Robust Mean Index should be 0.746 with Large IBSI Phantom Image", 0.746, results["First Order Histogram::Robust Mean Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Robust Mean Value should be 1.746 with Large IBSI Phantom Image", 1.746, results["First Order Histogram::Robust Mean Value"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Number of Bins should be 6", 6, results["First Order Histogram::Number of Bins"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Bin Size should be 1", 1, results["First Order Histogram::Bin Size"], 0.01); // These values are taken from the IBSI Initiative to ensure compatibility // The values are given with an accuracy of 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Mean Index should be 2.15 with Large IBSI Phantom Image", 2.15, results["First Order Histogram::Mean Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Variance Index should be 3.05 with Large IBSI Phantom Image", 3.05, results["First Order Histogram::Variance Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Skewness Index should be 1.08 with Large IBSI Phantom Image", 1.08, results["First Order Histogram::Skewness Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Excess Kurtosis Index should be -0.355 with Large IBSI Phantom Image", -0.355, results["First Order Histogram::Excess Kurtosis Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Median Index should be 1 with Large IBSI Phantom Image", 1.0, results["First Order Histogram::Median Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Minimum Index should be 1 with Large IBSI Phantom Image", 1, results["First Order Histogram::Minimum Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Percentile 10 Index should be 1 with Large IBSI Phantom Image", 1, results["First Order Histogram::Percentile 10 Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Percentile 90 Index should be 2.15 with Large IBSI Phantom Image", 4, results["First Order Histogram::Percentile 90 Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Maximum Index should be 6 with Large IBSI Phantom Image", 6, results["First Order Histogram::Maximum Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Mode Index should be 1 with Large IBSI Phantom Image", 1, results["First Order Histogram::Mode Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Interquantile Range Index should be 3 with Large IBSI Phantom Image", 3, results["First Order Histogram::Interquantile Range Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Range Index should be 5 with Large IBSI Phantom Image", 5, results["First Order Histogram::Range Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Mean Absolute Deviation Index should be 3 with Large IBSI Phantom Image", 1.55, results["First Order Histogram::Mean Absolute Deviation Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Robust Mean Absolute Deviation Index should be 1.11 with Large IBSI Phantom Image", 1.11, results["First Order Histogram::Robust Mean Absolute Deviation Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Median Absolute Deviation Index should be 1.14 with Large IBSI Phantom Image", 1.14, results["First Order Histogram::Median Absolute Deviation Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Coefficient of Variation Index should be 0.812 with Large IBSI Phantom Image", 0.812, results["First Order Histogram::Coefficient of Variation Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Quantile coefficient of Dispersion Index should be 0.6 with Large IBSI Phantom Image", 0.6, results["First Order Histogram::Quantile coefficient of Dispersion Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Entropy Index should be 1.27 with Large IBSI Phantom Image", 1.27, results["First Order Histogram::Entropy Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Uniformity Index should be 0.512 with Large IBSI Phantom Image", 0.512, results["First Order Histogram::Uniformity Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Maximum Gradient should be 8 with Large IBSI Phantom Image", 8, results["First Order Histogram::Maximum Gradient"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Maximum Gradient Index should be 3 with Large IBSI Phantom Image", 3, results["First Order Histogram::Maximum Gradient Index"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Minimum Gradient should be -50 with Large IBSI Phantom Image", -50, results["First Order Histogram::Minimum Gradient"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("First Order Histogram::Minimum Gradient Index should be 3 with Large IBSI Phantom Image", 1, results["First Order Histogram::Minimum Gradient Index"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFFirstOrderHistogramStatistics ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelDistanceZoneTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelDistanceZoneTest.cpp index 5114133e30..6df2796c38 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelDistanceZoneTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelDistanceZoneTest.cpp @@ -1,147 +1,147 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFGreyLevelDistanceZoneTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFGreyLevelDistanceZoneTestSuite ); MITK_TEST(ImageDescription_PhantomTest_3D); MITK_TEST(ImageDescription_PhantomTest_2D); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest_3D() { mitk::GIFGreyLevelDistanceZone::Pointer featureCalculator = mitk::GIFGreyLevelDistanceZone::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 19 features.", std::size_t(19), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Small Distance Emphasis with Large IBSI Phantom Image", 1, results["Grey Level Distance Zone::Small Distance Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Large Distance Emphasis with Large IBSI Phantom Image", 1, results["Grey Level Distance Zone::Large Distance Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Low Grey Level Emphasis with Large IBSI Phantom Image", 0.253, results["Grey Level Distance Zone::Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::High Grey Level Emphasis with Large IBSI Phantom Image", 15.6, results["Grey Level Distance Zone::High Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Small Distance Low Grey Level Emphasis with Large IBSI Phantom Image", 0.253, results["Grey Level Distance Zone::Small Distance Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Small Distance High Grey Level Emphasis with Large IBSI Phantom Image", 15.6, results["Grey Level Distance Zone::Small Distance High Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Large Distance Low Grey Level Emphasis with Large IBSI Phantom Image", 0.253, results["Grey Level Distance Zone::Large Distance Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Large Distance High Grey Level Emphasis with Large IBSI Phantom Image", 15.6, results["Grey Level Distance Zone::Large Distance High Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Grey Level Non-Uniformity with Large IBSI Phantom Image", 1.4, results["Grey Level Distance Zone::Grey Level Non-Uniformity"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Grey Level Non-Uniformity Normalized with Large IBSI Phantom Image", 0.28, results["Grey Level Distance Zone::Grey Level Non-Uniformity Normalized"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Distance Size Non-Uniformity with Large IBSI Phantom Image", 5, results["Grey Level Distance Zone::Distance Size Non-Uniformity"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Distance Size Non-Uniformity Normalized with Large IBSI Phantom Image", 1, results["Grey Level Distance Zone::Distance Size Non-Uniformity Normalized"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Zone Percentage with Large IBSI Phantom Image", 0.0676, results["Grey Level Distance Zone::Zone Percentage"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Grey Level Variance with Large IBSI Phantom Image", 2.64, results["Grey Level Distance Zone::Grey Level Variance"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Zone Distance Variance with Large IBSI Phantom Image", 0, results["Grey Level Distance Zone::Zone Distance Variance"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Zone Distance Entropy with Large IBSI Phantom Image", 1.92, results["Grey Level Distance Zone::Zone Distance Entropy"], 0.01); //CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone:: with Large IBSI Phantom Image", 0.045, results["Grey Level Distance Zone::"], 0.001); // These values are obtained by manually running the tool // Values might be wrong. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Grey Level Mean with Large IBSI Phantom Image", 3.6, results["Grey Level Distance Zone::Grey Level Mean"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Zone Distance Mean with Large IBSI Phantom Image", 1, results["Grey Level Distance Zone::Zone Distance Mean"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone::Grey Level Entropy with Large IBSI Phantom Image", 1.92, results["Grey Level Distance Zone::Grey Level Entropy"], 0.01); } void ImageDescription_PhantomTest_2D() { mitk::GIFGreyLevelDistanceZone::Pointer featureCalculator = mitk::GIFGreyLevelDistanceZone::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeaturesSlicewise(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large, 2); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 114 features.", std::size_t(114), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis with Large IBSI Phantom Image", 0.946, results["SliceWise Mean Grey Level Distance Zone::Small Distance Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Large Distance Emphasis with Large IBSI Phantom Image", 1.21, results["SliceWise Mean Grey Level Distance Zone::Large Distance Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Low Grey Level Emphasis with Large IBSI Phantom Image", 0.371, results["SliceWise Mean Grey Level Distance Zone::Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::High Grey Level Emphasis with Large IBSI Phantom Image", 16.4, results["SliceWise Mean Grey Level Distance Zone::High Grey Level Emphasis"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Small Distance Low Grey Level Emphasis with Large IBSI Phantom Image", 0.367, results["SliceWise Mean Grey Level Distance Zone::Small Distance Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Small Distance High Grey Level Emphasis with Large IBSI Phantom Image", 15.2, results["SliceWise Mean Grey Level Distance Zone::Small Distance High Grey Level Emphasis"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Large Distance Low Grey Level Emphasis with Large IBSI Phantom Image", 0.386, results["SliceWise Mean Grey Level Distance Zone::Large Distance Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Large Distance High Grey Level Emphasis with Large IBSI Phantom Image", 21.3, results["SliceWise Mean Grey Level Distance Zone::Large Distance High Grey Level Emphasis"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity with Large IBSI Phantom Image", 1.41, results["SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity Normalized with Large IBSI Phantom Image", 0.323, results["SliceWise Mean Grey Level Distance Zone::Grey Level Non-Uniformity Normalized"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity with Large IBSI Phantom Image", 3.79, results["SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity Normalized with Large IBSI Phantom Image", 0.898, results["SliceWise Mean Grey Level Distance Zone::Distance Size Non-Uniformity Normalized"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Zone Percentage with Large IBSI Phantom Image", 0.24, results["SliceWise Mean Grey Level Distance Zone::Zone Percentage"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Grey Level Variance with Large IBSI Phantom Image", 3.97, results["SliceWise Mean Grey Level Distance Zone::Grey Level Variance"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Zone Distance Variance with Large IBSI Phantom Image", 0.051, results["SliceWise Mean Grey Level Distance Zone::Zone Distance Variance"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Zone Distance Entropy with Large IBSI Phantom Image", 1.73, results["SliceWise Mean Grey Level Distance Zone::Zone Distance Entropy"], 0.01); //CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Distance Zone:: with Large IBSI Phantom Image", 0.045, results["Grey Level Distance Zone::"], 0.001); // These values are obtained by manually running the tool // Values might be wrong. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Grey Level Mean with Large IBSI Phantom Image", 3.526, results["SliceWise Mean Grey Level Distance Zone::Grey Level Mean"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Zone Distance Mean with Large IBSI Phantom Image", 1.071, results["SliceWise Mean Grey Level Distance Zone::Zone Distance Mean"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Distance Zone::Grey Level Entropy with Large IBSI Phantom Image", 1.732, results["SliceWise Mean Grey Level Distance Zone::Grey Level Entropy"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFGreyLevelDistanceZone ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelSizeZoneTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelSizeZoneTest.cpp index 6c3d21dcec..8adcba8d93 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelSizeZoneTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFGreyLevelSizeZoneTest.cpp @@ -1,145 +1,145 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFGreyLevelSizeZoneTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFGreyLevelSizeZoneTestSuite ); MITK_TEST(ImageDescription_PhantomTest_3D); MITK_TEST(ImageDescription_PhantomTest_2D); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest_3D() { mitk::GIFGreyLevelSizeZone::Pointer featureCalculator = mitk::GIFGreyLevelSizeZone::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 18 features.", std::size_t(18), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Small Zone Emphasis with Large IBSI Phantom Image", 0.255, results["Grey Level Size Zone::Small Zone Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Large Zone Emphasis with Large IBSI Phantom Image", 550, results["Grey Level Size Zone::Large Zone Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Low Grey Level Emphasis with Large IBSI Phantom Image", 0.253, results["Grey Level Size Zone::Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::High Grey Level Emphasis with Large IBSI Phantom Image", 15.6, results["Grey Level Size Zone::High Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Small Zone Low Grey Level Emphasis with Large IBSI Phantom Image", 0.0256, results["Grey Level Size Zone::Small Zone Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Small Zone High Grey Level Emphasis with Large IBSI Phantom Image", 2.76, results["Grey Level Size Zone::Small Zone High Grey Level Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Large Zone Low Grey Level Emphasis with Large IBSI Phantom Image", 503, results["Grey Level Size Zone::Large Zone Low Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Large Zone High Grey Level Emphasis with Large IBSI Phantom Image", 1495, results["Grey Level Size Zone::Large Zone High Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Grey Level Non-Uniformity with Large IBSI Phantom Image", 1.4, results["Grey Level Size Zone::Grey Level Non-Uniformity"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Grey Level Non-Uniformity Normalized with Large IBSI Phantom Image", 0.28, results["Grey Level Size Zone::Grey Level Non-Uniformity Normalized"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Zone Size Non-Uniformity with Large IBSI Phantom Image", 1, results["Grey Level Size Zone::Zone Size Non-Uniformity"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Zone Size Non-Uniformity Normalized with Large IBSI Phantom Image", 0.2, results["Grey Level Size Zone::Zone Size Non-Uniformity Normalized"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Zone Percentage with Large IBSI Phantom Image", 0.0676, results["Grey Level Size Zone::Zone Percentage"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Grey Level Variance with Large IBSI Phantom Image", 2.64, results["Grey Level Size Zone::Grey Level Variance"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Zone Size Variance with Large IBSI Phantom Image", 331, results["Grey Level Size Zone::Zone Size Variance"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Zone Size Entropy with Large IBSI Phantom Image", 2.32, results["Grey Level Size Zone::Zone Size Entropy"], 0.01); //CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone:: with Large IBSI Phantom Image", 0.045, results["Grey Level Size Zone::"], 0.001); // These values are obtained by manually running the tool // Values might be wrong. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Grey Level Mean with Large IBSI Phantom Image", 3.6, results["Grey Level Size Zone::Grey Level Mean"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Grey Level Size Zone::Zone Size Mean with Large IBSI Phantom Image", 14.8, results["Grey Level Size Zone::Zone Size Mean"], 0.001); } void ImageDescription_PhantomTest_2D() { mitk::GIFGreyLevelSizeZone::Pointer featureCalculator = mitk::GIFGreyLevelSizeZone::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeaturesSlicewise(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large, 2); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 108 features.", std::size_t(108), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Small Zone Emphasis with Large IBSI Phantom Image", 0.363, results["SliceWise Mean Grey Level Size Zone::Small Zone Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Large Zone Emphasis with Large IBSI Phantom Image", 43.9, results["SliceWise Mean Grey Level Size Zone::Large Zone Emphasis"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Low Grey Level Emphasis with Large IBSI Phantom Image", 0.371, results["SliceWise Mean Grey Level Size Zone::Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::High Grey Level Emphasis with Large IBSI Phantom Image", 16.4, results["SliceWise Mean Grey Level Size Zone::High Grey Level Emphasis"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Small Zone Low Grey Level Emphasis with Large IBSI Phantom Image", 0.0259, results["SliceWise Mean Grey Level Size Zone::Small Zone Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Small Zone High Grey Level Emphasis with Large IBSI Phantom Image", 10.3, results["SliceWise Mean Grey Level Size Zone::Small Zone High Grey Level Emphasis"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Large Zone Low Grey Level Emphasis with Large IBSI Phantom Image", 40.4, results["SliceWise Mean Grey Level Size Zone::Large Zone Low Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Large Zone High Grey Level Emphasis with Large IBSI Phantom Image", 113, results["SliceWise Mean Grey Level Size Zone::Large Zone High Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity with Large IBSI Phantom Image", 1.41, results["SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity Normalized with Large IBSI Phantom Image", 0.323, results["SliceWise Mean Grey Level Size Zone::Grey Level Non-Uniformity Normalized"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity with Large IBSI Phantom Image", 1.49, results["SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity Normalized with Large IBSI Phantom Image", 0.333, results["SliceWise Mean Grey Level Size Zone::Zone Size Non-Uniformity Normalized"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Zone Percentage with Large IBSI Phantom Image", 0.24, results["SliceWise Mean Grey Level Size Zone::Zone Percentage"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Grey Level Variance with Large IBSI Phantom Image", 3.97, results["SliceWise Mean Grey Level Size Zone::Grey Level Variance"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Zone Size Variance with Large IBSI Phantom Image", 21, results["SliceWise Mean Grey Level Size Zone::Zone Size Variance"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Zone Size Entropy with Large IBSI Phantom Image", 1.93, results["SliceWise Mean Grey Level Size Zone::Zone Size Entropy"], 0.01); //CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone:: with Large IBSI Phantom Image", 0.045, results["SliceWise Mean Grey Level Size Zone::"], 0.001); // These values are obtained by manually running the tool // Values might be wrong. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Grey Level Mean with Large IBSI Phantom Image", 3.526, results["SliceWise Mean Grey Level Size Zone::Grey Level Mean"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Grey Level Size Zone::Zone Size Mean with Large IBSI Phantom Image", 4.59524, results["SliceWise Mean Grey Level Size Zone::Zone Size Mean"], 0.001); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFGreyLevelSizeZone ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFImageDescriptionFeaturesTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFImageDescriptionFeaturesTest.cpp index 95c1287997..4aadb069fb 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFImageDescriptionFeaturesTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFImageDescriptionFeaturesTest.cpp @@ -1,95 +1,95 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFImageDescriptionFeaturesTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFImageDescriptionFeaturesTestSuite ); MITK_TEST(ImageDescription_PhantomTest); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest() { mitk::GIFImageDescriptionFeatures::Pointer featureCalculator = mitk::GIFImageDescriptionFeatures::New(); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 22 features.", std::size_t(22), featureList.size()); // These values are calculated obtained by using this filter. Changes, especially with mean values could happen. CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Image Dimension X should be 7 with Large IBSI Phantom Image", int(7), int(results["Diagnostic::Image Dimension X"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Image Dimension Y should be 6 with Large IBSI Phantom Image", int(6), int(results["Diagnostic::Image Dimension Y"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Image Dimension Z should be 6 with Large IBSI Phantom Image", int(6), int(results["Diagnostic::Image Dimension Z"])); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Image Spacing X should be 2 with Large IBSI Phantom Image", 2.0, results["Diagnostic::Image Spacing X"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Image Spacing Y should be 2 with Large IBSI Phantom Image", 2.0, results["Diagnostic::Image Spacing Y"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Image Spacing Z should be 2 with Large IBSI Phantom Image", 2.0, results["Diagnostic::Image Spacing Z"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Image Mean intensity should be 0.6865 with Large IBSI Phantom Image", 0.686508, results["Diagnostic::Image Mean intensity"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Image Minimum intensity should be 0 with Large IBSI Phantom Image", 0, results["Diagnostic::Image Minimum intensity"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Image Maximum intensity should be 9 with Large IBSI Phantom Image", 9, results["Diagnostic::Image Maximum intensity"], 0.0001); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask Dimension X should be 7 with Large IBSI Phantom Image", int(7), int(results["Diagnostic::Mask Dimension X"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask Dimension Y should be 6 with Large IBSI Phantom Image", int(6), int(results["Diagnostic::Mask Dimension Y"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask Dimension Z should be 6 with Large IBSI Phantom Image", int(6), int(results["Diagnostic::Mask Dimension Z"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask bounding box X should be 5 with Large IBSI Phantom Image", int(5), int(results["Diagnostic::Mask bounding box X"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask bounding box Y should be 4 with Large IBSI Phantom Image", int(4), int(results["Diagnostic::Mask bounding box Y"])); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask bounding box Z should be 4 with Large IBSI Phantom Image", int(4), int(results["Diagnostic::Mask bounding box Z"])); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Mask Spacing X should be 2 with Large IBSI Phantom Image", 2.0, results["Diagnostic::Mask Spacing X"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Mask Spacing Y should be 2 with Large IBSI Phantom Image", 2.0, results["Diagnostic::Mask Spacing Y"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Mask Spacing Z should be 2 with Large IBSI Phantom Image", 2.0, results["Diagnostic::Mask Spacing Z"], 0.0001); CPPUNIT_ASSERT_EQUAL_MESSAGE("Diagnostic::Mask Voxel Count should be 74 with Large IBSI Phantom Image", int(74), int(results["Diagnostic::Mask Voxel Count"])); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Mask Mean intensity should be 2.14865 with Large IBSI Phantom Image", 2.14865, results["Diagnostic::Mask Mean intensity"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Mask Minimum intensity should be 1 with Large IBSI Phantom Image", 1, results["Diagnostic::Mask Minimum intensity"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Diagnostic::Mask Maximum intensity should be 6 with Large IBSI Phantom Image", 6, results["Diagnostic::Mask Maximum intensity"], 0.0001); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFImageDescriptionFeatures ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFLocalIntensityTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFLocalIntensityTest.cpp index 42dd52eb83..0357fa1a21 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFLocalIntensityTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFLocalIntensityTest.cpp @@ -1,114 +1,114 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFLocalIntensityTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFLocalIntensityTestSuite); MITK_TEST(ImageDescription_PhantomTest_Small); MITK_TEST(ImageDescription_PhantomTest_Large); MITK_TEST(ImageDescription_PhantomTest_Large_RangeChanged); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest_Small() { mitk::GIFLocalIntensity::Pointer featureCalculator = mitk::GIFLocalIntensity::New(); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Small, m_IBSI_Phantom_Mask_Small); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 2 features.", std::size_t(2), featureList.size()); // These values are obtained in cooperation with IBSI // Reported with an accuracy of 0.1 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Local Intensity::Local Intensity Peak with Large IBSI Phantom Image", 2.6, results["Local Intensity::Local Intensity Peak"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Local Intensity::Global Intensity Peak with Large IBSI Phantom Image", 3.1, results["Local Intensity::Global Intensity Peak"], 0.1); } void ImageDescription_PhantomTest_Large() { mitk::GIFLocalIntensity::Pointer featureCalculator = mitk::GIFLocalIntensity::New(); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 2 features.", std::size_t(2), featureList.size()); // These values are obtained by running the tool // They might be wrong CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Local Intensity::Local Intensity Peak with Large IBSI Phantom Image", 1.43, results["Local Intensity::Local Intensity Peak"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Local Intensity::Global Intensity Peak with Large IBSI Phantom Image", 1.43, results["Local Intensity::Global Intensity Peak"], 0.01); } void ImageDescription_PhantomTest_Large_RangeChanged() { mitk::GIFLocalIntensity::Pointer featureCalculator = mitk::GIFLocalIntensity::New(); featureCalculator->SetRange(1); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 2 features.", std::size_t(2), featureList.size()); // These values are obtained by running the tool // They might be wrong CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Local Intensity::Local Intensity Peak with Large IBSI Phantom Image", 2.81, results["Local Intensity::Local Intensity Peak"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Local Intensity::Global Intensity Peak with Large IBSI Phantom Image", 3.15, results["Local Intensity::Global Intensity Peak"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFLocalIntensity ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTest.cpp index b9f28e45ee..e70b3aa357 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTest.cpp @@ -1,111 +1,111 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFNeighbourhoodGreyToneDifferenceFeaturesTestSuite); MITK_TEST(ImageDescription_PhantomTest_3D); MITK_TEST(ImageDescription_PhantomTest_2D); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest_3D() { mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::Pointer featureCalculator = mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 5 features.", std::size_t(5), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbourhood Grey Tone Difference::Coarsness with Large IBSI Phantom Image", 0.0296, results["Neighbourhood Grey Tone Difference::Coarsness"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbourhood Grey Tone Difference::Contrast with Large IBSI Phantom Image", 0.584, results["Neighbourhood Grey Tone Difference::Contrast"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbourhood Grey Tone Difference::Busyness with Large IBSI Phantom Image", 6.54, results["Neighbourhood Grey Tone Difference::Busyness"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbourhood Grey Tone Difference::Complexity with Large IBSI Phantom Image", 13.5, results["Neighbourhood Grey Tone Difference::Complexity"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbourhood Grey Tone Difference::Strength with Large IBSI Phantom Image", 0.763, results["Neighbourhood Grey Tone Difference::Strength"], 0.01); } void ImageDescription_PhantomTest_2D() { mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::Pointer featureCalculator = mitk::GIFNeighbourhoodGreyToneDifferenceFeatures::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeaturesSlicewise(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large, 2); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 30 features.", std::size_t(30), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness with Large IBSI Phantom Image", 0.121, results["SliceWise Mean Neighbourhood Grey Tone Difference::Coarsness"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbourhood Grey Tone Difference::Contrast with Large IBSI Phantom Image", 0.925, results["SliceWise Mean Neighbourhood Grey Tone Difference::Contrast"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbourhood Grey Tone Difference::Busyness with Large IBSI Phantom Image", 2.99, results["SliceWise Mean Neighbourhood Grey Tone Difference::Busyness"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbourhood Grey Tone Difference::Complexity with Large IBSI Phantom Image", 10.4, results["SliceWise Mean Neighbourhood Grey Tone Difference::Complexity"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbourhood Grey Tone Difference::Strength with Large IBSI Phantom Image", 2.88, results["SliceWise Mean Neighbourhood Grey Tone Difference::Strength"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFNeighbourhoodGreyToneDifferenceFeatures ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFNeighbouringGreyLevelDependenceFeatureTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFNeighbouringGreyLevelDependenceFeatureTest.cpp index 8ca9a82e45..65449509c3 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFNeighbouringGreyLevelDependenceFeatureTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFNeighbouringGreyLevelDependenceFeatureTest.cpp @@ -1,155 +1,155 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFNeighbouringGreyLevelDependenceFeatureTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFNeighbouringGreyLevelDependenceFeatureTestSuite ); MITK_TEST(ImageDescription_PhantomTest_3D); MITK_TEST(ImageDescription_PhantomTest_2D); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest_3D() { mitk::GIFNeighbouringGreyLevelDependenceFeature::Pointer featureCalculator = mitk::GIFNeighbouringGreyLevelDependenceFeature::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 24 features.", std::size_t(24), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Low Dependence Emphasis with Large IBSI Phantom Image", 0.045, results["Neighbouring Grey Level Dependence::Low Dependence Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::High Dependence Emphasis with Large IBSI Phantom Image", 109, results["Neighbouring Grey Level Dependence::High Dependence Emphasis"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis with Large IBSI Phantom Image", 0.693, results["Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::High Grey Level Count Emphasis with Large IBSI Phantom Image", 7.66, results["Neighbouring Grey Level Dependence::High Grey Level Count Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis with Large IBSI Phantom Image", 0.00963, results["Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis with Large IBSI Phantom Image", 0.736, results["Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis with Large IBSI Phantom Image", 102, results["Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis with Large IBSI Phantom Image", 235, results["Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Grey Level Non-Uniformity with Large IBSI Phantom Image", 37.9, results["Neighbouring Grey Level Dependence::Grey Level Non-Uniformity"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised with Large IBSI Phantom Image", 0.512, results["Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity with Large IBSI Phantom Image", 4.86, results["Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised with Large IBSI Phantom Image", 0.0657, results["Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Percentage with Large IBSI Phantom Image", 1, results["Neighbouring Grey Level Dependence::Dependence Count Percentage"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Grey Level Variance with Large IBSI Phantom Image", 3.05, results["Neighbouring Grey Level Dependence::Grey Level Variance"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Variance with Large IBSI Phantom Image", 22.1, results["Neighbouring Grey Level Dependence::Dependence Count Variance"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Entropy with Large IBSI Phantom Image", 4.4, results["Neighbouring Grey Level Dependence::Dependence Count Entropy"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Energy with Large IBSI Phantom Image", 0.0533, results["Neighbouring Grey Level Dependence::Dependence Count Energy"], 0.01); // These values are obtained by manually running the tool // Values might be wrong. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Grey Level Mean with Large IBSI Phantom Image", 2.15, results["Neighbouring Grey Level Dependence::Grey Level Mean"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Dependence Count Mean with Large IBSI Phantom Image", 9.32, results["Neighbouring Grey Level Dependence::Dependence Count Mean"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Expected Neighbourhood Size with Large IBSI Phantom Image", 26, results["Neighbouring Grey Level Dependence::Expected Neighbourhood Size"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Average Neighbourhood Size with Large IBSI Phantom Image", 14.24, results["Neighbouring Grey Level Dependence::Average Neighbourhood Size"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Average Incomplete Neighbourhood Size with Large IBSI Phantom Image", 14.24, results["Neighbouring Grey Level Dependence::Average Incomplete Neighbourhood Size"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Percentage of complete Neighbourhoods with Large IBSI Phantom Image", 0, results["Neighbouring Grey Level Dependence::Percentage of complete Neighbourhoods"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Neighbouring Grey Level Dependence::Percentage of Dependence Neighbour Voxels with Large IBSI Phantom Image", 0.584, results["Neighbouring Grey Level Dependence::Percentage of Dependence Neighbour Voxels"], 0.01); } void ImageDescription_PhantomTest_2D() { mitk::GIFNeighbouringGreyLevelDependenceFeature::Pointer featureCalculator = mitk::GIFNeighbouringGreyLevelDependenceFeature::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeaturesSlicewise(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large, 2); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 144 features.", std::size_t(144), featureList.size()); // These values are obtained with IBSI // Standard accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis with Large IBSI Phantom Image", 0.158, results["SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Emphasis with Large IBSI Phantom Image", 19.2, results["SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Emphasis"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis with Large IBSI Phantom Image", 0.702, results["SliceWise Mean Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::High Grey Level Count Emphasis with Large IBSI Phantom Image", 7.49, results["SliceWise Mean Neighbouring Grey Level Dependence::High Grey Level Count Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis with Large IBSI Phantom Image", 0.0473, results["SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis with Large IBSI Phantom Image", 3.06, results["SliceWise Mean Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis with Large IBSI Phantom Image", 17.6, results["SliceWise Mean Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis with Large IBSI Phantom Image", 49.5, results["SliceWise Mean Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis"], 1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity with Large IBSI Phantom Image", 10.2, results["SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised with Large IBSI Phantom Image", 0.562, results["SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Non-Uniformity Normalised"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity with Large IBSI Phantom Image", 3.96, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised with Large IBSI Phantom Image", 0.212, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Non-Uniformity Normalised"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Percentage with Large IBSI Phantom Image", 1, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Percentage"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Variance with Large IBSI Phantom Image", 2.7, results["SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Variance"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Variance with Large IBSI Phantom Image", 2.73, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Variance"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Entropy with Large IBSI Phantom Image", 2.71, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Entropy"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Energy with Large IBSI Phantom Image", 0.17, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Energy"], 0.01); // These values are obtained by manually running the tool // Values might be wrong. CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Mean with Large IBSI Phantom Image", 2.12, results["SliceWise Mean Neighbouring Grey Level Dependence::Grey Level Mean"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Mean with Large IBSI Phantom Image", 3.98, results["SliceWise Mean Neighbouring Grey Level Dependence::Dependence Count Mean"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Expected Neighbourhood Size with Large IBSI Phantom Image", 8, results["SliceWise Mean Neighbouring Grey Level Dependence::Expected Neighbourhood Size"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Average Neighbourhood Size with Large IBSI Phantom Image", 5.20, results["SliceWise Mean Neighbouring Grey Level Dependence::Average Neighbourhood Size"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Average Incomplete Neighbourhood Size with Large IBSI Phantom Image", 4.5598, results["SliceWise Mean Neighbouring Grey Level Dependence::Average Incomplete Neighbourhood Size"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Percentage of complete Neighbourhoods with Large IBSI Phantom Image", 0.1831, results["SliceWise Mean Neighbouring Grey Level Dependence::Percentage of complete Neighbourhoods"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("SliceWise Mean Neighbouring Grey Level Dependence::Percentage of Dependence Neighbour Voxels with Large IBSI Phantom Image", 0.579, results["SliceWise Mean Neighbouring Grey Level Dependence::Percentage of Dependence Neighbour Voxels"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFNeighbouringGreyLevelDependenceFeature ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFVolumetricDensityStatisticsTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFVolumetricDensityStatisticsTest.cpp index 2dfe9fe711..adde06ef97 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFVolumetricDensityStatisticsTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFVolumetricDensityStatisticsTest.cpp @@ -1,92 +1,92 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFVolumetricDensityStatisticsTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFVolumetricDensityStatisticsTestSuite); MITK_TEST(ImageDescription_PhantomTest); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest() { mitk::GIFVolumetricDensityStatistics::Pointer featureCalculator = mitk::GIFVolumetricDensityStatistics::New(); featureCalculator->SetUseBinsize(true); featureCalculator->SetBinsize(1.0); featureCalculator->SetUseMinimumIntensity(true); featureCalculator->SetUseMaximumIntensity(true); featureCalculator->SetMinimumIntensity(0.5); featureCalculator->SetMaximumIntensity(6.5); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Image Diagnostics should calculate 13 features.", std::size_t(13), featureList.size()); // These values are obtained by a run of the filter. // The might be wrong! // These values are obtained in collaboration with IBSI. // They are usually reported with an accuracy of 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume integrated intensity with Large IBSI Phantom Image", 1195, results["Morphological Density::Volume integrated intensity"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Moran's I index with Large IBSI Phantom Image", 0.0397, results["Morphological Density::Volume Moran's I index"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Geary's C measure with Large IBSI Phantom Image", 0.974, results["Morphological Density::Volume Geary's C measure"], 0.001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Volume density axis-aligned bounding box with Large IBSI Phantom Image", 0.87, results["Morphological Density::Volume density axis-aligned bounding box"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Surface Volume density axis-aligned bounding box with Large IBSI Phantom Image", 0.87, results["Morphological Density::Surface density axis-aligned bounding box"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Volume oriented minimum bounding box with Large IBSI Phantom Image", 0.87, results["Morphological Density::Volume density oriented minimum bounding box"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Surface Volume oriented minimum bounding box with Large IBSI Phantom Image", 0.86, results["Morphological Density::Surface density oriented minimum bounding box"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Volume approx. enclosing ellipsoid with Large IBSI Phantom Image", 1.17, results["Morphological Density::Volume density approx. enclosing ellipsoid"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Surface Volume approx. enclosing ellipsoid with Large IBSI Phantom Image", 1.34, results["Morphological Density::Surface density approx. enclosing ellipsoid"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Volume minimum volume enclosing ellipsoid with Large IBSI Phantom Image", 0.24, results["Morphological Density::Volume density approx. minimum volume enclosing ellipsoid"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Surface Volume minimum volume enclosing ellipsoid with Large IBSI Phantom Image", 0.46, results["Morphological Density::Surface density approx. minimum volume enclosing ellipsoid"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Volume Volume convex hull with Large IBSI Phantom Image", 0.96, results["Morphological Density::Volume density convex hull"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Morphological Density::Surface Volume convex hull with Large IBSI Phantom Image", 1.03, results["Morphological Density::Surface density convex hull"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFVolumetricDensityStatistics ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGIFVolumetricStatisticsTest.cpp b/Modules/Classification/CLUtilities/test/mitkGIFVolumetricStatisticsTest.cpp index 993b9028b5..78c452962c 100644 --- a/Modules/Classification/CLUtilities/test/mitkGIFVolumetricStatisticsTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGIFVolumetricStatisticsTest.cpp @@ -1,105 +1,105 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkGIFVolumetricStatisticsTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGIFVolumetricStatisticsTestSuite); MITK_TEST(ImageDescription_PhantomTest); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_IBSI_Phantom_Image_Small; mitk::Image::Pointer m_IBSI_Phantom_Image_Large; mitk::Image::Pointer m_IBSI_Phantom_Mask_Small; mitk::Image::Pointer m_IBSI_Phantom_Mask_Large; public: void setUp(void) override { - m_IBSI_Phantom_Image_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); - m_IBSI_Phantom_Image_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); - m_IBSI_Phantom_Mask_Small = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); - m_IBSI_Phantom_Mask_Large = mitk::IOUtil::LoadImage(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); + m_IBSI_Phantom_Image_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Small.nrrd")); + m_IBSI_Phantom_Image_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Image_Large.nrrd")); + m_IBSI_Phantom_Mask_Small = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Small.nrrd")); + m_IBSI_Phantom_Mask_Large = mitk::IOUtil::Load(GetTestDataFilePath("Radiomics/IBSI_Phantom_Mask_Large.nrrd")); } void ImageDescription_PhantomTest() { mitk::GIFVolumetricStatistics::Pointer featureCalculator = mitk::GIFVolumetricStatistics::New(); auto featureList = featureCalculator->CalculateFeatures(m_IBSI_Phantom_Image_Large, m_IBSI_Phantom_Mask_Large); std::map results; for (auto valuePair : featureList) { MITK_INFO << valuePair.first << " : " << valuePair.second; results[valuePair.first] = valuePair.second; } CPPUNIT_ASSERT_EQUAL_MESSAGE("Volume Statistic should calculate 33 features.", std::size_t(33), featureList.size()); // These values are obtained in cooperation with IBSI // Default accuracy is 0.01 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Volume (mesh based) with Large IBSI Phantom Image", 556, results["Volumetric Features::Volume (mesh based)"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Volume (voxel based) with Large IBSI Phantom Image", 592, results["Volumetric Features::Volume (voxel based)"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Surface (mesh based) with Large IBSI Phantom Image", 388, results["Volumetric Features::Surface (mesh based)"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Surface to volume ratio (mesh based) with Large IBSI Phantom Image", 0.698, results["Volumetric Features::Surface to volume ratio (mesh based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Compactness 1 (mesh based) with Large IBSI Phantom Image", 0.0437, results["Volumetric Features::Compactness 1 (mesh based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Compactness 2 (mesh based) with Large IBSI Phantom Image", 0.678, results["Volumetric Features::Compactness 2 (mesh based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Spherical disproportion (mesh based) with Large IBSI Phantom Image", 1.14, results["Volumetric Features::Spherical disproportion (mesh based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Sphericity (mesh based) with Large IBSI Phantom Image", 0.879, results["Volumetric Features::Sphericity (mesh based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Asphericity (mesh based) with Large IBSI Phantom Image", 0.138, results["Volumetric Features::Asphericity (mesh based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Ceentre of mass shift with Large IBSI Phantom Image", 0.672, results["Volumetric Features::Centre of mass shift"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Maximum 3D diameter with Large IBSI Phantom Image", 11.66, results["Volumetric Features::Maximum 3D diameter"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Major axis length with Large IBSI Phantom Image", 11.40, results["Volumetric Features::PCA Major axis length"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Minor axis length with Large IBSI Phantom Image", 9.31, results["Volumetric Features::PCA Minor axis length"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Least axis length with Large IBSI Phantom Image", 8.54, results["Volumetric Features::PCA Least axis length"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Elongation with Large IBSI Phantom Image", 0.816, results["Volumetric Features::PCA Elongation"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Flatness with Large IBSI Phantom Image", 0.749, results["Volumetric Features::PCA Flatness"], 0.01); // These values are obtained by running the filter // They might be wrong! CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Voxel Volume with Large IBSI Phantom Image", 8, results["Volumetric Features::Voxel Volume"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Volume (voxel based) with Large IBSI Phantom Image", 592, results["Volumetric Features::Volume (voxel based)"], 0.1); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Surface (voxel based) with Large IBSI Phantom Image", 488, results["Volumetric Features::Surface (voxel based)"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Centre of mass shift (uncorrected) with Large IBSI Phantom Image", 0.672, results["Volumetric Features::Centre of mass shift (uncorrected)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Bounding Box Volume with Large IBSI Phantom Image", 288, results["Volumetric Features::Bounding Box Volume"], 1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Surface to volume ratio (voxel based) with Large IBSI Phantom Image", 0.824, results["Volumetric Features::Surface to volume ratio (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Sphericity (voxel based) with Large IBSI Phantom Image", 0.699, results["Volumetric Features::Sphericity (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Asphericity (voxel based) with Large IBSI Phantom Image", 0.431, results["Volumetric Features::Asphericity (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Compactness 1 (voxel based) with Large IBSI Phantom Image", 0.031, results["Volumetric Features::Compactness 1 (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Compactness 1 old (voxel based) with Large IBSI Phantom Image", 5.388, results["Volumetric Features::Compactness 1 old (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Compactness 2 (voxel based) with Large IBSI Phantom Image", 0.341, results["Volumetric Features::Compactness 2 (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Spherical disproportion (voxel based) with Large IBSI Phantom Image", 1.43, results["Volumetric Features::Spherical disproportion (voxel based)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Major axis length (uncorrected) with Large IBSI Phantom Image", 11.40, results["Volumetric Features::PCA Major axis length (uncorrected)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Minor axis length (uncorrected) with Large IBSI Phantom Image", 9.31, results["Volumetric Features::PCA Minor axis length (uncorrected)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Least axis length (uncorrected) with Large IBSI Phantom Image", 8.54, results["Volumetric Features::PCA Least axis length (uncorrected)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Elongation (uncorrected) with Large IBSI Phantom Image", 0.816, results["Volumetric Features::PCA Elongation (uncorrected)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::PCA Flatness (uncorrected) with Large IBSI Phantom Image", 0.749, results["Volumetric Features::PCA Flatness (uncorrected)"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Volumetric Features::Compactness 1 old (mesh based) with Large IBSI Phantom Image", 6.278, results["Volumetric Features::Compactness 1 old (mesh based)"], 0.01); } }; MITK_TEST_SUITE_REGISTRATION(mitkGIFVolumetricStatistics ) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkGlobalFeaturesTest.cpp b/Modules/Classification/CLUtilities/test/mitkGlobalFeaturesTest.cpp index c4f2f6ac51..23a91b5afb 100644 --- a/Modules/Classification/CLUtilities/test/mitkGlobalFeaturesTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkGlobalFeaturesTest.cpp @@ -1,316 +1,316 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include #include #include #include #include template static mitk::Image::Pointer GenerateMaskImage(unsigned int dimX, unsigned int dimY, unsigned int dimZ, float spacingX = 1, float spacingY = 1, float spacingZ = 1) { typedef itk::Image< TPixelType, 3 > ImageType; typename ImageType::RegionType imageRegion; imageRegion.SetSize(0, dimX); imageRegion.SetSize(1, dimY); imageRegion.SetSize(2, dimZ); typename ImageType::SpacingType spacing; spacing[0] = spacingX; spacing[1] = spacingY; spacing[2] = spacingZ; mitk::Point3D origin; origin.Fill(0.0); itk::Matrix directionMatrix; directionMatrix.SetIdentity(); typename ImageType::Pointer image = ImageType::New(); image->SetSpacing( spacing ); image->SetOrigin( origin ); image->SetDirection( directionMatrix ); image->SetLargestPossibleRegion( imageRegion ); image->SetBufferedRegion( imageRegion ); image->SetRequestedRegion( imageRegion ); image->Allocate(); image->FillBuffer(1); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( image.GetPointer() ); mitkImage->SetVolume( image->GetBufferPointer() ); return mitkImage; } template static mitk::Image::Pointer GenerateGradientWithDimXImage(unsigned int dimX, unsigned int dimY, unsigned int dimZ, float spacingX = 1, float spacingY = 1, float spacingZ = 1) { typedef itk::Image< TPixelType, 3 > ImageType; typename ImageType::RegionType imageRegion; imageRegion.SetSize(0, dimX); imageRegion.SetSize(1, dimY); imageRegion.SetSize(2, dimZ); typename ImageType::SpacingType spacing; spacing[0] = spacingX; spacing[1] = spacingY; spacing[2] = spacingZ; mitk::Point3D origin; origin.Fill(0.0); itk::Matrix directionMatrix; directionMatrix.SetIdentity(); typename ImageType::Pointer image = ImageType::New(); image->SetSpacing( spacing ); image->SetOrigin( origin ); image->SetDirection( directionMatrix ); image->SetLargestPossibleRegion( imageRegion ); image->SetBufferedRegion( imageRegion ); image->SetRequestedRegion( imageRegion ); image->Allocate(); image->FillBuffer(0.0); typedef itk::ImageRegionIterator IteratorOutputType; IteratorOutputType it(image, imageRegion); it.GoToBegin(); TPixelType val = 0; while(!it.IsAtEnd()) { it.Set(val % dimX); val++; ++it; } mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( image.GetPointer() ); mitkImage->SetVolume( image->GetBufferPointer() ); return mitkImage; } class mitkGlobalFeaturesTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkGlobalFeaturesTestSuite ); MITK_TEST(FirstOrder_SinglePoint); MITK_TEST(FirstOrder_QubicArea); //MITK_TEST(RunLenght_QubicArea); MITK_TEST(Coocurrence_QubicArea); //MITK_TEST(TestFirstOrderStatistic); // MITK_TEST(TestThreadedDecisionForest); CPPUNIT_TEST_SUITE_END(); private: typedef itk::Image ImageType; typedef itk::Image MaskType; mitk::Image::Pointer m_Image,m_Mask,m_Mask1; ImageType::Pointer m_ItkImage; MaskType::Pointer m_ItkMask,m_ItkMask1; mitk::Image::Pointer m_GradientImage, m_GradientMask; public: void setUp(void) override { // Load Image Data - m_Image = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + m_Image = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); mitk::CastToItkImage(m_Image,m_ItkImage); // Create a single mask with only one pixel within the regions - mitk::Image::Pointer mask1 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + mitk::Image::Pointer mask1 = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); mitk::CastToItkImage(mask1,m_ItkMask); m_ItkMask->FillBuffer(0); MaskType::IndexType index; index[0]=88;index[1]=81;index[2]=13; m_ItkMask->SetPixel(index, 1); MITK_INFO << "Pixel Value: "<GetPixel(index); mitk::CastToMitkImage(m_ItkMask, m_Mask); // Create a mask with a covered region - mitk::Image::Pointer lmask1 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + mitk::Image::Pointer lmask1 = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); mitk::CastToItkImage(lmask1,m_ItkMask1); m_ItkMask1->FillBuffer(0); int range=2; for (int x = 88-range;x < 88+range+1;++x) { for (int y=81-range;y<81+range+1;++y) { for (int z=13-range;z<13+range+1;++z) { index[0] = x; index[1] = y; index[2] = z; //MITK_INFO << "Pixel: " <GetPixel(index); m_ItkMask1->SetPixel(index, 1); } } } mitk::CastToMitkImage(m_ItkMask1, m_Mask1); m_GradientImage=GenerateGradientWithDimXImage(5,5,5); m_GradientMask = GenerateMaskImage(5,5,5); } void FirstOrder_SinglePoint() { mitk::GIFFirstOrderStatistics::Pointer calculator = mitk::GIFFirstOrderStatistics::New(); //calculator->SetHistogramSize(4096); //calculator->SetUseCtRange(true); auto features = calculator->CalculateFeatures(m_Image, m_Mask); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The range of a single pixel should be 0",0.0, results["FirstOrder Range"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The uniformity of a single pixel should be 1",1.0, results["FirstOrder Uniformity"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The entropy of a single pixel should be 0",0.0, results["FirstOrder Entropy"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Root-Means-Square of a single pixel with (-352) should be 352",352.0, results["FirstOrder RMS"], 0.01); CPPUNIT_ASSERT_EQUAL_MESSAGE("The Kurtosis of a single pixel should be undefined",results["FirstOrder Kurtosis"]==results["FirstOrder Kurtosis"], false); CPPUNIT_ASSERT_EQUAL_MESSAGE("The Skewness of a single pixel should be undefined",results["FirstOrder Skewness"]==results["FirstOrder Skewness"], false); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean absolute deviation of a single pixel with (-352) should be 0",0, results["FirstOrder Mean absolute deviation"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Covered image intensity range of a single pixel with (-352) should be 0",0, results["FirstOrder Covered Image Intensity Range"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Minimum of a single pixel with (-352) should be -352",-352, results["FirstOrder Minimum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Maximum of a single pixel with (-352) should be -352",-352, results["FirstOrder Maximum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean of a single pixel with (-352) should be -352",-352, results["FirstOrder Mean"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Variance (corrected) of a single pixel with (-352) should be 0",0, results["FirstOrder Variance"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Sum of a single pixel with (-352) should be -352",-352, results["FirstOrder Sum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Median of a single pixel with (-352) should be -352",-352, results["FirstOrder Median"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Standard deviation (corrected) of a single pixel with (-352) should be -352",0, results["FirstOrder Standard deviation"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The number of voxels of a single pixel should be 1",1, results["FirstOrder No. of Voxel"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Energy of a single pixel should be 352*352",352*352, results["FirstOrder Energy"], 0.0); // MITK_ASSERT_EQUAL(results["FirstOrder Range"]==0.0,true,"The range of a single pixel should be 0"); } void FirstOrder_QubicArea() { mitk::GIFFirstOrderStatistics::Pointer calculator = mitk::GIFFirstOrderStatistics::New(); //calculator->SetHistogramSize(4096); //calculator->SetUseCtRange(true); auto features = calculator->CalculateFeatures(m_Image, m_Mask1); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The range should be 981",981, results["FirstOrder Range"], 0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Root-Means-Square of a single pixel with (-352) should be 352",402.895778, results["FirstOrder RMS"], 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Minimum of a single pixel with (-352) should be -352",-937, results["FirstOrder Minimum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Maximum of a single pixel with (-352) should be -352",44, results["FirstOrder Maximum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean of a single pixel with (-352) should be -352",-304.448, results["FirstOrder Mean"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Sum of a single pixel with (-352) should be -352",-38056, results["FirstOrder Sum"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Median of a single pixel with (-352) should be -352",-202, results["FirstOrder Median"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The number of voxels of a single pixel should be 1",125, results["FirstOrder No. of Voxel"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Standard deviation (corrected) of a single pixel with (-352) should be -352",264.949066, results["FirstOrder Standard deviation"], 0.000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Energy of a single pixel should be 352*352",20290626, results["FirstOrder Energy"], 0.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The uniformity of a single pixel should be 1",0.0088960, results["FirstOrder Uniformity"], 0.0000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The entropy of a single pixel should be 0",-6.853784285, results["FirstOrder Entropy"], 0.000000005); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Variance (corrected) of a single pixel with (-352) should be 0",70198.0074, results["FirstOrder Variance"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Kurtosis of a single pixel should be 0",2.63480121, results["FirstOrder Kurtosis"], 0.0001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Skewness of a single pixel should be 0",-0.91817318, results["FirstOrder Skewness"], 0.00001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Mean absolute deviation of a single pixel with (-352) should be 0",219.348608, results["FirstOrder Mean absolute deviation"], 0.000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The Covered image intensity range of a single pixel with (-352) should be 0",0.41149329, results["FirstOrder Covered Image Intensity Range"], 0.000001); } void RunLenght_QubicArea() { mitk::GIFGreyLevelRunLength::Pointer calculator = mitk::GIFGreyLevelRunLength::New(); //calculator->SetHistogramSize(4096); auto features = calculator->CalculateFeatures(m_Image, m_Mask1); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } } void Coocurrence_QubicArea() { /* * Expected Matrix: (Direction 0,0,1) * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 0 | 20 | 0 | 0 | 0 | * |------------------------| * | 0 | 0 | 20 | 0 | 0 | * |------------------------| * | 0 | 0 | 0 | 20 | 0 | * |------------------------| * | 0 | 0 | 0 | 0 | 20 | * |------------------------| * Expected Matrix: (Direction (1,0,0),(0,1,0)) * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| * | 20 | 0 | 0 | 0 | 0 | * |------------------------| */ mitk::GIFCooccurenceMatrix::Pointer calculator = mitk::GIFCooccurenceMatrix::New(); //calculator->SetHistogramSize(4096); //calculator->SetUseCtRange(true); //calculator->SetRange(981); calculator->SetDirection(1); auto features = calculator->CalculateFeatures(m_GradientImage, m_GradientMask); std::map results; for (auto iter=features.begin(); iter!=features.end();++iter) { results[(*iter).first]=(*iter).second; MITK_INFO << (*iter).first << " : " << (*iter).second; } CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean energy value should be 0.2",0.2, results["co-occ. (1) Energy Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean entropy value should be 0.2",2.321928, results["co-occ. (1) Entropy Means"], 0.000001); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean contrast value should be 0.0",0, results["co-occ. (1) Contrast Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean dissimilarity value should be 0.0",0, results["co-occ. (1) Dissimilarity Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean homogenity1 value should be 1.0",1, results["co-occ. (1) Homogeneity1 Means"], mitk::eps); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("The mean InverseDifferenceMoment value should be 1.0",1, results["co-occ. (1) InverseDifferenceMoment Means"], mitk::eps); } }; MITK_TEST_SUITE_REGISTRATION(mitkGlobalFeatures) \ No newline at end of file diff --git a/Modules/Classification/CLUtilities/test/mitkSmoothedClassProbabilitesTest.cpp b/Modules/Classification/CLUtilities/test/mitkSmoothedClassProbabilitesTest.cpp index c7f6a8535e..f1e695cb66 100644 --- a/Modules/Classification/CLUtilities/test/mitkSmoothedClassProbabilitesTest.cpp +++ b/Modules/Classification/CLUtilities/test/mitkSmoothedClassProbabilitesTest.cpp @@ -1,94 +1,94 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include class mitkSmoothedClassProbabilitesTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSmoothedClassProbabilitesTestSuite ); MITK_TEST(TrainSVMClassifier); // MITK_TEST(TestThreadedDecisionForest); CPPUNIT_TEST_SUITE_END(); private: typedef itk::Image ImageType; mitk::Image::Pointer p1,p2,p3,pmask; ImageType::Pointer i1,i2,i3,imask; public: void setUp(void) { // Load Image Data - p1 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-0_0.nrrd"))[0].GetPointer()); - p2 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-1_0.nrrd"))[0].GetPointer()); - p3 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-2_0.nrrd"))[0].GetPointer()); - pmask = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/mask.nrrd"))[0].GetPointer()); + p1 = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-0_0.nrrd")); + p2 = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-1_0.nrrd")); + p3 = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/ResultProb_Class-2_0.nrrd")); + pmask = mitk::IOUtil::Load(GetTestDataFilePath("Classification/Algorithm/mask.nrrd")); mitk::CastToItkImage(p1,i1); mitk::CastToItkImage(p2,i2); mitk::CastToItkImage(p3,i3); mitk::CastToItkImage(pmask,imask); } void TrainSVMClassifier() { itk::SmoothedClassProbabilites::Pointer filter = itk::SmoothedClassProbabilites::New(); filter->SetInput(0,i1); filter->SetInput(1,i2); filter->SetInput(2,i3); filter->SetMaskImage(imask); filter->SetSigma(1.0); filter->Update(); mitk::Image::Pointer out; mitk::CastToMitkImage(filter->GetOutput(), out); mitk::IOUtil::Save(out, "/Users/jc/test.nrrd"); } void TestThreadedDecisionForest() { // m_LoadedDecisionForest->SetCollection(m_TrainDatacollection); // m_LoadedDecisionForest->SetModalities(m_Selected_items); // m_LoadedDecisionForest->SetMaskName("ClassMask"); // m_LoadedDecisionForest->SetResultMask("ResultMask"); // m_LoadedDecisionForest->SetResultProb("ResultProb"); // m_LoadedDecisionForest->TestThreaded(); // mitk::DataCollection::Pointer res_col = dynamic_cast(dynamic_cast(m_TrainDatacollection->GetData("Test-Study").GetPointer())->GetData("Test-Subject").GetPointer()); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultMask"),"/Users/jc/res_mask.nrrd"); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultProb_Class-0"),"/Users/jc/res_prob_0.nrrd"); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultProb_Class-1"),"/Users/jc/res_prob_1.nrrd"); // mitk::IOUtil::Save(res_col->GetMitkImage("ResultProb_Class-2"),"/Users/jc/res_prob_2.nrrd"); } }; MITK_TEST_SUITE_REGISTRATION(mitkSmoothedClassProbabilites) diff --git a/Modules/Classification/DataCollection/ReaderWriter/mitkCollectionReader.cpp b/Modules/Classification/DataCollection/ReaderWriter/mitkCollectionReader.cpp index e7c69b2af4..3c387944ba 100644 --- a/Modules/Classification/DataCollection/ReaderWriter/mitkCollectionReader.cpp +++ b/Modules/Classification/DataCollection/ReaderWriter/mitkCollectionReader.cpp @@ -1,392 +1,392 @@ /*=================================================================== 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. ===================================================================*/ #ifdef _MSC_VER # pragma warning (disable : 4996) #endif #include "mitkCollectionReader.h" #include #include //#include #include //XML StateMachine Tags // Objects const std::string COLLECTION = "col"; const std::string SUBCOLLECTION = "subcol"; const std::string DATA = "data"; const std::string ITEM = "item"; // Properties const std::string NAME = "name"; const std::string ID = "id"; const std::string FILEPATH = "description"; const std::string LINK = "link"; static std::string GetName(std::string fileName,std::string suffix) { fileName = QFileInfo(QString::fromStdString(fileName)).fileName().toStdString(); return fileName.substr(0,fileName.length() -suffix.length()-9); // 8 = date length } static std::string GetDate(std::string fileName,std::string suffix) { fileName = QFileInfo(QString::fromStdString(fileName)).fileName().toStdString(); fileName = fileName.substr(fileName.length() - suffix.length()-8,8); // 8 = date length fileName.insert(6,"-"); fileName.insert(4,"-"); return fileName; } mitk::CollectionReader::CollectionReader() : m_Collection(nullptr), m_SubCollection(nullptr), m_DataItemCollection(nullptr), m_ColIgnore(false), m_ItemIgnore(false) { } mitk::CollectionReader::~CollectionReader() { this->Clear(); } /** * @brief Loads the xml file filename and generates the necessary instances. **/ mitk::DataCollection::Pointer mitk::CollectionReader::LoadCollection(const std::string& xmlFileName) { QDir fileName = QFileInfo(xmlFileName.c_str()).absoluteDir(); m_BaseDir = fileName.path().toStdString() + QDir::separator().toLatin1(); this->SetFileName(xmlFileName.c_str()); this->Parse(); if (m_Collection.IsNotNull()) m_Collection->SetXMLFile(xmlFileName); return m_Collection; } void mitk::CollectionReader::AddDataElementIds(std::vector dataElemetIds) { m_SelectedDataItemIds.insert( m_SelectedDataItemIds.end(), dataElemetIds.begin(), dataElemetIds.end() ); } void mitk::CollectionReader::AddSubColIds(std::vector subColIds) { m_SelectedSubColIds.insert( m_SelectedSubColIds.end(), subColIds.begin(), subColIds.end() ); } void mitk::CollectionReader::SetDataItemNames(std::vector itemNames) { m_SelectedDataItemNames = itemNames; } void mitk::CollectionReader::ClearDataElementIds() { m_SelectedDataItemIds.clear(); } void mitk::CollectionReader::ClearSubColIds() { m_SelectedSubColIds.clear(); } void mitk::CollectionReader::Clear() { m_DataItemCollection = nullptr; m_SubCollection = nullptr; m_Collection = nullptr; } mitk::DataCollection::Pointer mitk::CollectionReader::FolderToCollection(std::string folder, std::vector suffixes,std::vector seriesNames, bool allowGaps) { // Parse folder and look up all data, // after sanitation only fully available groups are included (that is all suffixes are found) FileListType fileList = SanitizeFileList(GenerateFileLists(folder, suffixes, allowGaps)); if (fileList.size() <= 0) return nullptr; DataCollection::Pointer collection = DataCollection::New(); collection->SetName(GetName(fileList.at(0).at(0),suffixes.at(0))); for (unsigned int k=0; k < fileList.at(0).size(); ++k) // all groups have the same amount of items, so looking at 0 is ok. { DataCollection::Pointer subCollection = DataCollection::New(); for (unsigned int i=0; i< suffixes.size(); ++i) { - Image::Pointer image = dynamic_cast(IOUtil::Load(fileList.at(i).at(k))[0].GetPointer()); + auto image = IOUtil::Load(fileList.at(i).at(k)); subCollection->AddData(image.GetPointer(),seriesNames.at(i), fileList.at(i).at(k)); } std::string sDate = GetDate(fileList.at(0).at(k),suffixes.at(0)); collection->AddData(subCollection.GetPointer(),sDate,"--"); } return collection; } void mitk::CollectionReader::StartElement(const char* elementName, const char **atts) { std::string name(elementName); if (name == COLLECTION) { m_Collection = DataCollection::New(); std::string colName = ReadXMLStringAttribut(NAME, atts); m_Collection->SetName(colName); } else if (name == SUBCOLLECTION) { m_ColIgnore = false; m_ItemIgnore = false; std::string subColName = ReadXMLStringAttribut(NAME, atts); std::string subColId = ReadXMLStringAttribut(ID, atts); if (m_SelectedSubColIds.size() > 0 && std::find(m_SelectedSubColIds.begin(), m_SelectedSubColIds.end(), subColId) == m_SelectedSubColIds.end() ) { // a) a selection list is provided AND b) the item is not in the list m_ColIgnore = true; return; } // Create subcollection m_SubCollection = DataCollection::New(); m_SubCollection->Init(subColName); } else if (name == DATA) { if (m_ColIgnore) return; std::string dataId = ReadXMLStringAttribut(ID, atts); if (m_SelectedDataItemIds.size() > 0 && std::find(m_SelectedDataItemIds.begin(), m_SelectedDataItemIds.end(), dataId) == m_SelectedDataItemIds.end() ) { // a) a selection list is provided AND b) the item is not in the list m_ItemIgnore = true; return; } m_ItemIgnore = false; std::string dataName = ReadXMLStringAttribut(NAME, atts); m_DataItemCollection = DataCollection::New(); m_DataItemCollection->Init(dataName); } else if (name == ITEM) { if (m_ColIgnore || m_ItemIgnore) return; std::string relativeItemLink = ReadXMLStringAttribut(LINK, atts); std::string itemLink = m_BaseDir + relativeItemLink; std::string itemName = ReadXMLStringAttribut(NAME, atts); // if item names are provided and name is not in list, do not load it if (m_SelectedDataItemNames.size() != 0 && std::find(m_SelectedDataItemNames.begin(), m_SelectedDataItemNames.end(), itemName) == m_SelectedDataItemNames.end() ) return; // Populate Sub-Collection - Image::Pointer image = dynamic_cast(IOUtil::Load(itemLink)[0].GetPointer()); + auto image = IOUtil::Load(itemLink); if (image.IsNotNull()) m_DataItemCollection->AddData(image.GetPointer(),itemName,relativeItemLink); else MITK_ERROR << "File could not be loaded: " << itemLink << ". Wihtin Sub-Collection " << m_SubCollection->GetName() << ", within " << m_DataItemCollection->GetName() ; } else MITK_WARN<< "Malformed description ? -- unknown tag: " << name; } void mitk::CollectionReader::EndElement(const char* elementName) { std::string name(elementName); if (name == SUBCOLLECTION) { if (m_SubCollection.IsNull()) return; if (m_ColIgnore || m_SubCollection->Size() == 0) return; m_Collection->AddData(m_SubCollection.GetPointer(),m_SubCollection->GetName()); m_SubCollection = DataCollection::New(); } if (name == DATA) { if (m_DataItemCollection.IsNull()) return; if (m_DataItemCollection->Size() == 0) return; m_SubCollection->AddData(m_DataItemCollection.GetPointer(),m_DataItemCollection->GetName()); m_DataItemCollection = DataCollection::New(); } } std::string mitk::CollectionReader::ReadXMLStringAttribut(std::string name, const char** atts) { if (atts) { const char** attsIter = atts; while (*attsIter) { if (name == *attsIter) { attsIter++; return *attsIter; } attsIter++; attsIter++; } } return std::string(); } bool mitk::CollectionReader::ReadXMLBooleanAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); std::transform(s.begin(), s.end(), s.begin(), ::toupper); if (s == "TRUE") return true; else return false; } int mitk::CollectionReader::ReadXMLIntegerAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); return atoi(s.c_str()); } mitk::CollectionReader::FileListType mitk::CollectionReader::GenerateFileLists(std::string folder, std::vector suffixes, bool allowGaps) { FileListType fileList; QString qFolder = QString::fromStdString(folder); if (!QFileInfo(qFolder).isDir()) { MITK_ERROR << "Folder does not exist."; return fileList; } // Add vector for each suffix for (unsigned int i=0; i< suffixes.size(); ++i) { std::vector list; fileList.push_back(list); } // if gaps are allowed, file names are build up from reference file (first suffix) // else all lists a file, file by file with regular sorting of the files, // if one suffix has more/less images than the others loading is aborted if (allowGaps) { QDir parseDir; parseDir.setFilter(QDir::Files); parseDir.setPath(qFolder); QStringList filterMorph; filterMorph << "*" + QString::fromStdString( suffixes.at(0) ); parseDir.setNameFilters( filterMorph ); QFileInfoList qFileList = parseDir.entryInfoList(); // now populate lists with files names, non-existing files will be marked with an empty string for (int i = 0; i < qFileList.size(); ++i) { std::string baseFileName = qFileList.at(i).absoluteFilePath().toStdString(); fileList.at(0).push_back( baseFileName ); //check for different suffixes for (unsigned int suffNo=1; suffNo < suffixes.size(); ++suffNo) { std::string derivedFileName = baseFileName.substr(0,baseFileName.length() -suffixes.at(0).length()) + suffixes.at(suffNo); // checking if file exists if (QFileInfo(QString::fromStdString(derivedFileName)).isFile()) fileList.at(suffNo).push_back(derivedFileName); else fileList.at(suffNo).push_back(""); } } } else { int numberOfFiles=-1; for (unsigned int i=0; i< suffixes.size(); ++i) { QDir parseDir; parseDir.setFilter(QDir::Files); parseDir.setPath(qFolder); QStringList filterMorph; filterMorph << "*" + QString::fromStdString( suffixes.at(i) ); parseDir.setNameFilters( filterMorph ); QFileInfoList qFileList = parseDir.entryInfoList(); if (numberOfFiles == -1) numberOfFiles = qFileList.size(); if (numberOfFiles != qFileList.size() ) { MITK_ERROR << "Series contain different number of images. Loading aborting."; fileList.clear(); break; } for (int fileNo=0; fileNo indexRemoval; // Parse through all items and check for empty strings, if one occurs mark this index // for removal. int modalities = list.size(); int timeSteps = list.at(0).size(); MITK_INFO << "Modalities " << modalities; MITK_INFO << "TimeSteps " << timeSteps; if (timeSteps == 0) MITK_ERROR << "No files found. Fatal."; for (int listIndex = 0 ; listIndex < timeSteps; listIndex++) { for (int modalityIndex = 0 ; modalityIndex < modalities; modalityIndex++) { if (list.at(modalityIndex).at(listIndex) == "") { MITK_INFO << "Marked Index " << listIndex << " for removal."; indexRemoval.push_back(listIndex); break; } } } for (int listIndex = indexRemoval.size()-1 ; listIndex >= 0; --listIndex) { for (int i = 0 ; i < modalities; i++) { list.at(i).erase(list.at(i).begin()+indexRemoval.at(listIndex)) ; } } MITK_INFO << "Time Steps after sanitizing: " << list.at(0).size(); return list; } diff --git a/Modules/Classification/DataCollection/Testing/mitkSherwoodTest.cpp b/Modules/Classification/DataCollection/Testing/mitkSherwoodTest.cpp index c77548dcf7..7cf9dbc374 100644 --- a/Modules/Classification/DataCollection/Testing/mitkSherwoodTest.cpp +++ b/Modules/Classification/DataCollection/Testing/mitkSherwoodTest.cpp @@ -1,269 +1,269 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include class mitkSherwoodTestClass { public: std::unique_ptr< mitk::SWForest > m_Forest; mitk::ImageDataCollections m_TrainingData; mitk::ImageDataCollections m_TestData; unsigned int m_NumberOfSets; unsigned int m_NumberOfModalities; unsigned int m_Trees; std::vector m_TrainingDataPaths; std::vector m_TestDataPaths; void LoadForest(std::string path) { m_Forest = mitk::SWForest::ReadFromFile(path); } void SaveForest(std::string path) { m_Forest->PrintToFile(path); } void GenerateTrainingData() { m_TrainingData.SetNumberOfSets(m_NumberOfSets); m_TrainingData.SetNumberOfModalities(m_NumberOfModalities); for (int set = 0; set < m_NumberOfSets; ++set) { for (int modality = 0; modality < m_NumberOfModalities; ++modality) { mitk::Image::Pointer image = mitk::ImageGenerator::GenerateGradientImage(5,5,5); m_TrainingData.AddImage(set,modality, image); } } } void TrainForest() { mitk::SWRandom random; // Definde Training parameters0 mitk::SWTrainingParameters parameters; parameters.NumberOfTrees = m_Trees; parameters.NumberOfCandidateFeatures = 10; parameters.NumberOfCandidateThresholdsPerFeature = 200; parameters.MaxDecisionLevels = 19; parameters.Verbose = false; // mitk::SWTrainingContext trainingContext; trainingContext.SetClasses(4); trainingContext.SetModalities(m_TrainingData.GetNumberOfModalities()); mitk::SWHistogramAggregator hist = trainingContext.GetStatisticsAggregator(); for (int i = 0; i < m_TrainingData.Count(); ++i) { if (m_TrainingData.IsLabeled(i)) { hist.Aggregate(m_TrainingData, i); } } trainingContext.SetStatistic(hist); mitk::SWForestTrainer forestTrainer; mitk::ParallelForestTrainer trainer; trainer.SetTreeNumber(parameters.NumberOfTrees); m_Forest = trainer.TrainForest (random, parameters, trainingContext, m_TrainingData); } void ApplyForest(std::string labelPath, std::string probPath) { typedef itk::Image LabelImageType; typedef itk::Image PropImageType; typedef itk::SWHistogramToImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetForest(m_Forest); filter->SetCollection(m_TestData); filter->SetSet(0); filter->Update(); LabelImageType::Pointer labelImage = filter->GetLabelImage(); PropImageType::Pointer propImage = filter->GetPropabilityImage(); mitk::Image::Pointer mLabelImage = mitk::Image::New(); mitk::Image::Pointer mPropImage = mitk::Image::New(); mitk::CastToMitkImage(labelImage, mLabelImage); mitk::CastToMitkImage(propImage, mPropImage); mitk::IOUtil::Save(mLabelImage, labelPath); mitk::IOUtil::Save(mPropImage, probPath); } void ParseCommandline(int argc, char* argv[]) { m_TrainingDataPaths.clear(); m_TestDataPaths.clear(); for (int i = 0; i < argc; i++) { if ((std::string(argv[i]) == "--trees" || std::string(argv[i]) == "-t") && i < argc-1) { MITK_INFO << "trees"; m_Trees = atoi(argv[i+1]); i++; } if ((std::string(argv[i]) == "--sets" || std::string(argv[i]) == "-s") && i < argc-1) { MITK_INFO << "sets"; m_NumberOfSets = atoi(argv[i+1]); i++; } if ((std::string(argv[i]) == "--modalities" || std::string(argv[i]) == "-m") && i < argc-1) { MITK_INFO << "modalities"; m_NumberOfModalities = atoi(argv[i+1]); i++; } if (std::string(argv[i]) == "--generate-training-data") { MITK_INFO << "generate-training-data"; this->GenerateTrainingData(); } if (std::string(argv[i]) == "--test-equal-training" || (std::string(argv[i]) == "-tet")) { MITK_INFO << "test-equal-training"; m_TestData = m_TrainingData; } if ((std::string(argv[i]) == "--read-forest" || std::string(argv[i]) == "-r") && i < argc-1) { MITK_INFO << "read-forest"; this->LoadForest(argv[i+1]); i++; } if ((std::string(argv[i]) == "--save-forest" || std::string(argv[i]) == "-s") && i < argc-1) { MITK_INFO << "save-forest"; this->SaveForest(argv[i+1]); i++; } if (std::string(argv[i]) == "--train") { MITK_INFO << "train"; m_TrainingData.GetDataPoint(0,0); this->TrainForest(); } if (std::string(argv[i]) == "--apply" && i < argc-2) { MITK_INFO << "apply"; this->ApplyForest(argv[i+1],argv[i+2]); i++;i++; } if (std::string(argv[i]) == "--testdata") { MITK_INFO << "testdata"; m_TestData.SetNumberOfSets(m_NumberOfSets); m_TestData.SetNumberOfModalities(m_NumberOfModalities); for (int set = 0; set < 1; ++set) { for (int modality = 0; modality < m_NumberOfModalities; ++modality) { ++i; if ( i >= argc || argv[i][0] == '-') break; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(argv[i])[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(argv[i]); m_TestData.AddImage(set,modality, image); } if ( i >= argc || argv[i][0] == '-') break; } } if (std::string(argv[i]) == "--traindata") { MITK_INFO << "traindata"; m_TrainingData.SetNumberOfSets(m_NumberOfSets); m_TrainingData.SetNumberOfModalities(m_NumberOfModalities); for (int set = 0; set < m_NumberOfSets; ++set) { for (int modality = 0; modality < m_NumberOfModalities; ++modality) { ++i; if ( i >= argc || argv[i][0] == '-') break; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(argv[i])[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(argv[i]); m_TrainingData.AddImage(set,modality, image); } ++i; if ( i >= argc || argv[i][0] == '-') break; - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(argv[i])[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(argv[i]); m_TrainingData.SetLabelImage(set, image); } } } } }; int mitkSherwoodTest(int argc, char* argv[]) { MITK_TEST_BEGIN("mitkSherwoodTest"); mitkSherwoodTestClass test; test.ParseCommandline(argc,argv); // Basically to test features bool btest = false; if (btest) { typedef itk::Image ImageType; typedef itk::FeatureImageFilter Zikic1FilterType; Zikic1FilterType::Pointer zikic1 = Zikic1FilterType::New(); } MITK_TEST_CONDITION_REQUIRED(true, "Message"); MITK_TEST_END(); MITK_INFO << "Press Key and Enter to leave test"; char ch; std::cin >> ch; } \ No newline at end of file diff --git a/Modules/Core/include/mitkIOUtil.h b/Modules/Core/include/mitkIOUtil.h index 5afe1b38de..878ae54ad0 100644 --- a/Modules/Core/include/mitkIOUtil.h +++ b/Modules/Core/include/mitkIOUtil.h @@ -1,446 +1,428 @@ /*=================================================================== 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 MITKIOUTIL_H #define MITKIOUTIL_H #include #include #include #include #include #include #include #include #include #include namespace us { class ModuleResource; } namespace mitk { /** * \ingroup IO * * \brief A utility class to load and save data from/to the local file system. * * \see QmitkIOUtil */ class MITKCORE_EXPORT IOUtil { public: /**Struct that containes information regarding the current loading process. (e.g. Path that should be loaded, all found readers for the load path,...). It is set be IOUtil and used to pass information via the option callback in load operations. */ struct MITKCORE_EXPORT LoadInfo { LoadInfo(const std::string &path); std::string m_Path; std::vector m_Output; FileReaderSelector m_ReaderSelector; bool m_Cancel; }; /**Struct that is the base class for option callbacks used in load operations. The callback is used by IOUtil, if more than one suitable reader was found or the a reader containes options that can be set. The callback allows to change option settings and select the reader that should be used (via loadInfo). */ struct MITKCORE_EXPORT ReaderOptionsFunctorBase { virtual bool operator()(LoadInfo &loadInfo) const = 0; }; struct MITKCORE_EXPORT SaveInfo { SaveInfo(const BaseData *baseData, const MimeType &mimeType, const std::string &path); bool operator<(const SaveInfo &other) const; /// The BaseData object to save. const BaseData *m_BaseData; /// Contains a set of IFileWriter objects. FileWriterSelector m_WriterSelector; /// The selected mime-type, used to restrict results from FileWriterSelector. MimeType m_MimeType; /// The path to write the BaseData object to. std::string m_Path; /// Flag indicating if sub-sequent save operations are to be canceled. bool m_Cancel; }; /**Struct that is the base class for option callbacks used in save operations. The callback is used by IOUtil, if more than one suitable writer was found or the a writer containes options that can be set. The callback allows to change option settings and select the writer that should be used (via saveInfo). */ struct MITKCORE_EXPORT WriterOptionsFunctorBase { virtual bool operator()(SaveInfo &saveInfo) const = 0; }; /** * Get the file system path where the running executable is located. * * @return The location of the currently running executable, without the filename. */ static std::string GetProgramPath(); /** * Get the default temporary path. * * @return The default path for temporary data. */ static std::string GetTempPath(); /** * Returns the Directory Seperator for the current OS. * * @return the Directory Seperator for the current OS, i.e. "\\" for Windows and "/" otherwise. */ static char GetDirectorySeparator(); /** * Create and open a temporary file. * * This method generates a unique temporary filename from \c templateName, creates * and opens the file using the output stream \c tmpStream and returns the name of * the newly create file. * * The \c templateName argument must contain six consective 'X' characters ("XXXXXX") * and these are replaced with a string that makes the filename unique. * * The file is created with read and write permissions for owner only. * * @param tmpStream The output stream for writing to the temporary file. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(std::ofstream &tmpStream, const std::string &templateName = "XXXXXX", std::string path = std::string()); /** * Create and open a temporary file. * * This method generates a unique temporary filename from \c templateName, creates * and opens the file using the output stream \c tmpStream and the specified open * mode \c mode and returns the name of the newly create file. The open mode is always * OR'd with \begin{code}std::ios_base::out | std::ios_base::trunc\end{code}. * * The \c templateName argument must contain six consective 'X' characters ("XXXXXX") * and these are replaced with a string that makes the filename unique. * * The file is created with read and write permissions for owner only. * * @param tmpStream The output stream for writing to the temporary file. * @param mode The open mode for the temporary file stream. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(std::ofstream &tmpStream, std::ios_base::openmode mode, const std::string &templateName = "XXXXXX", std::string path = std::string()); /** * Creates an empty temporary file. * * This method generates a unique temporary filename from \c templateName and creates * this file. * * The file is created with read and write permissions for owner only. * * --- * This version is potentially unsafe because the created temporary file is not kept open * and could be used by another process between calling this method and opening the returned * file path for reading or writing. * --- * * @return The filename of the created temporary file. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(const std::string &templateName = "XXXXXX", std::string path = std::string()); /** * Create a temporary directory. * * This method generates a uniquely named temporary directory from \c templateName. * The last set of six consecutive 'X' characters in \c templateName is replaced * with a string that makes the directory name unique. * * The directory is created with read, write and executable permissions for owner only. * * @param templateName An optional template for the directory name. * @param path An optional path where the temporary directory should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary directory could not be created. */ static std::string CreateTemporaryDirectory(const std::string &templateName = "XXXXXX", std::string path = std::string()); /** * @brief Load a file into the given DataStorage. * * This method calls Load(const std::vector&, DataStorage&) with a * one-element vector. * * @param path The absolute file name including the file extension. * @param storage A DataStorage object to which the loaded data will be added. * @param optionsCallback Pointer to a callback instance. The callback is used by * the load operation if more the suitable reader was found or the reader has options * that can be set. * @return The set of added DataNode objects. * @throws mitk::Exception if \c path could not be loaded. * * @sa Load(const std::vector&, DataStorage&) */ static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage, const ReaderOptionsFunctorBase *optionsCallback = nullptr); /** * @brief Load a file into the given DataStorage given user defined IFileReader::Options. * * This method calls Load(const std::vector&, DataStorage&) with a * one-element vector. * * @param path The absolute file name including the file extension. * @param options IFileReader option instance that should be used if selected reader * has options. * @param storage A DataStorage object to which the loaded data will be added. * @return The set of added DataNode objects. * @throws mitk::Exception if \c path could not be loaded. * * @sa Load(const std::vector&, DataStorage&) */ static DataStorage::SetOfObjects::Pointer Load(const std::string &path, const IFileReader::Options &options, DataStorage &storage); /** * @brief Load a file and return the loaded data. * * This method calls Load(const std::vector&) with a * one-element vector. * * @param path The absolute file name including the file extension. * @param optionsCallback Pointer to a callback instance. The callback is used by * the load operation if more the suitable reader was found or the reader has options * that can be set. * @return The set of added DataNode objects. * @throws mitk::Exception if \c path could not be loaded. * * @sa Load(const std::vector&, DataStorage&) */ static std::vector Load(const std::string &path, const ReaderOptionsFunctorBase *optionsCallback = nullptr); + template + static typename T::Pointer Load(const std::string& path, const ReaderOptionsFunctorBase *optionsCallback = nullptr) + { + return dynamic_cast(Load(path, optionsCallback).at(0).GetPointer()); + } + /** * @brief Load a file and return the loaded data. * * This method calls Load(const std::vector&) with a * one-element vector. * * @param path The absolute file name including the file extension. * @param options IFileReader option instance that should be used if selected reader * has options. * @return The set of added DataNode objects. * @throws mitk::Exception if \c path could not be loaded. * * @sa Load(const std::vector&, DataStorage&) */ static std::vector Load(const std::string &path, const IFileReader::Options &options); + template + static typename T::Pointer Load(const std::string& path, const IFileReader::Options &options) + { + return dynamic_cast(Load(path, options).at(0).GetPointer()); + } + /** * @brief Loads a list of file paths into the given DataStorage. * * If an entry in \c paths cannot be loaded, this method will continue to load * the remaining entries into \c storage and throw an exception afterwards. * * @param paths A list of absolute file names including the file extension. * @param storage A DataStorage object to which the loaded data will be added. * @param optionsCallback Pointer to a callback instance. The callback is used by * the load operation if more the suitable reader was found or the reader has options * that can be set. * @return The set of added DataNode objects. * @throws mitk::Exception if an entry in \c paths could not be loaded. */ static DataStorage::SetOfObjects::Pointer Load(const std::vector &paths, DataStorage &storage, const ReaderOptionsFunctorBase *optionsCallback = nullptr); static std::vector Load(const std::vector &paths, const ReaderOptionsFunctorBase *optionsCallback = nullptr); - /** - * @brief LoadImage Convenience method to load an arbitrary mitkImage. - * @param path The path to the image including file name and file extension. - * @param optionsCallback Pointer to a callback instance. The callback is used by - * the load operation if more the suitable reader was found or the reader has options - * that can be set. - * @throws mitk::Exception This exception is thrown when the Image is nullptr. - * @return Returns the mitkImage. - */ - static mitk::Image::Pointer LoadImage(const std::string &path, - const ReaderOptionsFunctorBase *optionsCallback = nullptr); - - /** - * @brief LoadSurface Convenience method to load an arbitrary mitkSurface. - * @param path The path to the surface including file name and file extension. - * @param optionsCallback Pointer to a callback instance. The callback is used by - * the load operation if more the suitable reader was found or the reader has options - * that can be set. - * @throws mitk::Exception This exception is thrown when the Surface is nullptr. - * @return Returns the mitkSurface. - */ - static mitk::Surface::Pointer LoadSurface(const std::string &path, - const ReaderOptionsFunctorBase *optionsCallback = nullptr); - - /** - * @brief LoadPointSet Convenience method to load an arbitrary mitkPointSet. - * @param path The path to the pointset including file name and file extension (currently, only .mps is supported). - * @param optionsCallback Pointer to a callback instance. The callback is used by - * the load operation if more the suitable reader was found or the reader has options - * that can be set. - * @throws mitk::Exception This exception is thrown when the PointSet is nullptr. - * @return Returns the mitkPointSet. - */ - static mitk::PointSet::Pointer LoadPointSet(const std::string &path, - const ReaderOptionsFunctorBase *optionsCallback = nullptr); - /** * @brief Loads the contents of a us::ModuleResource and returns the corresponding mitk::BaseData * @param usResource a ModuleResource, representing a BaseData object * @param mode Optional parameter to set the openmode of the stream * @return The set of loaded BaseData objects. \c Should contain either one or zero elements, since a resource * stream * respresents one object. * @throws mitk::Exception if no reader was found for the stream. */ static std::vector Load(const us::ModuleResource &usResource, std::ios_base::openmode mode = std::ios_base::in); + template + static typename T::Pointer Load(const us::ModuleResource &usResource, std::ios_base::openmode mode = std::ios_base::in) + { + return dynamic_cast(Load(usResource, mode).at(0).GetPointer()); + } + /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param path The path to the image including file name and and optional file extension. * If no extension is set, the default extension and mime-type for the * BaseData type of \c data is used. * @throws mitk::Exception if no writer for \c data is available or the writer * is not able to write the image. */ static void Save(const mitk::BaseData *data, const std::string &path); /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param path The path to the image including file name and an optional file extension. * If no extension is set, the default extension and mime-type for the * BaseData type of \c data is used. * @param options The IFileWriter options to use for the selected writer. * @throws mitk::Exception if no writer for \c data is available or the writer * is not able to write the image. */ static void Save(const mitk::BaseData *data, const std::string &path, const IFileWriter::Options &options); /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param mimeType The mime-type to use for writing \c data. * @param path The path to the image including file name and an optional file extension. * @param addExtension If \c true, an extension according to the given \c mimeType * is added to \c path if it does not contain one. If \c path already contains * a file name extension, it is not checked for compatibility with \c mimeType. * * @throws mitk::Exception if no writer for the combination of \c data and \c mimeType is * available or the writer is not able to write the image. */ static void Save(const mitk::BaseData *data, const std::string &mimeType, const std::string &path, bool addExtension = true); /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param mimeType The mime-type to use for writing \c data. * @param path The path to the image including file name and an optional file extension. * @param options Configuration data for the used IFileWriter instance. * @param addExtension If \c true, an extension according to the given \c mimeType * is added to \c path if it does not contain one. If \c path already contains * a file name extension, it is not checked for compatibility with \c mimeType. * * @throws mitk::Exception if no writer for the combination of \c data and \c mimeType is * available or the writer is not able to write the image. */ static void Save(const mitk::BaseData *data, const std::string &mimeType, const std::string &path, const mitk::IFileWriter::Options &options, bool addExtension = true); /** * @brief Use SaveInfo objects to save BaseData instances. * * This is a low-level method for directly working with SaveInfo objects. Usually, * the Save() methods taking a BaseData object as an argument are more appropriate. * * @param saveInfos A list of SaveInfo objects for saving contained BaseData objects. * * @see Save(const mitk::BaseData*, const std::string&) */ static void Save(std::vector &saveInfos); protected: static std::string Load(std::vector &loadInfos, DataStorage::SetOfObjects *nodeResult, DataStorage *ds, const ReaderOptionsFunctorBase *optionsCallback); static std::string Save(const BaseData *data, const std::string &mimeType, const std::string &path, WriterOptionsFunctorBase *optionsCallback, bool addExtension); static std::string Save(std::vector &saveInfos, WriterOptionsFunctorBase *optionsCallback); private: struct Impl; }; } #endif // MITKIOUTIL_H diff --git a/Modules/Core/src/IO/mitkIOUtil.cpp b/Modules/Core/src/IO/mitkIOUtil.cpp index de2ceb9c6d..082c35e44f 100644 --- a/Modules/Core/src/IO/mitkIOUtil.cpp +++ b/Modules/Core/src/IO/mitkIOUtil.cpp @@ -1,1061 +1,1025 @@ /*=================================================================== 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 "mitkIOUtil.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ITK #include // VTK #include #include #include #include #include static std::string GetLastErrorStr() { #ifdef US_PLATFORM_POSIX return std::string(strerror(errno)); #else // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, nullptr); std::string errMsg((LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); return errMsg; #endif } #ifdef US_PLATFORM_WINDOWS #include #include // make the posix flags point to the obsolte bsd types on windows #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #else #include #include #include #endif #include #include static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // A cross-platform version of the mkstemps function static int mkstemps_compat(char *tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary files to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary file. To conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return -1; } /* This is where the Xs start. */ char *XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return -1; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, nullptr); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif for (unsigned int count = 0; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; int fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd >= 0) { errno = savedErrno; return fd; } else if (errno != EEXIST) { return -1; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return -1; } // A cross-platform version of the POSIX mkdtemp function static char *mkdtemps_compat(char *tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary dirs to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary dir. To conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return nullptr; } /* This is where the Xs start. */ char *XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return nullptr; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, nullptr); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif unsigned int count = 0; for (; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; #ifdef US_PLATFORM_WINDOWS int fd = _mkdir(tmpl); //, _S_IREAD | _S_IWRITE | _S_IEXEC); #else int fd = mkdir(tmpl, S_IRUSR | S_IWUSR | S_IXUSR); #endif if (fd >= 0) { errno = savedErrno; return tmpl; } else if (errno != EEXIST) { return nullptr; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return nullptr; } //#endif //************************************************************** // mitk::IOUtil method definitions namespace mitk { struct IOUtil::Impl { struct FixedReaderOptionsFunctor : public ReaderOptionsFunctorBase { FixedReaderOptionsFunctor(const IFileReader::Options &options) : m_Options(options) {} bool operator()(LoadInfo &loadInfo) const override { IFileReader *reader = loadInfo.m_ReaderSelector.GetSelected().GetReader(); if (reader) { reader->SetOptions(m_Options); } return false; } private: const IFileReader::Options &m_Options; }; struct FixedWriterOptionsFunctor : public WriterOptionsFunctorBase { FixedWriterOptionsFunctor(const IFileReader::Options &options) : m_Options(options) {} bool operator()(SaveInfo &saveInfo) const override { IFileWriter *writer = saveInfo.m_WriterSelector.GetSelected().GetWriter(); if (writer) { writer->SetOptions(m_Options); } return false; } private: const IFileWriter::Options &m_Options; }; static BaseData::Pointer LoadBaseDataFromFile(const std::string &path, const ReaderOptionsFunctorBase* optionsCallback = nullptr); static void SetDefaultDataNodeProperties(mitk::DataNode *node, const std::string &filePath = std::string()); }; BaseData::Pointer IOUtil::Impl::LoadBaseDataFromFile(const std::string &path, const ReaderOptionsFunctorBase *optionsCallback) { std::vector baseDataList = Load(path, optionsCallback); // The Load(path) call above should throw an exception if nothing could be loaded assert(!baseDataList.empty()); return baseDataList.front(); } #ifdef US_PLATFORM_WINDOWS std::string IOUtil::GetProgramPath() { char path[512]; std::size_t index = std::string(path, GetModuleFileName(nullptr, path, 512)).find_last_of('\\'); return std::string(path, index); } #elif defined(US_PLATFORM_APPLE) #include std::string IOUtil::GetProgramPath() { char path[512]; uint32_t size = sizeof(path); if (_NSGetExecutablePath(path, &size) == 0) { std::size_t index = std::string(path).find_last_of('/'); std::string strPath = std::string(path, index); // const char* execPath = strPath.c_str(); // mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false); return strPath; } return std::string(); } #else #include #include #include std::string IOUtil::GetProgramPath() { std::stringstream ss; ss << "/proc/" << getpid() << "/exe"; char proc[512] = {0}; ssize_t ch = readlink(ss.str().c_str(), proc, 512); if (ch == -1) return std::string(); std::size_t index = std::string(proc).find_last_of('/'); return std::string(proc, index); } #endif char IOUtil::GetDirectorySeparator() { #ifdef US_PLATFORM_WINDOWS return '\\'; #else return '/'; #endif } std::string IOUtil::GetTempPath() { static std::string result; if (result.empty()) { #ifdef US_PLATFORM_WINDOWS char tempPathTestBuffer[1]; DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer); if (bufferLength == 0) { mitkThrow() << GetLastErrorStr(); } std::vector tempPath(bufferLength); bufferLength = ::GetTempPath(bufferLength, &tempPath[0]); if (bufferLength == 0) { mitkThrow() << GetLastErrorStr(); } result.assign(tempPath.begin(), tempPath.begin() + static_cast(bufferLength)); #else result = "/tmp/"; #endif } return result; } std::string IOUtil::CreateTemporaryFile(const std::string &templateName, std::string path) { ofstream tmpOutputStream; std::string returnValue = CreateTemporaryFile(tmpOutputStream, templateName, path); tmpOutputStream.close(); return returnValue; } std::string IOUtil::CreateTemporaryFile(std::ofstream &f, const std::string &templateName, std::string path) { return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path); } std::string IOUtil::CreateTemporaryFile(std::ofstream &f, std::ios_base::openmode mode, const std::string &templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } path += templateName; std::vector dst_path(path.begin(), path.end()); dst_path.push_back('\0'); std::size_t lastX = path.find_last_of('X'); std::size_t firstX = path.find_last_not_of('X', lastX); int firstNonX = firstX == std::string::npos ? -1 : firstX - 1; while (lastX != std::string::npos && (lastX - firstNonX) < 6) { lastX = path.find_last_of('X', firstX); firstX = path.find_last_not_of('X', lastX); firstNonX = firstX == std::string::npos ? -1 : firstX - 1; } std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; int fd = mkstemps_compat(&dst_path[0], suffixlen); if (fd != -1) { path.assign(dst_path.begin(), dst_path.end() - 1); f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc); close(fd); } else { mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr(); } return path; } std::string IOUtil::CreateTemporaryDirectory(const std::string &templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } path += GetDirectorySeparator() + templateName; std::vector dst_path(path.begin(), path.end()); dst_path.push_back('\0'); std::size_t lastX = path.find_last_of('X'); std::size_t firstX = path.find_last_not_of('X', lastX); int firstNonX = firstX == std::string::npos ? -1 : firstX - 1; while (lastX != std::string::npos && (lastX - firstNonX) < 6) { lastX = path.find_last_of('X', firstX); firstX = path.find_last_not_of('X', lastX); firstNonX = firstX == std::string::npos ? -1 : firstX - 1; } std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; if (mkdtemps_compat(&dst_path[0], suffixlen) == nullptr) { mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr(); } path.assign(dst_path.begin(), dst_path.end() - 1); return path; } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::string &path, DataStorage &storage, const ReaderOptionsFunctorBase *optionsCallback) { std::vector paths; paths.push_back(path); return Load(paths, storage, optionsCallback); } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::string &path, const IFileReader::Options &options, DataStorage &storage) { std::vector loadInfos; loadInfos.push_back(LoadInfo(path)); DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New(); Impl::FixedReaderOptionsFunctor optionsCallback(options); std::string errMsg = Load(loadInfos, nodeResult, &storage, &optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return nodeResult; } std::vector IOUtil::Load(const std::string &path, const ReaderOptionsFunctorBase *optionsCallback) { std::vector paths; paths.push_back(path); return Load(paths, optionsCallback); } std::vector IOUtil::Load(const std::string &path, const IFileReader::Options &options) { std::vector loadInfos; loadInfos.push_back(LoadInfo(path)); Impl::FixedReaderOptionsFunctor optionsCallback(options); std::string errMsg = Load(loadInfos, nullptr, nullptr, &optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return loadInfos.front().m_Output; } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::vector &paths, DataStorage &storage, const ReaderOptionsFunctorBase *optionsCallback) { DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New(); std::vector loadInfos; for (auto loadInfo : paths) { loadInfos.push_back(loadInfo); } std::string errMsg = Load(loadInfos, nodeResult, &storage, optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return nodeResult; } std::vector IOUtil::Load(const std::vector &paths, const ReaderOptionsFunctorBase *optionsCallback) { std::vector result; std::vector loadInfos; for (auto loadInfo : paths) { loadInfos.push_back(loadInfo); } std::string errMsg = Load(loadInfos, nullptr, nullptr, optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } for (std::vector::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd; ++iter) { result.insert(result.end(), iter->m_Output.begin(), iter->m_Output.end()); } return result; } - Image::Pointer IOUtil::LoadImage(const std::string &path, - const ReaderOptionsFunctorBase *optionsCallback) - { - BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path, optionsCallback); - mitk::Image::Pointer image = dynamic_cast(baseData.GetPointer()); - if (image.IsNull()) - { - mitkThrow() << path << " is not a mitk::Image but a " << baseData->GetNameOfClass(); - } - return image; - } - - Surface::Pointer IOUtil::LoadSurface(const std::string &path, - const ReaderOptionsFunctorBase *optionsCallback) - { - BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path, optionsCallback); - mitk::Surface::Pointer surface = dynamic_cast(baseData.GetPointer()); - if (surface.IsNull()) - { - mitkThrow() << path << " is not a mitk::Surface but a " << baseData->GetNameOfClass(); - } - return surface; - } - - PointSet::Pointer IOUtil::LoadPointSet(const std::string &path, - const ReaderOptionsFunctorBase *optionsCallback) - { - BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path, optionsCallback); - mitk::PointSet::Pointer pointset = dynamic_cast(baseData.GetPointer()); - if (pointset.IsNull()) - { - mitkThrow() << path << " is not a mitk::PointSet but a " << baseData->GetNameOfClass(); - } - return pointset; - } - std::string IOUtil::Load(std::vector &loadInfos, DataStorage::SetOfObjects *nodeResult, DataStorage *ds, const ReaderOptionsFunctorBase *optionsCallback) { if (loadInfos.empty()) { return "No input files given"; } int filesToRead = loadInfos.size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2 * filesToRead); std::string errMsg; std::map usedReaderItems; std::vector< std::string > read_files; for (auto &loadInfo : loadInfos) { if(std::find(read_files.begin(), read_files.end(), loadInfo.m_Path) != read_files.end()) continue; std::vector readers = loadInfo.m_ReaderSelector.Get(); if (readers.empty()) { if (!itksys::SystemTools::FileExists(loadInfo.m_Path.c_str())) { errMsg += "File '" + loadInfo.m_Path + "' does not exist\n"; } else { errMsg += "No reader available for '" + loadInfo.m_Path + "'\n"; } continue; } bool callOptionsCallback = readers.size() > 1 || !readers.front().GetReader()->GetOptions().empty(); // check if we already used a reader which should be re-used std::vector currMimeTypes = loadInfo.m_ReaderSelector.GetMimeTypes(); std::string selectedMimeType; for (std::vector::const_iterator mimeTypeIter = currMimeTypes.begin(), mimeTypeIterEnd = currMimeTypes.end(); mimeTypeIter != mimeTypeIterEnd; ++mimeTypeIter) { std::map::const_iterator oldSelectedItemIter = usedReaderItems.find(mimeTypeIter->GetName()); if (oldSelectedItemIter != usedReaderItems.end()) { // we found an already used item for a mime-type which is contained // in the current reader set, check all current readers if there service // id equals the old reader for (std::vector::const_iterator currReaderItem = readers.begin(), currReaderItemEnd = readers.end(); currReaderItem != currReaderItemEnd; ++currReaderItem) { if (currReaderItem->GetMimeType().GetName() == mimeTypeIter->GetName() && currReaderItem->GetServiceId() == oldSelectedItemIter->second.GetServiceId() && currReaderItem->GetConfidenceLevel() >= oldSelectedItemIter->second.GetConfidenceLevel()) { // okay, we used the same reader already, re-use its options selectedMimeType = mimeTypeIter->GetName(); callOptionsCallback = false; loadInfo.m_ReaderSelector.Select(oldSelectedItemIter->second.GetServiceId()); loadInfo.m_ReaderSelector.GetSelected().GetReader()->SetOptions( oldSelectedItemIter->second.GetReader()->GetOptions()); break; } } if (!selectedMimeType.empty()) break; } } if (callOptionsCallback && optionsCallback) { callOptionsCallback = (*optionsCallback)(loadInfo); if (!callOptionsCallback && !loadInfo.m_Cancel) { usedReaderItems.erase(selectedMimeType); FileReaderSelector::Item selectedItem = loadInfo.m_ReaderSelector.GetSelected(); usedReaderItems.insert(std::make_pair(selectedItem.GetMimeType().GetName(), selectedItem)); } } if (loadInfo.m_Cancel) { errMsg += "Reading operation(s) cancelled."; break; } IFileReader *reader = loadInfo.m_ReaderSelector.GetSelected().GetReader(); if (reader == nullptr) { errMsg += "Unexpected nullptr reader."; break; } // Do the actual reading try { DataStorage::SetOfObjects::Pointer nodes; if (ds != nullptr) { nodes = reader->Read(*ds); std::vector< std::string > new_files = reader->GetReadFiles(); read_files.insert( read_files.end(), new_files.begin(), new_files.end() ); } else { nodes = DataStorage::SetOfObjects::New(); std::vector baseData = reader->Read(); for (auto iter = baseData.begin(); iter != baseData.end(); ++iter) { if (iter->IsNotNull()) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(*iter); nodes->InsertElement(nodes->Size(), node); } } std::vector< std::string > new_files = reader->GetReadFiles(); read_files.insert( read_files.end(), new_files.begin(), new_files.end() ); } for (DataStorage::SetOfObjects::ConstIterator nodeIter = nodes->Begin(), nodeIterEnd = nodes->End(); nodeIter != nodeIterEnd; ++nodeIter) { const mitk::DataNode::Pointer &node = nodeIter->Value(); mitk::BaseData::Pointer data = node->GetData(); if (data.IsNull()) { continue; } mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New(loadInfo.m_Path); data->SetProperty("path", pathProp); loadInfo.m_Output.push_back(data); if (nodeResult) { nodeResult->push_back(nodeIter->Value()); } } if (loadInfo.m_Output.empty() || (nodeResult && nodeResult->Size() == 0)) { errMsg += "Unknown read error occurred reading " + loadInfo.m_Path; } } catch (const std::exception &e) { errMsg += "Exception occured when reading file " + loadInfo.m_Path + ":\n" + e.what() + "\n\n"; } mitk::ProgressBar::GetInstance()->Progress(2); --filesToRead; } if (!errMsg.empty()) { MITK_ERROR << errMsg; } mitk::ProgressBar::GetInstance()->Progress(2 * filesToRead); return errMsg; } std::vector IOUtil::Load(const us::ModuleResource &usResource, std::ios_base::openmode mode) { us::ModuleResourceStream resStream(usResource, mode); mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); std::vector mimetypes = mimeTypeProvider->GetMimeTypesForFile(usResource.GetResourcePath()); std::vector data; if (mimetypes.empty()) { mitkThrow() << "No mimetype for resource stream: " << usResource.GetResourcePath(); return data; } mitk::FileReaderRegistry fileReaderRegistry; std::vector> refs = fileReaderRegistry.GetReferences(mimetypes[0]); if (refs.empty()) { mitkThrow() << "No reader available for resource stream: " << usResource.GetResourcePath(); return data; } mitk::IFileReader *reader = fileReaderRegistry.GetReader(refs[0]); reader->SetInput(usResource.GetResourcePath(), &resStream); data = reader->Read(); return data; } void IOUtil::Save(const BaseData *data, const std::string &path) { Save(data, path, IFileWriter::Options()); } void IOUtil::Save(const BaseData *data, const std::string &path, const IFileWriter::Options &options) { Save(data, std::string(), path, options); } void IOUtil::Save(const BaseData *data, const std::string &mimeType, const std::string &path, bool addExtension) { Save(data, mimeType, path, IFileWriter::Options(), addExtension); } void IOUtil::Save(const BaseData *data, const std::string &mimeType, const std::string &path, const IFileWriter::Options &options, bool addExtension) { if ((data == nullptr) || (data->IsEmpty())) mitkThrow() << "BaseData cannotbe null or empty for save methods in IOUtil.h."; std::string errMsg; if (options.empty()) { errMsg = Save(data, mimeType, path, nullptr, addExtension); } else { Impl::FixedWriterOptionsFunctor optionsCallback(options); errMsg = Save(data, mimeType, path, &optionsCallback, addExtension); } if (!errMsg.empty()) { mitkThrow() << errMsg; } } void IOUtil::Save(std::vector &saveInfos) { std::string errMsg = Save(saveInfos, nullptr); if (!errMsg.empty()) { mitkThrow() << errMsg; } } std::string IOUtil::Save(const BaseData *data, const std::string &mimeTypeName, const std::string &path, WriterOptionsFunctorBase *optionsCallback, bool addExtension) { if (path.empty()) { return "No output filename given"; } mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); MimeType mimeType = mimeTypeProvider->GetMimeTypeForName(mimeTypeName); SaveInfo saveInfo(data, mimeType, path); std::string ext = itksys::SystemTools::GetFilenameExtension(path); if (saveInfo.m_WriterSelector.IsEmpty()) { return std::string("No suitable writer found for the current data of type ") + data->GetNameOfClass() + (mimeType.IsValid() ? (std::string(" and mime-type ") + mimeType.GetName()) : std::string()) + (ext.empty() ? std::string() : (std::string(" with extension ") + ext)); } // Add an extension if not already specified if (ext.empty() && addExtension) { saveInfo.m_MimeType.GetExtensions().empty() ? std::string() : "." + saveInfo.m_MimeType.GetExtensions().front(); } std::vector infos; infos.push_back(saveInfo); return Save(infos, optionsCallback); } std::string IOUtil::Save(std::vector &saveInfos, WriterOptionsFunctorBase *optionsCallback) { if (saveInfos.empty()) { return "No data for saving available"; } int filesToWrite = saveInfos.size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2 * filesToWrite); std::string errMsg; std::set usedSaveInfos; for (auto &saveInfo : saveInfos) { const std::string baseDataType = saveInfo.m_BaseData->GetNameOfClass(); std::vector writers = saveInfo.m_WriterSelector.Get(); // Error out if no compatible Writer was found if (writers.empty()) { errMsg += std::string("No writer available for ") + baseDataType + " data.\n"; continue; } bool callOptionsCallback = writers.size() > 1 || !writers[0].GetWriter()->GetOptions().empty(); // check if we already used a writer for this base data type // which should be re-used auto oldSaveInfoIter = usedSaveInfos.find(saveInfo); if (oldSaveInfoIter != usedSaveInfos.end()) { // we previously saved a base data object of the same data with the same mime-type, // check if the same writer is contained in the current writer set and if the // confidence level matches FileWriterSelector::Item oldSelectedItem = oldSaveInfoIter->m_WriterSelector.Get(oldSaveInfoIter->m_WriterSelector.GetSelectedId()); for (std::vector::const_iterator currWriterItem = writers.begin(), currWriterItemEnd = writers.end(); currWriterItem != currWriterItemEnd; ++currWriterItem) { if (currWriterItem->GetServiceId() == oldSelectedItem.GetServiceId() && currWriterItem->GetConfidenceLevel() >= oldSelectedItem.GetConfidenceLevel()) { // okay, we used the same writer already, re-use its options callOptionsCallback = false; saveInfo.m_WriterSelector.Select(oldSaveInfoIter->m_WriterSelector.GetSelectedId()); saveInfo.m_WriterSelector.GetSelected().GetWriter()->SetOptions(oldSelectedItem.GetWriter()->GetOptions()); break; } } } if (callOptionsCallback && optionsCallback) { callOptionsCallback = (*optionsCallback)(saveInfo); if (!callOptionsCallback && !saveInfo.m_Cancel) { usedSaveInfos.erase(saveInfo); usedSaveInfos.insert(saveInfo); } } if (saveInfo.m_Cancel) { errMsg += "Writing operation(s) cancelled."; break; } IFileWriter *writer = saveInfo.m_WriterSelector.GetSelected().GetWriter(); if (writer == nullptr) { errMsg += "Unexpected nullptr writer."; break; } // Do the actual writing try { writer->SetOutputLocation(saveInfo.m_Path); writer->Write(); } catch (const std::exception &e) { errMsg += std::string("Exception occurred when writing to ") + saveInfo.m_Path + ":\n" + e.what() + "\n"; } mitk::ProgressBar::GetInstance()->Progress(2); --filesToWrite; } if (!errMsg.empty()) { MITK_ERROR << errMsg; } mitk::ProgressBar::GetInstance()->Progress(2 * filesToWrite); return errMsg; } // This method can be removed after the deprecated LoadDataNode() method was removed void IOUtil::Impl::SetDefaultDataNodeProperties(DataNode *node, const std::string &filePath) { // path mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New(itksys::SystemTools::GetFilenamePath(filePath)); node->SetProperty(StringProperty::PATH, pathProp); // name already defined? mitk::StringProperty::Pointer nameProp = dynamic_cast(node->GetProperty("name")); if (nameProp.IsNull() || (strcmp(nameProp->GetValue(), "No Name!") == 0)) { // name already defined in BaseData mitk::StringProperty::Pointer baseDataNameProp = dynamic_cast(node->GetData()->GetProperty("name").GetPointer()); if (baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(), "No Name!") == 0)) { // name neither defined in node, nor in BaseData -> name = filename nameProp = mitk::StringProperty::New(itksys::SystemTools::GetFilenameWithoutExtension(filePath)); node->SetProperty("name", nameProp); } else { // name defined in BaseData! nameProp = mitk::StringProperty::New(baseDataNameProp->GetValue()); node->SetProperty("name", nameProp); } } // visibility if (!node->GetProperty("visible")) { node->SetVisibility(true); } } IOUtil::SaveInfo::SaveInfo(const BaseData *baseData, const MimeType &mimeType, const std::string &path) : m_BaseData(baseData), m_WriterSelector(baseData, mimeType.GetName(), path), m_MimeType(mimeType.IsValid() ? mimeType // use the original mime-type : (m_WriterSelector.IsEmpty() ? mimeType // no writer found, use the original invalid mime-type : m_WriterSelector.GetDefault().GetMimeType() // use the found default mime-type )), m_Path(path), m_Cancel(false) { } bool IOUtil::SaveInfo::operator<(const IOUtil::SaveInfo &other) const { int r = strcmp(m_BaseData->GetNameOfClass(), other.m_BaseData->GetNameOfClass()); if (r == 0) { return m_WriterSelector.GetSelected().GetMimeType() < other.m_WriterSelector.GetSelected().GetMimeType(); } return r < 0; } IOUtil::LoadInfo::LoadInfo(const std::string &path) : m_Path(path), m_ReaderSelector(path), m_Cancel(false) {} } diff --git a/Modules/Core/test/DirectOverlayTest.cpp b/Modules/Core/test/DirectOverlayTest.cpp index fa2d31d7d5..efd216fe9e 100644 --- a/Modules/Core/test/DirectOverlayTest.cpp +++ b/Modules/Core/test/DirectOverlayTest.cpp @@ -1,237 +1,237 @@ #include #include #include #include #include #include #include #include #include #include //#include class DirectOverlayTestClass { public: template static void InternalThreshold(const itk::Image *image, mitk::Image::Pointer &output, const double th[]) { typedef itk::Image InputImageType; typedef itk::Image OutputImageType; typedef itk::BinaryThresholdImageFilter BinaryThresholdFilterType; typename BinaryThresholdFilterType::Pointer thresholder = BinaryThresholdFilterType::New(); thresholder->SetInput(image); thresholder->SetLowerThreshold(th[0]); thresholder->SetUpperThreshold(th[1]); thresholder->SetInsideValue(255); thresholder->SetOutsideValue(0); thresholder->Update(); output = mitk::ImportItkImage(thresholder->GetOutput()); // mitk::IOUtil::Save( output, "/tmp/out.nii" ); std::cout << "extra line"; } template static void InternalThreshold2(const itk::Image *image, itk::Image::Pointer &output, const double th[]) { typedef itk::Image InputImageType; typedef itk::Image OutputImageType; typedef itk::BinaryThresholdImageFilter BinaryThresholdFilterType; typename BinaryThresholdFilterType::Pointer thresholder = BinaryThresholdFilterType::New(); thresholder->SetInput(image); thresholder->SetLowerThreshold(th[0]); thresholder->SetUpperThreshold(th[1]); thresholder->SetInsideValue(255); thresholder->SetOutsideValue(0); thresholder->Update(); output = thresholder->GetOutput(); } static void TestOverlay(mitk::Image::Pointer original, mitk::Image::Pointer truth, const double lower, const double upper) { mitk::Image::Pointer overlayImage; const double th[] = {lower, upper}; typedef itk::Image ImageType; ImageType::Pointer itkOverlayImage = ImageType::New(); AccessByItk_2(original, InternalThreshold, overlayImage, th); /* AccessFixedDimensionByItk_2( original, InternalThreshold2, 3, itkOverlayImage, th ); overlayImage = mitk::ImportItkImage( itkOverlayImage ); */ // mitk::IOUtil::Save(truth, "/tmp/truth_TestOverlay.nii"); try { // mitk::Image::Pointer temp = overlayImage; mitk::IOUtil::Save(overlayImage, "/tmp/overlayImage_TestOverlay.nrrd"); } catch (const itk::ExceptionObject &e) { MITK_ERROR << "Save image: exception : " << e.what(); } typedef itk::Image InputImageType; InputImageType::Pointer overlayItk; try { mitk::CastToItkImage(overlayImage, overlayItk); } catch (const mitk::Exception &e) { MITK_ERROR << "(CAST) Catched exception while creating accessor " << e.what(); // MITK_TEST_FAILED_MSG("Exception for ouverlay image"); } /* typedef itk::ImageFileWriter< InputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName("/tmp/overlayITK_TestOverlay.nii"); writer->SetInput(overlayItk); writer->Update(); */ InputImageType::Pointer truthItk; mitk::CastToItkImage(truth, truthItk); bool difference = false; /* try { typedef unsigned int TPixel; itk::ImageRegionConstIteratorWithIndex< InputImageType > iter( truthItk, truthItk->GetLargestPossibleRegion() ); iter.GoToBegin(); mitk::ImagePixelReadAccessor< TPixel, 3 > readAccessor( overlayImage, overlayImage->GetVolumeData(0), mitk::ImageAccessorBase::ExceptionIfLocked ); while( !iter.IsAtEnd() ) { TPixel ref = iter.Get(); TPixel val = readAccessor.GetPixelByIndex( iter.GetIndex() ); difference |= ( ref != val ); //if( difference ) //{ std::cout << iter.GetIndex() << ":" << ref << " ? " << val << "\n"; //} ++iter; } } catch( const mitk::Exception &e) { MITK_ERROR << "Catched exception while creating accessor "<< e.what(); //MITK_TEST_FAILED_MSG("Exception for ouverlay image"); } */ /* typedef itk::Testing::ComparisonImageFilter ComparisonImageFilterType; ComparisonImageFilterType::Pointer comp = ComparisonImageFilterType::New(); comp->SetValidInput(truthItk); comp->SetTestInput(overlayItk); try { comp->Update(); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "ITK Exception: " << e.what(); } */ typedef unsigned int TPixel; itk::ImageRegionConstIteratorWithIndex iter(truthItk, truthItk->GetLargestPossibleRegion()); itk::ImageRegionConstIteratorWithIndex iter2(overlayItk, overlayItk->GetLargestPossibleRegion()); iter.GoToBegin(); unsigned int counter = 0; while (!iter.IsAtEnd() && !iter2.IsAtEnd()) { TPixel ref = iter.Get(); TPixel val = iter2.Get(); if (ref != val) { counter++; // std::cout << iter.GetIndex() << ":" << ref << " ? " << val << "\n"; } ++iter; ++iter2; } std::cout << "Differs in " << counter << "voxels" << std::endl; MITK_TEST_CONDITION_REQUIRED( // comp->GetNumberOfPixelsWithDifferences() == 0, counter == 0, "Comparing overlay with ground truth") } static void TestDirectOverlay(char *in, char *gt, const int lower, const int upper) { - mitk::Image::Pointer original = dynamic_cast(mitk::IOUtil::Load(in)[0].GetPointer()); - mitk::Image::Pointer truth = dynamic_cast(mitk::IOUtil::Load(gt)[0].GetPointer()); + mitk::Image::Pointer original = mitk::IOUtil::Load(in); + mitk::Image::Pointer truth = mitk::IOUtil::Load(gt); if (original.IsNotNull() && original->GetDimension() == 3 && truth.IsNotNull() && truth->GetDimension() == 3 && upper > lower) { TestOverlay(original, truth, lower, upper); } else { MITK_TEST_FAILED_MSG(<< "Invalid parameters"); } } }; int DirectOverlayTest(int argc, char *argv[]) { MITK_TEST_BEGIN("DirectOverlay") MITK_TEST_CONDITION_REQUIRED(argc >= 5, "File to load has been specified on the command line"); unsigned int lower = 0, upper = 0; try { sscanf(argv[3], "%u", &lower); sscanf(argv[4], "%u", &upper); // lower = boost::lexical_cast(argv[3]); // upper = boost::lexical_cast(argv[4]); MITK_INFO << "Got values: " << lower << " : " << upper; } catch (std::exception &e) { MITK_TEST_FAILED_MSG(<< e.what()); } DirectOverlayTestClass::TestDirectOverlay(argv[1], argv[2], lower, upper); MITK_TEST_END() } diff --git a/Modules/Core/test/mitkDataStorageTest.cpp b/Modules/Core/test/mitkDataStorageTest.cpp index 929571597b..5f3970b321 100644 --- a/Modules/Core/test/mitkDataStorageTest.cpp +++ b/Modules/Core/test/mitkDataStorageTest.cpp @@ -1,878 +1,878 @@ /*=================================================================== 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 "mitkColorProperty.h" #include "mitkDataNode.h" #include "mitkGroupTagProperty.h" #include "mitkImage.h" #include "mitkReferenceCountWatcher.h" #include "mitkStringProperty.h" #include "mitkSurface.h" #include "mitkDataStorage.h" #include "mitkIOUtil.h" #include "mitkMessage.h" #include "mitkNodePredicateAnd.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateDimension.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateOr.h" #include "mitkNodePredicateProperty.h" #include "mitkNodePredicateSource.h" #include "mitkStandaloneDataStorage.h" //#include "mitkPicFileReader.h" #include "mitkTestingMacros.h" void TestDataStorage(mitk::DataStorage *ds, std::string filename); namespace mitk { class TestStandaloneDataStorage : public StandaloneDataStorage { public: mitkClassMacro(TestStandaloneDataStorage, mitk::DataStorage); itkFactorylessNewMacro(Self) itkCloneMacro(Self) std::map GetModifiedObserverTags() const { return m_NodeModifiedObserverTags; } std::map GetDeletedObserverTags() const { return m_NodeDeleteObserverTags; } protected: TestStandaloneDataStorage() {} }; } class DSEventReceiver // Helper class for event testing { public: const mitk::DataNode *m_NodeAdded; const mitk::DataNode *m_NodeRemoved; DSEventReceiver() : m_NodeAdded(nullptr), m_NodeRemoved(nullptr) {} void OnAdd(const mitk::DataNode *node) { m_NodeAdded = node; } void OnRemove(const mitk::DataNode *node) { m_NodeRemoved = node; } }; /// /// \brief a class for checking if the datastorage is really thread safe /// /// Therefore it listens to a node contained in the datastorage. when this node /// gets removed and deleted, this class gets informed by calling OnObjectDelete(). /// in OnObjectDelete() an empty node gets added. this must not cause a deadlock /// struct ItkDeleteEventListener { ItkDeleteEventListener(mitk::DataStorage *ds) : m_Node(nullptr), m_DataStorage(ds), m_DeleteObserverTag(0) {} void SetNode(mitk::DataNode *_Node) { if (m_Node) return; m_Node = _Node; itk::MemberCommand::Pointer onObjectDelete = itk::MemberCommand::New(); onObjectDelete->SetCallbackFunction(this, &ItkDeleteEventListener::OnObjectDelete); m_DeleteObserverTag = m_Node->AddObserver(itk::DeleteEvent(), onObjectDelete); } void OnObjectDelete(const itk::Object * /*caller*/, const itk::EventObject &) { mitk::DataNode::Pointer node = mitk::DataNode::New(); m_DataStorage->Add(node); // SHOULD NOT CAUSE A DEADLOCK! m_DataStorage->Remove(node); // tidy up: remove the empty node again m_Node = nullptr; } protected: mitk::DataNode *m_Node; mitk::DataStorage::Pointer m_DataStorage; unsigned int m_DeleteObserverTag; }; //## Documentation //## main testing method //## NOTE: the current Singleton implementation of DataTreeStorage will lead to crashes if a testcase fails //## and therefore mitk::DataStorage::ShutdownSingleton() is not called. int mitkDataStorageTest(int argc, char *argv[]) { MITK_TEST_BEGIN("DataStorageTest"); // muellerm: test observer tag remove mitk::TestStandaloneDataStorage::Pointer testDS = mitk::TestStandaloneDataStorage::New(); mitk::DataNode::Pointer n1 = mitk::DataNode::New(); testDS->Add(n1); MITK_TEST_CONDITION_REQUIRED(testDS->GetModifiedObserverTags().size() == 1, "Testing if modified" " observer was added."); MITK_TEST_CONDITION_REQUIRED(testDS->GetDeletedObserverTags().size() == 1, "Testing if delete" " observer was added."); testDS->Remove(n1); MITK_TEST_CONDITION_REQUIRED(testDS->GetModifiedObserverTags().size() == 0, "Testing if modified" " observer was removed."); MITK_TEST_CONDITION_REQUIRED(testDS->GetDeletedObserverTags().size() == 0, "Testing if delete" " observer was removed."); /* Create StandaloneDataStorage */ MITK_TEST_OUTPUT(<< "Create StandaloneDataStorage : "); mitk::StandaloneDataStorage::Pointer sds; try { sds = mitk::StandaloneDataStorage::New(); MITK_TEST_CONDITION_REQUIRED(sds.IsNotNull(), "Testing Instatiation"); } catch (...) { MITK_TEST_FAILED_MSG(<< "Exception during creation of StandaloneDataStorage"); } MITK_TEST_OUTPUT(<< "Testing StandaloneDataStorage: "); MITK_TEST_CONDITION_REQUIRED(argc > 1, "Testing correct test invocation"); TestDataStorage(sds, argv[1]); // TODO: Add specific StandaloneDataStorage Tests here sds = nullptr; MITK_TEST_END(); } //##Documentation //## @brief Test for the DataStorage class and its associated classes (e.g. the predicate classes) //## This method will be called once for each subclass of DataStorage void TestDataStorage(mitk::DataStorage *ds, std::string filename) { /* DataStorage valid? */ MITK_TEST_CONDITION_REQUIRED(ds != nullptr, "DataStorage valid?"); // Take the ItkImageFile Reader for the .nrrd data format. // (was previously pic which is now deprecated format) - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(filename); // create some DataNodes to fill the ds mitk::DataNode::Pointer n1 = mitk::DataNode::New(); // node with image and name property // mitk::Image::Pointer image = mitk::Image::New(); // unsigned int imageDimensions[] = { 10, 10, 10, 10 }; // mitk::PixelType pt(typeid(int)); // image->Initialize( pt, 4, imageDimensions ); n1->SetData(image); n1->SetProperty("name", mitk::StringProperty::New("Node 1 - Image Node")); mitk::DataStorage::SetOfObjects::Pointer parents1 = mitk::DataStorage::SetOfObjects::New(); mitk::DataNode::Pointer n2 = mitk::DataNode::New(); // node with surface and name and color properties mitk::Surface::Pointer surface = mitk::Surface::New(); n2->SetData(surface); n2->SetProperty("name", mitk::StringProperty::New("Node 2 - Surface Node")); mitk::Color color; color.Set(1.0f, 1.0f, 0.0f); n2->SetColor(color); n2->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New()); mitk::DataStorage::SetOfObjects::Pointer parents2 = mitk::DataStorage::SetOfObjects::New(); parents2->InsertElement(0, n1); // n1 (image node) is source of n2 (surface node) mitk::DataNode::Pointer n3 = mitk::DataNode::New(); // node without data but with name property n3->SetProperty("name", mitk::StringProperty::New("Node 3 - Empty Node")); n3->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New()); n3->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New()); mitk::DataStorage::SetOfObjects::Pointer parents3 = mitk::DataStorage::SetOfObjects::New(); parents3->InsertElement(0, n2); // n2 is source of n3 mitk::DataNode::Pointer n4 = mitk::DataNode::New(); // node without data but with color property n4->SetColor(color); n4->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New()); mitk::DataStorage::SetOfObjects::Pointer parents4 = mitk::DataStorage::SetOfObjects::New(); parents4->InsertElement(0, n2); parents4->InsertElement(1, n3); // n2 and n3 are sources of n4 mitk::DataNode::Pointer n5 = mitk::DataNode::New(); // extra node n5->SetProperty("name", mitk::StringProperty::New("Node 5")); try /* adding objects */ { /* Add an object */ ds->Add(n1, parents1); MITK_TEST_CONDITION_REQUIRED((ds->GetAll()->Size() == 1) && (ds->GetAll()->GetElement(0) == n1), "Testing Adding a new object"); /* Check exception on adding the same object again */ MITK_TEST_OUTPUT(<< "Check exception on adding the same object again: "); MITK_TEST_FOR_EXCEPTION(..., ds->Add(n1, parents1)); MITK_TEST_CONDITION(ds->GetAll()->Size() == 1, "Test if object count is correct after exception"); /* Add an object that has a source object */ ds->Add(n2, parents2); MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 2, "Testing Adding an object that has a source object"); /* Add some more objects needed for further tests */ ds->Add(n3, parents3); // n3 object that has name property and one parent ds->Add(n4, parents4); // n4 object that has color property ds->Add(n5); // n5 has no parents MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 5, "Adding some more objects needed for further tests"); } catch (...) { MITK_TEST_FAILED_MSG(<< "Exeption during object creation"); } try /* object retrieval methods */ { /* Requesting all Objects */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll(); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((stlAll.size() == 5) // check if all tree nodes are in resultset && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()), "Testing GetAll()"); } /* Requesting a named object */ { mitk::NodePredicateProperty::Pointer predicate( mitk::NodePredicateProperty::New("name", mitk::StringProperty::New("Node 2 - Surface Node"))); mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting a named object"); } /* Requesting objects of specific data type */ { mitk::NodePredicateDataType::Pointer predicate(mitk::NodePredicateDataType::New("Image")); mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific data type") } /* Requesting objects of specific dimension */ { mitk::NodePredicateDimension::Pointer predicate(mitk::NodePredicateDimension::New(4)); mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific dimension") } /* Requesting objects with specific data object */ { mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(image)); mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects with specific data object") } /* Requesting objects with nullptr data */ { mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(nullptr)); mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 3) && (std::find(all->begin(), all->end(), n3) != all->end()) && (std::find(all->begin(), all->end(), n4) != all->end()) && (std::find(all->begin(), all->end(), n5) != all->end()), "Requesting objects with nullptr data"); } /* Requesting objects that meet a conjunction criteria */ { mitk::NodePredicateDataType::Pointer p1 = mitk::NodePredicateDataType::New("Surface"); mitk::NodePredicateProperty::Pointer p2 = mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color)); mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New(); predicate->AddPredicate(p1); predicate->AddPredicate(p2); // objects must be of datatype "Surface" and have red color (= n2) const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting objects that meet a conjunction criteria"); } /* Requesting objects that meet a disjunction criteria */ { mitk::NodePredicateDataType::Pointer p1(mitk::NodePredicateDataType::New("Image")); mitk::NodePredicateProperty::Pointer p2( mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color))); mitk::NodePredicateOr::Pointer predicate = mitk::NodePredicateOr::New(); predicate->AddPredicate(p1); predicate->AddPredicate(p2); // objects must be of datatype "Surface" or have red color (= n1, n2, n4) const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); MITK_TEST_CONDITION((all->Size() == 3) && (std::find(all->begin(), all->end(), n1) != all->end()) && (std::find(all->begin(), all->end(), n2) != all->end()) && (std::find(all->begin(), all->end(), n4) != all->end()), "Requesting objects that meet a disjunction criteria"); } /* Requesting objects that do not meet a criteria */ { mitk::ColorProperty::Pointer cp = mitk::ColorProperty::New(color); mitk::NodePredicateProperty::Pointer proppred(mitk::NodePredicateProperty::New("color", cp)); mitk::NodePredicateNot::Pointer predicate(mitk::NodePredicateNot::New(proppred)); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 3) // check if correct objects are in resultset && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()), "Requesting objects that do not meet a criteria"); } /* Requesting *direct* source objects */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, nullptr, true); // Get direct parents of n3 (=n2) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()), "Requesting *direct* source objects"); } /* Requesting *all* source objects */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, nullptr, false); // Get all parents of n3 (= n1 + n2) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 2) && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()), "Requesting *all* source objects"); // check if n1 and n2 are the resultset } /* Requesting *all* sources of object with multiple parents */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, nullptr, false); // Get all parents of n4 (= n1 + n2 + n3) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION( (all->Size() == 3) && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset , "Requesting *all* sources of object with multiple parents"); } /* Requesting *direct* derived objects */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, nullptr, true); // Get direct childs of n1 (=n2) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) // check if n1 is the resultset , "Requesting *direct* derived objects"); } ///* Requesting *direct* derived objects with multiple parents/derivations */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n2, nullptr, true); // Get direct childs of n2 (=n3 + n4) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION( (all->Size() == 2) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n3 is the resultset && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) // check if n4 is the resultset , "Requesting *direct* derived objects with multiple parents/derivations"); } //* Requesting *all* derived objects */ { const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, nullptr, false); // Get all childs of n1 (=n2, n3, n4) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 3) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()), "Requesting *all* derived objects"); } /* Checking for circular source relationships */ { parents1->InsertElement(0, n4); // make n1 derived from n4 (which is derived from n2, which is derived from n1) const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources( n4, nullptr, false); // Get all parents of n4 (= n1 + n2 + n3, not n4 itself and not multiple versions of the nodes!) std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION( (all->Size() == 3) && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset , "Checking for circular source relationships"); } ///* Checking for circular derivation relationships can not be performed, because the internal derivations /// datastructure // can not be accessed from the outside. (Therefore it should not be possible to create these circular relations // */ //* Checking GroupTagProperty */ { mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New(); mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 1", tp)); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 2) // check if n2 and n3 are in resultset && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()), "Checking GroupTagProperty"); } /* Checking GroupTagProperty 2 */ { mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New(); mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 2", tp)); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 2) // check if n3 and n4 are in resultset && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()), "Checking GroupTagProperty 2"); } /* Checking direct sources with condition */ { mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Surface"); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, true); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 1) // check if n2 is in resultset && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()), "checking direct sources with condition"); } /* Checking all sources with condition */ { mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Image"); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 1) // check if n1 is in resultset && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()), "Checking all sources with condition"); } /* Checking all sources with condition with empty resultset */ { mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("VesselTree"); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false); MITK_TEST_CONDITION(all->Size() == 0, "Checking all sources with condition with empty resultset"); // check if resultset is empty } /* Checking direct derivations with condition */ { mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color"); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, true); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 1) // check if n2 is in resultset && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()), "Checking direct derivations with condition"); } /* Checking all derivations with condition */ { mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color"); const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, false); std::vector stlAll = all->CastToSTLConstContainer(); MITK_TEST_CONDITION((all->Size() == 2) // check if n2 and n4 are in resultset && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()), "Checking direct derivations with condition"); } /* Checking named node method */ MITK_TEST_CONDITION(ds->GetNamedNode("Node 2 - Surface Node") == n2, "Checking named node method"); MITK_TEST_CONDITION(ds->GetNamedNode(std::string("Node 2 - Surface Node")) == n2, "Checking named node(std::string) method"); /* Checking named node method with wrong name */ MITK_TEST_CONDITION(ds->GetNamedNode("This name does not exist") == nullptr, "Checking named node method with wrong name"); /* Checking named object method */ MITK_TEST_CONDITION(ds->GetNamedObject("Node 1 - Image Node") == image, "Checking named object method"); MITK_TEST_CONDITION(ds->GetNamedObject(std::string("Node 1 - Image Node")) == image, "Checking named object(std::string) method"); /* Checking named object method with wrong DataType */ MITK_TEST_CONDITION(ds->GetNamedObject("Node 1 - Image Node") == nullptr, "Checking named object method with wrong DataType"); /* Checking named object method with wrong name */ MITK_TEST_CONDITION(ds->GetNamedObject("This name does not exist") == nullptr, "Checking named object method with wrong name"); /* Checking GetNamedDerivedNode with valid name and direct derivation only */ MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 2 - Surface Node", n1, true) == n2, "Checking GetNamedDerivedNode with valid name & direct derivation only"); /* Checking GetNamedDerivedNode with invalid Name and direct derivation only */ MITK_TEST_CONDITION(ds->GetNamedDerivedNode("wrong name", n1, true) == nullptr, "Checking GetNamedDerivedNode with invalid name & direct derivation only"); /* Checking GetNamedDerivedNode with invalid Name and direct derivation only */ MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, false) == n3, "Checking GetNamedDerivedNode with invalid name & direct derivation only"); /* Checking GetNamedDerivedNode with valid Name but direct derivation only */ MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, true) == nullptr, "Checking GetNamedDerivedNode with valid Name but direct derivation only"); /* Checking GetNode with valid predicate */ { mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("Image")); MITK_TEST_CONDITION(ds->GetNode(p) == n1, "Checking GetNode with valid predicate"); } /* Checking GetNode with invalid predicate */ { mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("PointSet")); MITK_TEST_CONDITION(ds->GetNode(p) == nullptr, "Checking GetNode with invalid predicate"); } } // object retrieval methods catch (...) { MITK_TEST_FAILED_MSG(<< "Exeption during object retrieval (GetXXX() Methods)"); } try /* object removal methods */ { /* Checking removal of a node without relations */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); int refCountbeforeDS = watcher->GetReferenceCount(); ds->Add(extra); MITK_TEST_CONDITION(ds->GetNamedNode("extra") == extra, "Adding extra node"); ds->Remove(extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr) && (refCountbeforeDS == watcher->GetReferenceCount()), "Checking removal of a node without relations"); extra = nullptr; } /* Checking removal of a node with a parent */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); int refCountbeforeDS = watcher->GetReferenceCount(); ds->Add(extra, n1); // n1 is parent of extra MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1 , "Adding extra node"); ds->Remove(extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr) && (refCountbeforeDS == watcher->GetReferenceCount()) && (ds->GetDerivations(n1)->Size() == 1), "Checking removal of a node with a parent"); extra = nullptr; } /* Checking removal of a node with two parents */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); int refCountbeforeDS = watcher->GetReferenceCount(); mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New(); p->push_back(n1); p->push_back(n2); ds->Add(extra, p); // n1 and n2 are parents of extra MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1 && (ds->GetDerivations(n2)->Size() == 3), "add extra node"); ds->Remove(extra); MITK_TEST_CONDITION( (ds->GetNamedNode("extra") == nullptr) && (refCountbeforeDS == watcher->GetReferenceCount()) && (ds->GetDerivations(n1)->Size() == 1) // after remove, only n2 should be derived from n1 && (ds->GetDerivations(n2)->Size() == 2) // after remove, only n3 and n4 should be derived from n2 , "Checking removal of a node with two parents"); extra = nullptr; } /* Checking removal of a node with two derived nodes */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); int refCountbeforeDS = watcher->GetReferenceCount(); ds->Add(extra); mitk::DataNode::Pointer d1 = mitk::DataNode::New(); d1->SetProperty("name", mitk::StringProperty::New("d1")); ds->Add(d1, extra); mitk::DataNode::Pointer d2 = mitk::DataNode::New(); d2->SetProperty("name", mitk::StringProperty::New("d2")); ds->Add(d2, extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1") == d1) && (ds->GetNamedNode("d2") == d2) && (ds->GetSources(d1)->Size() == 1) // extra should be source of d1 && (ds->GetSources(d2)->Size() == 1) // extra should be source of d2 && (ds->GetDerivations(extra)->Size() == 2) // d1 and d2 should be derived from extra , "add extra node"); ds->Remove(extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr) && (ds->GetNamedNode("d1") == d1) && (ds->GetNamedNode("d2") == d2) && (refCountbeforeDS == watcher->GetReferenceCount()) && (ds->GetSources(d1)->Size() == 0) // after remove, d1 should not have a source anymore && (ds->GetSources(d2)->Size() == 0) // after remove, d2 should not have a source anymore , "Checking removal of a node with two derived nodes"); extra = nullptr; } /* Checking removal of a node with two parents and two derived nodes */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); mitk::ReferenceCountWatcher::Pointer n1watcher = new mitk::ReferenceCountWatcher(n1); int refCountbeforeDS = watcher->GetReferenceCount(); mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New(); p->push_back(n1); p->push_back(n2); ds->Add(extra, p); // n1 and n2 are parents of extra mitk::DataNode::Pointer d1 = mitk::DataNode::New(); d1->SetProperty("name", mitk::StringProperty::New("d1x")); ds->Add(d1, extra); mitk::DataNode::Pointer d2 = mitk::DataNode::New(); d2->SetProperty("name", mitk::StringProperty::New("d2x")); ds->Add(d2, extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1x") == d1) && (ds->GetNamedNode("d2x") == d2) && (ds->GetSources(d1)->Size() == 1) // extra should be source of d1 && (ds->GetSources(d2)->Size() == 1) // extra should be source of d2 && (ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1 && (ds->GetDerivations(n2)->Size() == 3) // n3, n4 and extra should be derived from n2 && (ds->GetDerivations(extra)->Size() == 2) // d1 and d2 should be derived from extra , "add extra node"); ds->Remove(extra); MITK_TEST_CONDITION( (ds->GetNamedNode("extra") == nullptr) && (ds->GetNamedNode("d1x") == d1) && (ds->GetNamedNode("d2x") == d2) && (refCountbeforeDS == watcher->GetReferenceCount()) && (ds->GetDerivations(n1)->Size() == 1) // after remove, only n2 should be derived from n1 && (ds->GetDerivations(n2)->Size() == 2) // after remove, only n3 and n4 should be derived from n2 && (ds->GetSources(d1)->Size() == 0) // after remove, d1 should not have a source anymore && (ds->GetSources(d2)->Size() == 0) // after remove, d2 should not have a source anymore , "Checking removal of a node with two parents and two derived nodes"); extra = nullptr; } } catch (...) { MITK_TEST_FAILED_MSG(<< "Exeption during object removal methods"); } /* Checking for node is it's own parent exception */ { MITK_TEST_FOR_EXCEPTION_BEGIN(...); mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New(); p->push_back(n1); p->push_back(extra); // extra is parent of extra!!! ds->Add(extra, p); MITK_TEST_FOR_EXCEPTION_END(...); } /* Checking reference count of node after add and remove */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); extra->SetProperty("name", mitk::StringProperty::New("extra")); mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New(); p->push_back(n1); p->push_back(n3); ds->Add(extra, p); extra = nullptr; ds->Remove(ds->GetNamedNode("extra")); MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Checking reference count of node after add and remove"); } /* Checking removal of a node with two derived nodes [ dataStorage->GetDerivations( rootNode )] see bug #3426 */ { mitk::DataNode::Pointer extra = mitk::DataNode::New(); extra->SetProperty("name", mitk::StringProperty::New("extra")); ds->Add(extra); mitk::DataNode::Pointer d1y = mitk::DataNode::New(); d1y->SetProperty("name", mitk::StringProperty::New("d1y")); mitk::ReferenceCountWatcher::Pointer watcherD1y = new mitk::ReferenceCountWatcher(d1y); int refCountbeforeDS = watcherD1y->GetReferenceCount(); ds->Add(d1y, extra); mitk::DataNode::Pointer d2y = mitk::DataNode::New(); d2y->SetProperty("name", mitk::StringProperty::New("d2y")); ds->Add(d2y, extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1y") == d1y) && (ds->GetNamedNode("d2y") == d2y) && (ds->GetSources(d1y)->Size() == 1) // extra should be source of d1y && (ds->GetSources(d2y)->Size() == 1) // extra should be source of d2y && (ds->GetDerivations(extra)->Size() == 2) // d1y and d2y should be derived from extra , "add extra node"); ds->Remove(ds->GetDerivations(extra)); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1y") == nullptr) // d1y should be nullptr now && (ds->GetNamedNode("d2y") == nullptr) // d2y should be nullptr now && (refCountbeforeDS == watcherD1y->GetReferenceCount()), "Checking removal of subset of two derived nodes from one parent node"); ds->Remove(extra); MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr), "Checking removal of a parent node"); extra = nullptr; } /* Checking GetGrouptags() */ { const std::set groupTags = ds->GetGroupTags(); MITK_TEST_CONDITION((groupTags.size() == 2) && (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 1") != groupTags.end()) && (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 2") != groupTags.end()), "Checking GetGrouptags()"); } /* Checking Event handling */ DSEventReceiver listener; try { ds->AddNodeEvent += mitk::MessageDelegate1(&listener, &DSEventReceiver::OnAdd); ds->RemoveNodeEvent += mitk::MessageDelegate1(&listener, &DSEventReceiver::OnRemove); mitk::DataNode::Pointer extra = mitk::DataNode::New(); mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra); ds->Add(extra); MITK_TEST_CONDITION(listener.m_NodeAdded == extra.GetPointer(), "Checking AddEvent"); ds->Remove(extra); MITK_TEST_CONDITION(listener.m_NodeRemoved == extra.GetPointer(), "Checking RemoveEvent"); /* RemoveListener */ ds->AddNodeEvent -= mitk::MessageDelegate1(&listener, &DSEventReceiver::OnAdd); ds->RemoveNodeEvent -= mitk::MessageDelegate1(&listener, &DSEventReceiver::OnRemove); listener.m_NodeAdded = nullptr; listener.m_NodeRemoved = nullptr; ds->Add(extra); ds->Remove(extra); MITK_TEST_CONDITION((listener.m_NodeRemoved == nullptr) && (listener.m_NodeAdded == nullptr), "Checking RemoveListener"); std::cout << "Pointer handling after event handling: " << std::flush; extra = nullptr; // delete reference to the node. its memory should be freed now MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Pointer handling after event handling"); } catch (...) { /* cleanup */ ds->AddNodeEvent -= mitk::MessageDelegate1(&listener, &DSEventReceiver::OnAdd); ds->RemoveNodeEvent -= mitk::MessageDelegate1(&listener, &DSEventReceiver::OnRemove); MITK_TEST_FAILED_MSG(<< "Exception during object removal methods"); } // Checking ComputeBoundingGeometry3D method*/ const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll(); mitk::TimeGeometry::Pointer geometry = ds->ComputeBoundingGeometry3D(); MITK_TEST_CONDITION(geometry->CountTimeSteps() == 4, "Test for number or time steps with ComputeBoundingGeometry()"); mitk::TimeBounds timebounds = geometry->GetTimeBounds(); MITK_TEST_CONDITION((timebounds[0] == 0) && (timebounds[1] == 4), "Test for timebounds with ComputeBoundingGeometry()"); for (unsigned int i = 0; i < geometry->CountTimeSteps(); i++) { mitk::BaseGeometry::Pointer subGeometry = geometry->GetGeometryForTimeStep(i); mitk::TimeBounds bounds = geometry->GetTimeBounds(i); MITK_TEST_CONDITION((bounds[0] == i) && (bounds[1] == i + 1), "Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()"); } geometry = ds->ComputeBoundingGeometry3D(all); MITK_TEST_CONDITION(geometry->CountTimeSteps() == 4, "Test for number or time steps with ComputeBoundingGeometry(allNodes)"); timebounds = geometry->GetTimeBounds(); MITK_TEST_CONDITION((timebounds[0] == 0) && (timebounds[1] == 4), "Test for timebounds with ComputeBoundingGeometry(allNodes)"); for (unsigned int i = 0; i < geometry->CountTimeSteps(); i++) { mitk::BaseGeometry::Pointer subGeometry = geometry->GetGeometryForTimeStep(i); mitk::TimeBounds bounds = geometry->GetTimeBounds(i); MITK_TEST_CONDITION((bounds[0] == i) && (bounds[1] == i + 1), "Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()"); } // test for thread safety of DataStorage try { mitk::StandaloneDataStorage::Pointer standaloneDataStorage = mitk::StandaloneDataStorage::New(); ItkDeleteEventListener listener(standaloneDataStorage); { mitk::DataNode::Pointer emptyNode = mitk::DataNode::New(); mitk::DataNode *pEmptyNode = emptyNode; listener.SetNode(emptyNode); standaloneDataStorage->Add(emptyNode); emptyNode = nullptr; // emptyNode is still alive because standaloneDataStorage // owns it standaloneDataStorage->Remove(pEmptyNode); // this should not freeze the whole thing } } catch (...) { MITK_TEST_FAILED_MSG(<< "Exception during testing DataStorage thread safe"); } /* Clear DataStorage */ ds->Remove(ds->GetAll()); MITK_TEST_CONDITION(ds->GetAll()->Size() == 0, "Checking Clear DataStorage"); } diff --git a/Modules/Core/test/mitkExtractSliceFilterTest.cpp b/Modules/Core/test/mitkExtractSliceFilterTest.cpp index d4a6b7d801..b0193d8cf8 100644 --- a/Modules/Core/test/mitkExtractSliceFilterTest.cpp +++ b/Modules/Core/test/mitkExtractSliceFilterTest.cpp @@ -1,1073 +1,1073 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // use this to create the test volume on the fly #define CREATE_VOLUME // use this to save the created volume //#define SAVE_VOLUME // use this to calculate the error from the sphere mathematical model to our pixel based one //#define CALC_TESTFAILURE_DEVIATION // use this to render an oblique slice through a specified image //#define SHOW_SLICE_IN_RENDER_WINDOW // use this to have infos printed in mbilog //#define EXTRACTOR_DEBUG /*these are the deviations calculated by the function CalcTestFailureDeviation (see for details)*/ #define Testfailure_Deviation_Mean_128 0.853842 #define Testfailure_Deviation_Volume_128 0.145184 #define Testfailure_Deviation_Diameter_128 1.5625 #define Testfailure_Deviation_Mean_256 0.397693 #define Testfailure_Deviation_Volume_256 0.0141357 #define Testfailure_Deviation_Diameter_256 0.78125 #define Testfailure_Deviation_Mean_512 0.205277 #define Testfailure_Deviation_Volume_512 0.01993 #define Testfailure_Deviation_Diameter_512 0.390625 class mitkExtractSliceFilterTestClass { public: static void TestSlice(mitk::PlaneGeometry *planeGeometry, std::string testname) { TestPlane = planeGeometry; TestName = testname; mitk::ScalarType centerCoordValue = TestvolumeSize / 2.0; mitk::ScalarType center[3] = {centerCoordValue, centerCoordValue, centerCoordValue}; mitk::Point3D centerIndex(center); double radius = TestvolumeSize / 4.0; if (TestPlane->Distance(centerIndex) >= radius) return; // outside sphere // feed ExtractSliceFilter mitk::ExtractSliceFilter::Pointer slicer = mitk::ExtractSliceFilter::New(); slicer->SetInput(TestVolume); slicer->SetWorldGeometry(TestPlane); slicer->Update(); MITK_TEST_CONDITION_REQUIRED(slicer->GetOutput() != nullptr, "Extractor returned a slice"); mitk::Image::Pointer reslicedImage = slicer->GetOutput(); AccessFixedDimensionByItk(reslicedImage, TestSphereRadiusByItk, 2); AccessFixedDimensionByItk(reslicedImage, TestSphereAreaByItk, 2); /* double devArea, devDiameter; if(TestvolumeSize == 128.0){ devArea = Testfailure_Deviation_Volume_128; devDiameter = Testfailure_Deviation_Diameter_128; } else if(TestvolumeSize == 256.0){devArea = Testfailure_Deviation_Volume_256; devDiameter = Testfailure_Deviation_Diameter_256;} else if (TestvolumeSize == 512.0){devArea = Testfailure_Deviation_Volume_512; devDiameter = Testfailure_Deviation_Diameter_512;} else{devArea = Testfailure_Deviation_Volume_128; devDiameter = Testfailure_Deviation_Diameter_128;} */ std::string areatestName = TestName.append(" area"); std::string diametertestName = TestName.append(" testing diameter"); // TODO think about the deviation, 1% makes no sense at all MITK_TEST_CONDITION(std::abs(100 - testResults.percentageAreaCalcToPixel) < 1, areatestName); MITK_TEST_CONDITION(std::abs(100 - testResults.percentageRadiusToPixel) < 1, diametertestName); #ifdef EXTRACTOR_DEBUG MITK_INFO << TestName << " >>> " << "planeDistanceToSphereCenter: " << testResults.planeDistanceToSphereCenter; MITK_INFO << "area in pixels: " << testResults.areaInPixel << " <-> area in mm: " << testResults.areaCalculated << " = " << testResults.percentageAreaCalcToPixel << "%"; MITK_INFO << "calculated diameter: " << testResults.diameterCalculated << " <-> diameter in mm: " << testResults.diameterInMM << " <-> diameter in pixel: " << testResults.diameterInPixel << " = " << testResults.percentageRadiusToPixel << "%"; #endif } /* * get the radius of the slice of a sphere based on pixel distance from edge to edge of the circle. */ template static void TestSphereRadiusByItk(itk::Image *inputImage) { typedef itk::Image InputImageType; // set the index to the middle of the image's edge at x and y axis typename InputImageType::IndexType currentIndexX; currentIndexX[0] = (int)(TestvolumeSize / 2.0); currentIndexX[1] = 0; typename InputImageType::IndexType currentIndexY; currentIndexY[0] = 0; currentIndexY[1] = (int)(TestvolumeSize / 2.0); // remember the last pixel value double lastValueX = inputImage->GetPixel(currentIndexX); double lastValueY = inputImage->GetPixel(currentIndexY); // storage for the index marks std::vector indicesX; std::vector indicesY; /*Get four indices on the edge of the circle*/ while (currentIndexX[1] < TestvolumeSize && currentIndexX[0] < TestvolumeSize) { // move x direction currentIndexX[1] += 1; // move y direction currentIndexY[0] += 1; if (inputImage->GetPixel(currentIndexX) > lastValueX) { // mark the current index typename InputImageType::IndexType markIndex; markIndex[0] = currentIndexX[0]; markIndex[1] = currentIndexX[1]; indicesX.push_back(markIndex); } else if (inputImage->GetPixel(currentIndexX) < lastValueX) { // mark the current index typename InputImageType::IndexType markIndex; markIndex[0] = currentIndexX[0]; markIndex[1] = currentIndexX[1] - 1; // value inside the sphere indicesX.push_back(markIndex); } if (inputImage->GetPixel(currentIndexY) > lastValueY) { // mark the current index typename InputImageType::IndexType markIndex; markIndex[0] = currentIndexY[0]; markIndex[1] = currentIndexY[1]; indicesY.push_back(markIndex); } else if (inputImage->GetPixel(currentIndexY) < lastValueY) { // mark the current index typename InputImageType::IndexType markIndex; markIndex[0] = currentIndexY[0]; markIndex[1] = currentIndexY[1] - 1; // value inside the sphere indicesY.push_back(markIndex); } // found both marks? if (indicesX.size() == 2 && indicesY.size() == 2) break; // the new 'last' values lastValueX = inputImage->GetPixel(currentIndexX); lastValueY = inputImage->GetPixel(currentIndexY); } /* *If we are here we found the four marks on the edge of the circle. *For the case our plane is rotated and shifted, we have to calculate the center of the circle, *else the center is the intersection of both straight lines between the marks. *When we have the center, the diameter of the circle will be checked to the reference value(math!). */ // each distance from the first mark of each direction to the center of the straight line between the marks double distanceToCenterX = std::abs(indicesX[0][1] - indicesX[1][1]) / 2.0; // double distanceToCenterY = std::abs(indicesY[0][0] - indicesY[1][0]) / 2.0; // the center of the straight lines typename InputImageType::IndexType centerX; // typename InputImageType::IndexType centerY; centerX[0] = indicesX[0][0]; centerX[1] = indicesX[0][1] + distanceToCenterX; // TODO think about implicit cast to int. this is not the real center of the image, which could be between two // pixels // centerY[0] = indicesY[0][0] + distanceToCenterY; // centerY[1] = inidcesY[0][1]; typename InputImageType::IndexType currentIndex(centerX); lastValueX = inputImage->GetPixel(currentIndex); long sumpixels = 0; std::vector diameterIndices; // move up while (currentIndex[1] < TestvolumeSize) { currentIndex[1] += 1; if (inputImage->GetPixel(currentIndex) != lastValueX) { typename InputImageType::IndexType markIndex; markIndex[0] = currentIndex[0]; markIndex[1] = currentIndex[1] - 1; diameterIndices.push_back(markIndex); break; } sumpixels++; lastValueX = inputImage->GetPixel(currentIndex); } currentIndex[1] -= sumpixels; // move back to center to go in the other direction lastValueX = inputImage->GetPixel(currentIndex); // move down while (currentIndex[1] >= 0) { currentIndex[1] -= 1; if (inputImage->GetPixel(currentIndex) != lastValueX) { typename InputImageType::IndexType markIndex; markIndex[0] = currentIndex[0]; markIndex[1] = currentIndex[1]; // outside sphere because we want to calculate the distance from edge to edge diameterIndices.push_back(markIndex); break; } sumpixels++; lastValueX = inputImage->GetPixel(currentIndex); } /* *Now sumpixels should be the apromximate diameter of the circle. This is checked with the calculated diameter from *the plane transformation(math). */ mitk::Point3D volumeCenter; volumeCenter[0] = volumeCenter[1] = volumeCenter[2] = TestvolumeSize / 2.0; double planeDistanceToSphereCenter = TestPlane->Distance(volumeCenter); double sphereRadius = TestvolumeSize / 4.0; // calculate the radius of the circle cut from the sphere by the plane double diameter = 2.0 * std::sqrt(std::pow(sphereRadius, 2) - std::pow(planeDistanceToSphereCenter, 2)); double percentageRadiusToPixel = 100 / diameter * sumpixels; /* *calculate the radius in mm by the both marks of the center line by using the world coordinates */ // get the points as 3D coordinates mitk::Vector3D diameterPointRight, diameterPointLeft; diameterPointRight[2] = diameterPointLeft[2] = 0.0; diameterPointLeft[0] = diameterIndices[0][0]; diameterPointLeft[1] = diameterIndices[0][1]; diameterPointRight[0] = diameterIndices[1][0]; diameterPointRight[1] = diameterIndices[1][1]; // transform to worldcoordinates TestVolume->GetGeometry()->IndexToWorld(diameterPointLeft, diameterPointLeft); TestVolume->GetGeometry()->IndexToWorld(diameterPointRight, diameterPointRight); // euklidian distance double diameterInMM = ((diameterPointLeft * -1.0) + diameterPointRight).GetNorm(); testResults.diameterInMM = diameterInMM; testResults.diameterCalculated = diameter; testResults.diameterInPixel = sumpixels; testResults.percentageRadiusToPixel = percentageRadiusToPixel; testResults.planeDistanceToSphereCenter = planeDistanceToSphereCenter; } /*brute force the area pixel by pixel*/ template static void TestSphereAreaByItk(itk::Image *inputImage) { typedef itk::Image InputImageType; typedef itk::ImageRegionConstIterator ImageIterator; ImageIterator imageIterator(inputImage, inputImage->GetLargestPossibleRegion()); imageIterator.GoToBegin(); int sumPixelsInArea = 0; while (!imageIterator.IsAtEnd()) { if (inputImage->GetPixel(imageIterator.GetIndex()) == pixelValueSet) sumPixelsInArea++; ++imageIterator; } mitk::Point3D volumeCenter; volumeCenter[0] = volumeCenter[1] = volumeCenter[2] = TestvolumeSize / 2.0; double planeDistanceToSphereCenter = TestPlane->Distance(volumeCenter); double sphereRadius = TestvolumeSize / 4.0; // calculate the radius of the circle cut from the sphere by the plane double radius = std::sqrt(std::pow(sphereRadius, 2) - std::pow(planeDistanceToSphereCenter, 2)); double areaInMM = 3.14159265358979 * std::pow(radius, 2); testResults.areaCalculated = areaInMM; testResults.areaInPixel = sumPixelsInArea; testResults.percentageAreaCalcToPixel = 100 / areaInMM * sumPixelsInArea; } /* * random a voxel. define plane through this voxel. reslice at the plane. compare the pixel vaues of the voxel * in the volume with the pixel value in the resliced image. * there are some indice shifting problems which causes the test to fail for oblique planes. seems like the chosen * worldcoordinate is not corrresponding to the index in the 2D image. and so the pixel values are not the same as * expected. */ static void PixelvalueBasedTest() { /* setup itk image */ typedef itk::Image ImageType; typedef itk::ImageRegionConstIterator ImageIterator; ImageType::Pointer image = ImageType::New(); ImageType::IndexType start; start[0] = start[1] = start[2] = 0; ImageType::SizeType size; size[0] = size[1] = size[2] = 32; ImageType::RegionType imgRegion; imgRegion.SetSize(size); imgRegion.SetIndex(start); image->SetRegions(imgRegion); image->SetSpacing(1.0); image->Allocate(); ImageIterator imageIterator(image, image->GetLargestPossibleRegion()); imageIterator.GoToBegin(); unsigned short pixelValue = 0; // fill the image with distinct values while (!imageIterator.IsAtEnd()) { image->SetPixel(imageIterator.GetIndex(), pixelValue); ++imageIterator; ++pixelValue; } /* end setup itk image */ mitk::Image::Pointer imageInMitk; CastToMitkImage(image, imageInMitk); /*mitk::ImageWriter::Pointer writer = mitk::ImageWriter::New(); writer->SetInput(imageInMitk); std::string file = "C:\\Users\\schroedt\\Desktop\\cube.nrrd"; writer->SetFileName(file); writer->Update();*/ PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Frontal); PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Sagittal); PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Axial); } static void PixelvalueBasedTestByPlane(mitk::Image *imageInMitk, mitk::PlaneGeometry::PlaneOrientation orientation) { typedef itk::Image ImageType; // set the seed of the rand function srand((unsigned)time(nullptr)); /* setup a random orthogonal plane */ int sliceindex = 17; // rand() % 32; bool isFrontside = true; bool isRotated = false; if (orientation == mitk::PlaneGeometry::Axial) { /*isFrontside = false; isRotated = true;*/ } mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); plane->InitializeStandardPlane(imageInMitk->GetGeometry(), orientation, sliceindex, isFrontside, isRotated); mitk::Point3D origin = plane->GetOrigin(); mitk::Vector3D normal; normal = plane->GetNormal(); normal.Normalize(); origin += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 plane->SetOrigin(origin); // we dont need this any more, because we are only testing orthogonal planes /*mitk::Vector3D rotationVector; rotationVector[0] = randFloat(); rotationVector[1] = randFloat(); rotationVector[2] = randFloat(); float degree = randFloat() * 180.0; mitk::RotationOperation* op = new mitk::RotationOperation(mitk::OpROTATE, plane->GetCenter(), rotationVector, degree); plane->ExecuteOperation(op); delete op;*/ /* end setup plane */ /* define a point in the 3D volume. * add the two axis vectors of the plane (each multiplied with a * random number) to the origin. now the two random numbers * become our index coordinates in the 2D image, because the * length of the axis vectors is 1. */ mitk::Point3D planeOrigin = plane->GetOrigin(); mitk::Vector3D axis0, axis1; axis0 = plane->GetAxisVector(0); axis1 = plane->GetAxisVector(1); axis0.Normalize(); axis1.Normalize(); unsigned char n1 = 7; // rand() % 32; unsigned char n2 = 13; // rand() % 32; mitk::Point3D testPoint3DInWorld; testPoint3DInWorld = planeOrigin + (axis0 * n1) + (axis1 * n2); // get the index of the point in the 3D volume ImageType::IndexType testPoint3DInIndex; imageInMitk->GetGeometry()->WorldToIndex(testPoint3DInWorld, testPoint3DInIndex); itk::Index<3> testPoint2DInIndex; /* end define a point in the 3D volume.*/ // do reslicing at the plane mitk::ExtractSliceFilter::Pointer slicer = mitk::ExtractSliceFilter::New(); slicer->SetInput(imageInMitk); slicer->SetWorldGeometry(plane); slicer->Update(); mitk::Image::Pointer slice = slicer->GetOutput(); // Get TestPoiont3D as Index in Slice slice->GetGeometry()->WorldToIndex(testPoint3DInWorld, testPoint2DInIndex); mitk::Point3D p, sliceIndexToWorld, imageIndexToWorld; p[0] = testPoint2DInIndex[0]; p[1] = testPoint2DInIndex[1]; p[2] = testPoint2DInIndex[2]; slice->GetGeometry()->IndexToWorld(p, sliceIndexToWorld); p[0] = testPoint3DInIndex[0]; p[1] = testPoint3DInIndex[1]; p[2] = testPoint3DInIndex[2]; imageInMitk->GetGeometry()->IndexToWorld(p, imageIndexToWorld); itk::Index<2> testPoint2DIn2DIndex; testPoint2DIn2DIndex[0] = testPoint2DInIndex[0]; testPoint2DIn2DIndex[1] = testPoint2DInIndex[1]; typedef mitk::ImagePixelReadAccessor VolumeReadAccessorType; typedef mitk::ImagePixelReadAccessor SliceReadAccessorType; VolumeReadAccessorType VolumeReadAccessor(imageInMitk); SliceReadAccessorType SliceReadAccessor(slice); // compare the pixelvalues of the defined point in the 3D volume with the value of the resliced image unsigned short valueAt3DVolume = VolumeReadAccessor.GetPixelByIndex(testPoint3DInIndex); unsigned short valueAtSlice = SliceReadAccessor.GetPixelByIndex(testPoint2DIn2DIndex); // valueAt3DVolume == valueAtSlice is not always working. because of rounding errors // indices are shifted MITK_TEST_CONDITION(valueAt3DVolume == valueAtSlice, "comparing pixelvalues for orthogonal plane"); vtkSmartPointer imageInVtk = imageInMitk->GetVtkImageData(); vtkSmartPointer sliceInVtk = slice->GetVtkImageData(); double PixelvalueByMitkOutput = sliceInVtk->GetScalarComponentAsDouble(n1, n2, 0, 0); // double valueVTKinImage = imageInVtk->GetScalarComponentAsDouble(testPoint3DInIndex[0], testPoint3DInIndex[1], // testPoint3DInIndex[2], 0); /* Test that everything is working equally if vtkoutput is used instead of the default output * from mitk ImageToImageFilter */ mitk::ExtractSliceFilter::Pointer slicerWithVtkOutput = mitk::ExtractSliceFilter::New(); slicerWithVtkOutput->SetInput(imageInMitk); slicerWithVtkOutput->SetWorldGeometry(plane); slicerWithVtkOutput->SetVtkOutputRequest(true); slicerWithVtkOutput->Update(); vtkSmartPointer vtkImageByVtkOutput = slicerWithVtkOutput->GetVtkOutput(); double PixelvalueByVtkOutput = vtkImageByVtkOutput->GetScalarComponentAsDouble(n1, n2, 0, 0); MITK_TEST_CONDITION(PixelvalueByMitkOutput == PixelvalueByVtkOutput, "testing convertion of image output vtk->mitk by reslicer"); /*================ mbilog outputs ===========================*/ #ifdef EXTRACTOR_DEBUG MITK_INFO << "\n" << "TESTINFO index: " << sliceindex << " orientation: " << orientation << " frontside: " << isFrontside << " rotated: " << isRotated; MITK_INFO << "\n" << "slice index to world: " << sliceIndexToWorld; MITK_INFO << "\n" << "image index to world: " << imageIndexToWorld; MITK_INFO << "\n" << "vtk: slice: " << PixelvalueByMitkOutput << ", image: " << valueVTKinImage; MITK_INFO << "\n" << "testPoint3D InWorld" << testPoint3DInWorld << " is " << testPoint2DInIndex << " in 2D"; MITK_INFO << "\n" << "randoms: " << ((int)n1) << ", " << ((int)n2); MITK_INFO << "\n" << "point is inside plane: " << plane->IsInside(testPoint3DInWorld) << " and volume: " << imageInMitk->GetGeometry()->IsInside(testPoint3DInWorld); MITK_INFO << "\n" << "volume idx: " << testPoint3DInIndex << " = " << valueAt3DVolume; MITK_INFO << "\n" << "volume world: " << testPoint3DInWorld << " = " << valueAt3DVolumeByWorld; MITK_INFO << "\n" << "slice idx: " << testPoint2DInIndex << " = " << valueAtSlice; itk::Index<3> curr; curr[0] = curr[1] = curr[2] = 0; for (int i = 0; i < 32; ++i) { for (int j = 0; j < 32; ++j) { ++curr[1]; if (SliceReadAccessor.GetPixelByIndex(curr) == valueAt3DVolume) { MITK_INFO << "\n" << valueAt3DVolume << " MATCHED mitk " << curr; } } curr[1] = 0; ++curr[0]; } typedef itk::Image Image2DType; Image2DType::Pointer img = Image2DType::New(); CastToItkImage(slice, img); typedef itk::ImageRegionConstIterator Iterator2D; Iterator2D iter(img, img->GetLargestPossibleRegion()); iter.GoToBegin(); while (!iter.IsAtEnd()) { if (img->GetPixel(iter.GetIndex()) == valueAt3DVolume) MITK_INFO << "\n" << valueAt3DVolume << " MATCHED itk " << iter.GetIndex(); ++iter; } #endif // EXTRACTOR_DEBUG } /* random a float value */ static float randFloat() { return (((float)rand() + 1.0) / ((float)RAND_MAX + 1.0)) + (((float)rand() + 1.0) / ((float)RAND_MAX + 1.0)) / ((float)RAND_MAX + 1.0); } /* create a sphere with the size of the given testVolumeSize*/ static void InitializeTestVolume() { #ifdef CREATE_VOLUME // do sphere creation ItkVolumeGeneration(); #ifdef SAVE_VOLUME // save in file mitk::ImageWriter::Pointer writer = mitk::ImageWriter::New(); writer->SetInput(TestVolume); std::string file; std::ostringstream filename; filename << "C:\\home\\schroedt\\MITK\\Modules\\ImageExtraction\\Testing\\Data\\sphere_"; filename << TestvolumeSize; filename << ".nrrd"; file = filename.str(); writer->SetFileName(file); writer->Update(); #endif // SAVE_VOLUME #endif #ifndef CREATE_VOLUME // read from file mitk::StandardFileLocations::Pointer locator = mitk::StandardFileLocations::GetInstance(); std::string filename = locator->FindFile("sphere_512.nrrd.mhd", "Modules/ImageExtraction/Testing/Data"); - TestVolume = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + TestVolume = mitk::IOUtil::Load(filename); #endif #ifdef CALC_TESTFAILURE_DEVIATION // get the TestFailureDeviation in % AccessFixedDimensionByItk(TestVolume, CalcTestFailureDeviation, 3); #endif } // the test result of the sphere reslice struct SliceProperties { double planeDistanceToSphereCenter; double diameterInMM; double diameterInPixel; double diameterCalculated; double percentageRadiusToPixel; double areaCalculated; double areaInPixel; double percentageAreaCalcToPixel; }; static mitk::Image::Pointer TestVolume; static double TestvolumeSize; static mitk::PlaneGeometry::Pointer TestPlane; static std::string TestName; static unsigned char pixelValueSet; static SliceProperties testResults; static double TestFailureDeviation; private: /* * Generate a sphere with a radius of TestvolumeSize / 4.0 */ static void ItkVolumeGeneration() { typedef itk::Image TestVolumeType; typedef itk::ImageRegionConstIterator ImageIterator; TestVolumeType::Pointer sphereImage = TestVolumeType::New(); TestVolumeType::IndexType start; start[0] = start[1] = start[2] = 0; TestVolumeType::SizeType size; size[0] = size[1] = size[2] = TestvolumeSize; TestVolumeType::RegionType imgRegion; imgRegion.SetSize(size); imgRegion.SetIndex(start); sphereImage->SetRegions(imgRegion); sphereImage->SetSpacing(1.0); sphereImage->Allocate(); sphereImage->FillBuffer(0); mitk::Vector3D center; center[0] = center[1] = center[2] = TestvolumeSize / 2.0; double radius = TestvolumeSize / 4.0; double pixelValue = pixelValueSet; ImageIterator imageIterator(sphereImage, sphereImage->GetLargestPossibleRegion()); imageIterator.GoToBegin(); mitk::Vector3D currentVoxelInIndex; while (!imageIterator.IsAtEnd()) { currentVoxelInIndex[0] = imageIterator.GetIndex()[0]; currentVoxelInIndex[1] = imageIterator.GetIndex()[1]; currentVoxelInIndex[2] = imageIterator.GetIndex()[2]; double distanceToCenter = (center + (currentVoxelInIndex * -1.0)).GetNorm(); // if distance to center is smaller then the radius of the sphere if (distanceToCenter < radius) { sphereImage->SetPixel(imageIterator.GetIndex(), pixelValue); } ++imageIterator; } CastToMitkImage(sphereImage, TestVolume); } /* calculate the devation of the voxel object to the mathematical sphere object. * this is use to make a statement about the accuracy of the resliced image, eg. the circle's diameter or area. */ template static void CalcTestFailureDeviation(itk::Image *inputImage) { typedef itk::Image InputImageType; typedef itk::ImageRegionConstIterator ImageIterator; ImageIterator iterator(inputImage, inputImage->GetLargestPossibleRegion()); iterator.GoToBegin(); int volumeInPixel = 0; while (!iterator.IsAtEnd()) { if (inputImage->GetPixel(iterator.GetIndex()) == pixelValueSet) volumeInPixel++; ++iterator; } double diameter = TestvolumeSize / 2.0; double volumeCalculated = (1.0 / 6.0) * 3.14159265358979 * std::pow(diameter, 3); double volumeDeviation = std::abs(100 - (100 / volumeCalculated * volumeInPixel)); typename InputImageType::IndexType index; index[0] = index[1] = TestvolumeSize / 2.0; index[2] = 0; int sumpixels = 0; while (index[2] < TestvolumeSize) { if (inputImage->GetPixel(index) == pixelValueSet) sumpixels++; index[2] += 1; } double diameterDeviation = std::abs(100 - (100 / diameter * sumpixels)); #ifdef DEBUG MITK_INFO << "volume deviation: " << volumeDeviation << " diameter deviation:" << diameterDeviation; #endif mitkExtractSliceFilterTestClass::TestFailureDeviation = (volumeDeviation + diameterDeviation) / 2.0; } }; /*================ #END class ================*/ /*================#BEGIN Instanciation of members ================*/ mitk::Image::Pointer mitkExtractSliceFilterTestClass::TestVolume = mitk::Image::New(); double mitkExtractSliceFilterTestClass::TestvolumeSize = 256.0; mitk::PlaneGeometry::Pointer mitkExtractSliceFilterTestClass::TestPlane = mitk::PlaneGeometry::New(); std::string mitkExtractSliceFilterTestClass::TestName = ""; unsigned char mitkExtractSliceFilterTestClass::pixelValueSet = 255; mitkExtractSliceFilterTestClass::SliceProperties mitkExtractSliceFilterTestClass::testResults = { -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}; double mitkExtractSliceFilterTestClass::TestFailureDeviation = 0.0; /*================ #END Instanciation of members ================*/ /*================ #BEGIN test main ================*/ int mitkExtractSliceFilterTest(int /*argc*/, char * /*argv*/ []) { MITK_TEST_BEGIN("mitkExtractSliceFilterTest") // pixelvalue based testing mitkExtractSliceFilterTestClass::PixelvalueBasedTest(); // initialize sphere test volume mitkExtractSliceFilterTestClass::InitializeTestVolume(); mitk::Vector3D spacing = mitkExtractSliceFilterTestClass::TestVolume->GetGeometry()->GetSpacing(); // the center of the sphere = center of image double sphereCenter = mitkExtractSliceFilterTestClass::TestvolumeSize / 2.0; double planeSize = mitkExtractSliceFilterTestClass::TestvolumeSize; /* axial plane */ mitk::PlaneGeometry::Pointer geometryAxial = mitk::PlaneGeometry::New(); geometryAxial->InitializeStandardPlane( planeSize, planeSize, spacing, mitk::PlaneGeometry::Axial, sphereCenter, false, true); geometryAxial->ChangeImageGeometryConsideringOriginOffset(true); mitk::Point3D origin = geometryAxial->GetOrigin(); mitk::Vector3D normal; normal = geometryAxial->GetNormal(); normal.Normalize(); origin += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 // geometryAxial->SetOrigin(origin); mitkExtractSliceFilterTestClass::TestSlice(geometryAxial, "Testing axial plane"); /* end axial plane */ /* sagittal plane */ mitk::PlaneGeometry::Pointer geometrySagital = mitk::PlaneGeometry::New(); geometrySagital->InitializeStandardPlane( planeSize, planeSize, spacing, mitk::PlaneGeometry::Sagittal, sphereCenter, true, false); geometrySagital->ChangeImageGeometryConsideringOriginOffset(true); origin = geometrySagital->GetOrigin(); normal = geometrySagital->GetNormal(); normal.Normalize(); origin += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 // geometrySagital->SetOrigin(origin); mitkExtractSliceFilterTestClass::TestSlice(geometrySagital, "Testing sagittal plane"); /* sagittal plane */ /* sagittal shifted plane */ mitk::PlaneGeometry::Pointer geometrySagitalShifted = mitk::PlaneGeometry::New(); geometrySagitalShifted->InitializeStandardPlane( planeSize, planeSize, spacing, mitk::PlaneGeometry::Sagittal, (sphereCenter - 14), true, false); geometrySagitalShifted->ChangeImageGeometryConsideringOriginOffset(true); origin = geometrySagitalShifted->GetOrigin(); normal = geometrySagitalShifted->GetNormal(); normal.Normalize(); origin += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 // geometrySagitalShifted->SetOrigin(origin); mitkExtractSliceFilterTestClass::TestSlice(geometrySagitalShifted, "Testing sagittal plane shifted"); /* end sagittal shifted plane */ /* coronal plane */ mitk::PlaneGeometry::Pointer geometryCoronal = mitk::PlaneGeometry::New(); geometryCoronal->InitializeStandardPlane( planeSize, planeSize, spacing, mitk::PlaneGeometry::Frontal, sphereCenter, true, false); geometryCoronal->ChangeImageGeometryConsideringOriginOffset(true); origin = geometryCoronal->GetOrigin(); normal = geometryCoronal->GetNormal(); normal.Normalize(); origin += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 // geometryCoronal->SetOrigin(origin); mitkExtractSliceFilterTestClass::TestSlice(geometryCoronal, "Testing coronal plane"); /* end coronal plane */ /* oblique plane */ mitk::PlaneGeometry::Pointer obliquePlane = mitk::PlaneGeometry::New(); obliquePlane->InitializeStandardPlane( planeSize, planeSize, spacing, mitk::PlaneGeometry::Sagittal, sphereCenter, true, false); obliquePlane->ChangeImageGeometryConsideringOriginOffset(true); origin = obliquePlane->GetOrigin(); normal = obliquePlane->GetNormal(); normal.Normalize(); origin += normal * 0.5; // pixelspacing is 1, so half the spacing is 0.5 // obliquePlane->SetOrigin(origin); mitk::Vector3D rotationVector; rotationVector[0] = 0.2; rotationVector[1] = 0.4; rotationVector[2] = 0.62; float degree = 37.0; mitk::RotationOperation *op = new mitk::RotationOperation(mitk::OpROTATE, obliquePlane->GetCenter(), rotationVector, degree); obliquePlane->ExecuteOperation(op); delete op; mitkExtractSliceFilterTestClass::TestSlice(obliquePlane, "Testing oblique plane"); /* end oblique plane */ #ifdef SHOW_SLICE_IN_RENDER_WINDOW /*================ #BEGIN vtk render code ================*/ // set reslicer for renderwindow - mitk::Image::Pointer pic = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer pic = mitk::IOUtil::Load(filename); vtkSmartPointer slicer = vtkSmartPointer::New(); slicer->SetInput(pic->GetVtkImageData()); mitk::PlaneGeometry::Pointer obliquePl = mitk::PlaneGeometry::New(); obliquePl->InitializeStandardPlane( pic->GetGeometry(), mitk::PlaneGeometry::Sagittal, pic->GetGeometry()->GetCenter()[0], true, false); obliquePl->ChangeImageGeometryConsideringOriginOffset(true); mitk::Point3D origin2 = obliquePl->GetOrigin(); mitk::Vector3D n; n = obliquePl->GetNormal(); n.Normalize(); origin2 += n * 0.5; // pixelspacing is 1, so half the spacing is 0.5 obliquePl->SetOrigin(origin2); mitk::Vector3D rotation; rotation[0] = 0.534307; rotation[1] = 0.000439605; rotation[2] = 0.423017; MITK_INFO << rotation; mitk::RotationOperation *operation = new mitk::RotationOperation(mitk::OpROTATE, obliquePl->GetCenter(), rotationVector, degree); obliquePl->ExecuteOperation(operation); delete operation; double origin[3]; origin[0] = obliquePl->GetOrigin()[0]; origin[1] = obliquePl->GetOrigin()[1]; origin[2] = obliquePl->GetOrigin()[2]; slicer->SetResliceAxesOrigin(origin); mitk::Vector3D right, bottom, normal; right = obliquePl->GetAxisVector(0); bottom = obliquePl->GetAxisVector(1); normal = obliquePl->GetNormal(); right.Normalize(); bottom.Normalize(); normal.Normalize(); double cosines[9]; mitk::vnl2vtk(right.GetVnlVector(), cosines); // x mitk::vnl2vtk(bottom.GetVnlVector(), cosines + 3); // y mitk::vnl2vtk(normal.GetVnlVector(), cosines + 6); // n slicer->SetResliceAxesDirectionCosines(cosines); slicer->SetOutputDimensionality(2); slicer->Update(); // set vtk renderwindow vtkSmartPointer vtkPlane = vtkSmartPointer::New(); vtkPlane->SetOrigin(0.0, 0.0, 0.0); // These two points define the axes of the plane in combination with the origin. // Point 1 is the x-axis and point 2 the y-axis. // Each plane is transformed according to the view (axial, coronal and saggital) afterwards. vtkPlane->SetPoint1(1.0, 0.0, 0.0); // P1: (xMax, yMin, depth) vtkPlane->SetPoint2(0.0, 1.0, 0.0); // P2: (xMin, yMax, depth) // these are not the correct values for all slices, only a square plane by now vtkSmartPointer imageMapper = vtkSmartPointer::New(); imageMapper->SetInputConnection(vtkPlane->GetOutputPort()); vtkSmartPointer lookupTable = vtkSmartPointer::New(); // built a default lookuptable lookupTable->SetRampToLinear(); lookupTable->SetSaturationRange(0.0, 0.0); lookupTable->SetHueRange(0.0, 0.0); lookupTable->SetValueRange(0.0, 1.0); lookupTable->Build(); // map all black values to transparent lookupTable->SetTableValue(0, 0.0, 0.0, 0.0, 0.0); lookupTable->SetRange(-255.0, 255.0); // lookupTable->SetRange(-1022.0, 1184.0);//pic3D range vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInput(slicer->GetOutput()); texture->SetLookupTable(lookupTable); texture->SetMapColorScalarsThroughLookupTable(true); vtkSmartPointer imageActor = vtkSmartPointer::New(); imageActor->SetMapper(imageMapper); imageActor->SetTexture(texture); // Setup renderers vtkSmartPointer renderer = vtkSmartPointer::New(); renderer->AddActor(imageActor); // Setup render window vtkSmartPointer renderWindow = vtkSmartPointer::New(); renderWindow->AddRenderer(renderer); // Setup render window interactor vtkSmartPointer renderWindowInteractor = vtkSmartPointer::New(); vtkSmartPointer style = vtkSmartPointer::New(); renderWindowInteractor->SetInteractorStyle(style); // Render and start interaction renderWindowInteractor->SetRenderWindow(renderWindow); // renderer->AddViewProp(imageActor); renderWindow->Render(); renderWindowInteractor->Start(); // always end with this! /*================ #END vtk render code ================*/ #endif // SHOW_SLICE_IN_RENDER_WINDOW MITK_TEST_END() } diff --git a/Modules/Core/test/mitkIOUtilTest.cpp b/Modules/Core/test/mitkIOUtilTest.cpp index 7c9886057e..dc057908fa 100644 --- a/Modules/Core/test/mitkIOUtilTest.cpp +++ b/Modules/Core/test/mitkIOUtilTest.cpp @@ -1,235 +1,235 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include class mitkIOUtilTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkIOUtilTestSuite); MITK_TEST(TestTempMethods); MITK_TEST(TestSaveEmptyData); MITK_TEST(TestLoadAndSaveImage); MITK_TEST(TestNullLoad); MITK_TEST(TestNullSave); MITK_TEST(TestLoadAndSavePointSet); MITK_TEST(TestLoadAndSaveSurface); MITK_TEST(TestTempMethodsForUniqueFilenames); MITK_TEST(TestTempMethodsForUniqueFilenames); CPPUNIT_TEST_SUITE_END(); private: std::string m_ImagePath; std::string m_SurfacePath; std::string m_PointSetPath; public: void setUp() override { m_ImagePath = GetTestDataFilePath("Pic3D.nrrd"); m_SurfacePath = GetTestDataFilePath("binary.stl"); m_PointSetPath = GetTestDataFilePath("pointSet.mps"); } void TestSaveEmptyData() { mitk::Surface::Pointer data = mitk::Surface::New(); CPPUNIT_ASSERT_THROW(mitk::IOUtil::Save(data, "/tmp/dummy"), mitk::Exception); } void TestTempMethods() { std::string tmpPath = mitk::IOUtil::GetTempPath(); CPPUNIT_ASSERT(!tmpPath.empty()); std::ofstream tmpFile; std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpFile); CPPUNIT_ASSERT(tmpFile && tmpFile.is_open()); CPPUNIT_ASSERT(tmpFilePath.size() > tmpPath.size()); CPPUNIT_ASSERT(tmpFilePath.substr(0, tmpPath.size()) == tmpPath); tmpFile.close(); CPPUNIT_ASSERT(std::remove(tmpFilePath.c_str()) == 0); std::string programPath = mitk::IOUtil::GetProgramPath(); CPPUNIT_ASSERT(!programPath.empty()); std::ofstream tmpFile2; std::string tmpFilePath2 = mitk::IOUtil::CreateTemporaryFile(tmpFile2, "my-XXXXXX", programPath); CPPUNIT_ASSERT(tmpFile2 && tmpFile2.is_open()); CPPUNIT_ASSERT(tmpFilePath2.size() > programPath.size()); CPPUNIT_ASSERT(tmpFilePath2.substr(0, programPath.size()) == programPath); tmpFile2.close(); CPPUNIT_ASSERT(std::remove(tmpFilePath2.c_str()) == 0); std::ofstream tmpFile3; std::string tmpFilePath3 = mitk::IOUtil::CreateTemporaryFile(tmpFile3, std::ios_base::binary, "my-XXXXXX.TXT", programPath); CPPUNIT_ASSERT(tmpFile3 && tmpFile3.is_open()); CPPUNIT_ASSERT(tmpFilePath3.size() > programPath.size()); CPPUNIT_ASSERT(tmpFilePath3.substr(0, programPath.size()) == programPath); CPPUNIT_ASSERT(tmpFilePath3.substr(tmpFilePath3.size() - 13, 3) == "my-"); CPPUNIT_ASSERT(tmpFilePath3.substr(tmpFilePath3.size() - 4) == ".TXT"); tmpFile3.close(); // CPPUNIT_ASSERT(std::remove(tmpFilePath3.c_str()) == 0) std::string tmpFilePath4 = mitk::IOUtil::CreateTemporaryFile(); std::ofstream file; file.open(tmpFilePath4.c_str()); CPPUNIT_ASSERT_MESSAGE("Testing if file exists after CreateTemporaryFile()", file.is_open()); CPPUNIT_ASSERT_THROW(mitk::IOUtil::CreateTemporaryFile(tmpFile2, "XX"), mitk::Exception); std::string tmpDir = mitk::IOUtil::CreateTemporaryDirectory(); CPPUNIT_ASSERT(tmpDir.size() > tmpPath.size()); CPPUNIT_ASSERT(tmpDir.substr(0, tmpPath.size()) == tmpPath); CPPUNIT_ASSERT(itksys::SystemTools::RemoveADirectory(tmpDir.c_str())); std::string tmpDir2 = mitk::IOUtil::CreateTemporaryDirectory("my-XXXXXX", programPath); CPPUNIT_ASSERT(tmpDir2.size() > programPath.size()); CPPUNIT_ASSERT(tmpDir2.substr(0, programPath.size()) == programPath); CPPUNIT_ASSERT(itksys::SystemTools::RemoveADirectory(tmpDir2.c_str())); } void TestTempMethodsForUniqueFilenames() { int numberOfFiles = 100; // create 100 empty files std::vector v100filenames; for (int i = 0; i < numberOfFiles; i++) { v100filenames.push_back(mitk::IOUtil::CreateTemporaryFile()); } // check if all of them are unique for (int i = 0; i < numberOfFiles; i++) for (int j = 0; j < numberOfFiles; j++) { if (i != j) { std::stringstream message; message << "Checking if file " << i << " and file " << j << " are different, which should be the case because each of them should be unique."; CPPUNIT_ASSERT_MESSAGE(message.str(), (v100filenames.at(i) != v100filenames.at(j))); } } // delete all the files / clean up for (int i = 0; i < numberOfFiles; i++) { std::remove(v100filenames.at(i).c_str()); } } void TestLoadAndSaveImage() { - mitk::Image::Pointer img1 = dynamic_cast(mitk::IOUtil::Load(m_ImagePath)[0].GetPointer()); + mitk::Image::Pointer img1 = mitk::IOUtil::Load(m_ImagePath); CPPUNIT_ASSERT(img1.IsNotNull()); std::ofstream tmpStream; std::string imagePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffpic3d-XXXXXX.nrrd"); tmpStream.close(); std::string imagePath2 = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffpic3d-XXXXXX.nii.gz"); tmpStream.close(); // the cases where no exception should be thrown CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(img1, imagePath)); CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(img1.GetPointer(), imagePath2)); // load data which does not exist CPPUNIT_ASSERT_THROW(mitk::IOUtil::Load("fileWhichDoesNotExist.nrrd"), mitk::Exception); // delete the files after the test is done std::remove(imagePath.c_str()); std::remove(imagePath2.c_str()); mitk::Image::Pointer relativImage = mitk::ImageGenerator::GenerateGradientImage(4, 4, 4, 1); std::string imagePath3 = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.nrrd"); tmpStream.close(); mitk::IOUtil::Save(relativImage, imagePath3); CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Load(imagePath3)); std::remove(imagePath3.c_str()); } /** * \brief This method calls all available load methods with a nullpointer and an empty pathand expects an exception **/ void TestNullLoad() { CPPUNIT_ASSERT_THROW(mitk::IOUtil::Load(""), mitk::Exception); } /** * \brief This method calls the save method (to which all other convenience save methods reference) with null *parameters **/ void TestNullSave() { CPPUNIT_ASSERT_THROW(mitk::IOUtil::Save(nullptr, mitk::IOUtil::CreateTemporaryFile()), mitk::Exception); CPPUNIT_ASSERT_THROW(mitk::IOUtil::Save(mitk::Image::New().GetPointer(), ""), mitk::Exception); } void TestLoadAndSavePointSet() { - mitk::PointSet::Pointer pointset = dynamic_cast(mitk::IOUtil::Load(m_PointSetPath)[0].GetPointer()); + mitk::PointSet::Pointer pointset = mitk::IOUtil::Load(m_PointSetPath); CPPUNIT_ASSERT(pointset.IsNotNull()); std::ofstream tmpStream; std::string pointSetPath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mps"); tmpStream.close(); std::string pointSetPathWithDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mps"); tmpStream.close(); std::string pointSetPathWithoutDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream); tmpStream.close(); // the cases where no exception should be thrown CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(pointset, pointSetPathWithDefaultExtension)); // test if defaultextension is inserted if no extension is present CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(pointset, pointSetPathWithoutDefaultExtension.c_str())); // delete the files after the test is done std::remove(pointSetPath.c_str()); std::remove(pointSetPathWithDefaultExtension.c_str()); std::remove(pointSetPathWithoutDefaultExtension.c_str()); } void TestLoadAndSaveSurface() { - mitk::Surface::Pointer surface = dynamic_cast(mitk::IOUtil::Load(m_SurfacePath)[0].GetPointer()); + mitk::Surface::Pointer surface = mitk::IOUtil::Load(m_SurfacePath); CPPUNIT_ASSERT(surface.IsNotNull()); std::ofstream tmpStream; std::string surfacePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffsurface-XXXXXX.stl"); // the cases where no exception should be thrown CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(surface, surfacePath)); // test if exception is thrown as expected on unknown extsension CPPUNIT_ASSERT_THROW(mitk::IOUtil::Save(surface, "testSurface.xXx"), mitk::Exception); // delete the files after the test is done std::remove(surfacePath.c_str()); } }; MITK_TEST_SUITE_REGISTRATION(mitkIOUtil) diff --git a/Modules/Core/test/mitkImageAccessorTest.cpp b/Modules/Core/test/mitkImageAccessorTest.cpp index 8dcb50bc25..516d5245ba 100644 --- a/Modules/Core/test/mitkImageAccessorTest.cpp +++ b/Modules/Core/test/mitkImageAccessorTest.cpp @@ -1,251 +1,251 @@ /*=================================================================== 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 "itkBarrier.h" #include "mitkIOUtil.h" #include "mitkImage.h" #include "mitkImagePixelReadAccessor.h" #include "mitkImagePixelWriteAccessor.h" #include "mitkImageReadAccessor.h" #include "mitkImageTimeSelector.h" #include "mitkImageWriteAccessor.h" #include #include #include #include #include #include struct ThreadData { itk::Barrier::Pointer m_Barrier; // holds a pointer to the used barrier mitk::Image::Pointer data; // some random data int m_NoOfThreads; // holds the number of generated threads bool m_Successful; // to check if everything worked }; itk::SimpleFastMutexLock testMutex; ITK_THREAD_RETURN_TYPE ThreadMethod(void *data) { /* extract data pointer from Thread Info structure */ auto *pInfo = (struct itk::MultiThreader::ThreadInfoStruct *)data; // some data validity checking if (pInfo == nullptr) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == nullptr) { return ITK_THREAD_RETURN_VALUE; } // obtain user data for processing auto *threadData = (ThreadData *)pInfo->UserData; srand(pInfo->ThreadID); mitk::Image::Pointer im = threadData->data; int nrSlices = im->GetDimension(2); // Create randomly a PixelRead- or PixelWriteAccessor for a slice and access all pixels in it. try { if (rand() % 2) { testMutex.Lock(); mitk::ImageDataItem *iDi = im->GetSliceData(rand() % nrSlices); testMutex.Unlock(); while (!iDi->IsComplete()) { } // MITK_INFO << "pixeltype: " << im->GetPixelType().GetComponentTypeAsString(); if ((im->GetPixelType().GetComponentTypeAsString() == "short") && (im->GetDimension() == 3)) { // Use pixeltype&dimension specific read accessor int xlength = im->GetDimension(0); int ylength = im->GetDimension(1); mitk::ImagePixelReadAccessor readAccessor(im, iDi); itk::Index<2> idx; for (int i = 0; i < xlength; ++i) { for (int j = 0; j < ylength; ++j) { idx[0] = i; idx[1] = j; readAccessor.GetPixelByIndexSafe(idx); } } } else { // use general accessor mitk::ImageReadAccessor *iRA = new mitk::ImageReadAccessor(im, iDi); delete iRA; } } else { testMutex.Lock(); mitk::ImageDataItem *iDi = im->GetSliceData(rand() % nrSlices); testMutex.Unlock(); while (!iDi->IsComplete()) { } if ((im->GetPixelType().GetComponentTypeAsString() == "short") && (im->GetDimension() == 3)) { // Use pixeltype&dimension specific read accessor int xlength = im->GetDimension(0); int ylength = im->GetDimension(1); mitk::ImagePixelWriteAccessor writeAccessor(im, iDi); itk::Index<2> idx; for (int i = 0; i < xlength; ++i) { for (int j = 0; j < ylength; ++j) { idx[0] = i; idx[1] = j; short newVal = rand() % 16000; writeAccessor.SetPixelByIndexSafe(idx, newVal); short val = writeAccessor.GetPixelByIndexSafe(idx); if (val != newVal) { threadData->m_Successful = false; } } } } else { // use general accessor mitk::ImageWriteAccessor iB(im, iDi); void *pointer = iB.GetData(); *((char *)pointer) = 0; } } } catch (mitk::MemoryIsLockedException &e) { threadData->m_Successful = false; e.Print(std::cout); } catch (mitk::Exception &e) { threadData->m_Successful = false; e.Print(std::cout); } // data processing end! threadData->m_Barrier->Wait(); return ITK_THREAD_RETURN_VALUE; } int mitkImageAccessorTest(int argc, char *argv[]) { MITK_TEST_BEGIN("mitkImageAccessorTest"); std::cout << "Loading file: "; if (argc == 0) { std::cout << "no file specified [FAILED]" << std::endl; return EXIT_FAILURE; } mitk::Image::Pointer image = nullptr; try { - image = dynamic_cast(mitk::IOUtil::Load(std::string(argv[1]))[0].GetPointer()); + image = mitk::IOUtil::Load(std::string(argv[1])); if (image.IsNull()) { MITK_TEST_FAILED_MSG(<< "file could not be loaded [FAILED]") } } catch (itk::ExceptionObject &ex) { MITK_TEST_FAILED_MSG(<< "Exception: " << ex << "[FAILED]") } // CHECK INAPPROPRIATE AND SPECIAL USAGE // recursive mutex lock MITK_TEST_OUTPUT(<< "Testing a recursive mutex lock attempt, should end in an exception ..."); MITK_TEST_FOR_EXCEPTION_BEGIN(mitk::Exception) mitk::ImageWriteAccessor first(image); mitk::ImageReadAccessor second(image); MITK_TEST_FOR_EXCEPTION_END(mitk::Exception) // ignore lock mechanism in read accessor try { mitk::ImageWriteAccessor first(image); mitk::ImageReadAccessor second(image, nullptr, mitk::ImageAccessorBase::IgnoreLock); MITK_TEST_CONDITION_REQUIRED(true, "Testing the option flag \"IgnoreLock\" in ReadAccessor"); } catch (const mitk::Exception & /*e*/) { MITK_TEST_CONDITION_REQUIRED(false, "Ignoring the lock mechanism leads to exception."); } // CREATE THREADS image->GetGeometry()->Initialize(); itk::MultiThreader::Pointer threader = itk::MultiThreader::New(); unsigned int noOfThreads = 100; // initialize barrier itk::Barrier::Pointer barrier = itk::Barrier::New(); barrier->Initialize(noOfThreads + 1); // add one for we stop the base thread when the worker threads are processing auto *threadData = new ThreadData; threadData->m_Barrier = barrier; threadData->m_NoOfThreads = noOfThreads; threadData->data = image; threadData->m_Successful = true; // spawn threads for (unsigned int i = 0; i < noOfThreads; ++i) { threader->SpawnThread(ThreadMethod, threadData); } // stop the base thread during worker thread execution barrier->Wait(); // terminate threads for (unsigned int j = 0; j < noOfThreads; ++j) { threader->TerminateThread(j); } bool TestSuccessful = threadData->m_Successful; delete threadData; MITK_TEST_CONDITION_REQUIRED(TestSuccessful, "Testing image access from multiple threads"); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkImageDimensionConverterTest.cpp b/Modules/Core/test/mitkImageDimensionConverterTest.cpp index d7299e2780..8e771a06e7 100644 --- a/Modules/Core/test/mitkImageDimensionConverterTest.cpp +++ b/Modules/Core/test/mitkImageDimensionConverterTest.cpp @@ -1,264 +1,264 @@ /*=================================================================== 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. ===================================================================*/ // mitk includes #include "mitkTestingConfig.h" #include #include #include #include #include #include #include #include #include #include // itk includes #include #include // stl includes #include // vtk includes #include int mitkImageDimensionConverterTest(int /*argc*/, char * /*argv*/ []) { MITK_TEST_BEGIN(mitkImageDimensionConverterTest); // Define an epsilon which is the allowed error float eps = 0.00001; // Define helper variables float error = 0; bool matrixIsEqual = true; std::stringstream sstream; mitk::Convert2Dto3DImageFilter::Pointer convertFilter = mitk::Convert2Dto3DImageFilter::New(); /////////////////////////////////////// // Create 2D Image with a 3D rotation from scratch. typedef itk::Image ImageType; ImageType::Pointer itkImage = ImageType::New(); ImageType::RegionType myRegion; ImageType::SizeType mySize; ImageType::IndexType myIndex; ImageType::SpacingType mySpacing; mySpacing[0] = 1; mySpacing[1] = 1; myIndex[0] = 0; myIndex[1] = 0; mySize[0] = 50; mySize[1] = 50; myRegion.SetSize(mySize); myRegion.SetIndex(myIndex); itkImage->SetSpacing(mySpacing); itkImage->SetRegions(myRegion); itkImage->Allocate(); itkImage->FillBuffer(50); mitk::Image::Pointer mitkImage2D; mitk::CastToMitkImage(itkImage, mitkImage2D); // rotate mitk::Point3D p; p[0] = 1; p[1] = 3; p[2] = 5; mitk::Vector3D v; v[0] = 0.3; v[1] = 1; v[2] = 0.1; mitk::RotationOperation op(mitk::OpROTATE, p, v, 35); mitkImage2D->GetGeometry()->ExecuteOperation(&op); // Save original Geometry infos mitk::Vector3D Original_col0, Original_col1, Original_col2; Original_col0.SetVnlVector( mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); Original_col1.SetVnlVector( mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); Original_col2.SetVnlVector( mitkImage2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); MITK_INFO << "Rotated Matrix: " << Original_col0 << " " << Original_col1 << " " << Original_col2; mitk::Point3D Original_Origin = mitkImage2D->GetGeometry()->GetOrigin(); mitk::Vector3D Original_Spacing = mitkImage2D->GetGeometry()->GetSpacing(); MITK_TEST_CONDITION_REQUIRED(mitkImage2D->GetDimension() == 2, "Created Image is Dimension 2"); /////////////////////////////////////// // mitkImage2D is now a 2D image with 3D Geometry information. // Save it without conversion and load it again. It should have an identitiy matrix sstream.clear(); sstream << MITK_TEST_OUTPUT_DIR << "" << "/rotatedImage2D.nrrd"; mitk::IOUtil::Save(mitkImage2D, sstream.str()); - mitk::Image::Pointer imageLoaded2D = dynamic_cast(mitk::IOUtil::Load(sstream.str())[0].GetPointer()); + mitk::Image::Pointer imageLoaded2D = mitk::IOUtil::Load(sstream.str()); // check if image can be loaded MITK_TEST_CONDITION_REQUIRED(imageLoaded2D.IsNotNull(), "Loading saved 2D Image"); MITK_TEST_CONDITION_REQUIRED(imageLoaded2D->GetDimension() == 2, "Loaded Image is Dimension 2"); // check if spacing is ok mitk::Vector3D Loaded2D_Spacing = imageLoaded2D->GetGeometry()->GetSpacing(); error = std::fabs(Loaded2D_Spacing[0] - Original_Spacing[0]) + std::fabs(Loaded2D_Spacing[1] - Original_Spacing[1]) + std::fabs(Loaded2D_Spacing[2] - 1); MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Spacing"); // Check origin mitk::Point3D Loaded2D_Origin = imageLoaded2D->GetGeometry()->GetOrigin(); error = std::fabs(Loaded2D_Origin[0] - Original_Origin[0]) + std::fabs(Loaded2D_Origin[1] - Original_Origin[1]) + std::fabs(Loaded2D_Origin[2] - 0); MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Origin"); // Check matrix mitk::Vector3D Loaded2D_col0, Loaded2D_col1, Loaded2D_col2; Loaded2D_col0.SetVnlVector( imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); Loaded2D_col1.SetVnlVector( imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); Loaded2D_col2.SetVnlVector( imageLoaded2D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); if ((std::fabs(1 - Loaded2D_col0[0]) > eps) || (std::fabs(0 - Loaded2D_col0[1]) > eps) || (std::fabs(0 - Loaded2D_col0[2]) > eps) || (std::fabs(0 - Loaded2D_col1[0]) > eps) || (std::fabs(1 - Loaded2D_col1[1]) > eps) || (std::fabs(0 - Loaded2D_col1[2]) > eps) || (std::fabs(0 - Loaded2D_col2[0]) > eps) || (std::fabs(0 - Loaded2D_col2[1]) > eps) || (std::fabs(1 - Loaded2D_col2[2]) > eps)) { matrixIsEqual = false; } else matrixIsEqual = true; MITK_TEST_CONDITION_REQUIRED(matrixIsEqual, "Compare Geometry: Matrix"); /////////////////////////////////////// // mitkImage2D is a 2D image with 3D Geometry information. // Convert it with filter to a 3D image and check if everything went well convertFilter->SetInput(mitkImage2D); convertFilter->Update(); mitk::Image::Pointer mitkImage3D = convertFilter->GetOutput(); MITK_TEST_CONDITION_REQUIRED(mitkImage3D->GetDimension() == 3, "Converted Image is Dimension 3"); // check if geometry is still same mitk::Vector3D Converted_Spacing = mitkImage3D->GetGeometry()->GetSpacing(); error = std::fabs(Converted_Spacing[0] - Original_Spacing[0]) + std::fabs(Converted_Spacing[1] - Original_Spacing[1]) + std::fabs(Converted_Spacing[2] - Original_Spacing[2]); MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Spacing"); mitk::Point3D Converted_Origin = mitkImage3D->GetGeometry()->GetOrigin(); error = std::fabs(Converted_Origin[0] - Original_Origin[0]) + std::fabs(Converted_Origin[1] - Original_Origin[1]) + std::fabs(Converted_Origin[2] - Original_Origin[2]); MITK_INFO << Converted_Origin << " and " << Original_Origin; MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Origin"); mitk::Vector3D Converted_col0, Converted_col1, Converted_col2; Converted_col0.SetVnlVector( mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); Converted_col1.SetVnlVector( mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); Converted_col2.SetVnlVector( mitkImage3D->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); if ((std::fabs(Original_col0[0] - Converted_col0[0]) > eps) || (std::fabs(Original_col0[1] - Converted_col0[1]) > eps) || (std::fabs(Original_col0[2] - Converted_col0[2]) > eps) || (std::fabs(Original_col1[0] - Converted_col1[0]) > eps) || (std::fabs(Original_col1[1] - Converted_col1[1]) > eps) || (std::fabs(Original_col1[2] - Converted_col1[2]) > eps) || (std::fabs(Original_col2[0] - Converted_col2[0]) > eps) || (std::fabs(Original_col2[1] - Converted_col2[1]) > eps) || (std::fabs(Original_col2[2] - Converted_col2[2]) > eps)) { MITK_INFO << "Oh No! Original Image Matrix and Converted Image Matrix are different!"; MITK_INFO << "original Image:" << Original_col0 << " " << Original_col1 << " " << Original_col2; MITK_INFO << "converted Image:" << Converted_col0 << " " << Converted_col1 << " " << Converted_col2; matrixIsEqual = false; } else matrixIsEqual = true; MITK_TEST_CONDITION_REQUIRED(matrixIsEqual, "Compare Geometry: Matrix"); /////////////////////////////////////// // So far it seems good! now try to save and load the file std::stringstream sstream2; sstream2 << MITK_TEST_OUTPUT_DIR << "" << "/rotatedImage.nrrd"; mitk::IOUtil::Save(mitkImage3D, sstream2.str()); - mitk::Image::Pointer imageLoaded = dynamic_cast(mitk::IOUtil::Load(sstream2.str())[0].GetPointer()); + mitk::Image::Pointer imageLoaded = mitk::IOUtil::Load(sstream2.str()); // check if image can be loaded MITK_TEST_CONDITION_REQUIRED(imageLoaded.IsNotNull(), "Loading saved Image"); // check if loaded image is still what it should be: MITK_TEST_CONDITION_REQUIRED(imageLoaded->GetDimension() == 3, "Loaded Image is Dimension 3"); // check if geometry is still same mitk::Vector3D Loaded_Spacing = imageLoaded->GetGeometry()->GetSpacing(); error = std::fabs(Loaded_Spacing[0] - Original_Spacing[0]) + std::fabs(Loaded_Spacing[1] - Original_Spacing[1]) + std::fabs(Loaded_Spacing[2] - Original_Spacing[2]); MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Spacing"); mitk::Point3D Loaded_Origin = imageLoaded->GetGeometry()->GetOrigin(); error = std::fabs(Loaded_Origin[0] - Original_Origin[0]) + std::fabs(Loaded_Origin[1] - Original_Origin[1]) + std::fabs(Loaded_Origin[2] - Original_Origin[2]); MITK_TEST_CONDITION_REQUIRED(error < eps, "Compare Geometry: Origin"); mitk::Vector3D Loaded_col0, Loaded_col1, Loaded_col2; Loaded_col0.SetVnlVector( imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0)); Loaded_col1.SetVnlVector( imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1)); Loaded_col2.SetVnlVector( imageLoaded->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2)); if ((std::fabs(Original_col0[0] - Loaded_col0[0]) > eps) || (std::fabs(Original_col0[1] - Loaded_col0[1]) > eps) || (std::fabs(Original_col0[2] - Loaded_col0[2]) > eps) || (std::fabs(Original_col1[0] - Loaded_col1[0]) > eps) || (std::fabs(Original_col1[1] - Loaded_col1[1]) > eps) || (std::fabs(Original_col1[2] - Loaded_col1[2]) > eps) || (std::fabs(Original_col2[0] - Loaded_col2[0]) > eps) || (std::fabs(Original_col2[1] - Loaded_col2[1]) > eps) || (std::fabs(Original_col2[2] - Loaded_col2[2]) > eps)) { MITK_INFO << "Oh No! Original Image Matrix and Converted Image Matrix are different!"; MITK_INFO << "original Image:" << Original_col0 << " " << Original_col1 << " " << Original_col2; MITK_INFO << "converted Image:" << Loaded_col0 << " " << Loaded_col1 << " " << Loaded_col2; matrixIsEqual = false; } else matrixIsEqual = true; MITK_TEST_CONDITION_REQUIRED(matrixIsEqual, "Compare Geometry: Matrix"); return 0; MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkImageSliceSelectorTest.cpp b/Modules/Core/test/mitkImageSliceSelectorTest.cpp index a377fee2cd..37f9954b43 100644 --- a/Modules/Core/test/mitkImageSliceSelectorTest.cpp +++ b/Modules/Core/test/mitkImageSliceSelectorTest.cpp @@ -1,211 +1,211 @@ /*=================================================================== 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 mitkImageSliceSelectorTest(int argc, char *argv[]) { int slice_nr = 1; std::cout << "Loading file: "; if (argc == 0) { std::cout << "no file specified [FAILED]" << std::endl; return EXIT_FAILURE; } mitk::Image::Pointer image; try { - image = dynamic_cast(mitk::IOUtil::Load(argv[1])[0].GetPointer()); + image = mitk::IOUtil::Load(argv[1]); } catch (const mitk::Exception &) { std::cout << "file not an image - test will not be applied [PASSED]" << std::endl; std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } catch (itk::ExceptionObject &ex) { std::cout << "Exception: " << ex << "[FAILED]" << std::endl; return EXIT_FAILURE; } if (image->GetDimension(2) < 2) slice_nr = 0; // Take a slice mitk::ImageSliceSelector::Pointer slice = mitk::ImageSliceSelector::New(); slice->SetInput(image); slice->SetSliceNr(slice_nr); slice->Update(); std::cout << "Testing IsInitialized(): "; if (slice->GetOutput()->IsInitialized() == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing IsSliceSet(): "; if (slice->GetOutput()->IsSliceSet(0) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; /* deactivated because IpPic is not available any more (see bug 16662) if(itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic")!=std::string::npos) { std::cout << "Testing whether the slice is identical with a slice loaded by mitkIpPicGetSlice:"; mitkIpPicDescriptor *picslice = mitkIpPicGetSlice(argv[1], nullptr, (image->GetDimension(2)-1-slice_nr)+1); int i, size = _mitkIpPicSize(picslice); char * p1 = (char*)slice->GetPic()->data; char * p2 = (char*)picslice->data; //picslice->info->write_protect=mitkIpFalse; //mitkIpPicPut("C:\\1aaaaIPPIC.pic", picslice); //mitkIpPicPut("C:\\1aaaaSEL.pic", slice->GetPic()); for(i=0; iSetInput(image); //the output size of this filter is smaller than the of the input!! cyl2cart->SetTargetXSize( 64 ); //Use the same slice-selector again, this time to take a slice of the filtered image //which is smaller than the one of the old input!! slice->SetInput(cyl2cart->GetOutput()); slice->SetSliceNr(1); //The requested region is still the old one, //therefore the following results in most ITK versions //in an exception! slice->Update(); //If no exception occured, check that the requested region is now //the one of the smaller image if(cyl2cart->GetOutput()->GetLargestPossibleRegion().GetSize()[0]!=64) { std::cout<<"Part 1 [FAILED]"<GetOutput()->GetDimensions()[0]!=64) || (cyl2cart->GetOutput()->GetDimensions()[1]!=64)) { std::cout<<"Part 1b [FAILED]"<ResetPipeline(); } */ try { slice->UpdateLargestPossibleRegion(); } catch (itk::ExceptionObject) { std::cout << "Part 2 [FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "Part 2 [PASSED]" << std::endl; std::cout << "Testing IsInitialized(): "; if (slice->GetOutput()->IsInitialized() == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing IsSliceSet(): "; if (slice->GetOutput()->IsSliceSet(0) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; if (image->GetDimension(3) > 1) { int time = image->GetDimension(3) - 1; std::cout << "Testing 3D+t: Setting time to " << time << ": "; slice->SetTimeNr(time); if (slice->GetTimeNr() != time) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing 3D+t: Updating slice: "; slice->Update(); if (slice->GetOutput()->IsInitialized() == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing 3D+t: IsSliceSet(): "; if (slice->GetOutput()->IsSliceSet(0) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; std::cout << "Testing 3D+t: First slice in reader available: "; if (image->IsSliceSet(0, time) == false) { std::cout << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << "[PASSED]" << std::endl; } std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } diff --git a/Modules/Core/test/mitkImageTest.cpp b/Modules/Core/test/mitkImageTest.cpp index a44828fe07..f5b4215bcd 100644 --- a/Modules/Core/test/mitkImageTest.cpp +++ b/Modules/Core/test/mitkImageTest.cpp @@ -1,556 +1,556 @@ /*=================================================================== 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. ===================================================================*/ // mitk includes #include "mitkException.h" #include "mitkIOUtil.h" #include "mitkImageGenerator.h" #include "mitkImagePixelReadAccessor.h" #include "mitkImageReadAccessor.h" #include "mitkPixelTypeMultiplex.h" #include #include #include #include #include #include "mitkImageSliceSelector.h" // itk includes #include #include // stl includes #include // vtk includes #include // Checks if reference count is correct after using GetVtkImageData() bool ImageVtkDataReferenceCheck(const char *fname) { const std::string filename = std::string(fname); try { - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(filename); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Non-nullptr image") vtkImageData *vtk = image->GetVtkImageData(); if (vtk == nullptr) return false; } catch (...) { MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename); return false; } return true; } template void TestRandomPixelAccess(const mitk::PixelType /*ptype*/, mitk::Image::Pointer image, mitk::Point3D &point, mitk::ScalarType &value) { // generate a random point in world coordinates mitk::Point3D xMax, yMax, zMax, xMaxIndex, yMaxIndex, zMaxIndex; xMaxIndex.Fill(0.0f); yMaxIndex.Fill(0.0f); zMaxIndex.Fill(0.0f); xMaxIndex[0] = image->GetLargestPossibleRegion().GetSize()[0]; yMaxIndex[1] = image->GetLargestPossibleRegion().GetSize()[1]; zMaxIndex[2] = image->GetLargestPossibleRegion().GetSize()[2]; image->GetGeometry()->IndexToWorld(xMaxIndex, xMax); image->GetGeometry()->IndexToWorld(yMaxIndex, yMax); image->GetGeometry()->IndexToWorld(zMaxIndex, zMax); MITK_INFO << "Origin " << image->GetGeometry()->GetOrigin()[0] << " " << image->GetGeometry()->GetOrigin()[1] << " " << image->GetGeometry()->GetOrigin()[2] << ""; MITK_INFO << "MaxExtend " << xMax[0] << " " << yMax[1] << " " << zMax[2] << ""; itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New(); randomGenerator->Initialize(std::rand()); // initialize with random value, to get sensible random points for the image point[0] = randomGenerator->GetUniformVariate(image->GetGeometry()->GetOrigin()[0], xMax[0]); point[1] = randomGenerator->GetUniformVariate(image->GetGeometry()->GetOrigin()[1], yMax[1]); point[2] = randomGenerator->GetUniformVariate(image->GetGeometry()->GetOrigin()[2], zMax[2]); MITK_INFO << "RandomPoint " << point[0] << " " << point[1] << " " << point[2] << ""; // test values and max/min mitk::ScalarType imageMin = image->GetStatistics()->GetScalarValueMin(); mitk::ScalarType imageMax = image->GetStatistics()->GetScalarValueMax(); // test accessing PixelValue with coordinate leading to a negative index const mitk::Point3D geom_origin = image->GetGeometry()->GetOrigin(); const mitk::Point3D geom_center = image->GetGeometry()->GetCenter(); // shift position from origin outside of the image ( in the opposite direction to [center-origin] vector which points // in the inside) mitk::Point3D position = geom_origin + (geom_origin - geom_center); MITK_INFO << "Testing access outside of the image"; unsigned int dim = image->GetDimension(); if (dim == 3 || dim == 4) { mitk::ImagePixelReadAccessor imAccess3(image, image->GetVolumeData(0)); // Comparison ?>=0 not needed since all position[i] and timestep are unsigned int // (position[0]>=0 && position[1] >=0 && position[2]>=0 && timestep>=0) // bug-11978 : we still need to catch index with negative values if (point[0] < 0 || point[1] < 0 || point[2] < 0) { MITK_WARN << "Given position (" << point << ") is out of image range, returning 0."; } else { value = static_cast(imAccess3.GetPixelByWorldCoordinates(point)); MITK_TEST_CONDITION((value >= imageMin && value <= imageMax), "Value returned is between max/min"); } itk::Index<3> itkIndex; image->GetGeometry()->WorldToIndex(position, itkIndex); MITK_TEST_FOR_EXCEPTION_BEGIN(mitk::Exception); imAccess3.GetPixelByIndexSafe(itkIndex); MITK_TEST_FOR_EXCEPTION_END(mitk::Exception); } MITK_INFO << imageMin << " " << imageMax << " " << value << ""; } class mitkImageTestClass { public: void SetClonedGeometry_None_ClonedEqualInput() { mitk::Image::Pointer image = mitk::ImageGenerator::GenerateRandomImage(100, 100, 100, 1, 0.2, 0.3, 0.4); //----------------- // geometry information for image mitk::Point3D origin; mitk::Vector3D right, bottom; mitk::Vector3D spacing; mitk::FillVector3D(origin, 17.0, 19.92, 7.83); mitk::FillVector3D(right, 1.0, 2.0, 3.0); mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); // InitializeStandardPlane(rightVector, downVector, spacing) mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); planegeometry->SetOrigin(origin); planegeometry->ChangeImageGeometryConsideringOriginOffset(true); image->SetClonedGeometry(planegeometry); mitk::BaseGeometry::Pointer imageGeometry = image->GetGeometry(); MITK_ASSERT_EQUAL(imageGeometry, planegeometry, "Matrix elements of cloned matrix equal original matrix"); } }; int mitkImageTest(int argc, char *argv[]) { MITK_TEST_BEGIN(mitkImageTest); mitkImageTestClass tester; tester.SetClonedGeometry_None_ClonedEqualInput(); // Create Image out of nowhere mitk::Image::Pointer imgMem = mitk::Image::New(); mitk::PixelType pt = mitk::MakeScalarPixelType(); unsigned int dim[] = {100, 100, 20}; MITK_TEST_CONDITION_REQUIRED(imgMem.IsNotNull(), "An image was created. "); // Initialize image imgMem->Initialize(pt, 3, dim); MITK_TEST_CONDITION_REQUIRED(imgMem->IsInitialized(), "Image::IsInitialized() ?"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetPixelType() == pt, "PixelType was set correctly."); int *p = nullptr; int *p2 = nullptr; try { mitk::ImageReadAccessor imgMemAcc(imgMem); p = (int *)imgMemAcc.GetData(); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION(p != nullptr, "GetData() returned not-nullptr pointer."); // filling image const unsigned int size = dim[0] * dim[1] * dim[2]; for (unsigned int i = 0; i < size; ++i, ++p) *p = (signed int)i; // Getting it again and compare with filled values: try { mitk::ImageReadAccessor imgMemAcc(imgMem); p2 = (int *)imgMemAcc.GetData(); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION(p2 != nullptr, "GetData() returned not-nullptr pointer."); bool isEqual = true; for (unsigned int i = 0; i < size; ++i, ++p2) { if (*p2 != (signed int)i) { isEqual = false; } } MITK_TEST_CONDITION(isEqual, "The values previously set as data are correct [pixelwise comparison]."); // Testing GetSliceData() and compare with filled values: try { mitk::ImageReadAccessor imgMemAcc(imgMem, imgMem->GetSliceData(dim[2] / 2)); p2 = (int *)imgMemAcc.GetData(); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION_REQUIRED(p2 != nullptr, "Valid slice data returned"); unsigned int xy_size = dim[0] * dim[1]; unsigned int start_mid_slice = (dim[2] / 2) * xy_size; isEqual = true; for (unsigned int i = 0; i < xy_size; ++i, ++p2) { if (*p2 != (signed int)(i + start_mid_slice)) { isEqual = false; } } MITK_TEST_CONDITION(isEqual, "The SliceData are correct [pixelwise comparison]. "); imgMem = mitk::Image::New(); // testing re-initialization of test image mitk::PixelType pType = mitk::MakePixelType(); imgMem->Initialize(pType, 3, dim); MITK_TEST_CONDITION_REQUIRED(imgMem->GetDimension() == 3, "Testing initialization parameter dimension!"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetPixelType() == pType, "Testing initialization parameter pixeltype!"); MITK_TEST_CONDITION_REQUIRED( imgMem->GetDimension(0) == dim[0] && imgMem->GetDimension(1) == dim[1] && imgMem->GetDimension(2) == dim[2], "Testing initialization of dimensions!"); MITK_TEST_CONDITION(imgMem->IsInitialized(), "Image is initialized."); // Setting volume again: try { mitk::ImageReadAccessor imgMemAcc(imgMem); imgMem->SetVolume(imgMemAcc.GetData()); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } //----------------- // geometry information for image mitk::Point3D origin; mitk::Vector3D right, bottom; mitk::Vector3D spacing; mitk::FillVector3D(origin, 17.0, 19.92, 7.83); mitk::FillVector3D(right, 1.0, 2.0, 3.0); mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); // InitializeStandardPlane(rightVector, downVector, spacing) mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); planegeometry->SetOrigin(origin); planegeometry->SetImageGeometry(true); // Testing Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int slices) with // PlaneGeometry and GetData(): "; imgMem->Initialize(mitk::MakePixelType(), *planegeometry); MITK_TEST_CONDITION_REQUIRED( imgMem->GetGeometry()->GetOrigin() == static_cast(planegeometry)->GetOrigin(), "Testing correct setting of geometry via initialize!"); try { mitk::ImageReadAccessor imgMemAcc(imgMem); p = (int *)imgMemAcc.GetData(); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION_REQUIRED(p != nullptr, "GetData() returned valid pointer."); // Testing Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry) and GetData(): "; imgMem->Initialize(mitk::MakePixelType(), 40, *planegeometry); try { mitk::ImageReadAccessor imgMemAcc(imgMem); p = (int *)imgMemAcc.GetData(); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } MITK_TEST_CONDITION_REQUIRED(p != nullptr, "GetData() returned valid pointer."); //----------------- // testing origin information and methods MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of origin via GetGeometry()->GetOrigin(): "); // Setting origin via SetOrigin(origin): "; mitk::FillVector3D(origin, 37.0, 17.92, 27.83); imgMem->SetOrigin(origin); // Test origin MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of changed origin via GetGeometry()->GetOrigin(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetPlaneGeometry(0)->GetOrigin(), origin), "Testing correctness of changed origin via GetSlicedGeometry()->GetPlaneGeometry(0)->GetOrigin(): "); //----------------- // testing spacing information and methodsunsigned int dim[]={100,100,20}; MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correct spacing from Geometry3D!"); mitk::FillVector3D(spacing, 7.0, 0.92, 1.83); imgMem->SetSpacing(spacing); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correctness of changed spacing via GetGeometry()->GetSpacing(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing(), spacing), "Testing correctness of changed spacing via GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing(): "); mitk::Image::Pointer vecImg = mitk::Image::New(); try { mitk::ImageReadAccessor imgMemAcc(imgMem); vecImg->Initialize(imgMem->GetPixelType(), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/); vecImg->SetImportChannel(const_cast(imgMemAcc.GetData()), 0, mitk::Image::CopyMemory); vecImg->SetImportChannel(const_cast(imgMemAcc.GetData()), 1, mitk::Image::CopyMemory); mitk::ImageReadAccessor vecImgAcc(vecImg); mitk::ImageReadAccessor vecImgAcc0(vecImg, vecImg->GetChannelData(0)); mitk::ImageReadAccessor vecImgAcc1(vecImg, vecImg->GetChannelData(1)); MITK_TEST_CONDITION_REQUIRED(vecImgAcc0.GetData() != nullptr && vecImgAcc1.GetData() != nullptr, "Testing set and return of channel data!"); MITK_TEST_CONDITION_REQUIRED(vecImg->IsValidSlice(0, 0, 1), ""); MITK_TEST_OUTPUT(<< " Testing whether CopyMemory worked"); MITK_TEST_CONDITION_REQUIRED(imgMemAcc.GetData() != vecImgAcc.GetData(), ""); MITK_TEST_OUTPUT(<< " Testing destruction after SetImportChannel"); vecImg = nullptr; MITK_TEST_CONDITION_REQUIRED(vecImg.IsNull(), "testing destruction!"); } catch (mitk::Exception &e) { MITK_ERROR << e.what(); } //----------------- MITK_TEST_OUTPUT(<< "Testing initialization via vtkImageData"); MITK_TEST_OUTPUT(<< " Setting up vtkImageData"); vtkImageData *vtkimage = vtkImageData::New(); vtkimage->Initialize(); vtkimage->SetDimensions(2, 3, 4); double vtkorigin[] = {-350, -358.203, -1363.5}; vtkimage->SetOrigin(vtkorigin); mitk::Point3D vtkoriginAsMitkPoint; mitk::vtk2itk(vtkorigin, vtkoriginAsMitkPoint); double vtkspacing[] = {1.367, 1.367, 2}; vtkimage->SetSpacing(vtkspacing); vtkimage->AllocateScalars(VTK_SHORT, 1); std::cout << "[PASSED]" << std::endl; MITK_TEST_OUTPUT(<< " Testing mitk::Image::Initialize(vtkImageData*, ...)"); mitk::Image::Pointer mitkByVtkImage = mitk::Image::New(); mitkByVtkImage->Initialize(vtkimage); MITK_TEST_CONDITION_REQUIRED(mitkByVtkImage->IsInitialized(), ""); vtkimage->Delete(); MITK_TEST_OUTPUT(<< " Testing whether spacing has been correctly initialized from vtkImageData"); mitk::Vector3D spacing2 = mitkByVtkImage->GetGeometry()->GetSpacing(); mitk::Vector3D vtkspacingAsMitkVector; mitk::vtk2itk(vtkspacing, vtkspacingAsMitkVector); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(spacing2, vtkspacingAsMitkVector), ""); MITK_TEST_OUTPUT( << " Testing whether GetSlicedGeometry(0)->GetOrigin() has been correctly initialized from vtkImageData"); mitk::Point3D origin2 = mitkByVtkImage->GetSlicedGeometry(0)->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2, vtkoriginAsMitkPoint), ""); MITK_TEST_OUTPUT(<< " Testing whether GetGeometry()->GetOrigin() has been correctly initialized from vtkImageData"); origin2 = mitkByVtkImage->GetGeometry()->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2, vtkoriginAsMitkPoint), ""); MITK_TEST_OUTPUT(<< " Testing if vtkOrigin is (0, 0, 0). This behaviour is due to historical development of MITK. " "Aslo see bug 5050!"); vtkImageData *vtkImage = imgMem->GetVtkImageData(); auto vtkOrigin = vtkImage->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vtkOrigin[0], 0), "testing vtkOrigin[0] to be 0"); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vtkOrigin[1], 0), "testing vtkOrigin[1] to be 0"); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vtkOrigin[2], 0), "testing vtkOrigin[2] to be 0"); // TODO test the following initializers on channel-incorporation // void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, unsigned int *dimensions, // unsigned int channels) // void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry2d, bool // flipped, unsigned int channels, int tDim ) // void mitk::Image::Initialize(const mitk::Image* image) // void mitk::Image::Initialize(const mitkIpPicDescriptor* pic, int channels, int tDim, int sDim) // mitk::Image::Pointer vecImg = mitk::Image::New(); // vecImg->Initialize(PixelType(typeid(float), 6, itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR), // *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, false /*shiftBoundingBoxMinimumToZero*/ ); // vecImg->Initialize(PixelType(typeid(itk::Vector)), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, // false /*shiftBoundingBoxMinimumToZero*/ ); // testing access by index coordinates and by world coordinates MITK_TEST_CONDITION_REQUIRED(argc == 2, "Check if test image is accessible!"); const std::string filename = std::string(argv[1]); mitk::Image::Pointer image; try { - image = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + image = mitk::IOUtil::Load(filename); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Non-nullptr image") } catch (...) { MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename); return 0; } mitk::Point3D point; mitk::ScalarType value = -1.; mitkPixelTypeMultiplex3( TestRandomPixelAccess, image->GetImageDescriptor()->GetChannelTypeById(0), image, point, value) { // testing the clone method of mitk::Image mitk::Image::Pointer cloneImage = image->Clone(); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension() == image->GetDimension(), "Clone (testing dimension)"); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetPixelType() == image->GetPixelType(), "Clone (testing pixel type)"); // After cloning an image the geometry of both images should be equal too MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetOrigin() == image->GetGeometry()->GetOrigin(), "Clone (testing origin)"); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetSpacing() == image->GetGeometry()->GetSpacing(), "Clone (testing spacing)"); MITK_TEST_CONDITION_REQUIRED( mitk::MatrixEqualElementWise(cloneImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix(), image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix()), "Clone (testing transformation matrix)"); MITK_TEST_CONDITION_REQUIRED( mitk::MatrixEqualElementWise(cloneImage->GetTimeGeometry() ->GetGeometryForTimeStep(cloneImage->GetDimension(3) - 1) ->GetIndexToWorldTransform() ->GetMatrix(), cloneImage->GetTimeGeometry() ->GetGeometryForTimeStep(image->GetDimension(3) - 1) ->GetIndexToWorldTransform() ->GetMatrix()), "Clone(testing time sliced geometry)"); for (unsigned int i = 0u; i < cloneImage->GetDimension(); ++i) { MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension(i) == image->GetDimension(i), "Clone (testing dimension " << i << ")"); } } // access via itk if (image->GetDimension() > 3) // CastToItk only works with 3d images so we need to check for 4d images { mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New(); selector->SetTimeNr(0); selector->SetInput(image); selector->Update(); image = selector->GetOutput(); } if (image->GetDimension() == 3) { typedef itk::Image ItkFloatImage3D; ItkFloatImage3D::Pointer itkimage; try { mitk::CastToItkImage(image, itkimage); MITK_TEST_CONDITION_REQUIRED(itkimage.IsNotNull(), "Test conversion to itk::Image!"); } catch (std::exception &e) { MITK_INFO << e.what(); } mitk::Point3D itkPhysicalPoint; image->GetGeometry()->WorldToItkPhysicalPoint(point, itkPhysicalPoint); MITK_INFO << "ITKPoint " << itkPhysicalPoint[0] << " " << itkPhysicalPoint[1] << " " << itkPhysicalPoint[2] << ""; mitk::Point3D backTransformedPoint; image->GetGeometry()->ItkPhysicalPointToWorld(itkPhysicalPoint, backTransformedPoint); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(point, backTransformedPoint), "Testing world->itk-physical->world consistency"); itk::Index<3> idx; bool status = itkimage->TransformPhysicalPointToIndex(itkPhysicalPoint, idx); MITK_INFO << "ITK Index " << idx[0] << " " << idx[1] << " " << idx[2] << ""; if (status && value != -1.) { float valByItk = itkimage->GetPixel(idx); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(valByItk, value), "Compare value of pixel returned by mitk in comparison to itk"); } else { MITK_WARN << "Index is out buffered region!"; } } else { MITK_INFO << "Image does not contain three dimensions, some test cases are skipped!"; } // clone generated 3D image with one slice in z direction (cf. bug 11058) auto *threeDdim = new unsigned int[3]; threeDdim[0] = 100; threeDdim[1] = 200; threeDdim[2] = 1; mitk::Image::Pointer threeDImage = mitk::Image::New(); threeDImage->Initialize(mitk::MakeScalarPixelType(), 3, threeDdim); mitk::Image::Pointer cloneThreeDImage = threeDImage->Clone(); // check that the clone image has the same dimensionality as the source image MITK_TEST_CONDITION_REQUIRED(cloneThreeDImage->GetDimension() == 3, "Testing if the clone image initializes with 3D!"); MITK_TEST_CONDITION_REQUIRED(ImageVtkDataReferenceCheck(argv[1]), "Checking reference count of Image after using GetVtkImageData()"); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkImageTimeSelectorTest.cpp b/Modules/Core/test/mitkImageTimeSelectorTest.cpp index 2bea7c99fa..011545d4cf 100644 --- a/Modules/Core/test/mitkImageTimeSelectorTest.cpp +++ b/Modules/Core/test/mitkImageTimeSelectorTest.cpp @@ -1,113 +1,113 @@ /*=================================================================== 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 "mitkImageGenerator.h" #include "mitkImageTimeSelector.h" #include "mitkTestingMacros.h" #include "mitkIOUtil.h" #include #include /** Global members common for all subtests */ namespace { std::string m_Filename; mitk::Image::Pointer m_Image; } // end of anonymous namespace /** @brief Global test setup */ static void Setup() { try { - m_Image = dynamic_cast(mitk::IOUtil::Load(m_Filename)[0].GetPointer()); + m_Image = mitk::IOUtil::Load(m_Filename); } catch (const itk::ExceptionObject &e) { MITK_TEST_FAILED_MSG(<< "(Setup) Caught exception from IOUtil while loading input : " << m_Filename << "\n" << e.what()) } } static void Valid_AllInputTimesteps_ReturnsTrue() { Setup(); mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(m_Image); // test all timesteps const unsigned int maxTimeStep = m_Image->GetTimeSteps(); for (unsigned int t = 0; t < maxTimeStep; t++) { timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer currentTimestepImage = timeSelector->GetOutput(); std::stringstream ss; ss << " : Valid image in timestep " << t; MITK_TEST_CONDITION_REQUIRED(currentTimestepImage.IsNotNull(), ss.str().c_str()); } } static void Valid_ImageExpandedByTimestep_ReturnsTrue() { Setup(); mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); const unsigned int maxTimeStep = m_Image->GetTimeSteps(); mitk::TimeGeometry *tsg = m_Image->GetTimeGeometry(); auto *ptg = dynamic_cast(tsg); ptg->Expand(maxTimeStep + 1); ptg->SetTimeStepGeometry(ptg->GetGeometryForTimeStep(0), maxTimeStep); mitk::Image::Pointer expandedImage = mitk::Image::New(); expandedImage->Initialize(m_Image->GetPixelType(0), *tsg); timeSelector->SetInput(expandedImage); for (unsigned int t = 0; t < maxTimeStep + 1; t++) { timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer currentTimestepImage = timeSelector->GetOutput(); std::stringstream ss; ss << " : Valid image in timestep " << t; MITK_TEST_CONDITION_REQUIRED(currentTimestepImage.IsNotNull(), ss.str().c_str()); } } int mitkImageTimeSelectorTest(int /*argc*/, char *argv[]) { MITK_TEST_BEGIN(mitkImageTimeSelectorTest); m_Filename = std::string(argv[1]); Valid_AllInputTimesteps_ReturnsTrue(); Valid_ImageExpandedByTimestep_ReturnsTrue(); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkImageToItkTest.cpp b/Modules/Core/test/mitkImageToItkTest.cpp index 1c061afd4a..54f1bd577c 100644 --- a/Modules/Core/test/mitkImageToItkTest.cpp +++ b/Modules/Core/test/mitkImageToItkTest.cpp @@ -1,163 +1,163 @@ /*=================================================================== 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 "itkDiffusionTensor3D.h" #include "mitkITKImageImport.h" #include "mitkImage.h" #include "mitkReferenceCountWatcher.h" #include "mitkTestFixture.h" #include "mitkTestingMacros.h" #include #include #include #include static mitk::Image::Pointer GetEmptyTestImageWithGeometry(mitk::PixelType pt) { // create empty image mitk::Image::Pointer imgMem; imgMem = mitk::Image::New(); // create geometry information for image mitk::Point3D origin; mitk::Vector3D right, bottom; mitk::Vector3D spacing; mitk::FillVector3D(origin, 17.0, 19.92, 7.83); mitk::FillVector3D(right, 1.0, 2.0, 3.0); mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); planegeometry->SetOrigin(origin); // initialize image imgMem->Initialize(pt, 40, *planegeometry); return imgMem; } class mitkImageToItkTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageToItkTestSuite); MITK_TEST(ImageCastIntToFloat_EmptyImage); MITK_TEST(ImageCastDoubleToFloat_EmptyImage); MITK_TEST(ImageCastFloatToFloatTensor_EmptyImage_ThrowsException); MITK_TEST(ImageCastFloatTensorToFloatTensor_EmptyImage); MITK_TEST(ImageCastDoubleToTensorDouble_EmptyImage_ThrowsException); MITK_TEST(ImageCastToItkAndBack_SamePointer_Success); MITK_TEST(ImageCastToItk_TestImage_Success); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_TestImage; public: void setUp() override { // empty on purpose } void tearDown() override { m_TestImage = nullptr; } void ImageCastIntToFloat_EmptyImage() { mitk::Image::Pointer m_TestImage = GetEmptyTestImageWithGeometry(mitk::MakeScalarPixelType()); itk::Image::Pointer itkImage; mitk::CastToItkImage(m_TestImage, itkImage); mitk::Image::Pointer mitkImageAfterCast = mitk::ImportItkImage(itkImage); CPPUNIT_ASSERT_MESSAGE("Cast output is not null", mitkImageAfterCast.IsNotNull()); } void ImageCastDoubleToFloat_EmptyImage() { mitk::Image::Pointer m_TestImage = GetEmptyTestImageWithGeometry(mitk::MakeScalarPixelType()); itk::Image::Pointer diffImage; mitk::CastToItkImage(m_TestImage, diffImage); CPPUNIT_ASSERT_MESSAGE("Casting scalar double (MITK) image to scalar float tensor (ITK). Result shouldn't be nullptr.", diffImage.IsNotNull()); } void ImageCastFloatToFloatTensor_EmptyImage_ThrowsException() { mitk::Image::Pointer m_TestImage = GetEmptyTestImageWithGeometry(mitk::MakeScalarPixelType()); itk::Image, 3>::Pointer diffImage; CPPUNIT_ASSERT_THROW_MESSAGE("Casting scalar float (MITK) image to scalar float (ITK) throws exception.", mitk::CastToItkImage(m_TestImage, diffImage), mitk::AccessByItkException); } void ImageCastFloatTensorToFloatTensor_EmptyImage() { typedef itk::Image, 3> ItkTensorImageType; mitk::Image::Pointer m_TestImage = GetEmptyTestImageWithGeometry(mitk::MakePixelType()); itk::Image, 3>::Pointer diffImage; mitk::CastToItkImage(m_TestImage, diffImage); MITK_TEST_CONDITION_REQUIRED(diffImage.IsNotNull(), "Casting float tensor (MITK) image to float tensor (ITK). Result shouldn't be nullptr"); mitk::Image::Pointer mitkImageAfterCast = mitk::ImportItkImage(diffImage); MITK_ASSERT_EQUAL(mitkImageAfterCast, m_TestImage, "Same type, images shoul be equal."); } void ImageCastDoubleToTensorDouble_EmptyImage_ThrowsException() { mitk::Image::Pointer m_TestImage = GetEmptyTestImageWithGeometry(mitk::MakeScalarPixelType()); itk::Image, 3>::Pointer diffImage; CPPUNIT_ASSERT_THROW(mitk::CastToItkImage(m_TestImage, diffImage), mitk::AccessByItkException); } void ImageCastToItkAndBack_SamePointer_Success() { typedef itk::Image ItkImageType; ItkImageType::Pointer itkImage = ItkImageType::New(); std::string m_ImagePath = GetTestDataFilePath("Pic3D.nrrd"); - mitk::Image::Pointer testDataImage = dynamic_cast(mitk::IOUtil::Load(m_ImagePath)[0].GetPointer()); + mitk::Image::Pointer testDataImage = mitk::IOUtil::Load(m_ImagePath); // modify ITK image itk::Matrix dir = itkImage->GetDirection(); dir *= 2; itkImage->SetDirection(dir); CPPUNIT_ASSERT_THROW_MESSAGE("No exception thrown for casting back the same memory", testDataImage = mitk::GrabItkImageMemory(itkImage, testDataImage), itk::ExceptionObject); CPPUNIT_ASSERT(testDataImage.IsNotNull()); } void ImageCastToItk_TestImage_Success() { itk::Image::Pointer itkImage; std::string m_ImagePath = GetTestDataFilePath("Pic3D.nrrd"); - mitk::Image::Pointer testDataImage = dynamic_cast(mitk::IOUtil::Load(m_ImagePath)[0].GetPointer()); + mitk::Image::Pointer testDataImage = mitk::IOUtil::Load(m_ImagePath); mitk::CastToItkImage(testDataImage, itkImage); mitk::Image::Pointer mitkImageAfterCast = mitk::ImportItkImage(itkImage); // dereference itk image itkImage = nullptr; MITK_ASSERT_EQUAL(mitkImageAfterCast, testDataImage, "Cast with test data followed by import produces same images"); } }; // END TEST SUITE CLASS DECL MITK_TEST_SUITE_REGISTRATION(mitkImageToItk); diff --git a/Modules/Core/test/mitkImageToSurfaceFilterTest.cpp b/Modules/Core/test/mitkImageToSurfaceFilterTest.cpp index ec28f494f5..1119b2a884 100644 --- a/Modules/Core/test/mitkImageToSurfaceFilterTest.cpp +++ b/Modules/Core/test/mitkImageToSurfaceFilterTest.cpp @@ -1,154 +1,154 @@ /*=================================================================== 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 "mitkException.h" #include "mitkImageToSurfaceFilter.h" #include "mitkTestFixture.h" #include "mitkTestingMacros.h" #include bool CompareSurfacePointPositions(mitk::Surface::Pointer s1, mitk::Surface::Pointer s2) { vtkPoints *p1 = s1->GetVtkPolyData()->GetPoints(); vtkPoints *p2 = s2->GetVtkPolyData()->GetPoints(); if (p1->GetNumberOfPoints() != p2->GetNumberOfPoints()) return false; for (int i = 0; i < p1->GetNumberOfPoints(); ++i) { if (p1->GetPoint(i)[0] != p2->GetPoint(i)[0] || p1->GetPoint(i)[1] != p2->GetPoint(i)[1] || p1->GetPoint(i)[2] != p2->GetPoint(i)[2]) { return true; } } return false; } class mitkImageToSurfaceFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageToSurfaceFilterTestSuite); MITK_TEST(testImageToSurfaceFilterInitialization); MITK_TEST(testInput); MITK_TEST(testSurfaceGeneration); MITK_TEST(testDecimatePromeshDecimation); MITK_TEST(testQuadricDecimation); MITK_TEST(testSmoothingOfSurface); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ mitk::Image::Pointer m_BallImage; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ - void setUp() override { m_BallImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30.nrrd"))[0].GetPointer()); } + void setUp() override { m_BallImage = mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30.nrrd")); } void tearDown() override {} void testImageToSurfaceFilterInitialization() { mitk::ImageToSurfaceFilter::Pointer testObject = mitk::ImageToSurfaceFilter::New(); CPPUNIT_ASSERT_MESSAGE("Testing instantiation of test object", testObject.IsNotNull()); // testing initialization of member variables! CPPUNIT_ASSERT_MESSAGE("Testing initialization of threshold member variable", testObject->GetThreshold() == 1.0f); CPPUNIT_ASSERT_MESSAGE("Testing initialization of smooth member variable", testObject->GetSmooth() == false); CPPUNIT_ASSERT_MESSAGE("Testing initialization of decimate member variable", testObject->GetDecimate() == mitk::ImageToSurfaceFilter::NoDecimation); CPPUNIT_ASSERT_MESSAGE("Testing initialization of target reduction member variable", testObject->GetTargetReduction() == 0.95f); } void testInput() { mitk::ImageToSurfaceFilter::Pointer testObject = mitk::ImageToSurfaceFilter::New(); testObject->SetInput(m_BallImage); CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", testObject->GetInput() == m_BallImage); } void testSurfaceGeneration() { mitk::ImageToSurfaceFilter::Pointer testObject = mitk::ImageToSurfaceFilter::New(); testObject->SetInput(m_BallImage); testObject->Update(); mitk::Surface::Pointer resultSurface = nullptr; resultSurface = testObject->GetOutput(); CPPUNIT_ASSERT_MESSAGE("Testing surface generation!", testObject->GetOutput() != nullptr); } void testDecimatePromeshDecimation() { mitk::ImageToSurfaceFilter::Pointer testObject = mitk::ImageToSurfaceFilter::New(); testObject->SetInput(m_BallImage); testObject->Update(); mitk::Surface::Pointer resultSurface = nullptr; resultSurface = testObject->GetOutput(); mitk::Surface::Pointer testSurface1 = testObject->GetOutput()->Clone(); testObject->SetDecimate(mitk::ImageToSurfaceFilter::DecimatePro); testObject->SetTargetReduction(0.5f); testObject->Update(); mitk::Surface::Pointer testSurface2 = testObject->GetOutput()->Clone(); CPPUNIT_ASSERT_MESSAGE("Testing DecimatePro mesh decimation!", testSurface1->GetVtkPolyData()->GetPoints()->GetNumberOfPoints() > testSurface2->GetVtkPolyData()->GetPoints()->GetNumberOfPoints()); } void testQuadricDecimation() { mitk::ImageToSurfaceFilter::Pointer testObject = mitk::ImageToSurfaceFilter::New(); testObject->SetInput(m_BallImage); testObject->Update(); mitk::Surface::Pointer resultSurface = nullptr; resultSurface = testObject->GetOutput(); mitk::Surface::Pointer testSurface1 = testObject->GetOutput()->Clone(); testObject->SetDecimate(mitk::ImageToSurfaceFilter::QuadricDecimation); testObject->SetTargetReduction(0.5f); testObject->Update(); mitk::Surface::Pointer testSurface3 = testObject->GetOutput()->Clone(); CPPUNIT_ASSERT_MESSAGE("Testing QuadricDecimation mesh decimation!", testSurface1->GetVtkPolyData()->GetPoints()->GetNumberOfPoints() > testSurface3->GetVtkPolyData()->GetPoints()->GetNumberOfPoints()); } void testSmoothingOfSurface() { mitk::ImageToSurfaceFilter::Pointer testObject = mitk::ImageToSurfaceFilter::New(); testObject->SetInput(m_BallImage); testObject->Update(); mitk::Surface::Pointer resultSurface = nullptr; resultSurface = testObject->GetOutput(); mitk::Surface::Pointer testSurface1 = testObject->GetOutput()->Clone(); testObject->SetSmooth(true); testObject->SetDecimate(mitk::ImageToSurfaceFilter::NoDecimation); testObject->Update(); mitk::Surface::Pointer testSurface4 = testObject->GetOutput()->Clone(); CPPUNIT_ASSERT_MESSAGE("Testing smoothing of surface changes point data!", CompareSurfacePointPositions(testSurface1, testSurface4)); } }; MITK_TEST_SUITE_REGISTRATION(mitkImageToSurfaceFilter) diff --git a/Modules/Core/test/mitkItkImageIOTest.cpp b/Modules/Core/test/mitkItkImageIOTest.cpp index 564306d92a..87322a0cd8 100644 --- a/Modules/Core/test/mitkItkImageIOTest.cpp +++ b/Modules/Core/test/mitkItkImageIOTest.cpp @@ -1,427 +1,427 @@ /*=================================================================== 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 "mitkException.h" #include #include #include #include "mitkIOUtil.h" #include "mitkITKImageImport.h" #include #include "itksys/SystemTools.hxx" #include #include #include #ifdef WIN32 #include "process.h" #else #include #endif class mitkItkImageIOTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkItkImageIOTestSuite); MITK_TEST(TestImageWriterJpg); MITK_TEST(TestImageWriterPng1); MITK_TEST(TestImageWriterPng2); MITK_TEST(TestImageWriterPng3); MITK_TEST(TestImageWriterSimple); MITK_TEST(TestWrite3DImageWithOnePlane); MITK_TEST(TestWrite3DImageWithTwoPlanes); MITK_TEST(TestWrite3DplusT_ArbitraryTG); MITK_TEST(TestWrite3DplusT_ProportionalTG); CPPUNIT_TEST_SUITE_END(); public: void setUp() override {} void tearDown() override {} void TestImageWriterJpg() { TestImageWriter("NrrdWritingTestImage.jpg"); } void TestImageWriterPng1() { TestImageWriter("Png2D-bw.png"); } void TestImageWriterPng2() { TestImageWriter("RenderingTestData/rgbImage.png"); } void TestImageWriterPng3() { TestImageWriter("RenderingTestData/rgbaImage.png"); } void TestWrite3DplusT_ArbitraryTG() { TestImageWriter("3D+t-ITKIO-TestData/LinearModel_4D_arbitrary_time_geometry.nrrd"); } void TestWrite3DplusT_ProportionalTG() { TestImageWriter("3D+t-ITKIO-TestData/LinearModel_4D_prop_time_geometry.nrrd"); } void TestImageWriterSimple() { // TODO } std::string AppendExtension(const std::string &filename, const char *extension) { std::string new_filename = filename; new_filename += extension; return new_filename; } bool CompareImageMetaData(mitk::Image::Pointer image, mitk::Image::Pointer reference, bool checkPixelType = true) { // switch to AreIdentical() methods as soon as Bug 11925 (Basic comparison operators) is fixed if (image->GetDimension() != reference->GetDimension()) { MITK_ERROR << "The image dimension differs: IN (" << image->GetDimension() << ") REF(" << reference->GetDimension() << ")"; return false; } // pixel type if (checkPixelType && (image->GetPixelType() != reference->GetPixelType() && image->GetPixelType().GetBitsPerComponent() != reference->GetPixelType().GetBitsPerComponent())) { MITK_ERROR << "Pixeltype differs ( image=" << image->GetPixelType().GetPixelTypeAsString() << "[" << image->GetPixelType().GetBitsPerComponent() << "]" << " reference=" << reference->GetPixelType().GetPixelTypeAsString() << "[" << reference->GetPixelType().GetBitsPerComponent() << "]" << " )"; return false; } return true; } /* Test writing picture formats like *.bmp, *.png, *.tiff or *.jpg NOTE: Saving as picture format must ignore PixelType comparison - not all bits per components are supported (see specification of the format) */ void TestPictureWriting(mitk::Image *image, const std::string &filename, const std::string &extension) { const std::string fullFileName = AppendExtension(filename, extension.c_str()); mitk::Image::Pointer singleSliceImage = nullptr; if (image->GetDimension() == 3) { mitk::ExtractSliceFilter::Pointer extractFilter = mitk::ExtractSliceFilter::New(); extractFilter->SetInput(image); extractFilter->SetWorldGeometry(image->GetSlicedGeometry()->GetPlaneGeometry(0)); extractFilter->Update(); singleSliceImage = extractFilter->GetOutput(); // test 3D writing in format supporting only 2D mitk::IOUtil::Save(image, fullFileName); // test images unsigned int foundImagesCount = 0; // if the image only contains one sinlge slice the itkImageSeriesWriter won't add a number like // filename.XX.extension if (image->GetDimension(2) == 1) { std::stringstream series_filenames; series_filenames << filename << extension; - mitk::Image::Pointer compareImage = dynamic_cast(mitk::IOUtil::Load(series_filenames.str())[0].GetPointer()); + mitk::Image::Pointer compareImage = mitk::IOUtil::Load(series_filenames.str()); if (compareImage.IsNotNull()) { foundImagesCount++; MITK_TEST_CONDITION( CompareImageMetaData(singleSliceImage, compareImage, false), "Image meta data unchanged after writing and loading again. "); // ignore bits per component } remove(series_filenames.str().c_str()); } else // test the whole slice stack { for (unsigned int i = 0; i < image->GetDimension(2); i++) { std::stringstream series_filenames; series_filenames << filename << "." << i + 1 << extension; - mitk::Image::Pointer compareImage = dynamic_cast(mitk::IOUtil::Load(series_filenames.str())[0].GetPointer()); + mitk::Image::Pointer compareImage = mitk::IOUtil::Load(series_filenames.str()); if (compareImage.IsNotNull()) { foundImagesCount++; MITK_TEST_CONDITION( CompareImageMetaData(singleSliceImage, compareImage, false), "Image meta data unchanged after writing and loading again. "); // ignore bits per component } remove(series_filenames.str().c_str()); } } MITK_TEST_CONDITION(foundImagesCount == image->GetDimension(2), "All 2D-Slices of a 3D image were stored correctly."); } else if (image->GetDimension() == 2) { singleSliceImage = image; } // test 2D writing if (singleSliceImage.IsNotNull()) { try { mitk::IOUtil::Save(singleSliceImage, fullFileName); - mitk::Image::Pointer compareImage = dynamic_cast(mitk::IOUtil::Load(fullFileName.c_str())[0].GetPointer()); + mitk::Image::Pointer compareImage = mitk::IOUtil::Load(fullFileName.c_str()); MITK_TEST_CONDITION_REQUIRED(compareImage.IsNotNull(), "Image stored was succesfully loaded again"); MITK_TEST_CONDITION_REQUIRED( CompareImageMetaData(singleSliceImage, compareImage, false), "Image meta data unchanged after writing and loading again. "); // ignore bits per component remove(fullFileName.c_str()); } catch (itk::ExceptionObject &e) { MITK_TEST_FAILED_MSG(<< "Exception during file writing for ." << extension << ": " << e.what()); } } } /** * test for writing NRRDs */ void TestNRRDWriting(const mitk::Image *image) { CPPUNIT_ASSERT_MESSAGE("Internal error. Passed reference image is null.", image); std::ofstream tmpStream; std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.nrrd"); tmpStream.close(); try { mitk::IOUtil::Save(image, tmpFilePath); - mitk::Image::Pointer compareImage = dynamic_cast(mitk::IOUtil::Load(tmpFilePath)[0].GetPointer()); + mitk::Image::Pointer compareImage = mitk::IOUtil::Load(tmpFilePath); CPPUNIT_ASSERT_MESSAGE("Image stored in NRRD format was succesfully loaded again", compareImage.IsNotNull()); /*It would make sence to check the images as well (see commented cppunit assert), but currently there seems to be a problem (exception) with most of the test images (partly it seems to be a problem when try to access the pixel content by AccessByItk_1 in mitk::CompareImageDataFilter. This problem should be dealt with in Bug 19533 - mitkITKImageIOTest needs improvement */ // CPPUNIT_ASSERT_MESSAGE("Images are equal.", mitk::Equal(*image, *compareImage, mitk::eps, true)); CPPUNIT_ASSERT_MESSAGE( "TimeGeometries are equal.", mitk::Equal(*(image->GetTimeGeometry()), *(compareImage->GetTimeGeometry()), mitk::eps, true)); remove(tmpFilePath.c_str()); } catch (...) { std::remove(tmpFilePath.c_str()); CPPUNIT_FAIL("Exception during NRRD file writing"); } } /** * test for writing MHDs */ void TestMHDWriting(const mitk::Image *image) { CPPUNIT_ASSERT_MESSAGE("Internal error. Passed reference image is null.", image); std::ofstream tmpStream; std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mhd"); tmpStream.close(); std::string tmpFilePathWithoutExt = tmpFilePath.substr(0, tmpFilePath.size() - 4); try { mitk::IOUtil::Save(image, tmpFilePath); - mitk::Image::Pointer compareImage = dynamic_cast(mitk::IOUtil::Load(tmpFilePath)[0].GetPointer()); + mitk::Image::Pointer compareImage = mitk::IOUtil::Load(tmpFilePath); CPPUNIT_ASSERT_MESSAGE("Image stored in MHD format was succesfully loaded again! ", compareImage.IsNotNull()); CPPUNIT_ASSERT_MESSAGE(".mhd file exists", itksys::SystemTools::FileExists((tmpFilePathWithoutExt + ".mhd").c_str())); CPPUNIT_ASSERT_MESSAGE(".raw or .zraw exists", itksys::SystemTools::FileExists((tmpFilePathWithoutExt + ".raw").c_str()) || itksys::SystemTools::FileExists((tmpFilePathWithoutExt + ".zraw").c_str())); /*It would make sence to check the images as well (see commented cppunit assert), but currently there seems to be a problem (exception) with most of the test images (partly it seems to be a problem when try to access the pixel content by AccessByItk_1 in mitk::CompareImageDataFilter. This problem should be dealt with in Bug 19533 - mitkITKImageIOTest needs improvement */ // CPPUNIT_ASSERT_MESSAGE("Images are equal.", mitk::Equal(*image, *compareImage, mitk::eps, true)); CPPUNIT_ASSERT_MESSAGE("TimeGeometries are equal.", mitk::Equal(*(image->GetTimeGeometry()), *(compareImage->GetTimeGeometry()), 5e-4, true)); // delete remove(tmpFilePath.c_str()); remove((tmpFilePathWithoutExt + ".raw").c_str()); remove((tmpFilePathWithoutExt + ".zraw").c_str()); } catch (...) { CPPUNIT_FAIL("Exception during.mhd file writing"); } } /** * test for "ImageWriter". * * argc and argv are the command line parameters which were passed to * the ADD_TEST command in the CMakeLists.txt file. For the automatic * tests, argv is either empty for the simple tests or contains the filename * of a test image for the image tests (see CMakeLists.txt). */ void TestImageWriter(std::string sourcefile) { sourcefile = GetTestDataFilePath(sourcefile); // load image CPPUNIT_ASSERT_MESSAGE("Checking whether source image exists", itksys::SystemTools::FileExists(sourcefile.c_str())); mitk::Image::Pointer image = nullptr; try { - image = dynamic_cast(mitk::IOUtil::Load(sourcefile)[0].GetPointer()); + image = mitk::IOUtil::Load(sourcefile); } catch (...) { CPPUNIT_FAIL("Exception during file loading:"); } CPPUNIT_ASSERT_MESSAGE("loaded image not nullptr", image.IsNotNull()); // write ITK .mhd image (2D and 3D only) if (image->GetDimension() <= 3) { TestMHDWriting(image); } // testing more component image writing as nrrd files TestNRRDWriting(image); std::ofstream tmpStream; std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX"); tmpStream.close(); TestPictureWriting(image, tmpFilePath, ".png"); TestPictureWriting(image, tmpFilePath, ".jpg"); TestPictureWriting(image, tmpFilePath, ".tiff"); TestPictureWriting(image, tmpFilePath, ".bmp"); // always end with this! } /** * Try to write a 3D image with only one plane (a 2D images in disguise for all intents and purposes) */ void TestWrite3DImageWithOnePlane() { typedef itk::Image ImageType; ImageType::Pointer itkImage = ImageType::New(); ImageType::IndexType start; start.Fill(0); ImageType::SizeType size; size[0] = 100; size[1] = 100; size[2] = 1; ImageType::RegionType region; region.SetSize(size); region.SetIndex(start); itkImage->SetRegions(region); itkImage->Allocate(); itkImage->FillBuffer(0); itk::ImageRegionIterator imageIterator(itkImage, itkImage->GetLargestPossibleRegion()); // Make two squares while (!imageIterator.IsAtEnd()) { if ((imageIterator.GetIndex()[0] > 5 && imageIterator.GetIndex()[0] < 20) && (imageIterator.GetIndex()[1] > 5 && imageIterator.GetIndex()[1] < 20)) { imageIterator.Set(255); } if ((imageIterator.GetIndex()[0] > 50 && imageIterator.GetIndex()[0] < 70) && (imageIterator.GetIndex()[1] > 50 && imageIterator.GetIndex()[1] < 70)) { imageIterator.Set(60); } ++imageIterator; } mitk::Image::Pointer image = mitk::ImportItkImage(itkImage); mitk::IOUtil::Save(image, mitk::IOUtil::CreateTemporaryFile("3Dto2DTestImageXXXXXX.nrrd")); mitk::IOUtil::Save(image, mitk::IOUtil::CreateTemporaryFile("3Dto2DTestImageXXXXXX.png")); } /** * Try to write a 3D image with only one plane (a 2D images in disguise for all intents and purposes) */ void TestWrite3DImageWithTwoPlanes() { typedef itk::Image ImageType; ImageType::Pointer itkImage = ImageType::New(); ImageType::IndexType start; start.Fill(0); ImageType::SizeType size; size[0] = 100; size[1] = 100; size[2] = 2; ImageType::RegionType region; region.SetSize(size); region.SetIndex(start); itkImage->SetRegions(region); itkImage->Allocate(); itkImage->FillBuffer(0); itk::ImageRegionIterator imageIterator(itkImage, itkImage->GetLargestPossibleRegion()); // Make two squares while (!imageIterator.IsAtEnd()) { if ((imageIterator.GetIndex()[0] > 5 && imageIterator.GetIndex()[0] < 20) && (imageIterator.GetIndex()[1] > 5 && imageIterator.GetIndex()[1] < 20)) { imageIterator.Set(255); } if ((imageIterator.GetIndex()[0] > 50 && imageIterator.GetIndex()[0] < 70) && (imageIterator.GetIndex()[1] > 50 && imageIterator.GetIndex()[1] < 70)) { imageIterator.Set(60); } ++imageIterator; } mitk::Image::Pointer image = mitk::ImportItkImage(itkImage); mitk::IOUtil::Save(image, mitk::IOUtil::CreateTemporaryFile("3Dto2DTestImageXXXXXX.nrrd")); CPPUNIT_ASSERT_THROW(mitk::IOUtil::Save(image, mitk::IOUtil::CreateTemporaryFile("3Dto2DTestImageXXXXXX.png")), mitk::Exception); } }; MITK_TEST_SUITE_REGISTRATION(mitkItkImageIO) diff --git a/Modules/Core/test/mitkLevelWindowManagerTest.cpp b/Modules/Core/test/mitkLevelWindowManagerTest.cpp index 98a1f26798..9aaf1f8f22 100644 --- a/Modules/Core/test/mitkLevelWindowManagerTest.cpp +++ b/Modules/Core/test/mitkLevelWindowManagerTest.cpp @@ -1,625 +1,625 @@ /*=================================================================== 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 "itkMersenneTwisterRandomVariateGenerator.h" #include "mitkLevelWindowManager.h" #include "mitkRenderingModeProperty.h" #include "mitkStandaloneDataStorage.h" #include #include #include #include #include #include #include #include class mitkLevelWindowManagerTestClass { public: static void TestInstantiation() { mitk::LevelWindowManager::Pointer manager; manager = mitk::LevelWindowManager::New(); MITK_TEST_CONDITION_REQUIRED(manager.IsNotNull(), "Testing mitk::LevelWindowManager::New()"); } static void TestSetGetDataStorage() { mitk::LevelWindowManager::Pointer manager; manager = mitk::LevelWindowManager::New(); MITK_TEST_OUTPUT(<< "Creating DataStorage: "); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); bool success = true; try { manager->SetDataStorage(ds); } catch (std::exception &e) { success = false; MITK_ERROR << "Exception: " << e.what(); } MITK_TEST_CONDITION_REQUIRED(success, "Testing mitk::LevelWindowManager SetDataStorage() "); MITK_TEST_CONDITION_REQUIRED(ds == manager->GetDataStorage(), "Testing mitk::LevelWindowManager GetDataStorage "); } static void TestMethodsWithInvalidParameters() { mitk::LevelWindowManager::Pointer manager; manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); bool success = false; mitk::LevelWindowProperty::Pointer levelWindowProperty = mitk::LevelWindowProperty::New(); try { manager->SetLevelWindowProperty(levelWindowProperty); } catch (const mitk::Exception &) { success = true; } MITK_TEST_CONDITION(success, "Testing mitk::LevelWindowManager SetLevelWindowProperty with invalid parameter"); } static void TestOtherMethods() { mitk::LevelWindowManager::Pointer manager; manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); MITK_TEST_CONDITION(manager->isAutoTopMost(), "Testing mitk::LevelWindowManager isAutoTopMost"); // It is not clear what the following code is supposed to test. The expression in // the catch(...) block does have no effect, so success is always true. // Related bugs are 13894 and 13889 /* bool success = true; try { mitk::LevelWindow levelWindow = manager->GetLevelWindow(); manager->SetLevelWindow(levelWindow); } catch (...) { success == false; } MITK_TEST_CONDITION(success,"Testing mitk::LevelWindowManager GetLevelWindow() and SetLevelWindow()"); */ manager->SetAutoTopMostImage(true); MITK_TEST_CONDITION(manager->isAutoTopMost(), "Testing mitk::LevelWindowManager isAutoTopMost()"); } static void TestRemoveObserver(std::string testImageFile) { mitk::LevelWindowManager::Pointer manager; manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); // add multiple objects to the data storage => multiple observers should be created - mitk::Image::Pointer image1 = dynamic_cast(mitk::IOUtil::Load(testImageFile)[0].GetPointer()); + mitk::Image::Pointer image1 = mitk::IOUtil::Load(testImageFile); mitk::DataNode::Pointer node1 = mitk::DataNode::New(); node1->SetData(image1); - mitk::Image::Pointer image2 = dynamic_cast(mitk::IOUtil::Load(testImageFile)[0].GetPointer()); + mitk::Image::Pointer image2 = mitk::IOUtil::Load(testImageFile); mitk::DataNode::Pointer node2 = mitk::DataNode::New(); node2->SetData(image2); ds->Add(node1); ds->Add(node2); MITK_TEST_CONDITION_REQUIRED(manager->GetRelevantNodes()->size() == 2, "Test if nodes have been added"); MITK_TEST_CONDITION_REQUIRED( static_cast(manager->GetRelevantNodes()->size()) == manager->GetNumberOfObservers(), "Test if number of nodes is similar to number of observers"); - mitk::Image::Pointer image3 = dynamic_cast(mitk::IOUtil::Load(testImageFile)[0].GetPointer()); + mitk::Image::Pointer image3 = mitk::IOUtil::Load(testImageFile); mitk::DataNode::Pointer node3 = mitk::DataNode::New(); node3->SetData(image3); ds->Add(node3); MITK_TEST_CONDITION_REQUIRED(manager->GetRelevantNodes()->size() == 3, "Test if another node have been added"); MITK_TEST_CONDITION_REQUIRED( static_cast(manager->GetRelevantNodes()->size()) == manager->GetNumberOfObservers(), "Test if number of nodes is similar to number of observers"); ds->Remove(node1); MITK_TEST_CONDITION_REQUIRED(manager->GetRelevantNodes()->size() == 2, "Deleted node 1 (test GetRelevantNodes())"); MITK_TEST_CONDITION_REQUIRED(manager->GetNumberOfObservers() == 2, "Deleted node 1 (test GetNumberOfObservers())"); ds->Remove(node2); MITK_TEST_CONDITION_REQUIRED(manager->GetRelevantNodes()->size() == 1, "Deleted node 2 (test GetRelevantNodes())"); MITK_TEST_CONDITION_REQUIRED(manager->GetNumberOfObservers() == 1, "Deleted node 2 (test GetNumberOfObservers())"); ds->Remove(node3); MITK_TEST_CONDITION_REQUIRED(manager->GetRelevantNodes()->size() == 0, "Deleted node 3 (test GetRelevantNodes())"); MITK_TEST_CONDITION_REQUIRED(manager->GetNumberOfObservers() == 0, "Deleted node 3 (test GetNumberOfObservers())"); } static bool VerifyRenderingModes() { bool ok = (mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR == 1) && (mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_LEVELWINDOW_COLOR == 2) && (mitk::RenderingModeProperty::LOOKUPTABLE_COLOR == 3) && (mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR == 4); return ok; } static void TestLevelWindowSliderVisibility(std::string testImageFile) { bool renderingModesValid = mitkLevelWindowManagerTestClass::VerifyRenderingModes(); if (!renderingModesValid) { MITK_ERROR << "Exception: Image Rendering.Mode property value types inconsistent."; } mitk::LevelWindowManager::Pointer manager; manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); // add multiple objects to the data storage => multiple observers should be created - mitk::Image::Pointer image1 = dynamic_cast(mitk::IOUtil::Load(testImageFile)[0].GetPointer()); + mitk::Image::Pointer image1 = mitk::IOUtil::Load(testImageFile); mitk::DataNode::Pointer node1 = mitk::DataNode::New(); node1->SetData(image1); ds->Add(node1); mitk::DataNode::Pointer node2 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node3 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); std::vector nodeVec; // nodeVec.resize( 3 ); nodeVec.push_back(node1); nodeVec.push_back(node2); nodeVec.push_back(node3); typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType; RandomGeneratorType::Pointer rnd = RandomGeneratorType::New(); rnd->Initialize(); for (unsigned int i = 0; i < 8; ++i) { unsigned int parity = i; for (unsigned int img = 0; img < 3; ++img) { if (parity & 1) { int mode = rnd->GetIntegerVariate() % 3; nodeVec[img]->SetProperty("Image Rendering.Mode", mitk::RenderingModeProperty::New(mode)); } else { int mode = rnd->GetIntegerVariate() % 2; nodeVec[img]->SetProperty("Image Rendering.Mode", mitk::RenderingModeProperty::New(3 + mode)); } parity >>= 1; } MITK_TEST_CONDITION( renderingModesValid && ((!manager->GetLevelWindowProperty() && !i) || (manager->GetLevelWindowProperty() && i)), "Testing level window property member according to rendering mode"); } } static void TestSetLevelWindowProperty(std::string testImageFile) { mitk::LevelWindowManager::Pointer manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); // add multiple objects to the data storage => multiple observers should be created mitk::DataNode::Pointer node3 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node2 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node1 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); node3->SetIntProperty("layer", 1); node2->SetIntProperty("layer", 2); node1->SetIntProperty("layer", 3); manager->SetAutoTopMostImage(true); bool isImageForLevelWindow1, isImageForLevelWindow2, isImageForLevelWindow3; node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(isImageForLevelWindow1 && !isImageForLevelWindow2 && !isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 1."); manager->SetAutoTopMostImage(false); mitk::LevelWindowProperty::Pointer prop = dynamic_cast(node2->GetProperty("levelwindow")); manager->SetLevelWindowProperty(prop); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(!isImageForLevelWindow1 && isImageForLevelWindow2 && !isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 2."); prop = dynamic_cast(node3->GetProperty("levelwindow")); manager->SetLevelWindowProperty(prop); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(!isImageForLevelWindow1 && !isImageForLevelWindow2 && isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 3."); prop = dynamic_cast(node1->GetProperty("levelwindow")); manager->SetLevelWindowProperty(prop); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(isImageForLevelWindow1 && !isImageForLevelWindow2 && !isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 3."); } static void TestImageForLevelWindowOnVisibilityChange(std::string testImageFile) { mitk::LevelWindowManager::Pointer manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); // add multiple objects to the data storage => multiple observers should be created mitk::DataNode::Pointer node3 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node2 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node1 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); node3->SetIntProperty("layer", 1); node2->SetIntProperty("layer", 2); node1->SetIntProperty("layer", 3); manager->SetAutoTopMostImage(false); bool isImageForLevelWindow1, isImageForLevelWindow2, isImageForLevelWindow3; node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(isImageForLevelWindow1 && !isImageForLevelWindow2 && !isImageForLevelWindow3, "Testing initial imageForLevelWindow setting."); node1->SetVisibility(false); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(!isImageForLevelWindow1 && isImageForLevelWindow2 && !isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 2."); node2->SetVisibility(false); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(!isImageForLevelWindow1 && !isImageForLevelWindow2 && isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 3."); node3->SetVisibility(false); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(!isImageForLevelWindow1 && !isImageForLevelWindow2 && isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 3."); node1->SetVisibility(true); node1->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow1); node2->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow2); node3->GetBoolProperty("imageForLevelWindow", isImageForLevelWindow3); MITK_TEST_CONDITION(isImageForLevelWindow1 && !isImageForLevelWindow2 && !isImageForLevelWindow3, "Testing exclusive imageForLevelWindow property for node 3."); } static void TestImageForLevelWindowOnRandomPropertyChange(std::string testImageFile) { typedef std::vector BoolVecType; typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType; // initialize the data storage mitk::LevelWindowManager::Pointer manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); mitk::DataNode::Pointer node3 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node2 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node1 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); node3->SetIntProperty("layer", 1); node2->SetIntProperty("layer", 2); node1->SetIntProperty("layer", 3); // node visibilities std::vector nodesVisible; nodesVisible.resize(3); std::fill(nodesVisible.begin(), nodesVisible.end(), true); // which node has the level window std::vector nodesForLevelWindow; nodesForLevelWindow.resize(3); std::fill(nodesForLevelWindow.begin(), nodesForLevelWindow.end(), false); // the nodes themselves std::vector nodes; nodes.push_back(node1); nodes.push_back(node2); nodes.push_back(node3); // status quo manager->SetAutoTopMostImage(false); bool lvlWin1, lvlWin2, lvlWin3; node1->GetBoolProperty("imageForLevelWindow", lvlWin1); node2->GetBoolProperty("imageForLevelWindow", lvlWin2); node3->GetBoolProperty("imageForLevelWindow", lvlWin3); MITK_TEST_CONDITION(lvlWin1 && !lvlWin2 && !lvlWin3, "Testing initial imageForLevelWindow setting."); nodesForLevelWindow[0] = lvlWin1; nodesForLevelWindow[1] = lvlWin2; nodesForLevelWindow[2] = lvlWin3; // prepare randomized visibility changes RandomGeneratorType::Pointer ranGen = RandomGeneratorType::New(); ranGen->Initialize(); int ranCount = 100; int validCount = 0; int invalidCount = 0; int mustHaveLvlWindow = 4; for (int run = 0; run < ranCount; ++run) { // toggle node visibility int ran = ranGen->GetIntegerVariate(2); nodes[ran]->SetBoolProperty("imageForLevelWindow", !nodesForLevelWindow[ran]); // one node must have the level window std::vector::const_iterator found = std::find(nodesForLevelWindow.begin(), nodesForLevelWindow.end(), true); if (found == nodesForLevelWindow.end()) { break; } // all invisible? found = std::find(nodesVisible.begin(), nodesVisible.end(), true); if (!nodesForLevelWindow[ran]) { mustHaveLvlWindow = pow(2, 2 - ran); } else { mustHaveLvlWindow = 4; } // get the current status node1->GetBoolProperty("imageForLevelWindow", lvlWin1); node2->GetBoolProperty("imageForLevelWindow", lvlWin2); node3->GetBoolProperty("imageForLevelWindow", lvlWin3); nodesForLevelWindow[0] = lvlWin1; nodesForLevelWindow[1] = lvlWin2; nodesForLevelWindow[2] = lvlWin3; int hasLevelWindow = 0; for (int i = 0; i < 3; ++i) { if (nodesForLevelWindow[i]) { hasLevelWindow += pow(2, 2 - i); } } validCount += hasLevelWindow == mustHaveLvlWindow ? 1 : 0; // test sensitivity int falseran = 0; while (falseran == 0) { falseran = ranGen->GetIntegerVariate(7); } BoolVecType falseNodes; falseNodes.push_back((falseran & 1) == 1 ? !lvlWin1 : lvlWin1); falseran >>= 1; falseNodes.push_back((falseran & 1) == 1 ? !lvlWin2 : lvlWin2); falseran >>= 1; falseNodes.push_back((falseran & 1) == 1 ? !lvlWin3 : lvlWin3); int falseLevelWindow = 0; for (int i = 0; i < 3; ++i) { if (falseNodes[i]) { falseLevelWindow += pow(2, 2 - i); } } invalidCount += falseLevelWindow == mustHaveLvlWindow ? 0 : 1; // in case of errors proceed anyway mustHaveLvlWindow = hasLevelWindow; } MITK_TEST_CONDITION(validCount == ranCount, "Testing proper node for level window property."); MITK_TEST_CONDITION(invalidCount == ranCount, "Sensitivity test."); } static void TestImageForLevelWindowOnRandomVisibilityChange(std::string testImageFile) { typedef std::vector BoolVecType; typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType; // initialize the data storage mitk::LevelWindowManager::Pointer manager = mitk::LevelWindowManager::New(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); manager->SetDataStorage(ds); mitk::DataNode::Pointer node3 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node2 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); mitk::DataNode::Pointer node1 = mitk::IOUtil::Load(testImageFile, *ds)->GetElement(0); node3->SetIntProperty("layer", 1); node2->SetIntProperty("layer", 2); node1->SetIntProperty("layer", 3); // node visibilities std::vector nodesVisible; nodesVisible.resize(3); std::fill(nodesVisible.begin(), nodesVisible.end(), true); // which node has the level window std::vector nodesForLevelWindow; nodesForLevelWindow.resize(3); std::fill(nodesForLevelWindow.begin(), nodesForLevelWindow.end(), false); // the nodes themselves std::vector nodes; nodes.push_back(node1); nodes.push_back(node2); nodes.push_back(node3); // status quo manager->SetAutoTopMostImage(false); bool lvlWin1, lvlWin2, lvlWin3; node1->GetBoolProperty("imageForLevelWindow", lvlWin1); node2->GetBoolProperty("imageForLevelWindow", lvlWin2); node3->GetBoolProperty("imageForLevelWindow", lvlWin3); MITK_TEST_CONDITION(lvlWin1 && !lvlWin2 && !lvlWin3, "Testing initial imageForLevelWindow setting."); nodesForLevelWindow[0] = lvlWin1; nodesForLevelWindow[1] = lvlWin2; nodesForLevelWindow[2] = lvlWin3; // prepare randomized visibility changes RandomGeneratorType::Pointer ranGen = RandomGeneratorType::New(); ranGen->Initialize(); int ranCount = 100; int validCount = 0; int invalidCount = 0; int mustHaveLvlWindow = 4; for (int run = 0; run < ranCount; ++run) { // toggle node visibility int ran = ranGen->GetIntegerVariate(2); nodesVisible[ran] = !nodesVisible[ran]; nodes[ran]->SetVisibility(nodesVisible[ran]); // one node must have the level window std::vector::const_iterator found = std::find(nodesForLevelWindow.begin(), nodesForLevelWindow.end(), true); if (found == nodesForLevelWindow.end()) { break; } int ind = found - nodesForLevelWindow.begin(); // all invisible? found = std::find(nodesVisible.begin(), nodesVisible.end(), true); bool allInvisible = (found == nodesVisible.end()); // which node shall get the level window now if (!allInvisible && !nodesVisible[ind]) { int count = 0; for (std::vector::const_iterator it = nodesVisible.begin(); it != nodesVisible.end(); ++it, ++count) { if (*it) { mustHaveLvlWindow = pow(2, 2 - count); break; } } } // get the current status node1->GetBoolProperty("imageForLevelWindow", lvlWin1); node2->GetBoolProperty("imageForLevelWindow", lvlWin2); node3->GetBoolProperty("imageForLevelWindow", lvlWin3); nodesForLevelWindow[0] = lvlWin1; nodesForLevelWindow[1] = lvlWin2; nodesForLevelWindow[2] = lvlWin3; int hasLevelWindow = 0; for (int i = 0; i < 3; ++i) { if (nodesForLevelWindow[i]) { hasLevelWindow += pow(2, 2 - i); } } validCount += hasLevelWindow == mustHaveLvlWindow ? 1 : 0; // test sensitivity int falseran = 0; while (falseran == 0) { falseran = ranGen->GetIntegerVariate(7); } BoolVecType falseNodes; falseNodes.push_back((falseran & 1) == 1 ? !lvlWin1 : lvlWin1); falseran >>= 1; falseNodes.push_back((falseran & 1) == 1 ? !lvlWin2 : lvlWin2); falseran >>= 1; falseNodes.push_back((falseran & 1) == 1 ? !lvlWin3 : lvlWin3); int falseLevelWindow = 0; for (int i = 0; i < 3; ++i) { if (falseNodes[i]) { falseLevelWindow += pow(2, 2 - i); } } invalidCount += falseLevelWindow == mustHaveLvlWindow ? 0 : 1; // in case of errors proceed anyway mustHaveLvlWindow = hasLevelWindow; } MITK_TEST_CONDITION(validCount == ranCount, "Testing proper node for level window property."); MITK_TEST_CONDITION(invalidCount == ranCount, "Sensitivity test."); } }; int mitkLevelWindowManagerTest(int argc, char *args[]) { MITK_TEST_BEGIN("mitkLevelWindowManager"); MITK_TEST_CONDITION_REQUIRED(argc >= 2, "Testing if test file is given."); std::string testImage = args[1]; mitkLevelWindowManagerTestClass::TestInstantiation(); mitkLevelWindowManagerTestClass::TestSetGetDataStorage(); mitkLevelWindowManagerTestClass::TestMethodsWithInvalidParameters(); mitkLevelWindowManagerTestClass::TestOtherMethods(); mitkLevelWindowManagerTestClass::TestRemoveObserver(testImage); mitkLevelWindowManagerTestClass::TestLevelWindowSliderVisibility(testImage); mitkLevelWindowManagerTestClass::TestSetLevelWindowProperty(testImage); mitkLevelWindowManagerTestClass::TestImageForLevelWindowOnVisibilityChange(testImage); mitkLevelWindowManagerTestClass::TestImageForLevelWindowOnRandomVisibilityChange(testImage); mitkLevelWindowManagerTestClass::TestImageForLevelWindowOnRandomPropertyChange(testImage); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkMultiComponentImageDataComparisonFilterTest.cpp b/Modules/Core/test/mitkMultiComponentImageDataComparisonFilterTest.cpp index 0f52599061..40025975f1 100644 --- a/Modules/Core/test/mitkMultiComponentImageDataComparisonFilterTest.cpp +++ b/Modules/Core/test/mitkMultiComponentImageDataComparisonFilterTest.cpp @@ -1,81 +1,81 @@ /*=================================================================== 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. ===================================================================*/ // mitk includes #include "mitkIOUtil.h" #include "mitkImageReadAccessor.h" #include "mitkMultiComponentImageDataComparisonFilter.h" #include "mitkTestingMacros.h" #include "itkNumericTraits.h" int mitkMultiComponentImageDataComparisonFilterTest(int /*argc*/, char *argv[]) { MITK_TEST_BEGIN("MultiComponentImageDataComparisonFilter"); // instantiation mitk::MultiComponentImageDataComparisonFilter::Pointer testObject = mitk::MultiComponentImageDataComparisonFilter::New(); MITK_TEST_CONDITION_REQUIRED(testObject.IsNotNull(), "Testing instantiation of test class!"); MITK_TEST_CONDITION_REQUIRED(testObject->GetCompareFilterResult() == nullptr, "Testing initialization of result struct"); MITK_TEST_CONDITION_REQUIRED(testObject->GetTolerance() == 0.0f, "Testing initialization of tolerance member"); MITK_TEST_CONDITION_REQUIRED(testObject->GetResult() == false, "Testing initialization of CompareResult member"); // initialize compare result struct and pass it to the filter mitk::CompareFilterResults compareResult; compareResult.m_MaximumDifference = 0.0f; compareResult.m_MinimumDifference = itk::NumericTraits::max(); compareResult.m_MeanDifference = 0.0f; compareResult.m_FilterCompleted = false; compareResult.m_TotalDifference = 0.0f; compareResult.m_PixelsWithDifference = 0; testObject->SetCompareFilterResult(&compareResult); MITK_TEST_CONDITION_REQUIRED(testObject->GetCompareFilterResult() != nullptr, "Testing set/get of compare result struct"); MITK_TEST_CONDITION_REQUIRED(testObject->GetResult() == false, "CompareResult still false"); // now load an image with several components and present it to the filter - mitk::Image::Pointer testImg = dynamic_cast(mitk::IOUtil::Load(argv[1])[0].GetPointer()); + mitk::Image::Pointer testImg = mitk::IOUtil::Load(argv[1]); mitk::Image::Pointer testImg2 = testImg->Clone(); testObject->SetValidImage(testImg); testObject->SetTestImage(testImg2); MITK_TEST_CONDITION_REQUIRED(testObject->GetNumberOfIndexedInputs() == 2, "Testing correct handling of input images"); testObject->Update(); MITK_TEST_CONDITION_REQUIRED(testObject->GetResult(), "Testing filter processing with equal image data"); // now change some of the data and check if the response is correct mitk::ImageReadAccessor imgAcc(testImg2); auto *imgData = (unsigned char *)imgAcc.GetData(); imgData[10] += 1; imgData[20] += 2; imgData[30] += 3; testObject->Update(); MITK_TEST_CONDITION_REQUIRED(testObject->GetResult() == false, "Testing filter processing with unequal image data"); MITK_TEST_CONDITION_REQUIRED( mitk::Equal((int)testObject->GetCompareFilterResult()->m_PixelsWithDifference, (int)3) && mitk::Equal((double)testObject->GetCompareFilterResult()->m_MaximumDifference, (double)3.0) && mitk::Equal((double)testObject->GetCompareFilterResult()->m_MeanDifference, (double)2.0), "Assessing calculated image differences"); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkPointSetDataInteractorTest.cpp b/Modules/Core/test/mitkPointSetDataInteractorTest.cpp index f335a9501f..8897425364 100644 --- a/Modules/Core/test/mitkPointSetDataInteractorTest.cpp +++ b/Modules/Core/test/mitkPointSetDataInteractorTest.cpp @@ -1,207 +1,207 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include "mitkInteractionTestHelper.h" #include #include #include #include #include class mitkPointSetDataInteractorTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPointSetDataInteractorTestSuite); /// \todo Fix VTK memory leaks. Bug 18144. vtkDebugLeaks::SetExitError(0); MITK_TEST(AddPointInteraction); MITK_TEST(MoveDeletePointInteraction); // MITK_TEST(RotatedPlanesInteraction); CPPUNIT_TEST_SUITE_END(); private: mitk::DataNode::Pointer m_TestPointSetNode; mitk::PointSetDataInteractor::Pointer m_DataInteractor; mitk::PointSet::Pointer m_TestPointSet; public: void setUp() { // Create DataNode as a container for our PointSet to be tested m_TestPointSetNode = mitk::DataNode::New(); // Create PointSetData Interactor m_DataInteractor = mitk::PointSetDataInteractor::New(); // Load the according state machine for regular point set interaction m_DataInteractor->LoadStateMachine("PointSet.xml"); // Set the configuration file that defines the triggers for the transitions m_DataInteractor->SetEventConfig("PointSetConfig.xml"); // Create new PointSet which will receive the interaction input m_TestPointSet = mitk::PointSet::New(); m_TestPointSetNode->SetData(m_TestPointSet); // set the DataNode (which already is added to the DataStorage) m_DataInteractor->SetDataNode(m_TestPointSetNode); } void tearDown() { // destroy all objects if (m_TestPointSetNode != nullptr) { m_TestPointSetNode->SetDataInteractor(nullptr); } m_TestPointSetNode = nullptr; m_TestPointSet = nullptr; m_DataInteractor = nullptr; } void AddPointInteraction() { // Path to the reference PointSet std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/TestAddPoints.mps"); // Path to the interaction xml file std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/TestAddPoints.xml"); std::string pic3D = GetTestDataFilePath("Pic3D.nrrd"); - mitk::Image::Pointer referenceImage = dynamic_cast(mitk::IOUtil::Load(pic3D)[0].GetPointer()); + mitk::Image::Pointer referenceImage = mitk::IOUtil::Load(pic3D); mitk::DataNode::Pointer refDN = mitk::DataNode::New(); refDN->SetData(referenceImage); // Create test helper to initialize all necessary objects for interaction mitk::InteractionTestHelper interactionTestHelper(interactionXmlPath); // Add our test node to the DataStorage of our test helper interactionTestHelper.AddNodeToStorage(m_TestPointSetNode); interactionTestHelper.AddNodeToStorage(refDN); // Start Interaction interactionTestHelper.PlaybackInteraction(); // Load the reference PointSet - mitk::PointSet::Pointer referencePointSet = dynamic_cast(mitk::IOUtil::Load(referencePointSetPath)[0].GetPointer()); + mitk::PointSet::Pointer referencePointSet = mitk::IOUtil::Load(referencePointSetPath); // Compare reference with the result of the interaction. Last parameter (false) is set to ignore the geometries. // They are not stored in a file and therefore not equal. CPPUNIT_ASSERT_MESSAGE("", mitk::Equal(referencePointSet, m_TestPointSet, .001, true, false)); } void RotatedPlanesInteraction() { // Path to the reference PointSet std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/PointSetDataInteractor_PointsAdd2d3d.mps"); // Path to the interaction xml file std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/PointSetDataInteractor_PointsAdd2d3d.xml"); std::string pic3D = GetTestDataFilePath("Pic3D.nrrd"); - mitk::Image::Pointer referenceImage = dynamic_cast(mitk::IOUtil::Load(pic3D)[0].GetPointer()); + mitk::Image::Pointer referenceImage = mitk::IOUtil::Load(pic3D); mitk::DataNode::Pointer refDN = mitk::DataNode::New(); refDN->SetData(referenceImage); // Create test helper to initialize all necessary objects for interaction mitk::InteractionTestHelper interactionTestHelper(interactionXmlPath); // Add our test node to the DataStorage of our test helper interactionTestHelper.AddNodeToStorage(m_TestPointSetNode); interactionTestHelper.AddNodeToStorage(refDN); // Start Interaction interactionTestHelper.PlaybackInteraction(); // Load the reference PointSet - mitk::PointSet::Pointer referencePointSet = dynamic_cast(mitk::IOUtil::Load(referencePointSetPath)[0].GetPointer()); + mitk::PointSet::Pointer referencePointSet = mitk::IOUtil::Load(referencePointSetPath); // Compare reference with the result of the interaction. Last parameter (false) is set to ignore the geometries. // They are not stored in a file and therefore not equal. CPPUNIT_ASSERT_MESSAGE("", mitk::Equal(referencePointSet, m_TestPointSet, .001, true, false)); } void PlayInteraction(std::string &xmlFile, mitk::DataNode *node) { mitk::InteractionTestHelper interactionTestHelper(xmlFile); interactionTestHelper.AddNodeToStorage(node); interactionTestHelper.PlaybackInteraction(); } void EvaluateState(std::string &refPsFile, mitk::PointSet::Pointer ps, int selected) { - mitk::PointSet::Pointer refPs = dynamic_cast(mitk::IOUtil::Load(refPsFile)[0].GetPointer()); + mitk::PointSet::Pointer refPs = mitk::IOUtil::Load(refPsFile); refPs->UpdateOutputInformation(); ps->UpdateOutputInformation(); MITK_ASSERT_EQUAL(ps, refPs, ""); MITK_TEST_CONDITION_REQUIRED(true, "Test against reference point set."); MITK_TEST_CONDITION_REQUIRED(ps->GetNumberOfSelected() == 1, "One selected point."); MITK_TEST_CONDITION_REQUIRED(ps->GetSelectInfo(selected), "Testing if proper point is selected."); } void SetupInteractor(mitk::PointSetDataInteractor *dataInteractor, mitk::DataNode *node) { dataInteractor->LoadStateMachine("PointSet.xml"); dataInteractor->SetEventConfig("PointSetConfig.xml"); dataInteractor->SetDataNode(node); } void MoveDeletePointInteraction() { // Path to the reference PointSet std::string referencePointSetPath = GetTestDataFilePath("InteractionTestData/ReferenceData/TestMoveRemovePoints.mps"); // Path to the interaction xml file std::string interactionXmlPath = GetTestDataFilePath("InteractionTestData/Interactions/TestMoveRemovePoints.xml"); std::string pic3D = GetTestDataFilePath("Pic3D.nrrd"); - mitk::Image::Pointer referenceImage = dynamic_cast(mitk::IOUtil::Load(pic3D)[0].GetPointer()); + mitk::Image::Pointer referenceImage = mitk::IOUtil::Load(pic3D); mitk::DataNode::Pointer refDN = mitk::DataNode::New(); refDN->SetData(referenceImage); // Create test helper to initialize all necessary objects for interaction mitk::InteractionTestHelper interactionTestHelper(interactionXmlPath); // Add our test node to the DataStorage of our test helper interactionTestHelper.AddNodeToStorage(m_TestPointSetNode); interactionTestHelper.AddNodeToStorage(refDN); // Start Interaction interactionTestHelper.PlaybackInteraction(); // Load the reference PointSet - mitk::PointSet::Pointer referencePointSet = dynamic_cast(mitk::IOUtil::Load(referencePointSetPath)[0].GetPointer()); + mitk::PointSet::Pointer referencePointSet = mitk::IOUtil::Load(referencePointSetPath); // Compare reference with the result of the interaction. Last parameter (false) is set to ignore the geometries. // They are not stored in a file and therefore not equal. CPPUNIT_ASSERT_MESSAGE("", mitk::Equal(referencePointSet, m_TestPointSet, .001, true, false)); } // this is only for the OpenGL check mitkPointSetDataInteractorTestSuite() : m_RenderingTestHelper(300, 300) {} private: mitk::RenderingTestHelper m_RenderingTestHelper; }; MITK_TEST_SUITE_REGISTRATION(mitkPointSetDataInteractor) diff --git a/Modules/Core/test/mitkPointSetFileIOTest.cpp b/Modules/Core/test/mitkPointSetFileIOTest.cpp index a80f9fa012..ea1023dc00 100644 --- a/Modules/Core/test/mitkPointSetFileIOTest.cpp +++ b/Modules/Core/test/mitkPointSetFileIOTest.cpp @@ -1,193 +1,193 @@ /*=================================================================== 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 "mitkFileWriterRegistry.h" #include "mitkIOUtil.h" #include "mitkPointSet.h" #include "mitkProportionalTimeGeometry.h" #include "mitkTestingMacros.h" #include #include #include #include // unsigned int numberOfTestPointSets = 1; unsigned int numberOfTimeSeries = 5; // create one test PointSet class mitkPointSetFileIOTestClass { public: mitk::PointSet::Pointer m_SavedPointSet; std::string m_FilePath; mitkPointSetFileIOTestClass() {} ~mitkPointSetFileIOTestClass() { if (!m_FilePath.empty()) { std::remove(m_FilePath.c_str()); } } mitk::PointSet::Pointer CreateTestPointSet(mitk::BaseGeometry *geometry = nullptr) { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); std::uniform_real_distribution<> r(0, 1); std::mt19937 gen; for (unsigned int t = 0; t < numberOfTimeSeries; t++) { for (unsigned int position = 0; position < 3; ++position) { mitk::Point3D point; mitk::FillVector3D(point, r(gen), r(gen), r(gen)); pointSet->SetPoint(position, point, t); } } m_SavedPointSet = pointSet; // we set the geometry AFTER adding points. Else all points added via SetPoint would already bee transformed if (geometry != nullptr) { mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New(); timeGeometry->Initialize(geometry, numberOfTimeSeries); pointSet->SetTimeGeometry(timeGeometry); } return pointSet; } void PointSetCompare(mitk::PointSet::Pointer pointSet2, mitk::PointSet::Pointer pointSet1, bool & /*identical*/) { MITK_TEST_CONDITION(pointSet1->GetSize() == pointSet2->GetSize(), "Testing if PointSet size is correct"); for (unsigned int t = 0; t < numberOfTimeSeries; t++) { for (unsigned int i = 0; i < (unsigned int)pointSet1->GetSize(t); ++i) { mitk::Point3D p1 = pointSet1->GetPoint(i); mitk::Point3D p2 = pointSet2->GetPoint(i); // test std::cout << "r point: " << p2 << std::endl; std::cout << "w point: " << p1 << std::endl; // test end MITK_TEST_CONDITION((p1[0] - p2[0]) <= 0.0001, "Testing if X coordinates of the Point are at the same Position"); MITK_TEST_CONDITION((p1[1] - p2[1]) <= 0.0001, "Testing if Y coordinates of the Point are at the same Position"); MITK_TEST_CONDITION((p1[2] - p2[2]) <= 0.0001, "Testing if Z coordinates of the Point are at the same Position"); } } // testing geometry MITK_TEST_CONDITION(mitk::Equal(*(pointSet1->GetGeometry()), *(pointSet2->GetGeometry()), 0.000001, true), "Restored geometry must equal original one."); } bool PointSetWrite(mitk::BaseGeometry *geometry = nullptr) { try { m_SavedPointSet = nullptr; std::ofstream tmpStream; m_FilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream) + ".mps"; MITK_INFO << "PointSet test file at " << m_FilePath; mitk::IOUtil::Save(CreateTestPointSet(geometry), m_FilePath); } catch (std::exception &e) { MITK_ERROR << "Error during pointset creation: " << e.what(); return false; } return true; } void PointSetLoadAndCompareTest() { try { - mitk::PointSet::Pointer pointSet = dynamic_cast(mitk::IOUtil::Load(m_FilePath)[0].GetPointer()); + mitk::PointSet::Pointer pointSet = mitk::IOUtil::Load(m_FilePath); MITK_TEST_CONDITION(pointSet.IsNotNull(), "Testing if the loaded Data are nullptr"); bool identical(true); PointSetCompare(pointSet.GetPointer(), m_SavedPointSet.GetPointer(), identical); } catch (std::exception &e) { MITK_ERROR << "Error during pointset creation: " << e.what(); } } }; // mitkPointSetFileIOTestClass int mitkPointSetFileIOTest(int, char *[]) { MITK_TEST_BEGIN("PointSet"); // minimum test w/ identity geometry { mitkPointSetFileIOTestClass test; MITK_TEST_CONDITION(test.PointSetWrite(), "Testing if the PointSetWriter writes Data"); test.PointSetLoadAndCompareTest(); // load - compare } // case with a more complex geometry { mitkPointSetFileIOTestClass test; mitk::Geometry3D::Pointer g = mitk::Geometry3D::New(); // define arbitrary transformation matrix // the number don't have much meaning - we just want them reproduced // by the writer/reader cycle mitk::BaseGeometry::BoundsArrayType bounds; bounds[0] = -918273645.18293746; bounds[1] = -52.723; bounds[2] = -1.002; bounds[3] = 918273645.18293746; bounds[4] = +1.002; bounds[5] = +52.723; g->SetBounds(bounds); mitk::ScalarType matrixCoeffs[9] = {0.0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8}; mitk::AffineTransform3D::MatrixType matrix; matrix.GetVnlMatrix().set(matrixCoeffs); mitk::AffineTransform3D::OffsetType offset; offset[0] = -43.1829374; offset[1] = 0.0; offset[2] = +43.1829374; mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New(); transform->SetMatrix(matrix); transform->SetOffset(offset); g->SetIndexToWorldTransform(transform); MITK_TEST_CONDITION(test.PointSetWrite(g), "Testing if the PointSetWriter writes Data _with_ geometry"); test.PointSetLoadAndCompareTest(); // load - compare } MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkPointSetLocaleTest.cpp b/Modules/Core/test/mitkPointSetLocaleTest.cpp index f5974259d7..62a82e818d 100644 --- a/Modules/Core/test/mitkPointSetLocaleTest.cpp +++ b/Modules/Core/test/mitkPointSetLocaleTest.cpp @@ -1,162 +1,162 @@ /*=================================================================== 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 "mitkIOUtil.h" #include "mitkPointSet.h" #include "mitkStandardFileLocations.h" #include "mitkTestingMacros.h" #include #include #include #include bool ChangeLocale(const std::string &locale) { try { MITK_TEST_OUTPUT(<< "\n** Changing locale from " << setlocale(LC_ALL, nullptr) << " to '" << locale << "'"); setlocale(LC_ALL, locale.c_str()); std::locale l(locale.c_str()); std::cin.imbue(l); std::cout.imbue(l); return true; } catch (...) { MITK_TEST_OUTPUT(<< "Could not activate locale " << locale << "\n"); return false; } } void ReaderLocaleTest(mitk::Point3D &refPoint, std::string filename) { MITK_TEST_OUTPUT(<< "---- Reader Test ---- "); - mitk::PointSet::Pointer pointSet = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::PointSet::Pointer pointSet = mitk::IOUtil::Load(filename); mitk::Point3D point; if (pointSet->GetPointIfExists(0, &point)) { MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[0] - point[0]) < 0.00001, "read x correct"); MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[1] - point[1]) < 0.00001, "read y correct"); MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[2] - point[2]) < 0.00001, "read z correct"); } else { MITK_TEST_FAILED_MSG(<< "File " << filename << " can not be read - test will not applied."); return; } } void WriterLocaleTest(mitk::Point3D &refPoint, std::string filename) { MITK_TEST_OUTPUT(<< "---- Writer Test---- "); // create pointset mitk::PointSet::Pointer refPointSet = mitk::PointSet::New(); refPointSet->InsertPoint(0, refPoint); // SetPoint(0, refPoint); std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile("testPointSet_XXXXXX.mps"); // write point set mitk::IOUtil::Save(refPointSet, tmpFilePath); std::ifstream stream(tmpFilePath.c_str()); // compare two .mps files std::ifstream refStream(filename.c_str()); MITK_TEST_CONDITION_REQUIRED(refStream, "Read reference point set"); MITK_TEST_CONDITION_REQUIRED(stream, "Read point set"); bool differ = false; if (stream.is_open() && refStream.is_open()) { std::string streamLine; std::string refStreamLine; while (!stream.eof() && !refStream.eof()) { getline(stream, streamLine); getline(refStream, refStreamLine); if (streamLine.compare(refStreamLine) != 0) { differ = true; break; } } stream.close(); refStream.close(); } MITK_TEST_CONDITION_REQUIRED(!differ, "Write point set correct"); } int mitkPointSetLocaleTest(int, char *[]) { MITK_TEST_BEGIN("PointSetLocaleTest"); // create reference point set mitk::PointSet::Pointer refPointSet = mitk::PointSet::New(); mitk::Point3D refPoint; refPoint[0] = 32.2946; refPoint[1] = -17.7359; refPoint[2] = 29.6502; refPointSet->SetPoint(0, refPoint); // create locale list typedef std::list StringList; StringList alllocales; alllocales.push_back("de_DE"); alllocales.push_back("de_DE.utf8"); alllocales.push_back("de_DE.UTF-8"); alllocales.push_back("de_DE@euro"); alllocales.push_back("German_Germany"); // QuickFix for MAC OS X // See for more the Bug #3894 comments #if defined(__APPLE__) || defined(MACOSX) alllocales.push_back("C"); #endif // write a reference file using the "C" locale once ChangeLocale("C"); std::string referenceFilePath = mitk::IOUtil::CreateTemporaryFile("refPointSet_XXXXXX.mps"); MITK_INFO << "Reference PointSet in " << referenceFilePath; // write point set mitk::IOUtil::Save(refPointSet, referenceFilePath); unsigned int numberOfTestedGermanLocales(0); for (auto iter = alllocales.begin(); iter != alllocales.end(); ++iter) { if (ChangeLocale(*iter)) { ++numberOfTestedGermanLocales; WriterLocaleTest(refPoint, referenceFilePath); ReaderLocaleTest(refPoint, referenceFilePath); } } if (numberOfTestedGermanLocales == 0) { MITK_TEST_OUTPUT(<< "Warning: No German locale was found on the system."); } // MITK_TEST_CONDITION_REQUIRED( numberOfTestedGermanLocales > 0, "Verify that at least one German locale has been // tested."); MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkRawImageFileReaderTest.cpp b/Modules/Core/test/mitkRawImageFileReaderTest.cpp index 8b70f53bda..395561e0e0 100644 --- a/Modules/Core/test/mitkRawImageFileReaderTest.cpp +++ b/Modules/Core/test/mitkRawImageFileReaderTest.cpp @@ -1,66 +1,66 @@ /*=================================================================== 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 "mitkIOConstants.h" #include "mitkIOUtil.h" #include "mitkTestFixture.h" #include "mitkTestingMacros.h" class mitkRawImageFileReaderTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkRawImageFileReaderTestSuite); MITK_TEST(testReadFile); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ std::string m_ImagePath; std::string m_ImagePathNrrdRef; // corresponding mhd path for comparision public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override { m_ImagePath = GetTestDataFilePath("brain.raw"); m_ImagePathNrrdRef = GetTestDataFilePath("brainHalfSize.nrrd"); // we need half size because the brain file has // spacing 2 and this reader doesn't support spacing } void tearDown() override {} void testReadFile() { mitk::IFileReader::Options options; options[mitk::IOConstants::DIMENSION()] = 3; options[mitk::IOConstants::PIXEL_TYPE()] = mitk::IOConstants::PIXEL_TYPE_FLOAT(); options[mitk::IOConstants::SIZE_X()] = 91; options[mitk::IOConstants::SIZE_Y()] = 109; options[mitk::IOConstants::SIZE_Z()] = 91; options[mitk::IOConstants::ENDIANNESS()] = mitk::IOConstants::ENDIANNESS_LITTLE(); mitk::Image::Pointer readFile = - dynamic_cast(mitk::IOUtil::Load(m_ImagePath, options).front().GetPointer()); + mitk::IOUtil::Load(m_ImagePath, options); CPPUNIT_ASSERT_MESSAGE("Testing reading a raw file.", readFile.IsNotNull()); // compare with the reference image - mitk::Image::Pointer compareImage = dynamic_cast(mitk::IOUtil::Load(m_ImagePathNrrdRef)[0].GetPointer()); + mitk::Image::Pointer compareImage = mitk::IOUtil::Load(m_ImagePathNrrdRef); MITK_ASSERT_EQUAL( compareImage, readFile, "Testing if image is equal to the same image as reference file loaded with mitk"); } }; MITK_TEST_SUITE_REGISTRATION(mitkRawImageFileReader) diff --git a/Modules/Core/test/mitkRotatedSlice4DTest.cpp b/Modules/Core/test/mitkRotatedSlice4DTest.cpp index 7e0f71305b..61a684c702 100644 --- a/Modules/Core/test/mitkRotatedSlice4DTest.cpp +++ b/Modules/Core/test/mitkRotatedSlice4DTest.cpp @@ -1,87 +1,87 @@ /*=================================================================== 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 "mitkExtractSliceFilter.h" #include "mitkIOUtil.h" #include "mitkImagePixelReadAccessor.h" #include "mitkImageTimeSelector.h" #include "mitkInteractionConst.h" #include "mitkRotationOperation.h" #include "mitkTestingMacros.h" #include /* * The mitkRotatedSlice4DTest loads a 4D image and extracts a specifically rotated slice in each time step's volume. */ int mitkRotatedSlice4DTest(int, char *argv[]) { MITK_TEST_BEGIN("mitkRotatedSlice4DTest"); std::string filename = argv[1]; // load 4D image - mitk::Image::Pointer image4D = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer image4D = mitk::IOUtil::Load(filename); // check inputs if (image4D.IsNull()) { MITK_INFO << "Could not load the file"; return false; } // for each time step... for (unsigned int ts = 0; ts < image4D->GetTimeSteps(); ts++) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(image4D); timeSelector->SetTimeNr(ts); timeSelector->Update(); mitk::Image::Pointer image3D = timeSelector->GetOutput(); int sliceNumber = 5; mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); plane->InitializeStandardPlane(image3D->GetGeometry(), mitk::PlaneGeometry::Frontal, sliceNumber, true, false); // rotate about an arbitrary point and axis... float angle = 30; mitk::Point3D point; point.Fill(sliceNumber); mitk::Vector3D rotationAxis; rotationAxis[0] = 1; rotationAxis[1] = 2; rotationAxis[2] = 3; rotationAxis.Normalize(); // Create Rotation Operation auto *op = new mitk::RotationOperation(mitk::OpROTATE, point, rotationAxis, angle); plane->ExecuteOperation(op); delete op; // Now extract mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(); extractor->SetInput(image3D); extractor->SetWorldGeometry(plane); extractor->Update(); mitk::Image::Pointer extractedPlane; extractedPlane = extractor->GetOutput(); std::stringstream ss; ss << " : Valid slice in timestep " << ts; MITK_TEST_CONDITION_REQUIRED(extractedPlane.IsNotNull(), ss.str().c_str()); } MITK_TEST_END(); } diff --git a/Modules/Core/test/mitkSTLFileReaderTest.cpp b/Modules/Core/test/mitkSTLFileReaderTest.cpp index 0e0b053c59..5e064018b4 100644 --- a/Modules/Core/test/mitkSTLFileReaderTest.cpp +++ b/Modules/Core/test/mitkSTLFileReaderTest.cpp @@ -1,69 +1,69 @@ /*=================================================================== 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 "mitkIOUtil.h" #include "mitkImage.h" #include "mitkSlicedGeometry3D.h" #include "mitkSurface.h" #include "mitkTestFixture.h" #include "mitkTestingMacros.h" #include #include #include #include class mitkSTLFileReaderTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSTLFileReaderTestSuite); MITK_TEST(testReadFile); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ std::string m_SurfacePath; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override { m_SurfacePath = GetTestDataFilePath("ball.stl"); } void tearDown() override {} void testReadFile() { // Read STL-Image from file - mitk::Surface::Pointer surface = dynamic_cast(mitk::IOUtil::Load(m_SurfacePath)[0].GetPointer()); + mitk::Surface::Pointer surface = mitk::IOUtil::Load(m_SurfacePath); // check some basic stuff CPPUNIT_ASSERT_MESSAGE("Reader output not nullptr", surface.IsNotNull()); CPPUNIT_ASSERT_MESSAGE("IsInitialized()", surface->IsInitialized()); CPPUNIT_ASSERT_MESSAGE("mitk::Surface::SetVtkPolyData()", (surface->GetVtkPolyData() != nullptr)); CPPUNIT_ASSERT_MESSAGE("Availability of geometry", (surface->GetGeometry() != nullptr)); // use vtk stl reader for reference vtkSmartPointer myVtkSTLReader = vtkSmartPointer::New(); myVtkSTLReader->SetFileName(m_SurfacePath.c_str()); myVtkSTLReader->Update(); vtkSmartPointer myVtkPolyData = myVtkSTLReader->GetOutput(); // vtkPolyData from vtkSTLReader directly int n = myVtkPolyData->GetNumberOfPoints(); // vtkPolyData from mitkSTLFileReader int m = surface->GetVtkPolyData()->GetNumberOfPoints(); CPPUNIT_ASSERT_MESSAGE("Number of Points in VtkPolyData", (n == m)); } }; MITK_TEST_SUITE_REGISTRATION(mitkSTLFileReader) diff --git a/Modules/Core/test/mitkSurfaceToImageFilterTest.cpp b/Modules/Core/test/mitkSurfaceToImageFilterTest.cpp index 46a2e01938..86f6964139 100644 --- a/Modules/Core/test/mitkSurfaceToImageFilterTest.cpp +++ b/Modules/Core/test/mitkSurfaceToImageFilterTest.cpp @@ -1,257 +1,257 @@ /*=================================================================== 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 #include "mitkSurfaceToImageFilter.h" #include "mitkTestFixture.h" #include class mitkSurfaceToImageFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSurfaceToImageFilterTestSuite); MITK_TEST(test3DSurfaceValidOutput); MITK_TEST(test3DSurfaceCorrect); MITK_TEST(test3DSurfaceIn4DImage); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ mitk::Surface::Pointer m_Surface; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ - void setUp() override { m_Surface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("ball.stl"))[0].GetPointer()); } + void setUp() override { m_Surface = mitk::IOUtil::Load(GetTestDataFilePath("ball.stl")); } void tearDown() override {} void test3DSurfaceValidOutput() { mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New(); mitk::Image::Pointer additionalInputImage = mitk::Image::New(); additionalInputImage->Initialize(mitk::MakeScalarPixelType(), *m_Surface->GetTimeGeometry()); // Arrange the filter surfaceToImageFilter->MakeOutputBinaryOn(); surfaceToImageFilter->SetInput(m_Surface); surfaceToImageFilter->SetImage(additionalInputImage); surfaceToImageFilter->Update(); CPPUNIT_ASSERT_MESSAGE( "SurfaceToImageFilter_AnyInputImageAndModeSetToBinary_ResultIsImageWithUCHARPixelType", surfaceToImageFilter->GetOutput()->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR); surfaceToImageFilter->SetUShortBinaryPixelType(true); surfaceToImageFilter->Update(); CPPUNIT_ASSERT_MESSAGE( "SurfaceToImageFilter_AnyInputImageAndModeSetToBinary_ResultIsImageWithUCHARPixelType", surfaceToImageFilter->GetOutput()->GetPixelType().GetComponentType() == itk::ImageIOBase::USHORT); } void test3DSurfaceCorrect() { mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New(); // todo I don't know if this image is always needed. There is no documentation of the filter. Use git blame and ask // the author. mitk::Image::Pointer additionalInputImage = mitk::Image::New(); auto *dims = new unsigned int[3]; dims[0] = 32; dims[1] = 32; dims[2] = 32; additionalInputImage->Initialize(mitk::MakeScalarPixelType(), 3, dims); additionalInputImage->SetOrigin(m_Surface->GetGeometry()->GetOrigin()); additionalInputImage->GetGeometry()->SetIndexToWorldTransform(m_Surface->GetGeometry()->GetIndexToWorldTransform()); // Arrange the filter // The docu does not really tell if this is always needed. Could we skip SetImage in any case? surfaceToImageFilter->MakeOutputBinaryOn(); surfaceToImageFilter->SetInput(m_Surface); surfaceToImageFilter->SetImage(additionalInputImage); surfaceToImageFilter->Update(); mitk::ImagePixelReadAccessor outputReader(surfaceToImageFilter->GetOutput()); itk::Index<3> idx; bool valuesCorrect = true; // Values outside the ball should be 0 idx[0] = 0; idx[1] = 0, idx[2] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 0; idx[1] = 15, idx[2] = 15; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 15; idx[1] = 15, idx[2] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 15; idx[1] = 0, idx[2] = 15; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 5; idx[1] = 9, idx[2] = 23; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); // Values inside the ball should be 1 idx[0] = 15; idx[1] = 15, idx[2] = 15; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 31; idx[1] = 15, idx[2] = 15; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 2; idx[1] = 15, idx[2] = 15; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 15; idx[1] = 15, idx[2] = 2; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 15; idx[1] = 2, idx[2] = 15; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 6; idx[1] = 9, idx[2] = 23; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); CPPUNIT_ASSERT_MESSAGE("SurfaceToImageFilter_BallSurfaceAsInput_OutputCorrect", valuesCorrect == true); } void test3DSurfaceIn4DImage() { mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New(); mitk::Image::Pointer additionalInputImage = mitk::Image::New(); auto *dims = new unsigned int[4]; dims[0] = 32; dims[1] = 32; dims[2] = 32; dims[3] = 2; additionalInputImage->Initialize(mitk::MakeScalarPixelType(), 4, dims); additionalInputImage->SetOrigin(m_Surface->GetGeometry()->GetOrigin()); additionalInputImage->GetGeometry()->SetIndexToWorldTransform(m_Surface->GetGeometry()->GetIndexToWorldTransform()); mitk::Image::Pointer secondStep = additionalInputImage->Clone(); unsigned int size = sizeof(unsigned char); for (unsigned int i = 0; i < secondStep->GetDimension(); ++i) { size *= secondStep->GetDimension(i); } { mitk::ImageWriteAccessor accessor(secondStep); memset(accessor.GetData(), 1, size); } additionalInputImage->GetTimeGeometry()->Expand(2); additionalInputImage->GetGeometry(1)->SetSpacing(secondStep->GetGeometry()->GetSpacing()); additionalInputImage->GetGeometry(1)->SetOrigin(secondStep->GetGeometry()->GetOrigin()); additionalInputImage->GetGeometry(1)->SetIndexToWorldTransform( secondStep->GetGeometry()->GetIndexToWorldTransform()); { mitk::ImageReadAccessor readAccess(secondStep); additionalInputImage->SetImportVolume(readAccess.GetData(), 0); additionalInputImage->SetImportVolume(readAccess.GetData(), 1); } // Arrange the filter surfaceToImageFilter->MakeOutputBinaryOn(); surfaceToImageFilter->SetInput(m_Surface); surfaceToImageFilter->SetImage(additionalInputImage); surfaceToImageFilter->Update(); mitk::ImagePixelReadAccessor outputReader(surfaceToImageFilter->GetOutput()); itk::Index<4> idx; bool valuesCorrect = true; // Values outside the ball should be 0 idx[0] = 0; idx[1] = 0, idx[2] = 0; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 0; idx[1] = 15, idx[2] = 15; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 15; idx[1] = 15, idx[2] = 0; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 15; idx[1] = 0, idx[2] = 15; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 5; idx[1] = 9, idx[2] = 23; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); // Values inside the ball should be 1 hould be 1 idx[0] = 15; idx[1] = 15, idx[2] = 15; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 31; idx[1] = 15, idx[2] = 15; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 2; idx[1] = 15, idx[2] = 15; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 15; idx[1] = 15, idx[2] = 2; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 15; idx[1] = 2, idx[2] = 15; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); idx[0] = 6; idx[1] = 9, idx[2] = 23; idx[3] = 0; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 1); // Values inside the ball but in the second timestep hould be 0 idx[0] = 15; idx[1] = 15, idx[2] = 15; idx[3] = 1; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 31; idx[1] = 15, idx[2] = 15; idx[3] = 1; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 2; idx[1] = 15, idx[2] = 15; idx[3] = 1; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 15; idx[1] = 15, idx[2] = 2; idx[3] = 1; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 15; idx[1] = 2, idx[2] = 15; idx[3] = 1; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); idx[0] = 6; idx[1] = 9, idx[2] = 23; idx[3] = 1; valuesCorrect = valuesCorrect && (outputReader.GetPixelByIndex(idx) == 0); CPPUNIT_ASSERT_MESSAGE("SurfaceToImageFilter_BallSurfaceAsInput_Output4DCorrect", valuesCorrect == true); } }; MITK_TEST_SUITE_REGISTRATION(mitkSurfaceToImageFilter) diff --git a/Modules/Core/test/mitkVolumeCalculatorTest.cpp b/Modules/Core/test/mitkVolumeCalculatorTest.cpp index 9c23430bbb..f238adf267 100644 --- a/Modules/Core/test/mitkVolumeCalculatorTest.cpp +++ b/Modules/Core/test/mitkVolumeCalculatorTest.cpp @@ -1,62 +1,62 @@ /*=================================================================== 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 "mitkIOUtil.h" #include "mitkImage.h" #include "mitkTestingMacros.h" #include "mitkVolumeCalculator.h" #include int mitkVolumeCalculatorTest(int /*argc*/, char *argv[]) { MITK_TEST_BEGIN("VolumeCalculator") const char *filename = argv[1]; const char *filename3D = argv[2]; mitk::VolumeCalculator::Pointer volumeCalculator = mitk::VolumeCalculator::New(); //********************************************************************* // Part I: Testing calculated volume. // The correct values have been manually calculated using external software. //********************************************************************* - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(filename); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "01 Check if test image could be loaded"); volumeCalculator->SetImage(image); volumeCalculator->SetThreshold(0); volumeCalculator->ComputeVolume(); float volume = volumeCalculator->GetVolume(); MITK_TEST_CONDITION_REQUIRED(volume == 1600, "02 Test Volume Result. Expected 1600 actual value " << volume); volumeCalculator->SetThreshold(255); volumeCalculator->ComputeVolume(); volume = volumeCalculator->GetVolume(); MITK_TEST_CONDITION_REQUIRED(volume == 1272.50, "03 Test Volume Result. Expected 1272.50 actual value " << volume); - image = dynamic_cast(mitk::IOUtil::Load(filename3D)[0].GetPointer()); + image = mitk::IOUtil::Load(filename3D); volumeCalculator->SetImage(image); volumeCalculator->SetThreshold(-1023); volumeCalculator->ComputeVolume(); std::vector volumes = volumeCalculator->GetVolumes(); for (auto it = volumes.begin(); it != volumes.end(); ++it) { MITK_TEST_CONDITION_REQUIRED((*it) == 24.576f, "04 Test Volume Result."); } MITK_TEST_END() } diff --git a/Modules/DataTypesExt/test/mitkCompressedImageContainerTest.cpp b/Modules/DataTypesExt/test/mitkCompressedImageContainerTest.cpp index 137f5e57f8..004db0caaa 100644 --- a/Modules/DataTypesExt/test/mitkCompressedImageContainerTest.cpp +++ b/Modules/DataTypesExt/test/mitkCompressedImageContainerTest.cpp @@ -1,186 +1,186 @@ /*=================================================================== 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 "mitkCompressedImageContainer.h" #include "mitkCoreObjectFactory.h" #include "mitkIOUtil.h" #include "mitkImageDataItem.h" #include "mitkImageReadAccessor.h" class mitkCompressedImageContainerTestClass { public: static void Test(mitk::CompressedImageContainer *container, mitk::Image *image, unsigned int &numberFailed) { container->SetImage(image); // compress mitk::Image::Pointer uncompressedImage = container->GetImage(); // uncompress // check dimensions if (image->GetDimension() != uncompressedImage->GetDimension()) { ++numberFailed; std::cerr << " (EE) Number of image dimensions wrong after uncompression (was: " << image->GetDimension() << ", now: " << uncompressedImage->GetDimension() << ")" << std::endl; } for (unsigned int dim = 0; dim < image->GetDimension(); ++dim) { if (image->GetDimension(dim) != uncompressedImage->GetDimension(dim)) { ++numberFailed; std::cerr << " (EE) Image dimension " << dim << " differs after uncompression (was: " << image->GetDimension(dim) << ", now: " << uncompressedImage->GetDimension(dim) << ")" << std::endl; } } // check pixel type if (image->GetPixelType() != uncompressedImage->GetPixelType()) { ++numberFailed; std::cerr << " (EE) Pixel type wrong after uncompression:" << std::endl; mitk::PixelType m_PixelType = image->GetPixelType(); std::cout << "Original pixel type:" << std::endl; std::cout << " PixelType: " << m_PixelType.GetTypeAsString() << std::endl; std::cout << " BitsPerElement: " << m_PixelType.GetBpe() << std::endl; std::cout << " NumberOfComponents: " << m_PixelType.GetNumberOfComponents() << std::endl; std::cout << " BitsPerComponent: " << m_PixelType.GetBitsPerComponent() << std::endl; // m_PixelType = uncompressedImage->GetPixelType(); std::cout << "Uncompressed pixel type:" << std::endl; std::cout << " PixelType: " << uncompressedImage->GetPixelType().GetTypeAsString() << std::endl; std::cout << " BitsPerElement: " << uncompressedImage->GetPixelType().GetBpe() << std::endl; std::cout << " NumberOfComponents: " << uncompressedImage->GetPixelType().GetNumberOfComponents() << std::endl; std::cout << " BitsPerComponent: " << uncompressedImage->GetPixelType().GetBitsPerComponent() << std::endl; } // check data mitk::PixelType m_PixelType = image->GetPixelType(); unsigned long oneTimeStepSizeInBytes = m_PixelType.GetBpe() >> 3; // bits per element divided by 8 for (unsigned int dim = 0; dim < image->GetDimension(); ++dim) { if (dim < 3) { oneTimeStepSizeInBytes *= image->GetDimension(dim); } } unsigned int numberOfTimeSteps(1); if (image->GetDimension() > 3) { numberOfTimeSteps = image->GetDimension(3); } for (unsigned int timeStep = 0; timeStep < numberOfTimeSteps; ++timeStep) { mitk::ImageReadAccessor origImgAcc(image, image->GetVolumeData(timeStep)); mitk::ImageReadAccessor unCompImgAcc(uncompressedImage, uncompressedImage->GetVolumeData(timeStep)); auto *originalData((unsigned char *)origImgAcc.GetData()); auto *uncompressedData((unsigned char *)unCompImgAcc.GetData()); unsigned long difference(0); for (unsigned long byte = 0; byte < oneTimeStepSizeInBytes; ++byte) { if (originalData[byte] != uncompressedData[byte]) { ++difference; } } if (difference > 0) { ++numberFailed; std::cerr << " (EE) Pixel data in timestep " << timeStep << " not identical after uncompression. " << difference << " pixels different." << std::endl; break; // break "for timeStep" } } } }; /// ctest entry point int mitkCompressedImageContainerTest(int argc, char *argv[]) { // one big variable to tell if anything went wrong unsigned int numberFailed(0); // need one parameter (image filename) if (argc == 0) { std::cerr << "No file specified [FAILED]" << std::endl; return EXIT_FAILURE; } // load the image mitk::Image::Pointer image = nullptr; try { std::cout << "Testing with parameter '" << argv[1] << "'" << std::endl; - image = dynamic_cast(mitk::IOUtil::Load(argv[1])[0].GetPointer()); + image = mitk::IOUtil::Load(argv[1]); } catch (const mitk::Exception &) { std::cout << "File not an image - test will not be applied [PASSED]" << std::endl; std::cout << "[TEST DONE]" << std::endl; return EXIT_SUCCESS; } catch (itk::ExceptionObject &ex) { ++numberFailed; std::cerr << "Exception: " << ex << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << " (II) Could load image." << std::endl; std::cout << "Testing instantiation" << std::endl; // instantiation mitk::CompressedImageContainer::Pointer container = mitk::CompressedImageContainer::New(); if (container.IsNotNull()) { std::cout << " (II) Instantiation works." << std::endl; } else { ++numberFailed; std::cout << "Test failed, and it's the ugliest one!" << std::endl; return EXIT_FAILURE; } // some real work mitkCompressedImageContainerTestClass::Test(container, image, numberFailed); std::cout << "Testing destruction" << std::endl; // freeing container = nullptr; std::cout << " (II) Freeing works." << std::endl; if (numberFailed > 0) { std::cerr << numberFailed << " tests failed." << std::endl; return EXIT_FAILURE; } else { std::cout << "PASSED all tests." << std::endl; return EXIT_SUCCESS; } } diff --git a/Modules/DicomRT/test/mitkRTDoseReaderServiceTest.cpp b/Modules/DicomRT/test/mitkRTDoseReaderServiceTest.cpp index 39a9241b8f..46e04a5bb7 100644 --- a/Modules/DicomRT/test/mitkRTDoseReaderServiceTest.cpp +++ b/Modules/DicomRT/test/mitkRTDoseReaderServiceTest.cpp @@ -1,74 +1,74 @@ /*=================================================================== 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 #include "mitkTemporoSpatialStringProperty.h" #include class mitkRTDoseReaderServiceTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkRTDoseReaderServiceTestSuite); MITK_TEST(TestDoseImage); MITK_TEST(TestProperties); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::ConstPointer m_doseImage; mitk::Image::ConstPointer m_referenceImage; public: void setUp() override { - m_referenceImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("RT/Dose/RT_Dose.nrrd")); - m_doseImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("RT/Dose/RD.dcm")); + m_referenceImage = mitk::IOUtil::Load(GetTestDataFilePath("RT/Dose/RT_Dose.nrrd")); + m_doseImage = mitk::IOUtil::Load(GetTestDataFilePath("RT/Dose/RD.dcm")); } void TestDoseImage() { CPPUNIT_ASSERT_EQUAL_MESSAGE("image should not be null", m_doseImage.IsNotNull(), true); CPPUNIT_ASSERT_EQUAL_MESSAGE("reference image and image should be equal", true, mitk::Equal(*m_doseImage, *m_referenceImage, mitk::eps, true)); } void TestProperties() { CheckStringProperty("DICOM.0008.0060", "RTDOSE"); //Modality auto prescibedDoseProperty = m_doseImage->GetProperty(mitk::RTConstants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str()); auto prescribedDoseGenericProperty = dynamic_cast*>(prescibedDoseProperty.GetPointer()); double actualPrescribedDose = prescribedDoseGenericProperty->GetValue(); double expectedPrescribedDose = 65535 * 0.0010494648*0.8; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("prescribed dose property is not as expected", expectedPrescribedDose, actualPrescribedDose, 1e-5); CheckStringProperty("DICOM.0020.000D", "1.2.826.0.1.3680043.8.176.2013826104517910.408.3433258507"); //StudyInstanceUID CheckStringProperty("DICOM.3004.000E", "0.0010494648"); //DoseGridScaling CheckStringProperty("DICOM.300C.0002.[0].0008.1155", "1.2.826.0.1.3680043.8.176.2013826104526987.672.1228523524"); //ReferencedRTPlanSequence.ReferencedSOPInstanceUID } void CheckStringProperty(const std::string& propertyName, const std::string& expectedPropertyValue) { auto actualProperty = m_doseImage->GetProperty(propertyName.c_str()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Property not found: " + propertyName, actualProperty.IsNotNull(), true); auto actualTemporoSpatialStringProperty = dynamic_cast(actualProperty.GetPointer()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Property has not type string: " + propertyName, actualTemporoSpatialStringProperty != nullptr, true); std::string actualStringProperty = actualTemporoSpatialStringProperty->GetValue(); CPPUNIT_ASSERT_EQUAL_MESSAGE(propertyName + " is not as expected", actualStringProperty, expectedPropertyValue); } }; MITK_TEST_SUITE_REGISTRATION(mitkRTDoseReaderService) diff --git a/Modules/DicomRT/test/mitkRTPlanReaderServiceTest.cpp b/Modules/DicomRT/test/mitkRTPlanReaderServiceTest.cpp index 5ed22e12fb..83b1adefab 100644 --- a/Modules/DicomRT/test/mitkRTPlanReaderServiceTest.cpp +++ b/Modules/DicomRT/test/mitkRTPlanReaderServiceTest.cpp @@ -1,75 +1,75 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkTestFixture.h" #include "mitkImage.h" #include "mitkTemporoSpatialStringProperty.h" #include "mitkBaseProperty.h" #include class mitkRTPlanReaderServiceTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkRTPlanReaderServiceTestSuite); MITK_TEST(TestProperties); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::ConstPointer m_image; public: void setUp() override { - m_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("RT/Plan/rtplan.dcm")); + m_image = mitk::IOUtil::Load(GetTestDataFilePath("RT/Plan/rtplan.dcm")); CPPUNIT_ASSERT_EQUAL(m_image.IsNotNull(), true); } void TestProperties() { CheckStringProperty("DICOM.300A.0010.[0].300A.0013", "1.2.246.352.72.11.320687012.17740.20090508173031"); CheckStringProperty("DICOM.300A.0010.[1].300A.0013", "1.2.246.352.72.11.320687012.17741.20090508173031"); CheckStringProperty("DICOM.300A.0010.[0].300A.0016", "Breast"); CheckStringProperty("DICOM.300A.0010.[1].300A.0016", "CALC POINT"); CheckStringProperty("DICOM.300A.0010.[0].300A.0026", "14"); CheckStringProperty("DICOM.300A.0010.[1].300A.0026", "11.3113869239676"); CheckStringProperty("DICOM.300A.0070.[0].300A.0078", "7"); CheckStringProperty("DICOM.300A.0070.[0].300A.0080", "4"); CheckStringProperty("DICOM.300A.00B0.[0].300A.00C6", "PHOTON"); CheckStringProperty("DICOM.300A.00B0.[1].300A.00C6", "PHOTON"); CheckStringProperty("DICOM.300A.00B0.[2].300A.00C6", "PHOTON"); CheckStringProperty("DICOM.300A.00B0.[3].300A.00C6", "PHOTON"); CheckStringProperty("DICOM.300C.0060.[0].0008.1155", "1.2.246.352.71.4.320687012.3190.20090511122144"); } void CheckStringProperty(const std::string& propertyName, const std::string& expectedPropertyValue) { auto actualProperty = m_image->GetProperty(propertyName.c_str()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Property not found: " + propertyName, actualProperty.IsNotNull(), true); auto actualTemporoSpatialStringProperty = dynamic_cast(actualProperty.GetPointer()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Property has not type string: " + propertyName, actualTemporoSpatialStringProperty != nullptr, true); std::string actualStringProperty = actualTemporoSpatialStringProperty->GetValue(); CPPUNIT_ASSERT_EQUAL_MESSAGE(propertyName + " is not as expected", actualStringProperty, expectedPropertyValue); } }; MITK_TEST_SUITE_REGISTRATION(mitkRTPlanReaderService) diff --git a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkConvertDWITypeTest.cpp b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkConvertDWITypeTest.cpp index 5fc297e330..7594f39ce9 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkConvertDWITypeTest.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkConvertDWITypeTest.cpp @@ -1,46 +1,46 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkIOUtil.h" #include "mitkDWIHeadMotionCorrectionFilter.h" /** * @brief Custom test to provide CMD-line access to the mitk::DWIHeadMotionCorrectionFilter * * @param argv : Input and Output image full path */ int mitkConvertDWITypeTest( int argc, char* argv[] ) { MITK_TEST_BEGIN("mitkConvertDWITypeTest"); MITK_TEST_CONDITION_REQUIRED( argc > 2, "Specify input and output."); - mitk::Image::Pointer inputImage = dynamic_cast(mitk::IOUtil::Load( argv[1] )[0].GetPointer()); + mitk::Image::Pointer inputImage = mitk::IOUtil::Load( argv[1] ); try { mitk::IOUtil::Save(inputImage, argv[2]); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Caught exception: " << e.what(); mitkThrow() << "Failed with exception from subprocess!"; } MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkDWHeadMotionCorrectionTest.cpp b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkDWHeadMotionCorrectionTest.cpp index d8590109e6..7a6ec764e2 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkDWHeadMotionCorrectionTest.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkDWHeadMotionCorrectionTest.cpp @@ -1,55 +1,55 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkIOUtil.h" #include typedef short DiffusionPixelType; typedef mitk::Image DiffusionImageType; /** * @brief Custom test to provide CMD-line access to the mitk::DWIHeadMotionCorrectionFilter * * @param argv : Input and Output image full path */ int mitkDWHeadMotionCorrectionTest( int argc, char* argv[] ) { MITK_TEST_BEGIN("mitkDWHeadMotionCorrectionTest"); MITK_TEST_CONDITION_REQUIRED( argc > 2, "Specify input and output."); - mitk::Image::Pointer inputImage = dynamic_cast(mitk::IOUtil::Load( argv[1] )[0].GetPointer()); + mitk::Image::Pointer inputImage = mitk::IOUtil::Load( argv[1] ); DiffusionImageType* dwimage = static_cast( inputImage.GetPointer() ); mitk::DWIHeadMotionCorrectionFilter::Pointer corrfilter = mitk::DWIHeadMotionCorrectionFilter::New(); corrfilter->SetInput( dwimage ); corrfilter->Update(); try { mitk::IOUtil::Save(corrfilter->GetOutput(), argv[2]); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Catched exception: " << e.what(); mitkThrow() << "Failed with exception from subprocess!"; } MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkExtractSingleShellTest.cpp b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkExtractSingleShellTest.cpp index ea86eec083..ece8cf2f9e 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkExtractSingleShellTest.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkExtractSingleShellTest.cpp @@ -1,102 +1,102 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkIOUtil.h" #include #include "mitkDWIHeadMotionCorrectionFilter.h" #include #include #include typedef short DiffusionPixelType; int mitkExtractSingleShellTest( int argc, char* argv[] ) { MITK_TEST_BEGIN("mitkExtractSingleShellTest"); MITK_TEST_CONDITION_REQUIRED( argc > 3, "Specify input and output and the shell to be extracted"); /* 1. Get input data */ - mitk::Image::Pointer dwimage = dynamic_cast(mitk::IOUtil::Load( argv[1] )[0].GetPointer()); + mitk::Image::Pointer dwimage = mitk::IOUtil::Load( argv[1] ); mitk::GradientDirectionsProperty::Pointer gradientsProperty = static_cast( dwimage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() ); MITK_TEST_CONDITION_REQUIRED( gradientsProperty.IsNotNull(), "Input is a dw-image"); unsigned int extract_value = 0; std::istringstream input(argv[3]); input >> extract_value; typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; typedef mitk::DiffusionPropertyHelper::BValueMapType BValueMap; // GetShellSelection from GUI BValueMap shellSelectionMap; BValueMap originalShellMap = static_cast(dwimage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); std::vector newNumGradientDirections; shellSelectionMap[extract_value] = originalShellMap[extract_value]; newNumGradientDirections.push_back( originalShellMap[extract_value].size() ) ; itk::VectorImage< short, 3 >::Pointer itkVectorImagePointer = itk::VectorImage< short, 3 >::New(); mitk::CastToItkImage(dwimage, itkVectorImagePointer); itk::VectorImage< short, 3 > *vectorImage = itkVectorImagePointer.GetPointer(); mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainer = static_cast( dwimage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetNumGradientDirections(newNumGradientDirections); filter->SetOriginalBValueMap(originalShellMap); filter->SetShellSelectionBValueMap(shellSelectionMap); try { filter->Update(); } catch( const itk::ExceptionObject& e) { MITK_TEST_FAILED_MSG( << "Failed due to ITK exception: " << e.what() ); } mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::CopyProperties(dwimage, outImage, true); outImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); /* * 3. Write output data **/ try { mitk::IOUtil::Save(outImage, argv[2]); } catch( const itk::ExceptionObject& e) { MITK_ERROR << "Catched exception: " << e.what(); mitkThrow() << "Failed with exception from subprocess!"; } MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkImageReconstructionTest.cpp b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkImageReconstructionTest.cpp index c5682e480c..0bec3ebd3b 100755 --- a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkImageReconstructionTest.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkImageReconstructionTest.cpp @@ -1,155 +1,155 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include int mitkImageReconstructionTest(int argc, char* argv[]) { MITK_TEST_BEGIN("mitkImageReconstructionTest"); MITK_TEST_CONDITION_REQUIRED(argc>1,"check for input data") try { - mitk::Image::Pointer dwi = dynamic_cast(mitk::IOUtil::Load(argv[1])[0].GetPointer()); + mitk::Image::Pointer dwi = mitk::IOUtil::Load(argv[1]); itk::VectorImage::Pointer itkVectorImagePointer = itk::VectorImage::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); float b_value = mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi ); mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradients = mitk::DiffusionPropertyHelper::GetGradientContainer(dwi); { MITK_INFO << "Tensor reconstruction " << argv[2]; - mitk::TensorImage::Pointer tensorImage = dynamic_cast(mitk::IOUtil::Load(argv[2])[0].GetPointer()); + mitk::TensorImage::Pointer tensorImage = mitk::IOUtil::Load(argv[2]); typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetBValue( b_value ); filter->SetGradientImage( gradients, itkVectorImagePointer ); filter->Update(); mitk::TensorImage::Pointer testImage = mitk::TensorImage::New(); testImage->InitializeByItk( filter->GetOutput() ); testImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(*testImage, *tensorImage, 0.0001, true), "tensor reconstruction test."); } { MITK_INFO << "Numerical Q-ball reconstruction " << argv[3]; - mitk::OdfImage::Pointer odfImage = dynamic_cast(mitk::IOUtil::Load(argv[3])[0].GetPointer()); + mitk::OdfImage::Pointer odfImage = mitk::IOUtil::Load(argv[3]); typedef itk::DiffusionQballReconstructionImageFilter QballReconstructionImageFilterType; QballReconstructionImageFilterType::Pointer filter = QballReconstructionImageFilterType::New(); filter->SetBValue( b_value ); filter->SetGradientImage( gradients, itkVectorImagePointer ); filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD); filter->Update(); mitk::OdfImage::Pointer testImage = mitk::OdfImage::New(); testImage->InitializeByItk( filter->GetOutput() ); testImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(*testImage, *odfImage, 0.0001, true), "Numerical Q-ball reconstruction test."); } { MITK_INFO << "Standard Q-ball reconstruction " << argv[4]; - mitk::OdfImage::Pointer odfImage = dynamic_cast(mitk::IOUtil::Load(argv[4])[0].GetPointer()); + mitk::OdfImage::Pointer odfImage = mitk::IOUtil::Load(argv[4]); typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetBValue( b_value ); filter->SetGradientImage( gradients, itkVectorImagePointer ); filter->SetLambda(0.006); filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); filter->Update(); mitk::OdfImage::Pointer testImage = mitk::OdfImage::New(); testImage->InitializeByItk( filter->GetOutput() ); testImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(*testImage, *odfImage, 0.0001, true), "Standard Q-ball reconstruction test."); } { MITK_INFO << "CSA Q-ball reconstruction " << argv[5]; - mitk::OdfImage::Pointer odfImage = dynamic_cast(mitk::IOUtil::Load(argv[5])[0].GetPointer()); + mitk::OdfImage::Pointer odfImage = mitk::IOUtil::Load(argv[5]); typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetBValue( b_value ); filter->SetGradientImage( gradients, itkVectorImagePointer ); filter->SetLambda(0.006); filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); mitk::OdfImage::Pointer testImage = mitk::OdfImage::New(); testImage->InitializeByItk( filter->GetOutput() ); testImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(*testImage, *odfImage, 0.0001, true), "CSA Q-ball reconstruction test."); } { MITK_INFO << "ADC profile reconstruction " << argv[6]; - mitk::OdfImage::Pointer odfImage = dynamic_cast(mitk::IOUtil::Load(argv[6])[0].GetPointer()); + mitk::OdfImage::Pointer odfImage = mitk::IOUtil::Load(argv[6]); typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetBValue( b_value ); filter->SetGradientImage( gradients, itkVectorImagePointer ); filter->SetLambda(0.006); filter->SetNormalizationMethod(FilterType::QBAR_ADC_ONLY); filter->Update(); mitk::OdfImage::Pointer testImage = mitk::OdfImage::New(); testImage->InitializeByItk( filter->GetOutput() ); testImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(*testImage, *odfImage, 0.0001, true), "ADC profile reconstruction test."); } { MITK_INFO << "Raw signal modeling " << argv[7]; - mitk::OdfImage::Pointer odfImage = dynamic_cast(mitk::IOUtil::Load(argv[7])[0].GetPointer()); + mitk::OdfImage::Pointer odfImage = mitk::IOUtil::Load(argv[7]); typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetBValue( b_value ); filter->SetGradientImage( gradients, itkVectorImagePointer ); filter->SetLambda(0.006); filter->SetNormalizationMethod(FilterType::QBAR_RAW_SIGNAL); filter->Update(); mitk::OdfImage::Pointer testImage = mitk::OdfImage::New(); testImage->InitializeByItk( filter->GetOutput() ); testImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(*testImage, *odfImage, 0.1, true), "Raw signal modeling test."); } } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkNonLocalMeansDenoisingTest.cpp b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkNonLocalMeansDenoisingTest.cpp index 17f3be9562..daa077efe1 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkNonLocalMeansDenoisingTest.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkNonLocalMeansDenoisingTest.cpp @@ -1,169 +1,169 @@ /*=================================================================== 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 "mitkIOUtil.h" #include "mitkTestingMacros.h" #include "mitkTestFixture.h" #include "itkNonLocalMeansDenoisingFilter.h" #include "mitkGradientDirectionsProperty.h" #include "mitkITKImageImport.h" #include class mitkNonLocalMeansDenoisingTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkNonLocalMeansDenoisingTestSuite); MITK_TEST(Denoise_NLMg_shouldReturnTrue); MITK_TEST(Denoise_NLMr_shouldReturnTrue); MITK_TEST(Denoise_NLMv_shouldReturnTrue); MITK_TEST(Denoise_NLMvr_shouldReturnTrue); CPPUNIT_TEST_SUITE_END(); private: typedef itk::VectorImage VectorImagetType; /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/ mitk::Image::Pointer m_Image; mitk::Image::Pointer m_ReferenceImage; mitk::Image::Pointer m_DenoisedImage; itk::Image::Pointer m_ImageMask; itk::NonLocalMeansDenoisingFilter::Pointer m_DenoisingFilter; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override { //generate test images std::string imagePath = GetTestDataFilePath("DiffusionImaging/Denoising/test_multi.dwi"); - m_Image = dynamic_cast(mitk::IOUtil::Load(imagePath)[0].GetPointer()); + m_Image = mitk::IOUtil::Load(imagePath); m_ReferenceImage = nullptr; m_DenoisedImage = mitk::Image::New(); //initialise Filter m_DenoisingFilter = itk::NonLocalMeansDenoisingFilter::New(); VectorImagetType::Pointer vectorImage; mitk::CastToItkImage(m_Image,vectorImage); m_DenoisingFilter->SetInputImage(vectorImage); m_DenoisingFilter->SetNumberOfThreads(1); m_DenoisingFilter->SetComparisonRadius(1); m_DenoisingFilter->SetSearchRadius(1); m_DenoisingFilter->SetVariance(500); } void tearDown() override { m_Image = nullptr; m_ImageMask = nullptr; m_ReferenceImage = nullptr; m_DenoisingFilter = nullptr; m_DenoisedImage = nullptr; } void Denoise_NLMg_shouldReturnTrue() { std::string referenceImagePath = GetTestDataFilePath("DiffusionImaging/Denoising/test_multi_NLMg.dwi"); - m_ReferenceImage = dynamic_cast(mitk::IOUtil::Load(referenceImagePath)[0].GetPointer()); + m_ReferenceImage = mitk::IOUtil::Load(referenceImagePath); m_DenoisingFilter->SetUseRicianAdaption(false); m_DenoisingFilter->SetUseJointInformation(false); try { m_DenoisingFilter->Update(); } catch(std::exception& e) { MITK_ERROR << e.what(); } mitk::GrabItkImageMemory(m_DenoisingFilter->GetOutput(),m_DenoisedImage); m_DenoisedImage->SetPropertyList(m_Image->GetPropertyList()->Clone()); MITK_ASSERT_EQUAL( m_DenoisedImage, m_ReferenceImage, "NLMg should always return the same result."); } void Denoise_NLMr_shouldReturnTrue() { std::string referenceImagePath = GetTestDataFilePath("DiffusionImaging/Denoising/test_multi_NLMr.dwi"); - m_ReferenceImage = dynamic_cast(mitk::IOUtil::Load(referenceImagePath)[0].GetPointer()); + m_ReferenceImage = mitk::IOUtil::Load(referenceImagePath); m_DenoisingFilter->SetUseRicianAdaption(true); m_DenoisingFilter->SetUseJointInformation(false); try { m_DenoisingFilter->Update(); } catch(std::exception& e) { MITK_ERROR << e.what(); } mitk::GrabItkImageMemory(m_DenoisingFilter->GetOutput(),m_DenoisedImage); m_DenoisedImage->SetPropertyList(m_Image->GetPropertyList()->Clone()); MITK_ASSERT_EQUAL( m_DenoisedImage, m_ReferenceImage, "NLMr should always return the same result."); } void Denoise_NLMv_shouldReturnTrue() { std::string referenceImagePath = GetTestDataFilePath("DiffusionImaging/Denoising/test_multi_NLMv.dwi"); - m_ReferenceImage = dynamic_cast(mitk::IOUtil::Load(referenceImagePath)[0].GetPointer()); + m_ReferenceImage = mitk::IOUtil::Load(referenceImagePath); m_DenoisingFilter->SetUseRicianAdaption(false); m_DenoisingFilter->SetUseJointInformation(true); try { m_DenoisingFilter->Update(); } catch(std::exception& e) { MITK_ERROR << e.what(); } mitk::GrabItkImageMemory(m_DenoisingFilter->GetOutput(),m_DenoisedImage); m_DenoisedImage->SetPropertyList(m_Image->GetPropertyList()->Clone()); MITK_ASSERT_EQUAL( m_DenoisedImage, m_ReferenceImage, "NLMv should always return the same result."); } void Denoise_NLMvr_shouldReturnTrue() { std::string referenceImagePath = GetTestDataFilePath("DiffusionImaging/Denoising/test_multi_NLMvr.dwi"); - m_ReferenceImage = dynamic_cast(mitk::IOUtil::Load(referenceImagePath)[0].GetPointer()); + m_ReferenceImage = mitk::IOUtil::Load(referenceImagePath); m_DenoisingFilter->SetUseRicianAdaption(true); m_DenoisingFilter->SetUseJointInformation(true); try { m_DenoisingFilter->Update(); } catch(std::exception& e) { MITK_ERROR << e.what(); } mitk::GrabItkImageMemory(m_DenoisingFilter->GetOutput(),m_DenoisedImage); m_DenoisedImage->SetPropertyList(m_Image->GetPropertyList()->Clone()); MITK_ASSERT_EQUAL( m_DenoisedImage, m_ReferenceImage, "NLMvr should always return the same result."); } }; MITK_TEST_SUITE_REGISTRATION(mitkNonLocalMeansDenoising) diff --git a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkPyramidImageRegistrationMethodTest.cpp b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkPyramidImageRegistrationMethodTest.cpp index f462ab8376..44a632e594 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Testing/mitkPyramidImageRegistrationMethodTest.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Testing/mitkPyramidImageRegistrationMethodTest.cpp @@ -1,156 +1,156 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkIOUtil.h" #include "Registration/mitkPyramidImageRegistrationMethod.h" #include int mitkPyramidImageRegistrationMethodTest( int argc, char* argv[] ) { if( argc < 4 ) { MITK_ERROR << "Not enough input \n Usage: fixed moving type [output_image [output_transform]]" << "\n \t fixed : the path to the fixed image \n" << " \t moving : path to the image to be registered" << " \t type : Affine or Rigid defining the type of the transformation" << " \t output_image : output file optional, (full) path, and optionally output_transform : also (full)path to file"; return EXIT_FAILURE; } MITK_TEST_BEGIN("PyramidImageRegistrationMethodTest"); - mitk::Image::Pointer fixedImage = dynamic_cast(mitk::IOUtil::Load( argv[1] )[0].GetPointer()); - mitk::Image::Pointer movingImage = dynamic_cast(mitk::IOUtil::Load( argv[2] )[0].GetPointer()); + mitk::Image::Pointer fixedImage = mitk::IOUtil::Load( argv[1] ); + mitk::Image::Pointer movingImage = mitk::IOUtil::Load( argv[2] ); std::string type_flag( argv[3] ); mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New(); registrationMethod->SetFixedImage( fixedImage ); registrationMethod->SetMovingImage( movingImage ); if( type_flag == "Rigid" ) { registrationMethod->SetTransformToRigid(); } else if( type_flag == "Affine" ) { registrationMethod->SetTransformToAffine(); } else { MITK_WARN << " No type specified, using 'Affine' ."; } registrationMethod->Update(); bool imageOutput = false; bool transformOutput = false; std::string image_out_filename, transform_out_filename; std::string first_output( argv[4] ); // check for txt, otherwise suppose it is an image if( first_output.find(".txt") != std::string::npos ) { transformOutput = true; transform_out_filename = first_output; } else { imageOutput = true; image_out_filename = first_output; } if( argc > 4 ) { std::string second_output( argv[5] ); if( second_output.find(".txt") != std::string::npos ) { transformOutput = true; transform_out_filename = second_output; } } MITK_INFO << " Selected output: " << transform_out_filename << " " << image_out_filename; try{ unsigned int paramCount = registrationMethod->GetNumberOfParameters(); double* params = new double[ paramCount ]; registrationMethod->GetParameters( ¶ms[0] ); std::cout << "Parameters: "; for( unsigned int i=0; i< paramCount; i++) { std::cout << params[ i ] << " "; } std::cout << std::endl; if( imageOutput ) { mitk::IOUtil::Save( registrationMethod->GetResampledMovingImage(), image_out_filename.c_str() ); } if( transformOutput ) { itk::TransformFileWriter::Pointer writer = itk::TransformFileWriter::New(); // Get transform parameter for resampling / saving // Affine if( paramCount == 12 ) { typedef itk::AffineTransform< double > TransformType; TransformType::Pointer transform = TransformType::New(); TransformType::ParametersType affine_params( paramCount ); registrationMethod->GetParameters( &affine_params[0] ); transform->SetParameters( affine_params ); writer->SetInput( transform ); } // Rigid else { typedef itk::Euler3DTransform< double > RigidTransformType; RigidTransformType::Pointer rtransform = RigidTransformType::New(); RigidTransformType::ParametersType rigid_params( paramCount ); registrationMethod->GetParameters( &rigid_params[0] ); rtransform->SetParameters( rigid_params ); writer->SetInput( rtransform ); } writer->SetFileName( transform_out_filename ); writer->Update(); } } catch( const std::exception &e) { MITK_ERROR << "Caught exception: " << e.what(); } MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp index 44de3cca72..d852c6626c 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/CopyGeometry.cpp @@ -1,114 +1,114 @@ /*=================================================================== 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 "mitkCommandLineParser.h" /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Copy Geometry"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Copies transformation matrix of one image to another"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false); parser.addArgument("ref", "r", mitkCommandLineParser::InputFile, "Reference:", "reference image", us::Any(), false); parser.addArgument("alignCentroid", "a", mitkCommandLineParser::Bool, "align centroids", "align centroids", us::Any(), true); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["in"]); std::string refImage = us::any_cast(parsedArgs["ref"]); std::string outImage = us::any_cast(parsedArgs["out"]); bool originOnly = false; // Show a help message if ( parsedArgs.count("alignCentroid") || parsedArgs.count("a")) { originOnly = true; } try { - mitk::Image::Pointer source = dynamic_cast(mitk::IOUtil::Load(refImage)[0].GetPointer()); - mitk::Image::Pointer target = dynamic_cast(mitk::IOUtil::Load(imageName)[0].GetPointer()); + mitk::Image::Pointer source = mitk::IOUtil::Load(refImage); + mitk::Image::Pointer target = mitk::IOUtil::Load(imageName); if (originOnly) { // Calculate correction to align centroids double c[3]; c[0] = source->GetGeometry()->GetOrigin()[0] + source->GetGeometry()->GetExtent(0)/2.0 - target->GetGeometry()->GetOrigin()[0] - target->GetGeometry()->GetExtent(0)/2.0; c[1] = source->GetGeometry()->GetOrigin()[1] + source->GetGeometry()->GetExtent(1)/2.0 - target->GetGeometry()->GetOrigin()[1] - target->GetGeometry()->GetExtent(1)/2.0; c[2] = source->GetGeometry()->GetOrigin()[2] + source->GetGeometry()->GetExtent(2)/2.0 - target->GetGeometry()->GetOrigin()[2] - target->GetGeometry()->GetExtent(2)/2.0; double newOrigin[3]; newOrigin[0] = target->GetGeometry()->GetOrigin()[0] +c[0]; newOrigin[1] = target->GetGeometry()->GetOrigin()[1] +c[1]; newOrigin[2] = target->GetGeometry()->GetOrigin()[2] +c[2]; target->GetGeometry()->SetOrigin(newOrigin); } else { mitk::BaseGeometry* s_geom = source->GetGeometry(); mitk::BaseGeometry* t_geom = target->GetGeometry(); t_geom->SetIndexToWorldTransform(s_geom->GetIndexToWorldTransform()); target->SetGeometry(t_geom); } mitk::IOUtil::Save(target, outImage); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DImp.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DImp.cpp index 7b5aa3b823..847039890b 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DImp.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DImp.cpp @@ -1,67 +1,67 @@ /*=================================================================== 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 "mitkCommandLineParser.h" /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("DIMP"); parser.setCategory("Preprocessing Tools"); parser.setDescription("TEMPORARY: Converts DICOM to other image types"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["in"]); std::string outImage = us::any_cast(parsedArgs["out"]); try { - mitk::Image::Pointer source = dynamic_cast(mitk::IOUtil::Load(imageName)[0].GetPointer()); + mitk::Image::Pointer source = mitk::IOUtil::Load(imageName); mitk::IOUtil::Save(source, outImage); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DReg.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DReg.cpp index d129043cb9..a14e4a983f 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/DReg.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/DReg.cpp @@ -1,133 +1,133 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include typedef mitk::DiffusionPropertyHelper DPH; /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("DREG"); parser.setCategory("Preprocessing Tools"); parser.setDescription("TEMPORARY: Rigid registration of two images"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "f", mitkCommandLineParser::InputFile, "Fixed:", "fixed image", us::Any(), false); parser.addArgument("", "m", mitkCommandLineParser::InputFile, "Moving:", "moving image", us::Any(), false); parser.addArgument("", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string f = us::any_cast(parsedArgs["f"]); std::string m = us::any_cast(parsedArgs["m"]); std::string o = us::any_cast(parsedArgs["o"]); try { typedef itk::Image< float, 3 > ItkFloatImageType; - mitk::Image::Pointer fixed = dynamic_cast(mitk::IOUtil::Load(f)[0].GetPointer()); - mitk::Image::Pointer moving = dynamic_cast(mitk::IOUtil::Load(m)[0].GetPointer()); + mitk::Image::Pointer fixed = mitk::IOUtil::Load(f); + mitk::Image::Pointer moving = mitk::IOUtil::Load(m); mitk::Image::Pointer fixed_single = fixed; mitk::Image::Pointer moving_single = moving; mitk::MultiModalRigidDefaultRegistrationAlgorithm< ItkFloatImageType >::Pointer algo = mitk::MultiModalRigidDefaultRegistrationAlgorithm< ItkFloatImageType >::New(); mitk::MITKAlgorithmHelper helper(algo); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(fixed)) { DPH::ImageType::Pointer itkVectorImagePointer = DPH::ImageType::New(); mitk::CastToItkImage(fixed, itkVectorImagePointer); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(0); filter->Update(); fixed_single = mitk::Image::New(); fixed_single->InitializeByItk( filter->GetOutput() ); fixed_single->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); } if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(moving)) { DPH::ImageType::Pointer itkVectorImagePointer = DPH::ImageType::New(); mitk::CastToItkImage(moving, itkVectorImagePointer); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(0); filter->Update(); moving_single = mitk::Image::New(); moving_single->InitializeByItk( filter->GetOutput() ); moving_single->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); } helper.SetData(moving_single, fixed_single); mitk::MAPRegistrationWrapper::Pointer reg = helper.GetMITKRegistrationWrapper(); mitk::Image::Pointer registered_image = mitk::ImageMappingHelper::refineGeometry(moving, reg, true); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(registered_image)) { mitk::DiffusionPropertyHelper propertyHelper( registered_image ); propertyHelper.InitializeImage(); std::string file_extension = itksys::SystemTools::GetFilenameExtension(o); if (file_extension==".nii" || file_extension==".nii.gz") mitk::IOUtil::Save(registered_image, "application/vnd.mitk.nii.gz", o); else mitk::IOUtil::Save(registered_image, o); } else mitk::IOUtil::Save(registered_image, o); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp index 5784d3389a..558c1873d6 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ImageResampler.cpp @@ -1,420 +1,420 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" #include "itkResampleDwiImageFilter.h" typedef itk::Image InputImageType; typedef itk::Image BinaryImageType; static mitk::Image::Pointer TransformToReference(mitk::Image *reference, mitk::Image *moving, bool sincInterpol = false, bool nn = false) { // Convert to itk Images // Identify Transform typedef itk::IdentityTransform T_Transform; T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 3> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); typedef itk::LinearInterpolateImageFunction< InputImageType> LinearInterpolateImageFunctionType; LinearInterpolateImageFunctionType::Pointer lin_interpolator = LinearInterpolateImageFunctionType::New(); typedef itk::NearestNeighborInterpolateImageFunction< BinaryImageType> NearestNeighborInterpolateImageFunctionType; NearestNeighborInterpolateImageFunctionType::Pointer nn_interpolator = NearestNeighborInterpolateImageFunctionType::New(); if (!nn) { InputImageType::Pointer itkReference = InputImageType::New(); InputImageType::Pointer itkMoving = InputImageType::New(); mitk::CastToItkImage(reference,itkReference); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); if ( sincInterpol) resampler->SetInterpolator(sinc_interpolator); else resampler->SetInterpolator(lin_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory( resampler->GetOutput() , result ); return result; } BinaryImageType::Pointer itkReference = BinaryImageType::New(); BinaryImageType::Pointer itkMoving = BinaryImageType::New(); mitk::CastToItkImage(reference,itkReference); mitk::CastToItkImage(moving,itkMoving); typedef itk::ResampleImageFilter ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkMoving); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); resampler->SetTransform(_pTransform); resampler->SetInterpolator(nn_interpolator); resampler->Update(); // Convert back to mitk mitk::Image::Pointer result = mitk::Image::New(); result->InitializeByItk(resampler->GetOutput()); GrabItkImageMemory( resampler->GetOutput() , result ); return result; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } static std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = true, bool useNN = false) { if (!useNN) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType; LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New(); typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); if (useLinInt) _pResizeFilter->SetInterpolator(lin_interpolator); else _pResizeFilter->SetInterpolator(sinc_interpolator); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } BinaryImageType::Pointer itkImage = BinaryImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. BinaryImageType::SpacingType inputSpacing = itkImage->GetSpacing(); BinaryImageType::SpacingType outputSpacing; const BinaryImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); BinaryImageType::SizeType outputSize; typedef BinaryImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::NearestNeighborInterpolateImageFunction< BinaryImageType> NearestNeighborInterpolateImageType; NearestNeighborInterpolateImageType::Pointer nn_interpolator = NearestNeighborInterpolateImageType::New(); _pResizeFilter->SetInterpolator(nn_interpolator); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } static mitk::Image::Pointer ResampleDWIbySpacing(mitk::Image::Pointer input, float* spacing) { itk::Vector spacingVector; spacingVector[0] = spacing[0]; spacingVector[1] = spacing[1]; spacingVector[2] = spacing[2]; typedef itk::ResampleDwiImageFilter ResampleFilterType; mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(input, itkVectorImagePointer); ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput( itkVectorImagePointer ); resampler->SetInterpolation(ResampleFilterType::Interpolate_Linear); resampler->SetNewSpacing(spacingVector); resampler->Update(); mitk::Image::Pointer output = mitk::GrabItkImageMemory( resampler->GetOutput() ); output->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( mitk::DiffusionPropertyHelper::GetGradientContainer(input) ) ); output->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( mitk::DiffusionPropertyHelper::GetReferenceBValue(input) ) ); mitk::DiffusionPropertyHelper propertyHelper( output ); propertyHelper.InitializeImage(); return output; } int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Image Resampler"); parser.setCategory("Preprocessing Tools"); parser.setContributor("MIC"); parser.setDescription("Resample an image to eigther a specific spacing or to a reference image."); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "Input:", "Input file",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output:", "Output file",us::Any(),false); parser.addArgument("spacing", "s", mitkCommandLineParser::String, "Spacing:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); parser.addArgument("reference", "r", mitkCommandLineParser::InputImage, "Reference:", "Resample using supplied reference image. Also cuts image to same dimensions",us::Any()); parser.addArgument("win-sinc", "w", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); parser.addArgument("nearest-neigh", "n", mitkCommandLineParser::Bool, "Nearest Neighbor:", "Use Nearest Neighbor interpolation instead of linear interpolation ",us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool useSpacing = false; bool useLinearInterpol = true; bool useNN= false; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("sinc-int")) useLinearInterpol = false; if (parsedArgs.count("nearest-neigh")) useNN = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string outputFile = us::any_cast(parsedArgs["output"]); std::string inputFile = us::any_cast(parsedArgs["input"]); std::vector spacings; float spacing[] = { 0.0f, 0.0f, 0.0f }; if (parsedArgs.count("spacing")) { std::string arg = us::any_cast(parsedArgs["spacing"]); if (arg != "") { spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); useSpacing = true; } } std::string refImageFile = ""; if (parsedArgs.count("reference")) { refImageFile = us::any_cast(parsedArgs["reference"]); } if (refImageFile =="" && useSpacing == false) { MITK_ERROR << "No information how to resample is supplied. Use eigther --spacing or --reference !"; return EXIT_FAILURE; } mitk::Image::Pointer refImage; if (!useSpacing) - refImage = dynamic_cast(mitk::IOUtil::Load(refImageFile)[0].GetPointer()); + refImage = mitk::IOUtil::Load(refImageFile); - mitk::Image::Pointer inputDWI = dynamic_cast(mitk::IOUtil::Load(inputFile)[0].GetPointer()); + mitk::Image::Pointer inputDWI = mitk::IOUtil::Load(inputFile); if ( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(inputDWI.GetPointer())) { mitk::Image::Pointer outputImage; if (useSpacing) outputImage = ResampleDWIbySpacing(inputDWI, spacing); else { MITK_WARN << "Not supported yet, to resample a DWI please set a new spacing."; return EXIT_FAILURE; } mitk::IOUtil::Save(outputImage, outputFile.c_str()); return EXIT_SUCCESS; } - mitk::Image::Pointer inputImage = dynamic_cast(mitk::IOUtil::Load(inputFile)[0].GetPointer()); + mitk::Image::Pointer inputImage = mitk::IOUtil::Load(inputFile); mitk::Image::Pointer resultImage; if (useSpacing) resultImage = ResampleBySpacing(inputImage,spacing,useLinearInterpol,useNN); else resultImage = TransformToReference(refImage,inputImage,useLinearInterpol,useNN); mitk::IOUtil::Save(resultImage, outputFile); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp index b4f2c2d26f..6f2b3c862d 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/Registration.cpp @@ -1,446 +1,446 @@ /*=================================================================== 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. ===================================================================*/ // CTK #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include // ITK #include #include #include "itkLinearInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkIdentityTransform.h" #include "itkResampleImageFilter.h" #include "itkNrrdImageIO.h" typedef std::vector FileListType; typedef itk::Image InputImageType; static mitk::Image::Pointer ExtractFirstTS(mitk::Image* image, std::string fileType) { if (fileType == ".dwi") return image; mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New(); selector->SetInput(image); selector->SetTimeNr(0); selector->UpdateLargestPossibleRegion(); mitk::Image::Pointer img =selector->GetOutput()->Clone(); return img; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } static std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } /// Create list of all files in provided folder ending with same postfix static FileListType CreateFileList(std::string folder , std::string postfix) { itk::Directory::Pointer dir = itk::Directory::New(); FileListType fileList; if( dir->Load(folder.c_str() ) ) { int n = dir->GetNumberOfFiles(); for(int r=0;rGetFile( r ); if (filename == "." || filename == "..") continue; filename = folder + filename; if (!itksys::SystemTools::FileExists( filename.c_str())) continue; if (filename.length() <= postfix.length() ) continue; if (filename.substr(filename.length() -postfix.length() ) == postfix) fileList.push_back(filename); } } return fileList; } static std::string GetSavePath(std::string outputFolder, std::string fileName) { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileName); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(fileName); std::string savePathAndFileName = outputFolder +fileStem + fileType; return savePathAndFileName; } static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing) { InputImageType::Pointer itkImage = InputImageType::New(); CastToItkImage(input,itkImage); /** * 1) Resampling * */ // Identity transform. // We don't want any transform on our image except rescaling which is not // specified by a transform but by the input/output spacing as we will see // later. // So no transform will be specified. typedef itk::IdentityTransform T_Transform; // The resampler type itself. typedef itk::ResampleImageFilter T_ResampleFilter; // Prepare the resampler. // Instantiate the transform and specify it should be the id transform. T_Transform::Pointer _pTransform = T_Transform::New(); _pTransform->SetIdentity(); // Instantiate the resampler. Wire in the transform and the interpolator. T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New(); _pResizeFilter->SetTransform(_pTransform); // Set the output origin. _pResizeFilter->SetOutputOrigin(itkImage->GetOrigin()); // Compute the size of the output. // The size (# of pixels) in the output is recomputed using // the ratio of the input and output sizes. InputImageType::SpacingType inputSpacing = itkImage->GetSpacing(); InputImageType::SpacingType outputSpacing; const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion(); InputImageType::SizeType outputSize; typedef InputImageType::SizeType::SizeValueType SizeValueType; // Set the output spacing. outputSpacing[0] = spacing[0]; outputSpacing[1] = spacing[1]; outputSpacing[2] = spacing[2]; outputSize[0] = static_cast(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5); outputSize[1] = static_cast(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5); outputSize[2] = static_cast(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5); _pResizeFilter->SetOutputSpacing(outputSpacing); _pResizeFilter->SetSize(outputSize); typedef itk::Function::WelchWindowFunction<4> WelchWindowFunction; typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4,WelchWindowFunction> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); _pResizeFilter->SetInterpolator(sinc_interpolator); // Specify the input. _pResizeFilter->SetInput(itkImage); _pResizeFilter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(_pResizeFilter->GetOutput()); mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image); return image; } /// Build a derived file name from moving images e.g. xxx_T2.nrrd becomes xxx_GTV.nrrd static FileListType CreateDerivedFileList(std::string baseFN, std::string baseSuffix, std::vector derivedPatterns) { FileListType files; for (unsigned int i=0; i < derivedPatterns.size(); i++) { std::string derResourceSuffix = derivedPatterns.at(i); std::string derivedResourceFilename = baseFN.substr(0,baseFN.length() -baseSuffix.length()) + derResourceSuffix; MITK_INFO <<" Looking for file: " << derivedResourceFilename; if (!itksys::SystemTools::FileExists(derivedResourceFilename.c_str())) { MITK_INFO << "CreateDerivedFileList: File does not exit. Skipping entry."; continue; } files.push_back(derivedResourceFilename); } return files; } /// Copy derived resources from first time step. Append _reg tag, but leave data untouched. static void CopyResources(FileListType fileList, std::string outputPath) { for (unsigned int j=0; j < fileList.size(); j++) { std::string derivedResourceFilename = fileList.at(j); std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(derivedResourceFilename); std::string savePathAndFileName = outputPath +fileStem + "." + fileType; MITK_INFO << "Copy resource " << savePathAndFileName; - mitk::Image::Pointer resImage = ExtractFirstTS(dynamic_cast(mitk::IOUtil::Load(derivedResourceFilename)[0].GetPointer()), fileType); + mitk::Image::Pointer resImage = ExtractFirstTS(mitk::IOUtil::Load(derivedResourceFilename), fileType); mitk::IOUtil::Save(resImage, savePathAndFileName); } } int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Folder Registration"); parser.setCategory("Preprocessing Tools"); parser.setDescription("For detail description see http://docs.mitk.org/nightly/DiffusionMiniApps.html"); parser.setContributor("MIC"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help", "Show this help text"); //parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input:", "Input folder",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "Output:", "Output folder (ending with /)",us::Any(),false); parser.addArgument("fixed", "f", mitkCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true); parser.addArgument("moving", "m", mitkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false); parser.addArgument("derived", "d", mitkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); parser.addArgument("silent", "s", mitkCommandLineParser::Bool, "Silent:", "No xml progress output."); parser.addArgument("resample", "r", mitkCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); parser.addArgument("binary", "b", mitkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); parser.addArgument("correct-origin", "c", mitkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Use switch when you reveive: Joint PDF summed to zero ",us::Any()); parser.addArgument("sinc-int", "s", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool silent = false; bool isBinary = false; bool alignOrigin = false; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("silent")) silent = true; if (parsedArgs.count("binary")) isBinary = true; if (parsedArgs.count("correct-origin")) alignOrigin = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string refPattern = ""; bool useFirstMoving = false; std::string movingImgPattern = us::any_cast(parsedArgs["moving"]); if (parsedArgs.count("fixed")) { refPattern = us::any_cast(parsedArgs["fixed"]); } else { useFirstMoving = true; refPattern = movingImgPattern; } std::string outputPath = us::any_cast(parsedArgs["output"]); std::string inputPath = us::any_cast(parsedArgs["input"]); //QString resampleReference = parsedArgs["resample"].toString(); //bool maskTumor = parsedArgs["usemask"].toBool(); // if derived sources pattern is provided, populate QStringList with possible filename postfixes std::vector derPatterns; if (parsedArgs.count("derived") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["derived"]); derPatterns = split(arg ,','); } std::vector spacings; float spacing[] = { 0.0f, 0.0f, 0.0f }; bool doResampling = false; if (parsedArgs.count("resample") || parsedArgs.count("d") ) { std::string arg = us::any_cast(parsedArgs["resample"]); spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); doResampling = true; } MITK_INFO << "Input Folder : " << inputPath; MITK_INFO << "Looking for reference image ..."; FileListType referenceFileList = CreateFileList(inputPath,refPattern); if ((!useFirstMoving && referenceFileList.size() != 1) || (useFirstMoving && referenceFileList.size() == 0)) { MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size(); MITK_INFO << "Choose a fixed arguement that is unique in the given folder!"; return EXIT_FAILURE; } std::string referenceFileName = referenceFileList.at(0); MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName; std::string fileType = itksys::SystemTools::GetFilenameExtension(referenceFileName); - mitk::Image::Pointer refImage = ExtractFirstTS(dynamic_cast(mitk::IOUtil::Load(referenceFileName)[0].GetPointer()), fileType); + mitk::Image::Pointer refImage = ExtractFirstTS(mitk::IOUtil::Load(referenceFileName), fileType); mitk::Image::Pointer resampleReference = nullptr; if (doResampling) { refImage = ResampleBySpacing(refImage,spacing); resampleReference = refImage; } if (refImage.IsNull()) MITK_ERROR << "Loaded fixed image is nullptr"; // Copy reference image to destination std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName); mitk::IOUtil::Save(refImage, savePathAndFileName); // Copy all derived resources also to output folder, adding _reg suffix referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns); CopyResources(referenceFileList, outputPath); std::string derivedResourceFilename; mitk::Image::Pointer referenceMask = nullptr; // union of all segmentations if (!silent) { // XML Output to report progress std::cout << ""; std::cout << "Batched Registration"; std::cout << "Starting registration ... "; std::cout << ""; } // Now iterate over all files and register them to the reference image, // also register derived resources based on file patterns // ------------------------------------------------------------------------------ // Create File list FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern); for (unsigned int i =0; i < movingImagesList.size(); i++) { std::string fileMorphName = movingImagesList.at(i); if (fileMorphName == referenceFileName) { // do not process reference image again continue; } MITK_INFO << "Processing image " << fileMorphName; // 1 Register morphological file to reference image if (!itksys::SystemTools::FileExists(fileMorphName.c_str())) { MITK_WARN << "File does not exit. Skipping entry."; continue; } // Origin of images is cancelled // TODO make this optional!! double transf[6]; double offset[3]; { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName); - mitk::Image::Pointer movingImage = ExtractFirstTS(dynamic_cast(mitk::IOUtil::Load(fileMorphName)[0].GetPointer()), fileType); + mitk::Image::Pointer movingImage = ExtractFirstTS(mitk::IOUtil::Load(fileMorphName), fileType); if (movingImage.IsNull()) MITK_ERROR << "Loaded moving image is nullptr"; // Store transformation, apply it to morph file MITK_INFO << "----------Registering moving image to reference----------"; mitk::RegistrationWrapper::GetTransformation(refImage, movingImage, transf, offset, alignOrigin, referenceMask); mitk::RegistrationWrapper::ApplyTransformationToImage(movingImage, transf,offset, resampleReference); // , resampleImage savePathAndFileName = GetSavePath(outputPath, fileMorphName); if (fileType == ".dwi") fileType = "dwi"; { mitk::ImageReadAccessor readAccess(movingImage); if (readAccess.GetData() == nullptr) MITK_INFO <<"POST DATA is null"; } mitk::IOUtil::Save(movingImage, savePathAndFileName); } if (!silent) { std::cout << "."; } // Now parse all derived resource and apply the above calculated transformation to them // ------------------------------------------------------------------------------------ FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns); if (fList.size() > 0) MITK_INFO << "----------DERIVED RESOURCES ---------"; for (unsigned int j=0; j < fList.size(); j++) { derivedResourceFilename = fList.at(j); MITK_INFO << "----Processing derived resorce " << derivedResourceFilename << " ..."; std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); - mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(dynamic_cast(mitk::IOUtil::Load(derivedResourceFilename)[0].GetPointer()), fileType); + mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(mitk::IOUtil::Load(derivedResourceFilename), fileType); // Apply transformation to derived resource, treat derived resource as binary mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, resampleReference,isBinary); savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename); mitk::IOUtil::Save(derivedMovingResource, savePathAndFileName); } } if (!silent) std::cout << ""; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp index ae015eade6..c87ecf2b02 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ResampleGradients.cpp @@ -1,243 +1,243 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include // itk includes #include // mitk includes #include #include "itkDWIVoxelFunctor.h" #include typedef short DiffusionPixelType; typedef itk::VectorImage< short, 3 > ItkDwiType; // itk includes #include "itkTimeProbe.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkB0ImageExtractionToSeparateImageFilter.h" #include "itkBrainMaskExtractionImageFilter.h" #include "itkCastImageFilter.h" #include "itkVectorContainer.h" #include #include #include #include #include #include // Multishell includes #include // Multishell Functors #include #include #include #include // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" //#include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include #include #include #include #include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkPreferenceListReaderOptionsFunctor.h" mitk::Image::Pointer DoReduceGradientDirections(mitk::Image::Pointer image, double BValue, unsigned int numOfGradientsToKeep) { bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) { std::cout << "Image is not a Diffusion Weighted Image" << std::endl; //return; } typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; typedef mitk::BValueMapProperty::BValueMap BValueMap; BValueMap shellSlectionMap; BValueMap originalShellMap = static_cast (image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() ) ->GetBValueMap(); std::vector newNumGradientDirections; //Keeps 1 b0 gradient double B0Value = 0; shellSlectionMap[B0Value] = originalShellMap[B0Value]; unsigned int num = 1; newNumGradientDirections.push_back(num); //BValue = 1000; shellSlectionMap[BValue] = originalShellMap[BValue]; //numOfGradientsToKeep = 32; newNumGradientDirections.push_back(numOfGradientsToKeep); if (newNumGradientDirections.empty()) { std::cout << "newNumGradientDirections is empty" << std::endl; //return; } itk::DwiGradientLengthCorrectionFilter::GradientDirectionContainerType::Pointer gradientContainer = static_cast ( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() ) ->GetGradientDirectionsContainer(); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(image, itkVectorImagePointer); std::cout << "1" << std::endl; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkVectorImagePointer ); filter->SetOriginalGradientDirections(gradientContainer); filter->SetNumGradientDirections(newNumGradientDirections); filter->SetOriginalBValueMap(originalShellMap); filter->SetShellSelectionBValueMap(shellSlectionMap); filter->Update(); std::cout << "2" << std::endl; if( filter->GetOutput() == nullptr) { std::cout << "filter get output is nullptr" << std::endl; } mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); mitk::DiffusionPropertyHelper::CopyProperties(image, newImage, true); newImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); //needed? return newImage; } /*! \brief Resample gradients of input DWI image. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Resample Gradients"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Resample gradients of input DWI image. You can select one b-value shell and the number of gradients within this shell you want to have. It will also keep one b0 image."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false); parser.addArgument("bValue", "b", mitkCommandLineParser::Float, "b-value:", "float", 1000, false); parser.addArgument("nrOfGradients", "n", mitkCommandLineParser::Int, "Nr of gradients:", "integer", 32, false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outFileName = us::any_cast(parsedArgs["output"]); double bValue = us::any_cast(parsedArgs["bValue"]); unsigned int nrOfGradients = us::any_cast(parsedArgs["nrOfGradients"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({ "Diffusion Weighted Images" }, {}); - mitk::Image::Pointer mitkImage = dynamic_cast(mitk::IOUtil::LoadImage(inFileName, &functor).GetPointer()); + mitk::Image::Pointer mitkImage = mitk::IOUtil::Load(inFileName, &functor); mitk::Image::Pointer newImage = DoReduceGradientDirections(mitkImage, bValue, nrOfGradients); //mitk::IOUtil::Save(newImage, outFileName); //save as dwi image mitk::IOUtil::Save(newImage, "application/vnd.mitk.nii.gz", outFileName); //save as nifti image } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ShToOdfImage.cpp b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ShToOdfImage.cpp index 95e1bde010..6af8fa510d 100644 --- a/Modules/DiffusionImaging/DiffusionCore/cmdapps/ShToOdfImage.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/cmdapps/ShToOdfImage.cpp @@ -1,110 +1,110 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include template mitk::OdfImage::Pointer TemplatedConvertShImage(mitk::ShImage::Pointer mitkImage) { typedef itk::ShToOdfImageFilter< float, ShOrder > ShConverterType; typename ShConverterType::InputImageType::Pointer itkvol = ShConverterType::InputImageType::New(); mitk::CastToItkImage(mitkImage, itkvol); typename ShConverterType::Pointer converter = ShConverterType::New(); converter->SetInput(itkvol); converter->Update(); mitk::OdfImage::Pointer image = mitk::OdfImage::New(); image->InitializeByItk( converter->GetOutput() ); image->SetVolume( converter->GetOutput()->GetBufferPointer() ); return image; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("ShToOdfImage"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Calculate discrete ODF image from SH coefficient image"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["in"]); std::string outImage = us::any_cast(parsedArgs["out"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"SH Image"}, {}); - mitk::ShImage::Pointer source = dynamic_cast(mitk::IOUtil::Load(imageName, &functor)[0].GetPointer()); + mitk::ShImage::Pointer source = mitk::IOUtil::Load(imageName, &functor); mitk::OdfImage::Pointer out_image = nullptr; switch (source->ShOrder()) { case 2: out_image = TemplatedConvertShImage<2>(source); break; case 4: out_image = TemplatedConvertShImage<4>(source); break; case 6: out_image = TemplatedConvertShImage<6>(source); break; case 8: out_image = TemplatedConvertShImage<8>(source); break; case 10: out_image = TemplatedConvertShImage<10>(source); break; case 12: out_image = TemplatedConvertShImage<12>(source); break; } if (out_image.IsNotNull()) mitk::IOUtil::Save(out_image, outImage); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp index 87c6c99c95..2f0af162f1 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberExtractionTest.cpp @@ -1,139 +1,139 @@ /*=================================================================== 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 #include #include #include #include #include #include /**Documentation * Test if fiber transfortaiom methods work correctly */ int mitkFiberExtractionTest(int argc, char* argv[]) { MITK_TEST_BEGIN("mitkFiberExtractionTest"); /// \todo Fix VTK memory leaks. Bug 18097. vtkDebugLeaks::SetExitError(0); MITK_INFO << "argc: " << argc; MITK_TEST_CONDITION_REQUIRED(argc==13,"check for input data"); omp_set_num_threads(1); try{ mitk::FiberBundle::Pointer groundTruthFibs = dynamic_cast( mitk::IOUtil::Load(argv[1]).front().GetPointer() ); mitk::FiberBundle::Pointer testFibs = dynamic_cast( mitk::IOUtil::Load(argv[2]).front().GetPointer() ); // test planar figure based extraction auto data = mitk::IOUtil::Load(argv[3])[0]; auto pf1 = mitk::DataNode::New(); pf1->SetData(data); data = mitk::IOUtil::Load(argv[4])[0]; auto pf2 = mitk::DataNode::New(); pf2->SetData(data); data = mitk::IOUtil::Load(argv[5])[0]; auto pf3 = mitk::DataNode::New(); pf3->SetData(data); mitk::StandaloneDataStorage::Pointer storage = mitk::StandaloneDataStorage::New(); mitk::PlanarFigureComposite::Pointer pfc2 = mitk::PlanarFigureComposite::New(); pfc2->setOperationType(mitk::PlanarFigureComposite::OR); mitk::DataNode::Pointer pfcNode2 = mitk::DataNode::New(); pfcNode2->SetData(pfc2); mitk::DataStorage::SetOfObjects::Pointer set2 = mitk::DataStorage::SetOfObjects::New(); set2->push_back(pfcNode2); mitk::PlanarFigureComposite::Pointer pfc1 = mitk::PlanarFigureComposite::New(); pfc1->setOperationType(mitk::PlanarFigureComposite::AND); mitk::DataNode::Pointer pfcNode1 = mitk::DataNode::New(); pfcNode1->SetData(pfc1); mitk::DataStorage::SetOfObjects::Pointer set1 = mitk::DataStorage::SetOfObjects::New(); set1->push_back(pfcNode1); storage->Add(pfcNode2); storage->Add(pf1, set2); storage->Add(pfcNode1, set2); storage->Add(pf2, set1); storage->Add(pf3, set1); MITK_INFO << "TEST1"; mitk::FiberBundle::Pointer extractedFibs = groundTruthFibs->ExtractFiberSubset(pfcNode2, storage); MITK_INFO << "TEST2"; MITK_TEST_CONDITION_REQUIRED(extractedFibs->Equals(testFibs),"check planar figure extraction"); MITK_INFO << "TEST3"; // test subtraction and addition mitk::FiberBundle::Pointer notExtractedFibs = groundTruthFibs->SubtractBundle(extractedFibs); MITK_INFO << argv[11]; - testFibs = dynamic_cast(mitk::IOUtil::Load(argv[11]).front().GetPointer()); + testFibs = mitk::IOUtil::Load(argv[11]); MITK_TEST_CONDITION_REQUIRED(notExtractedFibs->Equals(testFibs),"check bundle subtraction"); mitk::FiberBundle::Pointer joinded = extractedFibs->AddBundle(notExtractedFibs); - testFibs = dynamic_cast(mitk::IOUtil::Load(argv[12]).front().GetPointer()); + testFibs = mitk::IOUtil::Load(argv[12]); MITK_TEST_CONDITION_REQUIRED(joinded->Equals(testFibs),"check bundle addition"); // test binary image based extraction - mitk::Image::Pointer mitkRoiImage = dynamic_cast(mitk::IOUtil::Load(argv[6]).front().GetPointer()); + mitk::Image::Pointer mitkRoiImage = mitk::IOUtil::Load(argv[6]); typedef itk::Image< unsigned char, 3 > itkUCharImageType; itkUCharImageType::Pointer itkRoiImage = itkUCharImageType::New(); mitk::CastToItkImage(mitkRoiImage, itkRoiImage); { - testFibs = dynamic_cast(mitk::IOUtil::Load(argv[9]).front().GetPointer()); + testFibs = mitk::IOUtil::Load(argv[9]); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); mitk::FiberBundle::Pointer test = groundTruthFibs->GetDeepCopy(); test->ResampleLinear(0.2); extractor->SetInputFiberBundle(test); extractor->SetRoiImages({itkRoiImage}); extractor->SetOverlapFraction(0.0); extractor->SetBothEnds(true); extractor->SetDontResampleFibers(true); extractor->SetMode(itk::FiberExtractionFilter::MODE::OVERLAP); extractor->Update(); mitk::FiberBundle::Pointer passing = extractor->GetPositives().at(0); MITK_TEST_CONDITION_REQUIRED(passing->Equals(testFibs),"check passing mask extraction"); } { - testFibs = dynamic_cast(mitk::IOUtil::Load(argv[10]).front().GetPointer()); + testFibs = mitk::IOUtil::Load(argv[10]); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(groundTruthFibs); extractor->SetRoiImages({itkRoiImage}); extractor->SetOverlapFraction(0.0); extractor->SetBothEnds(true); extractor->SetMode(itk::FiberExtractionFilter::MODE::ENDPOINTS); extractor->Update(); mitk::FiberBundle::Pointer ending = extractor->GetPositives().at(0); MITK_TEST_CONDITION_REQUIRED(ending->Equals(testFibs),"check ending in mask extraction"); } } catch(...) { return EXIT_FAILURE; } // always end with this! MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberFitTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberFitTest.cpp index 047423b45b..1b2ff927db 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberFitTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberFitTest.cpp @@ -1,264 +1,264 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class mitkFiberFitTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkFiberFitTestSuite); MITK_TEST(Fit1); MITK_TEST(Fit2); MITK_TEST(Fit3); MITK_TEST(Fit4); MITK_TEST(Fit5); MITK_TEST(Fit6); CPPUNIT_TEST_SUITE_END(); typedef itk::Image ItkFloatImgType; private: /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/ typedef itk::FitFibersToImageFilter FitterType; FitterType::Pointer fitter; public: mitk::FiberBundle::Pointer LoadFib(std::string fib_name) { std::vector fibInfile = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberFit/" + fib_name)); mitk::BaseData::Pointer baseData = fibInfile.at(0); mitk::FiberBundle::Pointer fib = dynamic_cast(baseData.GetPointer()); return fib; } void setUp() override { std::vector tracts; tracts.push_back(LoadFib("Cluster_0.fib")); tracts.push_back(LoadFib("Cluster_1.fib")); tracts.push_back(LoadFib("Cluster_2.fib")); tracts.push_back(LoadFib("Cluster_3.fib")); tracts.push_back(LoadFib("Cluster_4.fib")); mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image"}, {}); - mitk::PeakImage::Pointer peaks = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberFit/csd_peak_image.nii.gz"), &functor)[0].GetPointer()); + mitk::PeakImage::Pointer peaks = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberFit/csd_peak_image.nii.gz"), &functor); typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(peaks); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer peak_image = caster->GetOutput(); fitter = FitterType::New(); fitter->SetPeakImage(peak_image); fitter->SetTractograms(tracts); } void tearDown() override { } void CompareFibs(mitk::FiberBundle::Pointer test, mitk::FiberBundle::Pointer ref, std::string out_name) { vtkSmartPointer weights = test->GetFiberWeights(); vtkSmartPointer ref_weights = ref->GetFiberWeights(); CPPUNIT_ASSERT_MESSAGE("Number of weights should be equal", weights->GetSize()==ref_weights->GetSize()); for (int i=0; iGetSize(); ++i) { if (ref_weights->GetValue(i)>0) { if (fabs( weights->GetValue(i)/ref_weights->GetValue(i)-1 )>0.01) { mitk::IOUtil::Save(test, mitk::IOUtil::GetTempPath()+out_name); CPPUNIT_ASSERT_MESSAGE("Weights should be equal", false); } } else if (weights->GetValue(i)>0) { mitk::IOUtil::Save(test, mitk::IOUtil::GetTempPath()+out_name); CPPUNIT_ASSERT_MESSAGE("Weights should be equal", false); } } } void CompareImages(mitk::PeakImage::ItkPeakImageType::Pointer testImage, std::string name) { typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); - caster->SetInput(mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/FiberFit/out/" + name))); + caster->SetInput(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberFit/out/" + name))); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer refImage = caster->GetOutput(); itk::ImageRegionConstIterator< mitk::PeakImage::ItkPeakImageType > it1(testImage, testImage->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< mitk::PeakImage::ItkPeakImageType > it2(refImage, refImage->GetLargestPossibleRegion()); while(!it1.IsAtEnd()) { if (it2.Get()>0.0001) { if (fabs( it1.Get()/it2.Get()-1 )>0.01) { itk::ImageFileWriter< mitk::PeakImage::ItkPeakImageType >::Pointer writer = itk::ImageFileWriter< mitk::PeakImage::ItkPeakImageType >::New(); writer->SetInput(testImage); writer->SetFileName(mitk::IOUtil::GetTempPath()+name); writer->Update(); MITK_INFO << it1.Get() << " - " << it2.Get(); CPPUNIT_ASSERT_MESSAGE("Peak images should be equal 1", false); } } else if (it1.Get()>0.0001) { itk::ImageFileWriter< mitk::PeakImage::ItkPeakImageType >::Pointer writer = itk::ImageFileWriter< mitk::PeakImage::ItkPeakImageType >::New(); writer->SetInput(testImage); writer->SetFileName(mitk::IOUtil::GetTempPath()+name); writer->Update(); CPPUNIT_ASSERT_MESSAGE("Peak images should be equal 2", false); } ++it1; ++it2; } } void Fit1() { omp_set_num_threads(1); fitter->SetLambda(0.1); fitter->SetFilterOutliers(false); fitter->SetRegularization(VnlCostFunction::NONE); fitter->Update(); std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); mitk::FiberBundle::Pointer test = mitk::FiberBundle::New(); test = test->AddBundles(output_tracts); mitk::FiberBundle::Pointer ref = LoadFib("out/NONE_fitted.fib"); CompareFibs(test, ref, "NONE_fitted.fib"); CompareImages(fitter->GetFittedImage(), "NONE_fitted_image.nrrd"); CompareImages(fitter->GetResidualImage(), "NONE_residual_image.nrrd"); } void Fit2() { omp_set_num_threads(1); fitter->SetLambda(0.1); fitter->SetFilterOutliers(false); fitter->SetRegularization(VnlCostFunction::MSM); fitter->Update(); std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); mitk::FiberBundle::Pointer test = mitk::FiberBundle::New(); test = test->AddBundles(output_tracts); mitk::FiberBundle::Pointer ref = LoadFib("out/MSM_fitted.fib"); CompareFibs(test, ref, "MSM_fitted.fib"); CompareImages(fitter->GetFittedImage(), "MSM_fitted_image.nrrd"); CompareImages(fitter->GetResidualImage(), "MSM_residual_image.nrrd"); } void Fit3() { omp_set_num_threads(1); fitter->SetLambda(0.1); fitter->SetFilterOutliers(false); fitter->SetRegularization(VnlCostFunction::VARIANCE); fitter->Update(); std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); mitk::FiberBundle::Pointer test = mitk::FiberBundle::New(); test = test->AddBundles(output_tracts); mitk::FiberBundle::Pointer ref = LoadFib("out/MSE_fitted.fib"); CompareFibs(test, ref, "MSE_fitted.fib"); CompareImages(fitter->GetFittedImage(), "MSE_fitted_image.nrrd"); CompareImages(fitter->GetResidualImage(), "MSE_residual_image.nrrd"); } void Fit4() { omp_set_num_threads(1); fitter->SetLambda(0.1); fitter->SetFilterOutliers(false); fitter->SetRegularization(VnlCostFunction::VOXEL_VARIANCE); fitter->Update(); std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); mitk::FiberBundle::Pointer test = mitk::FiberBundle::New(); test = test->AddBundles(output_tracts); mitk::FiberBundle::Pointer ref = LoadFib("out/LocalMSE_fitted.fib"); CompareFibs(test, ref, "LocalMSE_fitted.fib"); CompareImages(fitter->GetFittedImage(), "LocalMSE_fitted_image.nrrd"); CompareImages(fitter->GetResidualImage(), "LocalMSE_residual_image.nrrd"); } void Fit5() { omp_set_num_threads(1); fitter->SetLambda(0.1); fitter->SetFilterOutliers(false); fitter->SetRegularization(VnlCostFunction::GROUP_VARIANCE); fitter->Update(); std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); mitk::FiberBundle::Pointer test = mitk::FiberBundle::New(); test = test->AddBundles(output_tracts); mitk::FiberBundle::Pointer ref = LoadFib("out/GroupMSE_fitted.fib"); CompareFibs(test, ref, "GroupMSE_fitted.fib"); CompareImages(fitter->GetFittedImage(), "GroupMSE_fitted_image.nrrd"); CompareImages(fitter->GetResidualImage(), "GroupMSE_residual_image.nrrd"); } void Fit6() { omp_set_num_threads(1); fitter->SetLambda(10); fitter->SetFilterOutliers(false); fitter->SetRegularization(VnlCostFunction::GROUP_LASSO); fitter->Update(); std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); mitk::FiberBundle::Pointer test = mitk::FiberBundle::New(); test = test->AddBundles(output_tracts); mitk::FiberBundle::Pointer ref = LoadFib("out/GroupLasso_fitted.fib"); CompareFibs(test, ref, "GroupLasso_fitted.fib"); CompareImages(fitter->GetFittedImage(), "GroupLasso_fitted_image.nrrd"); CompareImages(fitter->GetResidualImage(), "GroupLasso_residual_image.nrrd"); } }; MITK_TEST_SUITE_REGISTRATION(mitkFiberFit) diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp index 287cfb6ea8..0f667d9f6c 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberGenerationTest.cpp @@ -1,80 +1,80 @@ /*=================================================================== 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 #include #include /**Documentation * Test if fiber transfortaiom methods work correctly */ int mitkFiberGenerationTest(int argc, char* argv[]) { omp_set_num_threads(1); MITK_TEST_BEGIN("mitkFiberGenerationTest"); MITK_TEST_CONDITION_REQUIRED(argc==6,"check for input data") try{ - mitk::PlanarEllipse::Pointer pf1 = dynamic_cast(mitk::IOUtil::Load(argv[1])[0].GetPointer()); - mitk::PlanarEllipse::Pointer pf2 = dynamic_cast(mitk::IOUtil::Load(argv[2])[0].GetPointer()); - mitk::PlanarEllipse::Pointer pf3 = dynamic_cast(mitk::IOUtil::Load(argv[3])[0].GetPointer()); - mitk::FiberBundle::Pointer uniform = dynamic_cast(mitk::IOUtil::Load(argv[4])[0].GetPointer()); - mitk::FiberBundle::Pointer gaussian = dynamic_cast(mitk::IOUtil::Load(argv[5])[0].GetPointer()); + mitk::PlanarEllipse::Pointer pf1 = mitk::IOUtil::Load(argv[1]); + mitk::PlanarEllipse::Pointer pf2 = mitk::IOUtil::Load(argv[2]); + mitk::PlanarEllipse::Pointer pf3 = mitk::IOUtil::Load(argv[3]); + mitk::FiberBundle::Pointer uniform = mitk::IOUtil::Load(argv[4]); + mitk::FiberBundle::Pointer gaussian = mitk::IOUtil::Load(argv[5]); FiberGenerationParameters parameters; std::vector< mitk::PlanarEllipse::Pointer > fid; fid.push_back(pf1); fid.push_back(pf2); fid.push_back(pf3); std::vector< unsigned int > flip; flip.push_back(0); flip.push_back(0); flip.push_back(0); parameters.m_Fiducials.push_back(fid); parameters.m_FlipList.push_back(flip); parameters.m_Density = 50; parameters.m_Tension = 0; parameters.m_Continuity = 0; parameters.m_Bias = 0; parameters.m_Sampling = 1; parameters.m_Variance = 0.1; // check uniform fiber distribution { itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New(); parameters.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM; filter->SetParameters(parameters); filter->Update(); std::vector< mitk::FiberBundle::Pointer > fiberBundles = filter->GetFiberBundles(); MITK_TEST_CONDITION_REQUIRED(uniform->Equals(fiberBundles.at(0)),"check uniform bundle") } // check gaussian fiber distribution { itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New(); parameters.m_Distribution = FiberGenerationParameters::DISTRIBUTE_GAUSSIAN; filter->SetParameters(parameters); filter->SetParameters(parameters); filter->Update(); std::vector< mitk::FiberBundle::Pointer > fiberBundles = filter->GetFiberBundles(); MITK_TEST_CONDITION_REQUIRED(gaussian->Equals(fiberBundles.at(0)),"check gaussian bundle") } } catch(...) { return EXIT_FAILURE; } // always end with this! MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberProcessingTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberProcessingTest.cpp index c989834cee..21b95933df 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberProcessingTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberProcessingTest.cpp @@ -1,304 +1,304 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include "mitkTestFixture.h" class mitkFiberProcessingTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkFiberProcessingTestSuite); MITK_TEST(Test1); MITK_TEST(Test2); MITK_TEST(Test3); MITK_TEST(Test4); MITK_TEST(Test5); MITK_TEST(Test6); MITK_TEST(Test7); MITK_TEST(Test8); MITK_TEST(Test9); MITK_TEST(Test10); MITK_TEST(Test11); MITK_TEST(Test12); MITK_TEST(Test13); MITK_TEST(Test14); MITK_TEST(Test15); MITK_TEST(Test16); MITK_TEST(Test17); MITK_TEST(Test18); CPPUNIT_TEST_SUITE_END(); typedef itk::Image ItkUcharImgType; private: /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/ mitk::FiberBundle::Pointer original; ItkUcharImgType::Pointer mask; public: void setUp() override { omp_set_num_threads(1); original = nullptr; - original = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/original.fib")).front().GetPointer()); + original = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/original.fib")); - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/MASK.nrrd"))[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/MASK.nrrd")); mask = ItkUcharImgType::New(); mitk::CastToItkImage(img, mask); } void tearDown() override { original = nullptr; } void Test1() { MITK_INFO << "TEST 1: Remove by direction"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); vnl_vector_fixed dir; dir[0] = 0; dir[1] = 1; dir[2] = 0; fib->RemoveDir(dir,cos(5.0*itk::Math::pi/180)); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_direction.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_direction.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test2() { MITK_INFO << "TEST 2: Remove by length"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->RemoveShortFibers(30); fib->RemoveLongFibers(40); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_length.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_length.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test3() { MITK_INFO << "TEST 3: Remove by curvature 1"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); auto filter = itk::FiberCurvatureFilter::New(); filter->SetInputFiberBundle(fib); filter->SetAngularDeviation(30); filter->SetDistance(5); filter->SetRemoveFibers(false); filter->SetUseMedian(true); filter->Update(); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_curvature1.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_curvature1.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(filter->GetOutputFiberBundle())); } void Test4() { MITK_INFO << "TEST 4: Remove by curvature 2"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); auto filter = itk::FiberCurvatureFilter::New(); filter->SetInputFiberBundle(fib); filter->SetAngularDeviation(30); filter->SetDistance(5); filter->SetRemoveFibers(true); filter->SetUseMedian(true); filter->Update(); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_curvature2.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_curvature2.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(filter->GetOutputFiberBundle())); } void Test5() { MITK_INFO << "TEST 5: Remove outside mask"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib = fib->RemoveFibersOutside(mask); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_outside.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_outside.fib")); // mitk::IOUtil::Save(fib, mitk::IOUtil::GetTempPath()+"remove_outside.fib"); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test6() { MITK_INFO << "TEST 6: Remove inside mask"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib = fib->RemoveFibersOutside(mask, true); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_inside.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_inside.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test7() { MITK_INFO << "TEST 7: Modify resample spline"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->ResampleSpline(5); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_resample.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_resample.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test8() { MITK_INFO << "TEST 8: Modify compress"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->Compress(0.1); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_compress.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_compress.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test9() { MITK_INFO << "TEST 9: Modify sagittal mirror"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->MirrorFibers(0); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_sagittal_mirror.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_sagittal_mirror.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test10() { MITK_INFO << "TEST 10: Modify coronal mirror"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->MirrorFibers(1); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_coronal_mirror.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_coronal_mirror.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test11() { MITK_INFO << "TEST 11: Modify axial mirror"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->MirrorFibers(2); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_axial_mirror.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_axial_mirror.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test12() { MITK_INFO << "TEST 12: Weight and join"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->SetFiberWeights(0.1); mitk::FiberBundle::Pointer fib2 = original->GetDeepCopy(); fib2->SetFiberWeight(3, 0.5); fib = fib->AddBundle(fib2); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_weighted_joined.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_weighted_joined.fib")); CPPUNIT_ASSERT_MESSAGE("Number of fibers", ref->GetNumFibers() == fib->GetNumFibers()); for (int i=0; iGetNumFibers(); i++) CPPUNIT_ASSERT_MESSAGE("Fiber weights", ref->GetFiberWeight(i) == fib->GetFiberWeight(i)); } void Test13() { MITK_INFO << "TEST 13: Subtract"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); - mitk::FiberBundle::Pointer fib2 = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_length.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer fib2 = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/remove_length.fib")); fib = fib->SubtractBundle(fib2); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/subtracted.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/subtracted.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test14() { MITK_INFO << "TEST 14: rotate"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->TransformFibers(1,2,3,0,0,0); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_rotate.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_rotate.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test15() { MITK_INFO << "TEST 15: translate"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->TransformFibers(0,0,0,1,2,3); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_translate.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_translate.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test16() { MITK_INFO << "TEST 16: scale 1"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->ScaleFibers(0.1, 0.2, 0.3); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_scale1.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_scale1.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test17() { MITK_INFO << "TEST 17: scale 2"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->ScaleFibers(0.1, 0.2, 0.3, false); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_scale2.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/transform_scale2.fib")); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } void Test18() { MITK_INFO << "TEST 18: Modify resample linear"; mitk::FiberBundle::Pointer fib = original->GetDeepCopy(); fib->ResampleLinear(); - mitk::FiberBundle::Pointer ref = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_resample_linear.fib")).front().GetPointer()); + mitk::FiberBundle::Pointer ref = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/FiberProcessing/modify_resample_linear.fib")); // mitk::IOUtil::Save(fib, mitk::IOUtil::GetTempPath()+"modify_resample_linear.fib"); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(fib)); } }; MITK_TEST_SUITE_REGISTRATION(mitkFiberProcessing) diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberTransformationTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberTransformationTest.cpp index fefad5947f..9f5e8e0f0d 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberTransformationTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberTransformationTest.cpp @@ -1,55 +1,55 @@ /*=================================================================== 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 /**Documentation * Test if fiber transfortaiom methods work correctly */ int mitkFiberTransformationTest(int argc, char* argv[]) { omp_set_num_threads(1); MITK_TEST_BEGIN("mitkFiberTransformationTest"); MITK_TEST_CONDITION_REQUIRED(argc==3,"check for input data") try{ - mitk::FiberBundle::Pointer groundTruthFibs = dynamic_cast(mitk::IOUtil::Load(argv[1])[0].GetPointer()); - mitk::FiberBundle::Pointer transformedFibs = dynamic_cast(mitk::IOUtil::Load(argv[2])[0].GetPointer()); + mitk::FiberBundle::Pointer groundTruthFibs = mitk::IOUtil::Load(argv[1]); + mitk::FiberBundle::Pointer transformedFibs = mitk::IOUtil::Load(argv[2]); groundTruthFibs->RotateAroundAxis(90, 45, 10); groundTruthFibs->TranslateFibers(2, 3, 5); groundTruthFibs->ScaleFibers(1, 0.1, 1.3); groundTruthFibs->RemoveLongFibers(150); groundTruthFibs->RemoveShortFibers(20); groundTruthFibs->ResampleSpline(1.0); groundTruthFibs->ApplyCurvatureThreshold(3.0, true); groundTruthFibs->MirrorFibers(0); groundTruthFibs->MirrorFibers(1); groundTruthFibs->MirrorFibers(2); MITK_TEST_CONDITION_REQUIRED(groundTruthFibs->Equals(transformedFibs),"check transformation") } catch(...) { return EXIT_FAILURE; } // always end with this! MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp index 754334c31d..efda007034 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkFiberfoxSignalGenerationTest.cpp @@ -1,267 +1,267 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkTestFixture.h" class mitkFiberfoxSignalGenerationTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkFiberfoxSignalGenerationTestSuite); // MITK_TEST(Test0); // apparently the noise generation causes issues across platforms. unclear why. the same type of random generator is used in other places without issues. // MITK_TEST(Test1); MITK_TEST(Test2); MITK_TEST(Test3); MITK_TEST(Test4); MITK_TEST(Test5); // MITK_TEST(Test6); // fails on windows for unknown reason. maybe floating point inaccuracy issues? MITK_TEST(Test7); MITK_TEST(Test8); CPPUNIT_TEST_SUITE_END(); typedef itk::VectorImage< short, 3> ItkDwiType; private: public: /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/ FiberBundle::Pointer m_FiberBundle; std::vector< FiberfoxParameters > m_Parameters; std::vector< mitk::Image::Pointer > m_RefImages; void setUp() override { std::srand(0); omp_set_num_threads(1); - m_FiberBundle = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/Signalgen.fib"))[0].GetPointer()); + m_FiberBundle = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/Signalgen.fib")); { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param1.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param1.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param1.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param2.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param2.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param2.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param3.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param3.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param3.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param4.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param4.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param4.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param5.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param5.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param5.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param6.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param6.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param6.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param7.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param7.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param7.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param8.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param8.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param8.dwi"))); } { FiberfoxParameters parameters; parameters.LoadParameters(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param9.ffp")); m_Parameters.push_back(parameters); - m_RefImages.push_back(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param9.dwi"))[0].GetPointer())); + m_RefImages.push_back(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/Fiberfox/params/param9.dwi"))); } } void tearDown() override { } bool CompareDwi(itk::VectorImage< short, 3 >* dwi1, itk::VectorImage< short, 3 >* dwi2) { bool out = true; typedef itk::VectorImage< short, 3 > DwiImageType; try{ itk::ImageRegionIterator< DwiImageType > it1(dwi1, dwi1->GetLargestPossibleRegion()); itk::ImageRegionIterator< DwiImageType > it2(dwi2, dwi2->GetLargestPossibleRegion()); int count = 0; while(!it1.IsAtEnd()) { for (unsigned int i=0; iGetVectorLength(); ++i) { short d = abs(it1.Get()[i]-it2.Get()[i]); if (d>0) { if (count<10) { MITK_INFO << "**************************************"; MITK_INFO << "Test value: " << it1.GetIndex() << ":" << it1.Get()[i]; MITK_INFO << "Ref. value: " << it2.GetIndex() << ":" << it2.Get()[i]; } out = false; count++; } } ++it1; ++it2; } if (count>=10) MITK_INFO << "Skipping errors."; MITK_INFO << "Errors detected: " << count; } catch(...) { return false; } return out; } void StartSimulation(FiberfoxParameters parameters, mitk::Image::Pointer refImage, std::string out) { itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); tractsToDwiFilter->SetUseConstantRandSeed(true); tractsToDwiFilter->SetParameters(parameters); tractsToDwiFilter->SetFiberBundle(m_FiberBundle); tractsToDwiFilter->Update(); mitk::Image::Pointer testImage = mitk::GrabItkImageMemory( tractsToDwiFilter->GetOutput() ); testImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( parameters.m_SignalGen.GetGradientDirections() ) ); testImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( parameters.m_SignalGen.GetBvalue() ) ); mitk::DiffusionPropertyHelper propertyHelper( testImage ); propertyHelper.InitializeImage(); if (refImage.IsNotNull()) { if( static_cast( refImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer().IsNotNull() ) { ItkDwiType::Pointer itkTestImagePointer = ItkDwiType::New(); mitk::CastToItkImage(testImage, itkTestImagePointer); ItkDwiType::Pointer itkRefImagePointer = ItkDwiType::New(); mitk::CastToItkImage(refImage, itkRefImagePointer); bool cond = CompareDwi(itkTestImagePointer, itkRefImagePointer); if (!cond) { MITK_INFO << "Saving test image to " << mitk::IOUtil::GetTempPath(); mitk::IOUtil::Save(testImage, mitk::IOUtil::GetTempPath()+out); } CPPUNIT_ASSERT_MESSAGE("Simulated images should be equal", cond); } } } void Test0() { StartSimulation(m_Parameters.at(0), m_RefImages.at(0), "param1.dwi"); } void Test1() { StartSimulation(m_Parameters.at(1), m_RefImages.at(1), "param2.dwi"); } void Test2() { StartSimulation(m_Parameters.at(2), m_RefImages.at(2), "param3.dwi"); } void Test3() { StartSimulation(m_Parameters.at(3), m_RefImages.at(3), "param4.dwi"); } void Test4() { StartSimulation(m_Parameters.at(4), m_RefImages.at(4), "param5.dwi"); } void Test5() { StartSimulation(m_Parameters.at(5), m_RefImages.at(5), "param6.dwi"); } void Test6() { StartSimulation(m_Parameters.at(6), m_RefImages.at(6), "param7.dwi"); } void Test7() { StartSimulation(m_Parameters.at(7), m_RefImages.at(7), "param8.dwi"); } void Test8() { StartSimulation(m_Parameters.at(8), m_RefImages.at(8), "param9.dwi"); } }; MITK_TEST_SUITE_REGISTRATION(mitkFiberfoxSignalGeneration) diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkLocalFiberPlausibilityTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkLocalFiberPlausibilityTest.cpp index bef2fe1e79..95c60988a8 100755 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkLocalFiberPlausibilityTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkLocalFiberPlausibilityTest.cpp @@ -1,156 +1,156 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include int mitkLocalFiberPlausibilityTest(int argc, char* argv[]) { omp_set_num_threads(1); MITK_TEST_BEGIN("mitkLocalFiberPlausibilityTest"); MITK_TEST_CONDITION_REQUIRED(argc==8,"check for input data") std::string fibFile = argv[1]; std::vector< std::string > referenceImages; referenceImages.push_back(argv[2]); referenceImages.push_back(argv[3]); std::string LDFP_ERROR_IMAGE = argv[4]; std::string LDFP_NUM_DIRECTIONS = argv[5]; std::string LDFP_VECTOR_FIELD = argv[6]; std::string LDFP_ERROR_IMAGE_IGNORE = argv[7]; float angularThreshold = 30; try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType; // load fiber bundle - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(fibFile)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); // load reference directions ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::Load(referenceImages.at(i))[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(referenceImages.at(i)); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg); } catch(...){ MITK_INFO << "could not load: " << referenceImages.at(i); } } ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0); itkMaskImage->SetSpacing( dirImg->GetSpacing() ); itkMaskImage->SetOrigin( dirImg->GetOrigin() ); itkMaskImage->SetDirection( dirImg->GetDirection() ); itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->Allocate(); itkMaskImage->FillBuffer(1); // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*itk::Math::pi/180)); fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::SINGLE_VEC_NORM); fOdfFilter->SetMaxNumDirections(3); fOdfFilter->SetSizeThreshold(0.3); fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->SetNumberOfThreads(1); fOdfFilter->Update(); itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer direction_image = fOdfFilter->GetDirectionImage(); // Get directions and num directions image ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); mitk::Image::Pointer mitkNumDirImage = mitk::Image::New(); mitkNumDirImage->InitializeByItk( numDirImage.GetPointer() ); mitkNumDirImage->SetVolume( numDirImage->GetBufferPointer() ); // mitk::FiberBundle::Pointer testDirections = fOdfFilter->GetOutputFiberBundle(); // evaluate directions with missing directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); // evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(false); evaluationFilter->Update(); EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); mitk::Image::Pointer mitkAngularErrorImage = mitk::Image::New(); mitkAngularErrorImage->InitializeByItk( angularErrorImage.GetPointer() ); mitkAngularErrorImage->SetVolume( angularErrorImage->GetBufferPointer() ); // evaluate directions without missing directions evaluationFilter->SetIgnoreMissingDirections(true); evaluationFilter->Update(); EvaluationFilterType::OutputImageType::Pointer angularErrorImageIgnore = evaluationFilter->GetOutput(0); mitk::Image::Pointer mitkAngularErrorImageIgnore = mitk::Image::New(); mitkAngularErrorImageIgnore->InitializeByItk( angularErrorImageIgnore.GetPointer() ); mitkAngularErrorImageIgnore->SetVolume( angularErrorImageIgnore->GetBufferPointer() ); - mitk::Image::Pointer gtAngularErrorImageIgnore = dynamic_cast(mitk::IOUtil::Load(LDFP_ERROR_IMAGE_IGNORE)[0].GetPointer()); - mitk::Image::Pointer gtAngularErrorImage = dynamic_cast(mitk::IOUtil::Load(LDFP_ERROR_IMAGE)[0].GetPointer()); - mitk::Image::Pointer gtNumTestDirImage = dynamic_cast(mitk::IOUtil::Load(LDFP_NUM_DIRECTIONS)[0].GetPointer()); + mitk::Image::Pointer gtAngularErrorImageIgnore = mitk::IOUtil::Load(LDFP_ERROR_IMAGE_IGNORE); + mitk::Image::Pointer gtAngularErrorImage = mitk::IOUtil::Load(LDFP_ERROR_IMAGE); + mitk::Image::Pointer gtNumTestDirImage = mitk::IOUtil::Load(LDFP_NUM_DIRECTIONS); MITK_ASSERT_EQUAL(gtAngularErrorImageIgnore, mitkAngularErrorImageIgnore, "Check if error images are equal (ignored missing directions)."); MITK_ASSERT_EQUAL(gtAngularErrorImage, mitkAngularErrorImage, "Check if error images are equal."); MITK_ASSERT_EQUAL(gtNumTestDirImage, mitkNumDirImage, "Check if num direction images are equal."); } catch (itk::ExceptionObject e) { MITK_INFO << e; return EXIT_FAILURE; } catch (std::exception e) { MITK_INFO << e.what(); return EXIT_FAILURE; } catch (...) { MITK_INFO << "ERROR!?!"; return EXIT_FAILURE; } MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkMachineLearningTrackingTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkMachineLearningTrackingTest.cpp index a06d1e6305..2e94c0b96b 100644 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkMachineLearningTrackingTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkMachineLearningTrackingTest.cpp @@ -1,109 +1,109 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include #include #include #include #include "mitkTestFixture.h" class mitkMachineLearningTrackingTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkMachineLearningTrackingTestSuite); MITK_TEST(Track1); CPPUNIT_TEST_SUITE_END(); typedef itk::Image ItkFloatImgType; private: /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/ mitk::FiberBundle::Pointer ref; mitk::TrackingHandlerRandomForest<6, 100>* tfh; mitk::Image::Pointer dwi; ItkFloatImgType::Pointer seed; public: void setUp() override { ref = nullptr; tfh = new mitk::TrackingHandlerRandomForest<6,100>(); std::vector fibInfile = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/ReferenceTracts.fib")); mitk::BaseData::Pointer baseData = fibInfile.at(0); ref = dynamic_cast(baseData.GetPointer()); - dwi = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/DiffusionImage.dwi"))[0].GetPointer()); + dwi = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/DiffusionImage.dwi")); - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/seed.nrrd"))[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/seed.nrrd")); seed = ItkFloatImgType::New(); mitk::CastToItkImage(img, seed); - mitk::TractographyForest::Pointer forest = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/forest.rf"))[0].GetPointer()); + mitk::TractographyForest::Pointer forest = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/MachineLearningTracking/forest.rf")); tfh->SetForest(forest); tfh->AddDwi(dwi); } void tearDown() override { delete tfh; ref = nullptr; } void Track1() { omp_set_num_threads(1); typedef itk::StreamlineTrackingFilter TrackerType; TrackerType::Pointer tracker = TrackerType::New(); tracker->SetDemoMode(false); tracker->SetInterpolateMasks(false); tracker->SetSeedImage(seed); tracker->SetSeedsPerVoxel(1); tracker->SetStepSize(-1); tracker->SetAngularThreshold(45); tracker->SetMinTractLength(20); tracker->SetMaxTractLength(400); tracker->SetTrackingHandler(tfh); tracker->SetAvoidStop(true); tracker->SetSamplingDistance(0.5); tracker->SetRandomSampling(false); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); //MITK_INFO << mitk::IOUtil::GetTempPath() << "ReferenceTracts.fib"; if (!ref->Equals(outFib)) mitk::IOUtil::Save(outFib, mitk::IOUtil::GetTempPath()+"ML_Track1.fib"); CPPUNIT_ASSERT_MESSAGE("Should be equal", ref->Equals(outFib)); } }; MITK_TEST_SUITE_REGISTRATION(mitkMachineLearningTracking) diff --git a/Modules/DiffusionImaging/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp b/Modules/DiffusionImaging/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp index 532ec5be84..55a5ed5676 100755 --- a/Modules/DiffusionImaging/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp @@ -1,426 +1,426 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include class mitkStreamlineTractographyTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkStreamlineTractographyTestSuite); MITK_TEST(Test_Peak1); MITK_TEST(Test_Peak2); MITK_TEST(Test_Tensor1); MITK_TEST(Test_Tensor2); MITK_TEST(Test_Tensor3); MITK_TEST(Test_Odf1); MITK_TEST(Test_Odf2); MITK_TEST(Test_Odf3); MITK_TEST(Test_Odf4); MITK_TEST(Test_Odf5); MITK_TEST(Test_Odf6); CPPUNIT_TEST_SUITE_END(); typedef itk::VectorImage< short, 3> ItkDwiType; private: public: /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/ typedef itk::Image ItkFloatImgType; mitk::TrackingHandlerOdf::ItkOdfImageType::Pointer itk_odf_image; mitk::TrackingHandlerTensor::ItkTensorImageType::ConstPointer itk_tensor_image; mitk::TrackingHandlerPeaks::PeakImgType::Pointer itk_peak_image; ItkFloatImgType::Pointer itk_seed_image; ItkFloatImgType::Pointer itk_mask_image; ItkFloatImgType::Pointer itk_gfa_image; float gfa_threshold; float odf_threshold; float peak_threshold; itk::StreamlineTrackingFilter::Pointer tracker; void setUp() override { omp_set_num_threads(1); gfa_threshold = 0.2; odf_threshold = 0.1; peak_threshold = 0.1; - mitk::Image::Pointer odf_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/qball_image.qbi")); - mitk::Image::Pointer tensor_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/tensor_image.dti")); - mitk::Image::Pointer peak_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/qball_peak_image.nii.gz")); - mitk::Image::Pointer seed_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/seed_image.nii.gz")); - mitk::Image::Pointer mask_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/mask_image.nii.gz")); - mitk::Image::Pointer gfa_image = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/gfa_image.nii.gz")); + mitk::Image::Pointer odf_image = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/qball_image.qbi")); + mitk::Image::Pointer tensor_image = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/tensor_image.dti")); + mitk::Image::Pointer peak_image = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/qball_peak_image.nii.gz")); + mitk::Image::Pointer seed_image = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/seed_image.nii.gz")); + mitk::Image::Pointer mask_image = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/mask_image.nii.gz")); + mitk::Image::Pointer gfa_image = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/gfa_image.nii.gz")); { typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(peak_image); caster->Update(); itk_peak_image = caster->GetOutput(); } { typedef mitk::ImageToItk< mitk::TrackingHandlerTensor::ItkTensorImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(tensor_image); caster->Update(); itk_tensor_image = caster->GetOutput(); } { typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(odf_image); caster->Update(); itk_odf_image = caster->GetOutput(); } itk_gfa_image = ItkFloatImgType::New(); mitk::CastToItkImage(gfa_image, itk_gfa_image); itk_seed_image = ItkFloatImgType::New(); mitk::CastToItkImage(seed_image, itk_seed_image); itk_mask_image = ItkFloatImgType::New(); mitk::CastToItkImage(mask_image, itk_mask_image); } mitk::FiberBundle::Pointer LoadReferenceFib(std::string filename) { mitk::FiberBundle::Pointer fib = nullptr; if (itksys::SystemTools::FileExists(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename))) { mitk::BaseData::Pointer baseData = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename)).at(0); fib = dynamic_cast(baseData.GetPointer()); } return fib; } mitk::Image::Pointer LoadReferenceImage(std::string filename) { mitk::Image::Pointer img = nullptr; if (itksys::SystemTools::FileExists(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename))) { - img = mitk::IOUtil::LoadImage(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename)); + img = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename)); } return img; } void SetupTracker(mitk::TrackingDataHandler* handler) { tracker = itk::StreamlineTrackingFilter::New(); tracker->SetRandom(false); tracker->SetInterpolateMasks(false); tracker->SetNumberOfSamples(0); tracker->SetAngularThreshold(-1); tracker->SetMaskImage(itk_mask_image); tracker->SetSeedImage(itk_seed_image); tracker->SetStoppingRegions(nullptr); tracker->SetSeedsPerVoxel(1); tracker->SetStepSize(0.5); tracker->SetSamplingDistance(0.25); tracker->SetUseStopVotes(true); tracker->SetOnlyForwardSamples(true); tracker->SetMinTractLength(20); tracker->SetMaxNumTracts(-1); tracker->SetTrackingHandler(handler); tracker->SetUseOutputProbabilityMap(false); } void tearDown() override { } void CheckFibResult(std::string ref_file, mitk::FiberBundle::Pointer test_fib) { mitk::FiberBundle::Pointer ref = LoadReferenceFib(ref_file); if (ref.IsNull()) { mitk::IOUtil::Save(test_fib, mitk::IOUtil::GetTempPath()+ref_file); CPPUNIT_FAIL("Reference file not found. Saving test file to " + mitk::IOUtil::GetTempPath() + ref_file); } else { bool is_equal = ref->Equals(test_fib); if (!is_equal) { mitk::IOUtil::Save(test_fib, mitk::IOUtil::GetTempPath()+ref_file); CPPUNIT_FAIL("Tractograms are not equal! Saving test file to " + mitk::IOUtil::GetTempPath() + ref_file); } } } void CheckImageResult(std::string ref_file, mitk::Image::Pointer test_img) { mitk::Image::Pointer ref = LoadReferenceImage(ref_file); if (ref.IsNull()) { mitk::IOUtil::Save(test_img, mitk::IOUtil::GetTempPath()+ref_file); CPPUNIT_FAIL("Reference file not found. Saving test file to " + mitk::IOUtil::GetTempPath() + ref_file); } else { MITK_ASSERT_EQUAL(test_img, ref, "Images should be equal"); } } void Test_Peak1() { mitk::TrackingHandlerPeaks* handler = new mitk::TrackingHandlerPeaks(); handler->SetPeakImage(itk_peak_image); handler->SetPeakThreshold(peak_threshold); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Peak1.fib", outFib); delete handler; } void Test_Peak2() { mitk::TrackingHandlerPeaks* handler = new mitk::TrackingHandlerPeaks(); handler->SetPeakImage(itk_peak_image); handler->SetPeakThreshold(peak_threshold); handler->SetInterpolate(false); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Peak2.fib", outFib); delete handler; } void Test_Tensor1() { mitk::TrackingHandlerTensor* handler = new mitk::TrackingHandlerTensor(); handler->SetTensorImage(itk_tensor_image); handler->SetFaThreshold(gfa_threshold); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Tensor1.fib", outFib); delete handler; } void Test_Tensor2() { mitk::TrackingHandlerTensor* handler = new mitk::TrackingHandlerTensor(); handler->SetTensorImage(itk_tensor_image); handler->SetFaThreshold(gfa_threshold); handler->SetInterpolate(false); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Tensor2.fib", outFib); delete handler; } void Test_Tensor3() { mitk::TrackingHandlerTensor* handler = new mitk::TrackingHandlerTensor(); handler->SetTensorImage(itk_tensor_image); handler->SetFaThreshold(gfa_threshold); handler->SetInterpolate(false); handler->SetF(0); handler->SetG(1); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Tensor3.fib", outFib); delete handler; } void Test_Odf1() { mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf(); handler->SetOdfImage(itk_odf_image); handler->SetGfaThreshold(gfa_threshold); handler->SetOdfThreshold(0); handler->SetSharpenOdfs(true); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Odf1.fib", outFib); delete handler; } void Test_Odf2() { mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf(); handler->SetOdfImage(itk_odf_image); handler->SetGfaThreshold(gfa_threshold); handler->SetOdfThreshold(0); handler->SetSharpenOdfs(false); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Odf2.fib", outFib); delete handler; } void Test_Odf3() { mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf(); handler->SetOdfImage(itk_odf_image); handler->SetGfaThreshold(gfa_threshold); handler->SetOdfThreshold(0); handler->SetSharpenOdfs(true); handler->SetInterpolate(false); SetupTracker(handler); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Odf3.fib", outFib); delete handler; } void Test_Odf4() { mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf(); handler->SetOdfImage(itk_odf_image); handler->SetGfaThreshold(gfa_threshold); handler->SetOdfThreshold(0); handler->SetSharpenOdfs(true); SetupTracker(handler); tracker->SetSeedsPerVoxel(3); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Odf4.fib", outFib); delete handler; } void Test_Odf5() { mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf(); handler->SetOdfImage(itk_odf_image); handler->SetGfaThreshold(gfa_threshold); handler->SetOdfThreshold(0); handler->SetSharpenOdfs(true); handler->SetMode(mitk::TrackingDataHandler::MODE::PROBABILISTIC); SetupTracker(handler); tracker->SetSeedsPerVoxel(3); tracker->Update(); vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); CheckFibResult("Test_Odf5.fib", outFib); delete handler; } void Test_Odf6() { mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf(); handler->SetOdfImage(itk_odf_image); handler->SetGfaThreshold(gfa_threshold); handler->SetOdfThreshold(0); handler->SetSharpenOdfs(true); handler->SetMode(mitk::TrackingDataHandler::MODE::PROBABILISTIC); SetupTracker(handler); tracker->SetSeedsPerVoxel(10); tracker->SetUseOutputProbabilityMap(true); tracker->Update(); itk::StreamlineTrackingFilter::ItkDoubleImgType::Pointer outImg = tracker->GetOutputProbabilityMap(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::Save(img, mitk::IOUtil::GetTempPath()+"Test_Odf6.nrrd"); CheckImageResult("Test_Odf6.nrrd", img); delete handler; } }; MITK_TEST_SUITE_REGISTRATION(mitkStreamlineTractography) diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberClustering.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberClustering.cpp index 647c18a791..00559e4c71 100644 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberClustering.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberClustering.cpp @@ -1,251 +1,251 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } /*! \brief Spatially cluster fibers */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Clustering"); parser.setCategory("Fiber Processing"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i", mitkCommandLineParser::InputFile, "Input:", "input fiber bundle (.fib, .trk, .tck)", us::Any(), false); parser.addArgument("", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("cluster_size", "", mitkCommandLineParser::Int, "Cluster size:", "", 10); parser.addArgument("fiber_points", "", mitkCommandLineParser::Int, "Fiber points:", "", 12); parser.addArgument("min_fibers", "", mitkCommandLineParser::Int, "Min. fibers per cluster:", "", 1); parser.addArgument("max_clusters", "", mitkCommandLineParser::Int, "Max. clusters:", ""); parser.addArgument("merge_clusters", "", mitkCommandLineParser::Float, "Merge clusters:", "", -1.0); parser.addArgument("output_centroids", "", mitkCommandLineParser::Bool, "Output centroids:", ""); parser.addArgument("metrics", "", mitkCommandLineParser::StringList, "Metrics:", "EU_MEAN, EU_STD, EU_MAX, ANAT, MAP, LENGTH"); parser.addArgument("metric_weights", "", mitkCommandLineParser::StringList, "Metric weights:", "add one float weight for each used metric"); parser.addArgument("input_centroids", "", mitkCommandLineParser::String, "Input centroids:", ""); parser.addArgument("scalar_map", "", mitkCommandLineParser::String, "Scalar map:", ""); parser.addArgument("parcellation", "", mitkCommandLineParser::String, "Parcellation:", ""); parser.addArgument("file_ending", "", mitkCommandLineParser::String, "File ending:", ""); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["i"]); std::string out_root = us::any_cast(parsedArgs["o"]); int cluster_size = 10; if (parsedArgs.count("cluster_size")) cluster_size = us::any_cast(parsedArgs["cluster_size"]); int fiber_points = 12; if (parsedArgs.count("fiber_points")) fiber_points = us::any_cast(parsedArgs["fiber_points"]); int min_fibers = 1; if (parsedArgs.count("min_fibers")) min_fibers = us::any_cast(parsedArgs["min_fibers"]); int max_clusters = 0; if (parsedArgs.count("max_clusters")) max_clusters = us::any_cast(parsedArgs["max_clusters"]); float merge_clusters = -1.0; if (parsedArgs.count("merge_clusters")) merge_clusters = us::any_cast(parsedArgs["merge_clusters"]); bool output_centroids = false; if (parsedArgs.count("output_centroids")) output_centroids = us::any_cast(parsedArgs["output_centroids"]); std::vector< std::string > metric_strings = {"EU_MEAN"}; if (parsedArgs.count("metrics")) metric_strings = us::any_cast(parsedArgs["metrics"]); std::vector< std::string > metric_weights = {"1.0"}; if (parsedArgs.count("metric_weights")) metric_weights = us::any_cast(parsedArgs["metric_weights"]); std::string input_centroids = ""; if (parsedArgs.count("input_centroids")) input_centroids = us::any_cast(parsedArgs["input_centroids"]); std::string scalar_map = ""; if (parsedArgs.count("scalar_map")) scalar_map = us::any_cast(parsedArgs["scalar_map"]); std::string parcellation = ""; if (parsedArgs.count("parcellation")) parcellation = us::any_cast(parsedArgs["parcellation"]); std::string file_ending = ".fib"; if (parsedArgs.count("file_ending")) file_ending = us::any_cast(parsedArgs["file_ending"]); if (metric_strings.size()!=metric_weights.size()) { MITK_INFO << "Each metric needs an associated metric weight!"; return EXIT_FAILURE; } try { typedef itk::Image< float, 3 > FloatImageType; typedef itk::Image< short, 3 > ShortImageType; mitk::FiberBundle::Pointer fib = LoadFib(inFileName); float max_d = 0; int i=1; std::vector< float > distances; while (max_d < fib->GetGeometry()->GetDiagonalLength()/2) { distances.push_back(cluster_size*i); max_d = cluster_size*i; ++i; } itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New(); clusterer->SetDistances(distances); clusterer->SetTractogram(fib); if (input_centroids!="") { mitk::FiberBundle::Pointer in_centroids = LoadFib(input_centroids); clusterer->SetInCentroids(in_centroids); } std::vector< mitk::ClusteringMetric* > metrics; int mc = 0; for (auto m : metric_strings) { float w = boost::lexical_cast(metric_weights.at(mc)); MITK_INFO << "Metric: " << m << " (w=" << w << ")"; if (m=="EU_MEAN") metrics.push_back({new mitk::ClusteringMetricEuclideanMean()}); else if (m=="EU_STD") metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); else if (m=="EU_MAX") metrics.push_back({new mitk::ClusteringMetricEuclideanMax()}); else if (m=="ANGLES") metrics.push_back({new mitk::ClusteringMetricInnerAngles()}); else if (m=="LENGTH") metrics.push_back({new mitk::ClusteringMetricLength()}); else if (m=="MAP" && scalar_map!="") { - mitk::Image::Pointer mitk_map = dynamic_cast(mitk::IOUtil::Load(scalar_map)[0].GetPointer()); + mitk::Image::Pointer mitk_map = mitk::IOUtil::Load(scalar_map); if (mitk_map->GetDimension()==3) { FloatImageType::Pointer itk_map = FloatImageType::New(); mitk::CastToItkImage(mitk_map, itk_map); mitk::ClusteringMetricScalarMap* metric = new mitk::ClusteringMetricScalarMap(); metric->SetImages({itk_map}); metric->SetScale(distances.at(0)); metrics.push_back(metric); } } else if (m=="ANAT" && parcellation!="") { - mitk::Image::Pointer mitk_map = dynamic_cast(mitk::IOUtil::Load(parcellation)[0].GetPointer()); + mitk::Image::Pointer mitk_map = mitk::IOUtil::Load(parcellation); if (mitk_map->GetDimension()==3) { ShortImageType::Pointer itk_map = ShortImageType::New(); mitk::CastToItkImage(mitk_map, itk_map); mitk::ClusteringMetricAnatomic* metric = new mitk::ClusteringMetricAnatomic(); metric->SetParcellations({itk_map}); metrics.push_back(metric); } } metrics.back()->SetScale(w); mc++; } if (metrics.empty()) { MITK_INFO << "No metric selected!"; return EXIT_FAILURE; } clusterer->SetMetrics(metrics); clusterer->SetMergeDuplicateThreshold(merge_clusters); clusterer->SetNumPoints(fiber_points); clusterer->SetMaxClusters(max_clusters); clusterer->SetMinClusterSize(min_fibers); clusterer->Update(); std::vector tracts = clusterer->GetOutTractograms(); std::vector centroids = clusterer->GetOutCentroids(); MITK_INFO << "Saving clusters"; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect unsigned int c = 0; for (auto f : tracts) { mitk::IOUtil::Save(f, out_root + "Cluster_" + boost::lexical_cast(c) + file_ending); if (output_centroids) mitk::IOUtil::Save(centroids.at(c), out_root + "Centroid_" + boost::lexical_cast(c) + file_ending); ++c; } std::cout.rdbuf (old); // <-- restore } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp index 4a7c34740b..225c8516d6 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberDirectionExtraction.cpp @@ -1,175 +1,175 @@ /*=================================================================== 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 #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include /*! \brief Extract principal fiber directions from a tractogram */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Direction Extraction"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Extract principal fiber directions from a tractogram"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib/.trk)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image"); parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); parser.addArgument("peakthresh", "t", mitkCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); parser.addArgument("numdirs", "d", mitkCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true); parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization method:", "1=global maximum, 2=single vector, 3=voxel-wise maximum", 1); parser.addArgument("file_ending", "f", mitkCommandLineParser::String, "Image type:", ".nrrd, .nii, .nii.gz"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string fibFile = us::any_cast(parsedArgs["input"]); std::string maskImage(""); if (parsedArgs.count("mask")) maskImage = us::any_cast(parsedArgs["mask"]); float peakThreshold = 0.2; if (parsedArgs.count("peakthresh")) peakThreshold = us::any_cast(parsedArgs["peakthresh"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); std::string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); int maxNumDirs = 3; if (parsedArgs.count("numdirs")) maxNumDirs = us::any_cast(parsedArgs["numdirs"]); int normalization = 1; if (parsedArgs.count("normalization")) normalization = us::any_cast(parsedArgs["normalization"]); std::string file_ending = ".nrrd"; if (parsedArgs.count("file_ending")) file_ending = us::any_cast(parsedArgs["file_ending"]); try { typedef itk::Image ItkUcharImgType; // load fiber bundle - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(fibFile)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); // load/create mask image ItkUcharImgType::Pointer itkMaskImage = nullptr; if (maskImage.compare("")!=0) { std::cout << "Using mask image"; itkMaskImage = ItkUcharImgType::New(); - mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::Load(maskImage)[0].GetPointer()); + mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::Load(maskImage); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); } // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*itk::Math::pi/180)); switch (normalization) { case 1: fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::GLOBAL_MAX); break; case 2: fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::SINGLE_VEC_NORM); break; case 3: fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter::NormalizationMethods::MAX_VEC_NORM); break; } fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->SetSizeThreshold(peakThreshold); fOdfFilter->SetMaxNumDirections(maxNumDirs); fOdfFilter->Update(); { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = fOdfFilter->GetDirectionImage(); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append("_DIRECTIONS"); outfilename.append(file_ending); writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } if (verbose) { // write num direction image ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS"); outfilename.append(file_ending); writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp index 124e9fb9b6..b534839be1 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtraction.cpp @@ -1,151 +1,151 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Extract fibers from a tractogram using planar figure ROIs */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Extraction"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Extract fibers from a tractogram using planar figure ROIs"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); parser.addArgument("planfirgure1", "pf1", mitkCommandLineParser::String, "Figure 1:", "first planar figure ROI", us::Any(), false); parser.addArgument("planfirgure2", "pf2", mitkCommandLineParser::String, "Figure 2:", "second planar figure ROI", us::Any()); parser.addArgument("operation", "op", mitkCommandLineParser::String, "Operation:", "logical operation (AND, OR, NOT)", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFib = us::any_cast(parsedArgs["input"]); std::string outFib = us::any_cast(parsedArgs["out"]); std::string pf1_path = us::any_cast(parsedArgs["planfirgure1"]); std::string operation(""); std::string pf2_path(""); if (parsedArgs.count("operation")) { operation = us::any_cast(parsedArgs["operation"]); if (parsedArgs.count("planfirgure2") && (operation=="AND" || operation=="OR")) pf2_path = us::any_cast(parsedArgs["planfirgure2"]); } try { // load fiber bundle - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(inFib)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(inFib); mitk::FiberBundle::Pointer result; mitk::StandaloneDataStorage::Pointer storage = mitk::StandaloneDataStorage::New(); auto data = mitk::IOUtil::Load(pf1_path)[0]; auto input1 = mitk::DataNode::New(); input1->SetData(data); if (input1.IsNotNull()) { mitk::PlanarFigureComposite::Pointer pfc = mitk::PlanarFigureComposite::New(); mitk::DataNode::Pointer pfcNode = mitk::DataNode::New(); pfcNode->SetData(pfc); mitk::DataStorage::SetOfObjects::Pointer set1 = mitk::DataStorage::SetOfObjects::New(); set1->push_back(pfcNode); storage->Add(pfcNode); auto input2 = mitk::DataNode::New(); if (!pf2_path.empty()) { data = mitk::IOUtil::Load(pf2_path)[0]; input2->SetData(data); } if (operation.empty()) { result = inputTractogram->ExtractFiberSubset(input1, nullptr); } else if (operation=="NOT") { pfc->setOperationType(mitk::PlanarFigureComposite::NOT); storage->Add(input1, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else if (operation=="AND" && input2.IsNotNull()) { pfc->setOperationType(mitk::PlanarFigureComposite::AND); storage->Add(input1, set1); storage->Add(input2, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else if (operation=="OR" && input2.IsNotNull()) { pfc->setOperationType(mitk::PlanarFigureComposite::OR); storage->Add(input1, set1); storage->Add(input2, set1); result = inputTractogram->ExtractFiberSubset(pfcNode, storage); } else { std::cout << "Could not process input:"; std::cout << pf1_path; std::cout << pf2_path; std::cout << operation; } } if (result.IsNotNull()) mitk::IOUtil::Save(result, outFib); else std::cout << "No valid fiber bundle extracted."; } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtractionRoi.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtractionRoi.cpp index 5306c39b48..a23ae3e9dc 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtractionRoi.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FiberExtractionRoi.cpp @@ -1,198 +1,198 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; ItkFloatImgType::Pointer LoadItkImage(const std::string& filename) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(filename); ItkFloatImgType::Pointer itk_image = ItkFloatImgType::New(); mitk::CastToItkImage(img, itk_image); return itk_image; } /*! \brief Extract fibers from a tractogram using binary image ROIs */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fiber Extraction With ROI Image"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Extract fibers from a tractogram using binary image ROIs"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk/.tck/.dcm)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); parser.addArgument("rois", "", mitkCommandLineParser::StringList, "ROI images:", "ROI images", us::Any(), false); parser.addArgument("both_ends", "", mitkCommandLineParser::Bool, "Both ends:", "Fibers are extracted if both endpoints are located in the ROI.", false); parser.addArgument("overlap_fraction", "", mitkCommandLineParser::Float, "Overlap fraction:", "Extract by overlap, not by endpoints. Extract fibers that overlap to at least the provided factor (0-1) with the ROI.", -1); parser.addArgument("invert", "", mitkCommandLineParser::Bool, "Invert:", "get streamlines not positive for any of the ROI images", false); parser.addArgument("interpolate", "", mitkCommandLineParser::Bool, "Interpolate:", "interpolate ROI images", false); parser.addArgument("threshold", "", mitkCommandLineParser::Float, "Threshold:", "positive means ROI image value threshold", 0.5); parser.addArgument("labels", "", mitkCommandLineParser::StringList, "Labels:", "positive means roi image value in labels vector", false); parser.addArgument("split_labels", "", mitkCommandLineParser::Bool, "Split labels:", "output a separate tractogram for each label-->label tract", false); parser.addArgument("skip_self_connections", "", mitkCommandLineParser::Bool, "Skip self connections:", "ignore streamlines between two identical labels", false); parser.addArgument("min_fibers", "", mitkCommandLineParser::Int, "Min. num. fibers:", "discard positive tracts with less fibers", 0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFib = us::any_cast(parsedArgs["input"]); std::string outFib = us::any_cast(parsedArgs["out"]); mitkCommandLineParser::StringContainerType roi_files = us::any_cast(parsedArgs["rois"]); bool both_ends = false; if (parsedArgs.count("both_ends")) both_ends = us::any_cast(parsedArgs["both_ends"]); bool invert = false; if (parsedArgs.count("invert")) invert = us::any_cast(parsedArgs["invert"]); unsigned int min_fibers = 0; if (parsedArgs.count("min_fibers")) min_fibers = us::any_cast(parsedArgs["min_fibers"]); bool split_labels = false; if (parsedArgs.count("split_labels")) split_labels = us::any_cast(parsedArgs["split_labels"]); bool skip_self_connections = false; if (parsedArgs.count("skip_self_connections")) skip_self_connections = us::any_cast(parsedArgs["skip_self_connections"]); float overlap_fraction = -1; if (parsedArgs.count("overlap_fraction")) overlap_fraction = us::any_cast(parsedArgs["overlap_fraction"]); bool any_point = false; if (overlap_fraction>=0) any_point = true; bool interpolate = false; if (parsedArgs.count("interpolate")) interpolate = us::any_cast(parsedArgs["interpolate"]); float threshold = 0.5; if (parsedArgs.count("threshold")) threshold = us::any_cast(parsedArgs["threshold"]); mitkCommandLineParser::StringContainerType labels; if (parsedArgs.count("labels")) labels = us::any_cast(parsedArgs["labels"]); try { // load fiber bundle - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(inFib)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(inFib); std::vector< ItkFloatImgType::Pointer > roi_images; for (std::size_t i=0; i roi_images2; for (auto roi : roi_images) roi_images2.push_back(roi); std::vector< unsigned short > short_labels; for (auto l : labels) short_labels.push_back(boost::lexical_cast(l)); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(inputTractogram); extractor->SetRoiImages(roi_images2); extractor->SetOverlapFraction(overlap_fraction); extractor->SetBothEnds(both_ends); extractor->SetInterpolate(interpolate); extractor->SetThreshold(threshold); extractor->SetLabels(short_labels); extractor->SetSplitLabels(split_labels); extractor->SetMinFibersPerTract(min_fibers); extractor->SetSkipSelfConnections(skip_self_connections); if (invert) extractor->SetNoPositives(true); else extractor->SetNoNegatives(true); if (!any_point) extractor->SetMode(itk::FiberExtractionFilter::MODE::ENDPOINTS); if (short_labels.size()>0) extractor->SetInputType(itk::FiberExtractionFilter::INPUT::LABEL_MAP); extractor->Update(); mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(nullptr); if (invert) mitk::IOUtil::Save(extractor->GetNegatives().at(0), outFib); else { if (!split_labels) { newFib = newFib->AddBundles(extractor->GetPositives()); mitk::IOUtil::Save(newFib, outFib); } else { int c = 0; std::vector< std::pair< unsigned int, unsigned int > > positive_labels = extractor->GetPositiveLabels(); for (auto fib : extractor->GetPositives()) { std::pair< unsigned int, unsigned int > l = positive_labels.at(c); mitk::IOUtil::Save(fib, outFib + "_" + boost::lexical_cast(l.first) + "-" + boost::lexical_cast(l.second) + ".trk"); ++c; } } } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FitFibersToImage.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FitFibersToImage.cpp index 7afad23cf4..d8577f4050 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FitFibersToImage.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/FitFibersToImage.cpp @@ -1,350 +1,350 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Point PointType4; typedef itk::Image< float, 4 > PeakImgType; std::vector< std::string > get_file_list(const std::string& path) { std::vector< std::string > file_list; itk::Directory::Pointer dir = itk::Directory::New(); if (dir->Load(path.c_str())) { int n = dir->GetNumberOfFiles(); for (int r = 0; r < n; r++) { const char *filename = dir->GetFile(r); std::string ext = ist::GetFilenameExtension(filename); if (ext==".fib" || ext==".trk") file_list.push_back(path + '/' + filename); } } return file_list; } /*! \brief Fits the tractogram to the input peak image by assigning a weight to each fiber (similar to https://doi.org/10.1016/j.neuroimage.2015.06.092). */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Fit Fibers To Image"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Assigns a weight to each fiber in order to optimally explain the input peak image"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i1", mitkCommandLineParser::StringList, "Input tractograms:", "input tractograms (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("", "i2", mitkCommandLineParser::InputFile, "Input image:", "input image", us::Any(), false); parser.addArgument("", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("max_iter", "", mitkCommandLineParser::Int, "Max. iterations:", "maximum number of optimizer iterations", 20); parser.addArgument("bundle_based", "", mitkCommandLineParser::Bool, "Bundle based fit:", "fit one weight per input tractogram/bundle, not for each fiber", false); parser.addArgument("min_g", "", mitkCommandLineParser::Float, "Min. g:", "lower termination threshold for gradient magnitude", 1e-5); parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "modifier for regularization", 0.1); parser.addArgument("save_res", "", mitkCommandLineParser::Bool, "Save Residuals:", "save residual images", false); parser.addArgument("save_weights", "", mitkCommandLineParser::Bool, "Save Weights:", "save fiber weights in a separate text file", false); parser.addArgument("filter_outliers", "", mitkCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false); parser.addArgument("join_tracts", "", mitkCommandLineParser::Bool, "Join output tracts:", "outout tracts are merged into a single tractogram", false); parser.addArgument("regu", "", mitkCommandLineParser::String, "Regularization:", "MSM, Variance, VoxelVariance (default), Lasso, GroupLasso, GroupVariance, NONE"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType fib_files = us::any_cast(parsedArgs["i1"]); std::string input_image_name = us::any_cast(parsedArgs["i2"]); std::string outRoot = us::any_cast(parsedArgs["o"]); bool single_fib = true; if (parsedArgs.count("bundle_based")) single_fib = !us::any_cast(parsedArgs["bundle_based"]); bool save_residuals = false; if (parsedArgs.count("save_res")) save_residuals = us::any_cast(parsedArgs["save_res"]); bool save_weights = false; if (parsedArgs.count("save_weights")) save_weights = us::any_cast(parsedArgs["save_weights"]); std::string regu = "VoxelVariance"; if (parsedArgs.count("regu")) regu = us::any_cast(parsedArgs["regu"]); bool join_tracts = false; if (parsedArgs.count("join_tracts")) join_tracts = us::any_cast(parsedArgs["join_tracts"]); int max_iter = 20; if (parsedArgs.count("max_iter")) max_iter = us::any_cast(parsedArgs["max_iter"]); float g_tol = 1e-5; if (parsedArgs.count("min_g")) g_tol = us::any_cast(parsedArgs["min_g"]); float lambda = 0.1; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); bool filter_outliers = false; if (parsedArgs.count("filter_outliers")) filter_outliers = us::any_cast(parsedArgs["filter_outliers"]); try { MITK_INFO << "Loading data"; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect std::vector< mitk::FiberBundle::Pointer > input_tracts; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image", "Fiberbundles"}, {}); std::vector< std::string > fib_names; for (auto item : fib_files) { if ( ist::FileIsDirectory(item) ) { for ( auto fibFile : get_file_list(item) ) { - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(fibFile)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); if (inputTractogram.IsNull()) continue; input_tracts.push_back(inputTractogram); fib_names.push_back(fibFile); } } else { - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(item)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(item); if (inputTractogram.IsNull()) continue; input_tracts.push_back(inputTractogram); fib_names.push_back(item); } } std::cout.rdbuf (old); // <-- restore itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input_image_name, &functor)[0].GetPointer(); mitk::Image::Pointer mitk_image = dynamic_cast(inputData.GetPointer()); mitk::PeakImage::Pointer mitk_peak_image = dynamic_cast(inputData.GetPointer()); if (mitk_peak_image.IsNotNull()) { typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(mitk_peak_image); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer peak_image = caster->GetOutput(); fitter->SetPeakImage(peak_image); } else if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image)) { fitter->SetDiffImage(mitk::DiffusionPropertyHelper::GetItkVectorImage(mitk_image)); mitk::TensorModel<>* model = new mitk::TensorModel<>(); model->SetBvalue(1000); model->SetDiffusivity1(0.0010); model->SetDiffusivity2(0.00015); model->SetDiffusivity3(0.00015); model->SetGradientList(mitk::DiffusionPropertyHelper::GetGradientContainer(mitk_image)); fitter->SetSignalModel(model); } else if (mitk_image->GetDimension()==3) { itk::FitFibersToImageFilter::DoubleImgType::Pointer scalar_image = itk::FitFibersToImageFilter::DoubleImgType::New(); mitk::CastToItkImage(mitk_image, scalar_image); fitter->SetScalarImage(scalar_image); } else { MITK_INFO << "Input image invalid. Valid options are peak image, 3D scalar image or raw diffusion-weighted image."; return EXIT_FAILURE; } fitter->SetTractograms(input_tracts); fitter->SetFitIndividualFibers(single_fib); fitter->SetMaxIterations(max_iter); fitter->SetGradientTolerance(g_tol); fitter->SetLambda(lambda); fitter->SetFilterOutliers(filter_outliers); if (regu=="MSM") fitter->SetRegularization(VnlCostFunction::REGU::MSM); else if (regu=="Variance") fitter->SetRegularization(VnlCostFunction::REGU::VARIANCE); else if (regu=="Lasso") fitter->SetRegularization(VnlCostFunction::REGU::LASSO); else if (regu=="VoxelVariance") fitter->SetRegularization(VnlCostFunction::REGU::VOXEL_VARIANCE); else if (regu=="GroupLasso") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_LASSO); else if (regu=="GroupVariance") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_VARIANCE); else if (regu=="NONE") fitter->SetRegularization(VnlCostFunction::REGU::NONE); fitter->Update(); if (save_residuals && mitk_peak_image.IsNotNull()) { itk::ImageFileWriter< PeakImgType >::Pointer writer = itk::ImageFileWriter< PeakImgType >::New(); writer->SetInput(fitter->GetFittedImage()); writer->SetFileName(outRoot + "_fitted.nii.gz"); writer->Update(); writer->SetInput(fitter->GetResidualImage()); writer->SetFileName(outRoot + "_residual.nii.gz"); writer->Update(); writer->SetInput(fitter->GetOverexplainedImage()); writer->SetFileName(outRoot + "_overexplained.nii.gz"); writer->Update(); writer->SetInput(fitter->GetUnderexplainedImage()); writer->SetFileName(outRoot + "_underexplained.nii.gz"); writer->Update(); } else if (save_residuals && mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image)) { { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetFittedImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_fitted_image.nii.gz"); } { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetResidualImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_residual_image.nii.gz"); } { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetOverexplainedImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_overexplained_image.nii.gz"); } { mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetUnderexplainedImageDiff().GetPointer() ); mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_underexplained_image.nii.gz"); } } else if (save_residuals) { itk::ImageFileWriter< itk::FitFibersToImageFilter::DoubleImgType >::Pointer writer = itk::ImageFileWriter< itk::FitFibersToImageFilter::DoubleImgType >::New(); writer->SetInput(fitter->GetFittedImageScalar()); writer->SetFileName(outRoot + "_fitted_image.nii.gz"); writer->Update(); writer->SetInput(fitter->GetResidualImageScalar()); writer->SetFileName(outRoot + "_residual_image.nii.gz"); writer->Update(); writer->SetInput(fitter->GetOverexplainedImageScalar()); writer->SetFileName(outRoot + "_overexplained_image.nii.gz"); writer->Update(); writer->SetInput(fitter->GetUnderexplainedImageScalar()); writer->SetFileName(outRoot + "_underexplained_image.nii.gz"); writer->Update(); } std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms(); if (!join_tracts) { for (unsigned int bundle=0; bundleGetNumFibers(); ++f) logfile << output_tracts.at(bundle)->GetFiberWeight(f) << "\n"; logfile.close(); } } } else { mitk::FiberBundle::Pointer out = mitk::FiberBundle::New(); out = out->AddBundles(output_tracts); out->ColorFibersByFiberWeights(false, true); mitk::IOUtil::Save(out, outRoot + "_fitted.fib"); if (save_weights) { ofstream logfile; logfile.open (outRoot + "_weights.txt"); for (int f=0; fGetNumFibers(); ++f) logfile << out->GetFiberWeight(f) << "\n"; logfile.close(); } } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/GetOverlappingTracts.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/GetOverlappingTracts.cpp index c6864cec9f..233e36bed0 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/GetOverlappingTracts.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/GetOverlappingTracts.cpp @@ -1,135 +1,135 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; /*! \brief Extract fibers from a tractogram using binary image ROIs */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Move Overlapping Tracts"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setDescription("Move tracts that overlap with one of the reference tracts"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::StringList, "Input:", "input tractograms (.fib/.trk/.tck/.dcm)", us::Any(), false); parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference:", "reference tractograms (.fib/.trk/.tck/.dcm)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output Folder:", "move input tracts that do/don't overlap here", us::Any(), false); parser.addArgument("overlap_fraction", "", mitkCommandLineParser::Float, "Overlap fraction:", "", 0.9); parser.addArgument("move_overlapping", "", mitkCommandLineParser::Bool, ":", ""); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType input = us::any_cast(parsedArgs["input"]); mitkCommandLineParser::StringContainerType reference = us::any_cast(parsedArgs["reference"]); std::string out_folder = us::any_cast(parsedArgs["out"]); bool move_overlapping = false; if (parsedArgs.count("move_overlapping")) move_overlapping = us::any_cast(parsedArgs["move_overlapping"]); float overlap_threshold = 0.9; if (parsedArgs.count("overlap_fraction")) overlap_threshold = us::any_cast(parsedArgs["overlap_fraction"]); try { itk::TractDensityImageFilter< ItkFloatImgType >::Pointer filter = itk::TractDensityImageFilter< ItkFloatImgType >::New(); filter->SetDoFiberResampling(true); filter->SetUpsamplingFactor(0.25); filter->SetBinaryOutput(true); std::vector< ItkFloatImgType::Pointer > masks; for (auto f : reference) { - mitk::FiberBundle::Pointer fib = dynamic_cast(mitk::IOUtil::Load(f)[0].GetPointer()); + mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(f); filter->SetFiberBundle(fib); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect filter->Update(); masks.push_back(filter->GetOutput()); std::cout.rdbuf (old); // <-- restore } boost::progress_display disp(input.size()); for (auto f : input) { ++disp; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect bool is_overlapping = false; - mitk::FiberBundle::Pointer fib = dynamic_cast(mitk::IOUtil::Load(f)[0].GetPointer()); + mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(f); fib->ResampleLinear(2); for (auto m : masks) { float overlap = fib->GetOverlap(m, false); if (overlap>=overlap_threshold) { is_overlapping = true; break; } } if (move_overlapping && is_overlapping) ist::CopyAFile(f, out_folder + ist::GetFilenameName(f)); else if (!move_overlapping && !is_overlapping) ist::CopyAFile(f, out_folder + ist::GetFilenameName(f)); std::cout.rdbuf (old); // <-- restore } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp index e0bd2354e7..13098ed6b0 100644 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensity.cpp @@ -1,215 +1,215 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } /*! \brief Modify input tractogram: fiber resampling, compression, pruning and transformation. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Tract Density"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Generate tract density image, fiber envelope or fiber endpoints image."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input fiber bundle (.fib)", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false); parser.addArgument("binary", "", mitkCommandLineParser::Bool, "Binary output:", "calculate binary tract envelope", us::Any()); parser.addArgument("normalize", "", mitkCommandLineParser::Bool, "Normalized output:", "normalize output to 0-1", us::Any()); parser.addArgument("endpoints", "", mitkCommandLineParser::Bool, "Output endpoints image:", "calculate image of fiber endpoints instead of mask", us::Any()); parser.addArgument("reference_image", "", mitkCommandLineParser::String, "Reference image:", "output image will have geometry of this reference image", us::Any()); parser.addArgument("upsampling", "", mitkCommandLineParser::Float, "Upsampling:", "upsampling", 1.0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool binary = false; if (parsedArgs.count("binary")) binary = us::any_cast(parsedArgs["binary"]); bool endpoints = false; if (parsedArgs.count("endpoints")) endpoints = us::any_cast(parsedArgs["endpoints"]); bool normalize = false; if (parsedArgs.count("normalize")) normalize = us::any_cast(parsedArgs["normalize"]); float upsampling = 1.0; if (parsedArgs.count("upsampling")) upsampling = us::any_cast(parsedArgs["upsampling"]); MITK_INFO << "Upsampling: " << upsampling; std::string reference_image = ""; if (parsedArgs.count("reference_image")) reference_image = us::any_cast(parsedArgs["reference_image"]); std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outFileName = us::any_cast(parsedArgs["output"]); try { mitk::FiberBundle::Pointer fib = LoadFib(inFileName); mitk::Image::Pointer ref_img; if (!reference_image.empty()) - ref_img = dynamic_cast(mitk::IOUtil::Load(reference_image)[0].GetPointer()); + ref_img = mitk::IOUtil::Load(reference_image); if (endpoints) { typedef unsigned int OutPixType; typedef itk::Image OutImageType; typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); generator->SetFiberBundle(fib); generator->SetUpsamplingFactor(upsampling); if (ref_img.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::Save(img, outFileName ); } else if (binary) { typedef unsigned char OutPixType; typedef itk::Image OutImageType; itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(fib); generator->SetBinaryOutput(binary); generator->SetOutputAbsoluteValues(!normalize); generator->SetWorkOnFiberCopy(false); generator->SetUpsamplingFactor(upsampling); if (ref_img.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::Save(img, outFileName ); } else { typedef float OutPixType; typedef itk::Image OutImageType; itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(fib); generator->SetBinaryOutput(binary); generator->SetOutputAbsoluteValues(!normalize); generator->SetWorkOnFiberCopy(false); generator->SetUpsamplingFactor(upsampling); if (ref_img.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(ref_img, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::IOUtil::Save(img, outFileName ); } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensityFilter.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensityFilter.cpp index 69c29a800f..a71cd7d507 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensityFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/FiberProcessing/TractDensityFilter.cpp @@ -1,111 +1,111 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; /*! \brief Extract fibers from a tractogram using binary image ROIs */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Filter Outliers by Tract Density"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk/.tck/.dcm)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false); parser.addArgument("threshold", "", mitkCommandLineParser::Float, "Threshold:", "positive means ROI image value threshold", 0.05); parser.addArgument("overlap", "", mitkCommandLineParser::Float, "Overlap:", "positive means ROI image value threshold", 0.5); parser.addArgument("min_fibers", "", mitkCommandLineParser::Int, "Min. num. fibers:", "discard positive tracts with less fibers", 0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFib = us::any_cast(parsedArgs["input"]); std::string outFib = us::any_cast(parsedArgs["out"]); int min_fibers = 0; if (parsedArgs.count("min_fibers")) min_fibers = us::any_cast(parsedArgs["min_fibers"]); float overlap = 0.5; if (parsedArgs.count("overlap")) overlap = us::any_cast(parsedArgs["overlap"]); float threshold = 0.05; if (parsedArgs.count("threshold")) threshold = us::any_cast(parsedArgs["threshold"]); try { - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(inFib)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(inFib); itk::TractDensityImageFilter< ItkFloatImgType >::Pointer generator = itk::TractDensityImageFilter< ItkFloatImgType >::New(); generator->SetFiberBundle(inputTractogram); generator->SetBinaryOutput(false); generator->SetOutputAbsoluteValues(false); generator->SetWorkOnFiberCopy(true); generator->Update(); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetRoiImages({generator->GetOutput()}); extractor->SetInputFiberBundle(inputTractogram); extractor->SetOverlapFraction(overlap); extractor->SetInterpolate(true); extractor->SetThreshold(threshold); extractor->SetNoNegatives(true); extractor->Update(); if (extractor->GetPositives().at(0)->GetNumFibers()>=min_fibers) mitk::IOUtil::Save(extractor->GetPositives().at(0), outFib); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/FiberfoxOptimization.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/FiberfoxOptimization.cpp old mode 100755 new mode 100644 index 52d2f8be9b..66c83ba95c --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/FiberfoxOptimization.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Fiberfox/FiberfoxOptimization.cpp @@ -1,831 +1,831 @@ /*=================================================================== 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 #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace mitk; double CalcErrorSignal(const std::vector& histo_mod, itk::VectorImage< short, 3 >* reference, itk::VectorImage< short, 3 >* simulation, itk::Image< unsigned char,3 >::Pointer mask, itk::Image< double,3 >::Pointer fa) { typedef itk::Image< double, 3 > DoubleImageType; typedef itk::VectorImage< short, 3 > DwiImageType; if (fa.IsNotNull()) { itk::ImageRegionIterator< DwiImageType > it1(reference, reference->GetLargestPossibleRegion()); itk::ImageRegionIterator< DwiImageType > it2(simulation, simulation->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< DoubleImageType > it3(fa, fa->GetLargestPossibleRegion()); unsigned int count = 0; double error = 0; while(!it1.IsAtEnd()) { if (mask.IsNull() || (mask.IsNotNull() && mask->GetLargestPossibleRegion().IsInside(it1.GetIndex()) && mask->GetPixel(it1.GetIndex())>0) ) { double fa = it3.Get(); if (fa>0) { double mod = 1.0; for (int i=histo_mod.size()-1; i>=0; --i) if (fa >= (double)i/histo_mod.size()) { mod = histo_mod.at(i); break; } for (unsigned int i=0; iGetVectorLength(); ++i) { if (it1.Get()[i]>0) { double diff = (double)it2.Get()[i]/it1.Get()[i] - 1.0; error += std::pow(mod, 4) * fabs(diff); count++; } } } } ++it1; ++it2; ++it3; } return error/count; } else { itk::ImageRegionIterator< DwiImageType > it1(reference, reference->GetLargestPossibleRegion()); itk::ImageRegionIterator< DwiImageType > it2(simulation, simulation->GetLargestPossibleRegion()); unsigned int count = 0; double error = 0; while(!it1.IsAtEnd()) { if (mask.IsNull() || (mask.IsNotNull() && mask->GetLargestPossibleRegion().IsInside(it1.GetIndex()) && mask->GetPixel(it1.GetIndex())>0) ) { for (unsigned int i=0; iGetVectorLength(); ++i) { if (it1.Get()[i]>0) { double diff = (double)it2.Get()[i]/it1.Get()[i] - 1.0; error += fabs(diff); count++; } } } ++it1; ++it2; } return error/count; } return -1; } double CalcErrorFA(const std::vector& histo_mod, mitk::Image::Pointer dwi1, itk::VectorImage< short, 3 >* dwi2, itk::Image< unsigned char,3 >::Pointer mask, itk::Image< double,3 >::Pointer fa1, itk::Image< double,3 >::Pointer md1, bool b0_contrast) { typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; typedef itk::Image< double, 3 > DoubleImageType; typedef itk::VectorImage< short, 3 > DwiType; DwiType::Pointer dwi1_itk = mitk::DiffusionPropertyHelper::GetItkVectorImage(dwi1); typedef itk::DiffusionTensor3DReconstructionImageFilter TensorReconstructionImageFilterType; DoubleImageType::Pointer fa2; { mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainerCopy = mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::New(); for(auto it = mitk::DiffusionPropertyHelper::GetGradientContainer(dwi1)->Begin(); it != mitk::DiffusionPropertyHelper::GetGradientContainer(dwi1)->End(); it++) gradientContainerCopy->push_back(it.Value()); TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New(); tensorReconstructionFilter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi1) ); tensorReconstructionFilter->SetGradientImage(gradientContainerCopy, dwi2 ); tensorReconstructionFilter->Update(); MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput( tensorReconstructionFilter->GetOutput() ); measurementsCalculator->SetMeasure(MeasurementsType::FA); measurementsCalculator->Update(); fa2 = measurementsCalculator->GetOutput(); } DoubleImageType::Pointer md2; if (md1.IsNotNull()) { typedef itk::AdcImageFilter< short, double > AdcFilterType; AdcFilterType::Pointer filter = AdcFilterType::New(); filter->SetInput( dwi2 ); filter->SetGradientDirections( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi1) ); filter->SetB_value( mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi1) ); filter->SetFitSignal(false); filter->Update(); md2 = filter->GetOutput(); } itk::ImageRegionConstIterator< DoubleImageType > it1(fa1, fa1->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< DoubleImageType > it2(fa2, fa2->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< itk::VectorImage< short, 3 > > it_diff1(dwi1_itk, dwi1_itk->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< itk::VectorImage< short, 3 > > it_diff2(dwi2, dwi2->GetLargestPossibleRegion()); unsigned int count = 0; double error = 0; if (md1.IsNotNull() && md2.IsNotNull()) { itk::ImageRegionConstIterator< DoubleImageType > it3(md1, md1->GetLargestPossibleRegion()); itk::ImageRegionConstIterator< DoubleImageType > it4(md2, md2->GetLargestPossibleRegion()); while(!it1.IsAtEnd()) { if (mask.IsNull() || (mask.IsNotNull() && mask->GetLargestPossibleRegion().IsInside(it1.GetIndex()) && mask->GetPixel(it1.GetIndex())>0) ) { double fa = it1.Get(); if (fa>0 && it3.Get()>0) { double mod = 1.0; for (int i=histo_mod.size()-1; i>=0; --i) if (fa >= (double)i/histo_mod.size()) { mod = histo_mod.at(i); break; } double fa_diff = std::fabs(it2.Get()/fa - 1.0); double md_diff = std::fabs(it4.Get()/it3.Get() - 1.0); error += std::pow(mod, 4) * (fa_diff + md_diff); count += 2; if (b0_contrast && it_diff1.Get()[0]>0) { double b0_diff = (double)it_diff2.Get()[0]/it_diff1.Get()[0] - 1.0; error += std::pow(mod, 4) * std::fabs(b0_diff); ++count; } } } ++it1; ++it2; ++it3; ++it4; ++it_diff1; ++it_diff2; } } else { unsigned int count = 0; double error = 0; while(!it1.IsAtEnd()) { if (mask.IsNull() || (mask.IsNotNull() && mask->GetLargestPossibleRegion().IsInside(it1.GetIndex()) && mask->GetPixel(it1.GetIndex())>0) ) { double fa = it1.Get(); if (fa>0) { double mod = 1.0; for (int i=histo_mod.size()-1; i>=0; --i) if (fa >= (double)i/histo_mod.size()) { mod = histo_mod.at(i); break; } double fa_diff = fabs(it2.Get()/fa - 1.0); error += std::pow(mod, 4) * fa_diff; ++count; if (b0_contrast && it_diff1.Get()[0]>0) { double b0_diff = (double)it_diff2.Get()[0]/it_diff1.Get()[0] - 1.0; error += std::pow(mod, 4) * std::fabs(b0_diff); ++count; } } } ++it1; ++it2; ++it_diff1; ++it_diff2; } } return error/count; } FiberfoxParameters MakeProposalScale(FiberfoxParameters old_params, double temperature) { FiberfoxParameters new_params(old_params); std::random_device r; std::default_random_engine randgen(r()); std::normal_distribution normal_dist(0, new_params.m_SignalGen.m_SignalScale*0.1*temperature); double add = 0; while (add == 0) add = normal_dist(randgen); new_params.m_SignalGen.m_SignalScale += add; MITK_INFO << "Proposal Signal Scale: " << new_params.m_SignalGen.m_SignalScale << " (" << add << ")"; return new_params; } FiberfoxParameters MakeProposalRelaxation(FiberfoxParameters old_params, double temperature) { FiberfoxParameters new_params(old_params); std::random_device r; std::default_random_engine randgen(r()); std::uniform_int_distribution uint1(0, 3); int prop = uint1(randgen); switch(prop) { case 0: { int model_index = rand()%new_params.m_NonFiberModelList.size(); double t2 = new_params.m_NonFiberModelList[model_index]->GetT2(); std::normal_distribution normal_dist(0, t2*0.1*temperature); double add = 0; while (add == 0) add = normal_dist(randgen); if ( (t2+add)*1.5 > new_params.m_NonFiberModelList[model_index]->GetT1() ) add = -add; t2 += add; new_params.m_NonFiberModelList[model_index]->SetT2(t2); MITK_INFO << "Proposal T2 (Non-Fiber " << model_index << "): " << t2 << " (" << add << ")"; break; } case 1: { int model_index = rand()%new_params.m_FiberModelList.size(); double t2 = new_params.m_FiberModelList[model_index]->GetT2(); std::normal_distribution normal_dist(0, t2*0.1*temperature); double add = 0; while (add == 0) add = normal_dist(randgen); if ( (t2+add)*1.5 > new_params.m_FiberModelList[model_index]->GetT1() ) add = -add; t2 += add; new_params.m_FiberModelList[model_index]->SetT2(t2); MITK_INFO << "Proposal T2 (Fiber " << model_index << "): " << t2 << " (" << add << ")"; break; } case 2: { int model_index = rand()%new_params.m_NonFiberModelList.size(); double t1 = new_params.m_NonFiberModelList[model_index]->GetT1(); std::normal_distribution normal_dist(0, t1*0.1*temperature); double add = 0; while (add == 0) add = normal_dist(randgen); if ( t1+add < new_params.m_NonFiberModelList[model_index]->GetT2() * 1.5 ) add = -add; t1 += add; new_params.m_NonFiberModelList[model_index]->SetT1(t1); MITK_INFO << "Proposal T1 (Non-Fiber " << model_index << "): " << t1 << " (" << add << ")"; break; } case 3: { int model_index = rand()%new_params.m_FiberModelList.size(); double t1 = new_params.m_FiberModelList[model_index]->GetT1(); std::normal_distribution normal_dist(0, t1*0.1*temperature); double add = 0; while (add == 0) add = normal_dist(randgen); if ( t1+add < new_params.m_FiberModelList[model_index]->GetT2() * 1.5 ) add = -add; t1 += add; new_params.m_FiberModelList[model_index]->SetT1(t1); MITK_INFO << "Proposal T1 (Fiber " << model_index << "): " << t1 << " (" << add << ")"; break; } } return new_params; } double UpdateDiffusivity(double d, double temperature) { std::random_device r; std::default_random_engine randgen(r()); std::normal_distribution normal_dist(0, d*0.1*temperature); double add = 0; while (add == 0) add = normal_dist(randgen); if (d+add > 0.0025) d -= add; else if ( d+add < 0.0 ) d -= add; else d += add; return d; } void ProposeDiffusivities(mitk::DiffusionSignalModel<>* signalModel, double temperature) { if (dynamic_cast*>(signalModel)) { mitk::StickModel<>* m = dynamic_cast*>(signalModel); double new_d = UpdateDiffusivity(m->GetDiffusivity(), temperature); MITK_INFO << "d: " << new_d << " (" << new_d-m->GetDiffusivity() << ")"; m->SetDiffusivity(new_d); } else if (dynamic_cast*>(signalModel)) { mitk::TensorModel<>* m = dynamic_cast*>(signalModel); double new_d1 = UpdateDiffusivity(m->GetDiffusivity1(), temperature); double new_d2 = UpdateDiffusivity(m->GetDiffusivity2(), temperature); while (new_d1GetDiffusivity2(), temperature); MITK_INFO << "d1: " << new_d1 << " (" << new_d1-m->GetDiffusivity1() << ")"; MITK_INFO << "d2: " << new_d2 << " (" << new_d2-m->GetDiffusivity2() << ")"; m->SetDiffusivity1(new_d1); m->SetDiffusivity2(new_d2); m->SetDiffusivity3(new_d2); } else if (dynamic_cast*>(signalModel)) { mitk::BallModel<>* m = dynamic_cast*>(signalModel); double new_d = UpdateDiffusivity(m->GetDiffusivity(), temperature); MITK_INFO << "d: " << new_d << " (" << new_d-m->GetDiffusivity() << ")"; m->SetDiffusivity(new_d); } else if (dynamic_cast*>(signalModel)) { mitk::AstroStickModel<>* m = dynamic_cast*>(signalModel); double new_d = UpdateDiffusivity(m->GetDiffusivity(), temperature); MITK_INFO << "d: " << new_d << " (" << new_d-m->GetDiffusivity() << ")"; m->SetDiffusivity(new_d); } } FiberfoxParameters MakeProposalDiff(FiberfoxParameters old_params, double temperature) { FiberfoxParameters new_params(old_params); std::random_device r; std::default_random_engine randgen(r()); std::uniform_int_distribution uint1(0, new_params.m_NonFiberModelList.size() + new_params.m_FiberModelList.size() - 1); unsigned int prop = uint1(randgen); if (prop::Pointer > frac, double temperature) { FiberfoxParameters new_params(old_params); MITK_INFO << "Proposal Volume"; std::random_device r; std::default_random_engine randgen(r()); { std::normal_distribution normal_dist(0, old_tdi_thr*0.1*temperature); new_tdi_thr = old_tdi_thr + normal_dist(randgen); while (new_tdi_thr<=0.01) new_tdi_thr = old_tdi_thr + normal_dist(randgen); } { std::normal_distribution normal_dist(0, old_sqrt*0.1*temperature); new_sqrt = old_sqrt + normal_dist(randgen); while (new_sqrt<=0.01) new_sqrt = old_sqrt + normal_dist(randgen); } itk::TdiToVolumeFractionFilter< double >::Pointer fraction_generator = itk::TdiToVolumeFractionFilter< double >::New(); fraction_generator->SetTdiThreshold(new_tdi_thr); fraction_generator->SetSqrt(new_sqrt); fraction_generator->SetInput(0, frac.at(0)); fraction_generator->SetInput(1, frac.at(1)); fraction_generator->SetInput(2, frac.at(2)); fraction_generator->SetInput(3, frac.at(3)); fraction_generator->SetInput(4, frac.at(4)); fraction_generator->Update(); new_params.m_FiberModelList[0]->SetVolumeFractionImage(fraction_generator->GetOutput(0)); new_params.m_FiberModelList[1]->SetVolumeFractionImage(fraction_generator->GetOutput(1)); new_params.m_NonFiberModelList[0]->SetVolumeFractionImage(fraction_generator->GetOutput(2)); new_params.m_NonFiberModelList[1]->SetVolumeFractionImage(fraction_generator->GetOutput(3)); MITK_INFO << "TDI Threshold: " << new_tdi_thr << " (" << new_tdi_thr-old_tdi_thr << ")"; MITK_INFO << "SQRT: " << new_sqrt << " (" << new_sqrt-old_sqrt << ")"; return new_params; } /*! * \brief Command line interface to optimize Fiberfox parameters. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("FiberfoxOptimization"); parser.setCategory("Optimize Fiberfox Parameters"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory Input:"); parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameter File:", "fiberfox parameter file (.ffp)", us::Any(), false); parser.addArgument("tracts", "t", mitkCommandLineParser::String, "Input Tractogram:", "Input tractogram.", us::Any(), false); parser.addArgument("out_folder", "o", mitkCommandLineParser::String, "Output Folder:", "", us::Any(), false); parser.addArgument("dmri", "d", mitkCommandLineParser::String, "Target image:", "Target dMRI to approximate.", us::Any(), false); parser.addArgument("mask", "", mitkCommandLineParser::InputFile, "Mask image:", "Error is only calculated inside the mask image", false); parser.endGroup(); parser.beginGroup("2. Parameters to optimize:"); parser.addArgument("no_diff", "", mitkCommandLineParser::Bool, "Don't optimize diffusivities:", "Don't optimize diffusivities"); parser.addArgument("no_relax", "", mitkCommandLineParser::Bool, "Don't optimize relaxation times:", "Don't optimize relaxation times"); parser.addArgument("no_scale", "", mitkCommandLineParser::Bool, "Don't optimize signal scale:", "Don't optimize global signal scale"); parser.endGroup(); parser.beginGroup("3. Error measure:"); parser.addArgument("fa_error", "", mitkCommandLineParser::Bool, "Optimize FA", "Optimize FA instead of raw signal. Requires FA image."); parser.addArgument("fa_image", "", mitkCommandLineParser::InputFile, "FA image:", "Weight error by FA histogram. Always necessary with option fa_error!"); parser.addArgument("md_image", "", mitkCommandLineParser::InputFile, "MD image:", "Optimize MD in conjunction with FA (recommended when optimizing FA)."); parser.endGroup(); parser.beginGroup("4. Optimization of volume fraction maps:"); parser.addArgument("tdi", "", mitkCommandLineParser::InputFile, "TDI:", "tract density image"); parser.addArgument("wm", "", mitkCommandLineParser::InputFile, "WM:", "white matter volume fraction image"); parser.addArgument("gm", "", mitkCommandLineParser::InputFile, "GM:", "gray matter volume fraction image"); parser.addArgument("dgm", "", mitkCommandLineParser::InputFile, "DGM:", "subcortical gray matter volume fraction image"); parser.addArgument("csf", "", mitkCommandLineParser::InputFile, "CSF:", "CSF volume fraction image"); parser.addArgument("tdi_threshold", "", mitkCommandLineParser::Float, "", "", 0.75); parser.addArgument("sqrt", "", mitkCommandLineParser::Float, "", "", 1.0); parser.endGroup(); parser.beginGroup("5. General parameters:"); parser.addArgument("iterations", "", mitkCommandLineParser::Int, "Iterations:", "Number of optimizations steps", 1000); parser.addArgument("start_temp", "", mitkCommandLineParser::Float, "Start temperature:", "Higher temperature means larger parameter change proposals", 1.0); parser.addArgument("end_temp", "", mitkCommandLineParser::Float, "End temperature:", "Higher temperature means larger parameter change proposals", 0.1); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string paramName = us::any_cast(parsedArgs["parameters"]); std::string out_folder = us::any_cast(parsedArgs["out_folder"]); std::string tract_file = us::any_cast(parsedArgs["tracts"]); MITK_INFO << "Loading target dMRI and parameters"; FiberfoxParameters parameters; parameters.LoadParameters(paramName); typedef itk::VectorImage< short, 3 > ItkDwiType; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images", "Fiberbundles"}, {}); - mitk::Image::Pointer dwi = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["dmri"]), &functor)[0].GetPointer()); + auto dwi = mitk::IOUtil::Load(us::any_cast(parsedArgs["dmri"]), &functor); ItkDwiType::Pointer reference = mitk::DiffusionPropertyHelper::GetItkVectorImage(dwi); parameters.m_SignalGen.m_ImageRegion = reference->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = reference->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = reference->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = reference->GetDirection(); parameters.SetBvalue(static_cast(dwi->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue()); parameters.SetGradienDirections(static_cast( dwi->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer()); - mitk::FiberBundle::Pointer tracts = dynamic_cast(mitk::IOUtil::Load(tract_file, &functor)[0].GetPointer()); + auto tracts = mitk::IOUtil::Load(tract_file, &functor); int iterations=1000; if (parsedArgs.count("iterations")) iterations = us::any_cast(parsedArgs["iterations"]); float start_temp=1.0; if (parsedArgs.count("start_temp")) start_temp = us::any_cast(parsedArgs["start_temp"]); float end_temp=0.1; if (parsedArgs.count("end_temp")) end_temp = us::any_cast(parsedArgs["end_temp"]); float tdi_threshold=0.75; if (parsedArgs.count("tdi_threshold")) tdi_threshold = us::any_cast(parsedArgs["tdi_threshold"]); float sqrt=1.0; if (parsedArgs.count("sqrt")) sqrt = us::any_cast(parsedArgs["sqrt"]); bool fa_error=false; if (parsedArgs.count("fa_error")) fa_error = true; std::string fa_file = ""; if (parsedArgs.count("fa_image")) fa_file = us::any_cast(parsedArgs["fa_image"]); std::string md_file = ""; if (parsedArgs.count("md_image")) md_file = us::any_cast(parsedArgs["md_image"]); std::vector< int > possible_proposals; if (!parsedArgs.count("no_diff")) { MITK_INFO << "Optimizing diffusivities"; possible_proposals.push_back(0); } if (!parsedArgs.count("no_relax")) { MITK_INFO << "Optimizing relaxation constants"; possible_proposals.push_back(1); } if (!parsedArgs.count("no_scale")) { MITK_INFO << "Optimizing global signal scale"; possible_proposals.push_back(2); } if (possible_proposals.empty()) { MITK_INFO << "Incompatible options. Nothing to optimize."; return EXIT_FAILURE; } itk::ImageFileReader< itk::Image< unsigned char, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< unsigned char, 3 > >::New(); reader->SetFileName( us::any_cast(parsedArgs["mask"]) ); reader->Update(); itk::Image< unsigned char,3 >::Pointer mask = reader->GetOutput(); std::vector< itk::Image< double, 3 >::Pointer > fracs; if ( parsedArgs.count("tdi")>0 && parsedArgs.count("wm")>0 && parsedArgs.count("gm")>0 && parsedArgs.count("dgm")>0 && parsedArgs.count("csf")>0 ) { MITK_INFO << "Optimizing volume fractions"; { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( us::any_cast(parsedArgs["tdi"]) ); reader->Update(); fracs.push_back(reader->GetOutput()); } { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( us::any_cast(parsedArgs["wm"]) ); reader->Update(); fracs.push_back(reader->GetOutput()); } { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( us::any_cast(parsedArgs["gm"]) ); reader->Update(); fracs.push_back(reader->GetOutput()); } { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( us::any_cast(parsedArgs["dgm"]) ); reader->Update(); fracs.push_back(reader->GetOutput()); } { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( us::any_cast(parsedArgs["csf"]) ); reader->Update(); fracs.push_back(reader->GetOutput()); } MITK_INFO << "Initial sqrt: " << sqrt; MITK_INFO << "Initial TDI threshold: " << tdi_threshold; possible_proposals.push_back(3); } std::vector< double > histogram_modifiers; itk::Image< double,3 >::Pointer fa_image = nullptr; if (fa_file.compare("")!=0) { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( fa_file ); reader->Update(); fa_image = reader->GetOutput(); int binsPerDimension = 20; using ImageToHistogramFilterType = itk::Statistics::MaskedImageToHistogramFilter< itk::Image< double,3 >, itk::Image< unsigned char,3 > >; ImageToHistogramFilterType::HistogramType::MeasurementVectorType lowerBound(binsPerDimension); lowerBound.Fill(0.0); ImageToHistogramFilterType::HistogramType::MeasurementVectorType upperBound(binsPerDimension); upperBound.Fill(1.0); ImageToHistogramFilterType::HistogramType::SizeType size(1); size.Fill(binsPerDimension); ImageToHistogramFilterType::Pointer imageToHistogramFilter = ImageToHistogramFilterType::New(); imageToHistogramFilter->SetInput( fa_image ); imageToHistogramFilter->SetHistogramBinMinimum( lowerBound ); imageToHistogramFilter->SetHistogramBinMaximum( upperBound ); imageToHistogramFilter->SetHistogramSize( size ); imageToHistogramFilter->SetMaskImage(mask); imageToHistogramFilter->SetMaskValue(1); imageToHistogramFilter->Update(); ImageToHistogramFilterType::HistogramType* histogram = imageToHistogramFilter->GetOutput(); unsigned int max = 0; for(unsigned int i = 0; i < histogram->GetSize()[0]; ++i) { if (histogram->GetFrequency(i)>max) max = histogram->GetFrequency(i); } MITK_INFO << "FA histogram modifiers:"; for(unsigned int i = 0; i < histogram->GetSize()[0]; ++i) { histogram_modifiers.push_back((double)max/histogram->GetFrequency(i)); MITK_INFO << std::pow(histogram_modifiers.back(), 4); } if (fa_error) MITK_INFO << "Using FA error measure."; } itk::Image< double,3 >::Pointer md_image = nullptr; if (md_file.compare("")!=0) { itk::ImageFileReader< itk::Image< double, 3 > >::Pointer reader = itk::ImageFileReader< itk::Image< double, 3 > >::New(); reader->SetFileName( md_file ); reader->Update(); md_image = reader->GetOutput(); if (fa_error) MITK_INFO << "Using MD error measure."; } if (fa_error && fa_image.IsNull()) { MITK_INFO << "Incompatible options. Need FA image to calculate FA error."; return EXIT_FAILURE; } itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); tractsToDwiFilter->SetFiberBundle(tracts); tractsToDwiFilter->SetParameters(parameters); tractsToDwiFilter->Update(); ItkDwiType::Pointer sim = tractsToDwiFilter->GetOutput(); { mitk::Image::Pointer image = mitk::GrabItkImageMemory( tractsToDwiFilter->GetOutput() ); image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( parameters.m_SignalGen.GetGradientDirections() ) ); image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( parameters.m_SignalGen.GetBvalue() ) ); mitk::DiffusionPropertyHelper propertyHelper( image ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(image, out_folder + "/initial.dwi"); } double old_tdi_thr = tdi_threshold; double old_sqrt = sqrt; double new_tdi_thr; double new_sqrt; MITK_INFO << "\n\n"; MITK_INFO << "Iterations: " << iterations; MITK_INFO << "start_temp: " << start_temp; MITK_INFO << "end_temp: " << end_temp; double alpha = log(end_temp/start_temp); int accepted = 0; double last_error = 9999999; if (fa_error) { MITK_INFO << "Calculating FA error"; last_error = CalcErrorFA(histogram_modifiers, dwi, sim, mask, fa_image, md_image, true); } else { MITK_INFO << "Calculating raw-image error"; last_error = CalcErrorSignal(histogram_modifiers, reference, sim, mask, fa_image); } MITK_INFO << "Initial E = " << last_error; MITK_INFO << "\n\n**************************************************************************************"; std::random_device r; std::default_random_engine randgen(r()); std::uniform_int_distribution uint1(0, possible_proposals.size()-1); for (int i=0; i::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); tractsToDwiFilter->SetFiberBundle(dynamic_cast(tracts.GetPointer())); tractsToDwiFilter->SetParameters(proposal); tractsToDwiFilter->Update(); ItkDwiType::Pointer sim = tractsToDwiFilter->GetOutput(); std::cout.rdbuf (old); // <-- restore double new_error = 9999999; if (fa_error && fa_image.IsNotNull()) new_error = CalcErrorFA(histogram_modifiers, dwi, sim, mask, fa_image, md_image, true); else new_error = CalcErrorSignal(histogram_modifiers, reference, sim, mask, fa_image); MITK_INFO << "E = " << new_error << "(" << new_error-last_error << ")"; if (last_errorGetOutput() ); image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( parameters.m_SignalGen.GetGradientDirections() ) ); image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( parameters.m_SignalGen.GetBvalue() ) ); mitk::DiffusionPropertyHelper propertyHelper( image ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(image, out_folder + "/optimized.dwi"); proposal.SaveParameters(out_folder + "/optimized.ffp"); std::cout.rdbuf (old); // <-- restore accepted++; old_tdi_thr = new_tdi_thr; old_sqrt = new_sqrt; MITK_INFO << "Accepted (acc. rate " << (float)accepted/(i+1) << ")"; parameters = FiberfoxParameters(proposal); last_error = new_error; } MITK_INFO << "\n\n\n"; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FlipPeaks.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FlipPeaks.cpp index 693fe775f9..1fd5d2dd0d 100644 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FlipPeaks.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/FlipPeaks.cpp @@ -1,104 +1,104 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Flip Peaks"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Flips the peaks of the input peak image along the given dimensions."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i", mitkCommandLineParser::InputFile, "Input", "input image", us::Any(), false); parser.addArgument("", "o", mitkCommandLineParser::OutputFile, "Output", "output image", us::Any(), false); parser.addArgument("", "x", mitkCommandLineParser::Bool, "Flip x", "flip along x-axis"); parser.addArgument("", "y", mitkCommandLineParser::Bool, "Flip y", "flip along y-axis"); parser.addArgument("", "z", mitkCommandLineParser::Bool, "Flip z", "flip along z-axis"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string imageName = us::any_cast(parsedArgs["i"]); std::string outImage = us::any_cast(parsedArgs["o"]); bool x = false; if (parsedArgs.count("x")) x = us::any_cast(parsedArgs["x"]); bool y = false; if (parsedArgs.count("y")) y = us::any_cast(parsedArgs["y"]); bool z = false; if (parsedArgs.count("z")) z = us::any_cast(parsedArgs["z"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image"}, {}); - mitk::PeakImage::Pointer image = dynamic_cast(mitk::IOUtil::Load(imageName, &functor)[0].GetPointer()); + mitk::PeakImage::Pointer image = mitk::IOUtil::Load(imageName, &functor); typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); mitk::PeakImage::ItkPeakImageType::Pointer itkImg = caster->GetOutput(); itk::FlipPeaksFilter< float >::Pointer flipper = itk::FlipPeaksFilter< float >::New(); flipper->SetInput(itkImg); flipper->SetFlipX(x); flipper->SetFlipY(y); flipper->SetFlipZ(z); flipper->Update(); mitk::Image::Pointer resultImage = dynamic_cast(mitk::PeakImage::New().GetPointer()); mitk::CastToMitkImage(flipper->GetOutput(), resultImage); resultImage->SetVolume(flipper->GetOutput()->GetBufferPointer()); mitk::IOUtil::Save(resultImage, outImage); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp index c0505da2e7..d3e4385371 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PeakExtraction.cpp @@ -1,357 +1,357 @@ /*=================================================================== 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 #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include template int StartPeakExtraction(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false); parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image"); parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true); parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true); parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", std::string("MITK"), true); parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention"); parser.addArgument("clusterThres", "c", mitkCommandLineParser::Float, "Clustering threshold", "directions closer together than the specified angular threshold will be clustered (in rad)", 0.9); parser.addArgument("flipX", "fx", mitkCommandLineParser::Bool, "Flip X", "Flip peaks in x direction"); parser.addArgument("flipY", "fy", mitkCommandLineParser::Bool, "Flip Y", "Flip peaks in y direction"); parser.addArgument("flipZ", "fz", mitkCommandLineParser::Bool, "Flip Z", "Flip peaks in z direction"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Peak Extraction"); parser.setDescription(""); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast(parsedArgs["image"]); std::string outRoot = us::any_cast(parsedArgs["outroot"]); // optional arguments std::string maskImageName(""); if (parsedArgs.count("mask")) maskImageName = us::any_cast(parsedArgs["mask"]); int normalization = 1; if (parsedArgs.count("normalization")) normalization = us::any_cast(parsedArgs["normalization"]); int numPeaks = 2; if (parsedArgs.count("numpeaks")) numPeaks = us::any_cast(parsedArgs["numpeaks"]); float peakThres = 0.4; if (parsedArgs.count("peakthres")) peakThres = us::any_cast(parsedArgs["peakthres"]); float absPeakThres = 0.06; if (parsedArgs.count("abspeakthres")) absPeakThres = us::any_cast(parsedArgs["abspeakthres"]); float clusterThres = 0.9; if (parsedArgs.count("clusterThres")) clusterThres = us::any_cast(parsedArgs["clusterThres"]); bool noFlip = false; if (parsedArgs.count("noFlip")) noFlip = us::any_cast(parsedArgs["noFlip"]); bool flipX = false; if (parsedArgs.count("flipX")) flipX = us::any_cast(parsedArgs["flipX"]); bool flipY = false; if (parsedArgs.count("flipY")) flipY = us::any_cast(parsedArgs["flipY"]); bool flipZ = false; if (parsedArgs.count("flipZ")) flipZ = us::any_cast(parsedArgs["flipZ"]); std::cout << "image: " << imageName; std::cout << "outroot: " << outRoot; if (!maskImageName.empty()) std::cout << "mask: " << maskImageName; else std::cout << "no mask image selected"; std::cout << "numpeaks: " << numPeaks; std::cout << "peakthres: " << peakThres; std::cout << "abspeakthres: " << absPeakThres; std::cout << "shOrder: " << shOrder; try { - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(imageName)[0].GetPointer()); - mitk::Image::Pointer mask = dynamic_cast(mitk::IOUtil::Load(maskImageName)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(imageName); + mitk::Image::Pointer mask = mitk::IOUtil::Load(maskImageName); typedef itk::Image ItkUcharImgType; typedef itk::FiniteDiffOdfMaximaExtractionFilter< float, shOrder, 20242 > MaximaExtractionFilterType; typename MaximaExtractionFilterType::Pointer peak_extraction_filter = MaximaExtractionFilterType::New(); int toolkitConvention = 0; if (parsedArgs.count("shConvention")) { std::string convention = us::any_cast(parsedArgs["shConvention"]).c_str(); if ( boost::algorithm::equals(convention, "FSL") ) { toolkitConvention = 1; std::cout << "Using FSL SH-basis"; } else if ( boost::algorithm::equals(convention, "MRtrix") ) { toolkitConvention = 2; std::cout << "Using MRtrix SH-basis"; } else std::cout << "Using MITK SH-basis"; } else std::cout << "Using MITK SH-basis"; ItkUcharImgType::Pointer itkMaskImage = nullptr; if (mask.IsNotNull()) { try{ itkMaskImage = ItkUcharImgType::New(); mitk::CastToItkImage(mask, itkMaskImage); peak_extraction_filter->SetMaskImage(itkMaskImage); } catch(...) { } } if (toolkitConvention>0) { std::cout << "Converting coefficient image to MITK format"; typedef itk::ShCoefficientImageImporter< float, shOrder > ConverterType; typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput(); typename ConverterType::Pointer converter = ConverterType::New(); if (noFlip) { converter->SetInputImage(itkImage); } else { std::cout << "Flipping image"; itk::FixedArray flipAxes; flipAxes[0] = true; flipAxes[1] = true; flipAxes[2] = false; flipAxes[3] = false; itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New(); flipper->SetInput(itkImage); flipper->SetFlipAxes(flipAxes); flipper->Update(); itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput(); itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1; flipped->SetDirection(m); itk::Point< float, 4 > o = itkImage->GetOrigin(); o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1); o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1); flipped->SetOrigin(o); converter->SetInputImage(flipped); } std::cout << "Starting conversion"; switch (toolkitConvention) { case 1: peak_extraction_filter->SetToolkit(MaximaExtractionFilterType::FSL); break; case 2: peak_extraction_filter->SetToolkit(MaximaExtractionFilterType::MRTRIX); break; default: peak_extraction_filter->SetToolkit(MaximaExtractionFilterType::FSL); break; } converter->GenerateData(); peak_extraction_filter->SetInput(converter->GetCoefficientImage()); } else { try{ typedef mitk::ImageToItk< typename MaximaExtractionFilterType::CoefficientImageType > CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput(image); caster->Update(); peak_extraction_filter->SetInput(caster->GetOutput()); } catch(...) { std::cout << "wrong image type"; return EXIT_FAILURE; } } peak_extraction_filter->SetMaxNumPeaks(numPeaks); peak_extraction_filter->SetPeakThreshold(peakThres); peak_extraction_filter->SetAbsolutePeakThreshold(absPeakThres); peak_extraction_filter->SetAngularThreshold(1); peak_extraction_filter->SetClusteringThreshold(clusterThres); peak_extraction_filter->SetFlipX(flipX); peak_extraction_filter->SetFlipY(flipY); peak_extraction_filter->SetFlipZ(flipZ); switch (normalization) { case 0: peak_extraction_filter->SetNormalizationMethod(MaximaExtractionFilterType::NO_NORM); break; case 1: peak_extraction_filter->SetNormalizationMethod(MaximaExtractionFilterType::MAX_VEC_NORM); break; case 2: peak_extraction_filter->SetNormalizationMethod(MaximaExtractionFilterType::SINGLE_VEC_NORM); break; } std::cout << "Starting extraction"; peak_extraction_filter->Update(); // write direction image { typename MaximaExtractionFilterType::PeakImageType::Pointer itkImg = peak_extraction_filter->GetPeakImage(); std::string outfilename = outRoot; outfilename.append("_PEAKS.nrrd"); typedef itk::ImageFileWriter< typename MaximaExtractionFilterType::PeakImageType > WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outfilename); writer->SetInput(itkImg); writer->Update(); } // write num directions image { ItkUcharImgType::Pointer numDirImage = peak_extraction_filter->GetNumDirectionsImage(); if (itkMaskImage.IsNotNull()) { numDirImage->SetDirection(itkMaskImage->GetDirection()); numDirImage->SetOrigin(itkMaskImage->GetOrigin()); } std::string outfilename = outRoot.c_str(); outfilename.append("_NUM_PEAKS.nrrd"); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outfilename); writer->SetInput(numDirImage); writer->Update(); } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } /*! \brief Extract maxima in the input spherical harmonics image. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false); parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order"); parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image"); parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true); parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true); parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true); parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true); parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", std::string("MITK"), true); parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention"); parser.setCategory("Preprocessing Tools"); parser.setTitle("Peak Extraction"); parser.setDescription("Extract maxima in the input spherical harmonics image."); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; int shOrder = -1; if (parsedArgs.count("shOrder")) shOrder = us::any_cast(parsedArgs["shOrder"]); switch (shOrder) { case 4: return StartPeakExtraction<4>(argc, argv); case 6: return StartPeakExtraction<6>(argc, argv); case 8: return StartPeakExtraction<8>(argc, argv); case 10: return StartPeakExtraction<10>(argc, argv); case 12: return StartPeakExtraction<12>(argc, argv); } return EXIT_FAILURE; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PythonTest.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PythonTest.cpp index a2aa7509b4..8c570f93ba 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PythonTest.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Misc/PythonTest.cpp @@ -1,80 +1,80 @@ /*=================================================================== 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 #include #include #include #include #include #include #include typedef itk::Image< float, 3 > ItkImageType; /*! \brief */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false); parser.addArgument("script", "s", mitkCommandLineParser::InputFile, "", "", us::Any(), false); parser.addArgument("params", "p", mitkCommandLineParser::InputFile, "", "", us::Any(), false); parser.addArgument("out_file", "o", mitkCommandLineParser::OutputDirectory, "Output image", "output image", us::Any(), false); parser.setCategory("TEST"); parser.setTitle("TEST"); parser.setDescription("TEST"); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string image_file = us::any_cast(parsedArgs["image"]); std::string script = us::any_cast(parsedArgs["script"]); std::string params = us::any_cast(parsedArgs["params"]); std::string out_file = us::any_cast(parsedArgs["out_file"]); - mitk::Image::Pointer mitk_image = mitk::IOUtil::LoadImage(image_file); + mitk::Image::Pointer mitk_image = mitk::IOUtil::Load(image_file); us::ModuleContext* context = us::GetModuleContext(); us::ServiceReference m_PythonServiceRef = context->GetServiceReference(); mitk::IPythonService* m_PythonService = dynamic_cast ( context->GetService(m_PythonServiceRef) ); mitk::IPythonService::ForceLoadModule(); m_PythonService->Execute("import SimpleITK as sitk"); m_PythonService->Execute("import SimpleITK._SimpleITK as _SimpleITK"); m_PythonService->Execute("import numpy"); m_PythonService->CopyToPythonAsSimpleItkImage( mitk_image, "myvar"); m_PythonService->Execute("myparams=\""+params+"\""); m_PythonService->ExecuteScript(script); mitk::Image::Pointer out_seg = m_PythonService->CopySimpleItkImageFromPython("out_image"); mitk::IOUtil::Save(out_seg, out_file); return EXIT_FAILURE; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GlobalTractography.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GlobalTractography.cpp index e65cea49b6..e4e4223abb 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GlobalTractography.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/GlobalTractography.cpp @@ -1,170 +1,170 @@ /*=================================================================== 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 #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include template typename itk::ShCoefficientImageImporter< float, shOrder >::OdfImageType::Pointer TemplatedConvertShCoeffs(mitk::Image::Pointer mitkImg) { typedef itk::ShToOdfImageFilter< float, shOrder > ShConverterType; typename ShConverterType::InputImageType::Pointer itkvol = ShConverterType::InputImageType::New(); mitk::CastToItkImage(mitkImg, itkvol); typename ShConverterType::Pointer converter = ShConverterType::New(); converter->SetInput(itkvol); converter->Update(); return converter->GetOutput(); } /*! \brief Perform global fiber tractography (Gibbs tractography) */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Gibbs Tracking"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Perform global fiber tractography (Gibbs tractography)"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (tensor, ODF or SH-coefficient image)", us::Any(), false); parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameters:", "parameter file (.gtp)", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "binary mask image"); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string paramFileName = us::any_cast(parsedArgs["parameters"]); std::string outFileName = us::any_cast(parsedArgs["outFile"]); try { // instantiate gibbs tracker typedef itk::Vector OdfVectorType; typedef itk::Image ItkOdfImageType; typedef itk::GibbsTrackingFilter GibbsTrackingFilterType; GibbsTrackingFilterType::Pointer gibbsTracker = GibbsTrackingFilterType::New(); // load input image mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"SH Image"}, {}); - mitk::Image::Pointer mitkImage = dynamic_cast(mitk::IOUtil::Load(inFileName, &functor)[0].GetPointer()); + mitk::Image::Pointer mitkImage = mitk::IOUtil::Load(inFileName, &functor); // try to cast to Odf image if( dynamic_cast(mitkImage.GetPointer()) ) { mitk::OdfImage::Pointer mitkOdfImage = dynamic_cast(mitkImage.GetPointer()); ItkOdfImageType::Pointer itk_odf = ItkOdfImageType::New(); mitk::CastToItkImage(mitkOdfImage, itk_odf); gibbsTracker->SetOdfImage(itk_odf.GetPointer()); } else if( dynamic_cast(mitkImage.GetPointer()) ) { typedef itk::Image< itk::DiffusionTensor3D, 3 > ItkTensorImage; mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast(mitkImage.GetPointer()); ItkTensorImage::Pointer itk_dti = ItkTensorImage::New(); mitk::CastToItkImage(mitkTensorImage, itk_dti); gibbsTracker->SetTensorImage(itk_dti); } else if ( dynamic_cast(mitkImage.GetPointer()) ) { mitk::ShImage::Pointer shImage = dynamic_cast(mitkImage.GetPointer()); switch (shImage->ShOrder()) { case 2: gibbsTracker->SetOdfImage(TemplatedConvertShCoeffs<2>(mitkImage)); break; case 4: gibbsTracker->SetOdfImage(TemplatedConvertShCoeffs<4>(mitkImage)); break; case 6: gibbsTracker->SetOdfImage(TemplatedConvertShCoeffs<6>(mitkImage)); break; case 8: gibbsTracker->SetOdfImage(TemplatedConvertShCoeffs<8>(mitkImage)); break; case 10: gibbsTracker->SetOdfImage(TemplatedConvertShCoeffs<10>(mitkImage)); break; case 12: gibbsTracker->SetOdfImage(TemplatedConvertShCoeffs<12>(mitkImage)); break; default: std::cout << "SH-order " << shImage->ShOrder() << " not supported"; } } else return EXIT_FAILURE; // global tracking if (parsedArgs.count("mask")) { typedef itk::Image MaskImgType; - mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["mask"]))[0].GetPointer()); + mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::Load(us::any_cast(parsedArgs["mask"])); MaskImgType::Pointer itk_mask = MaskImgType::New(); mitk::CastToItkImage(mitkMaskImage, itk_mask); gibbsTracker->SetMaskImage(itk_mask); } gibbsTracker->SetDuplicateImage(false); gibbsTracker->SetLoadParameterFile( paramFileName ); // gibbsTracker->SetLutPath( "" ); gibbsTracker->Update(); mitk::FiberBundle::Pointer mitkFiberBundle = mitk::FiberBundle::New(gibbsTracker->GetFiberBundle()); mitkFiberBundle->SetReferenceGeometry(mitkImage->GetGeometry()); mitk::IOUtil::Save(mitkFiberBundle, outFileName ); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp index efac33de14..f989b0c168 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/RfTraining.cpp @@ -1,239 +1,239 @@ /*=================================================================== 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 #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Train random forest classifier for machine learning based streamline tractography */ int main(int argc, char* argv[]) { MITK_INFO << "RfTraining"; mitkCommandLineParser parser; parser.setTitle("Trains Random Forests for Machine Learning Based Tractography"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Train random forest classifier for machine learning based streamline tractography"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); parser.addArgument("images", "i", mitkCommandLineParser::StringList, "DWIs:", "input diffusion-weighted images", us::Any(), false); parser.addArgument("tractograms", "t", mitkCommandLineParser::StringList, "Tractograms:", "input training tractograms (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("forest", "f", mitkCommandLineParser::OutputFile, "Forest:", "output random forest (HDF5)", us::Any(), false); parser.endGroup(); parser.beginGroup("2. Additional input images:"); parser.addArgument("masks", "", mitkCommandLineParser::StringList, "Masks:", "restrict training using a binary mask image", us::Any()); parser.addArgument("wm_masks", "", mitkCommandLineParser::StringList, "WM-Masks:", "if no binary white matter mask is specified, the envelope of the input tractogram is used", us::Any()); parser.addArgument("volume_modification_images", "", mitkCommandLineParser::StringList, "Volume modification images:", "specify a list of float images that modify the fiber density", us::Any()); parser.addArgument("additional_feature_images", "", mitkCommandLineParser::StringList, "Additional feature images:", "specify a list of float images that hold additional features (float)", us::Any()); parser.endGroup(); parser.beginGroup("3. Forest parameters:"); parser.addArgument("num_trees", "", mitkCommandLineParser::Int, "Number of trees:", "number of trees", 30); parser.addArgument("max_tree_depth", "", mitkCommandLineParser::Int, "Max. tree depth:", "maximum tree depth", 25); parser.addArgument("sample_fraction", "", mitkCommandLineParser::Float, "Sample fraction:", "fraction of samples used per tree", 0.7); parser.endGroup(); parser.beginGroup("4. Feature parameters:"); parser.addArgument("use_sh_features", "", mitkCommandLineParser::Bool, "Use SH features:", "use SH features", false); parser.addArgument("sampling_distance", "", mitkCommandLineParser::Float, "Sampling distance:", "resampling parameter for the input tractogram in mm (determines number of white-matter samples)", us::Any()); parser.addArgument("max_wm_samples", "", mitkCommandLineParser::Int, "Max. num. WM samples:", "upper limit for the number of WM samples"); parser.addArgument("num_gm_samples", "", mitkCommandLineParser::Int, "Number of gray matter samples per voxel:", "Number of gray matter samples per voxel", us::Any()); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; bool shfeatures = false; if (parsedArgs.count("use_sh_features")) shfeatures = us::any_cast(parsedArgs["use_sh_features"]); mitkCommandLineParser::StringContainerType imageFiles = us::any_cast(parsedArgs["images"]); mitkCommandLineParser::StringContainerType wmMaskFiles; if (parsedArgs.count("wm_masks")) wmMaskFiles = us::any_cast(parsedArgs["wm_masks"]); mitkCommandLineParser::StringContainerType volModFiles; if (parsedArgs.count("volume_modification_images")) volModFiles = us::any_cast(parsedArgs["volume_modification_images"]); mitkCommandLineParser::StringContainerType addFeatFiles; if (parsedArgs.count("additional_feature_images")) addFeatFiles = us::any_cast(parsedArgs["additional_feature_images"]); mitkCommandLineParser::StringContainerType maskFiles; if (parsedArgs.count("masks")) maskFiles = us::any_cast(parsedArgs["masks"]); std::string forestFile = us::any_cast(parsedArgs["forest"]); mitkCommandLineParser::StringContainerType tractogramFiles; if (parsedArgs.count("tractograms")) tractogramFiles = us::any_cast(parsedArgs["tractograms"]); int num_trees = 30; if (parsedArgs.count("num_trees")) num_trees = us::any_cast(parsedArgs["num_trees"]); int gm_samples = -1; if (parsedArgs.count("num_gm_samples")) gm_samples = us::any_cast(parsedArgs["num_gm_samples"]); float sampling_distance = -1; if (parsedArgs.count("sampling_distance")) sampling_distance = us::any_cast(parsedArgs["sampling_distance"]); int max_tree_depth = 25; if (parsedArgs.count("max_tree_depth")) max_tree_depth = us::any_cast(parsedArgs["max_tree_depth"]); double sample_fraction = 0.7; if (parsedArgs.count("sample_fraction")) sample_fraction = us::any_cast(parsedArgs["sample_fraction"]); int maxWmSamples = -1; if (parsedArgs.count("max_wm_samples")) maxWmSamples = us::any_cast(parsedArgs["max_wm_samples"]); MITK_INFO << "loading diffusion-weighted images"; std::vector< mitk::Image::Pointer > rawData; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); for (auto imgFile : imageFiles) { - mitk::Image::Pointer dwi = dynamic_cast(mitk::IOUtil::LoadImage(imgFile, &functor).GetPointer()); + auto dwi = mitk::IOUtil::Load(imgFile, &functor)); rawData.push_back(dwi); } typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUcharImgType; MITK_INFO << "loading mask images"; std::vector< ItkUcharImgType::Pointer > maskImageVector; for (auto maskFile : maskFiles) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(maskFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(maskFile); ItkUcharImgType::Pointer mask = ItkUcharImgType::New(); mitk::CastToItkImage(img, mask); maskImageVector.push_back(mask); } MITK_INFO << "loading white matter mask images"; std::vector< ItkUcharImgType::Pointer > wmMaskImageVector; for (auto wmFile : wmMaskFiles) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(wmFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(wmFile); ItkUcharImgType::Pointer wmmask = ItkUcharImgType::New(); mitk::CastToItkImage(img, wmmask); wmMaskImageVector.push_back(wmmask); } MITK_INFO << "loading tractograms"; std::vector< mitk::FiberBundle::Pointer > tractograms; for (auto tractFile : tractogramFiles) { - mitk::FiberBundle::Pointer fib = dynamic_cast(mitk::IOUtil::Load(tractFile).at(0).GetPointer()); + mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(tractFile); tractograms.push_back(fib); } MITK_INFO << "loading white volume modification images"; std::vector< ItkFloatImgType::Pointer > volumeModImages; for (auto file : volModFiles) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(file)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(file); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); volumeModImages.push_back(itkimg); } MITK_INFO << "loading additional feature images"; std::vector< std::vector< ItkFloatImgType::Pointer > > addFeatImages; for (std::size_t i=0; i()); int c = 0; for (auto file : addFeatFiles) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(file)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(file); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); addFeatImages.at(c%addFeatImages.size()).push_back(itkimg); c++; } mitk::TractographyForest::Pointer forest = nullptr; if (shfeatures) { mitk::TrackingHandlerRandomForest<6,28> forestHandler; forestHandler.SetDwis(rawData); forestHandler.SetMaskImages(maskImageVector); forestHandler.SetWhiteMatterImages(wmMaskImageVector); forestHandler.SetFiberVolumeModImages(volumeModImages); forestHandler.SetAdditionalFeatureImages(addFeatImages); forestHandler.SetTractograms(tractograms); forestHandler.SetNumTrees(num_trees); forestHandler.SetMaxTreeDepth(max_tree_depth); forestHandler.SetGrayMatterSamplesPerVoxel(gm_samples); forestHandler.SetSampleFraction(sample_fraction); forestHandler.SetFiberSamplingStep(sampling_distance); forestHandler.SetMaxNumWmSamples(maxWmSamples); forestHandler.StartTraining(); forest = forestHandler.GetForest(); } else { mitk::TrackingHandlerRandomForest<6,100> forestHandler; forestHandler.SetDwis(rawData); forestHandler.SetMaskImages(maskImageVector); forestHandler.SetWhiteMatterImages(wmMaskImageVector); forestHandler.SetFiberVolumeModImages(volumeModImages); forestHandler.SetAdditionalFeatureImages(addFeatImages); forestHandler.SetTractograms(tractograms); forestHandler.SetNumTrees(num_trees); forestHandler.SetMaxTreeDepth(max_tree_depth); forestHandler.SetGrayMatterSamplesPerVoxel(gm_samples); forestHandler.SetSampleFraction(sample_fraction); forestHandler.SetFiberSamplingStep(sampling_distance); forestHandler.SetMaxNumWmSamples(maxWmSamples); forestHandler.StartTraining(); forest = forestHandler.GetForest(); } mitk::IOUtil::Save(forest, forestFile); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/StreamlineTractography.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/StreamlineTractography.cpp index 425e5e764b..4f603408c6 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/StreamlineTractography.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/Tractography/StreamlineTractography.cpp @@ -1,574 +1,574 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include const int numOdfSamples = 200; typedef itk::Image< itk::Vector< float, numOdfSamples > , 3 > SampledShImageType; /*! \brief */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Streamline Tractography"); parser.setCategory("Fiber Tracking and Processing Methods"); parser.setDescription("Perform streamline tractography"); parser.setContributor("MIC"); // parameters fo all methods parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); parser.addArgument("input", "i", mitkCommandLineParser::StringList, "Input:", "input image (multiple possible for 'DetTensor' algorithm)", us::Any(), false); parser.addArgument("algorithm", "a", mitkCommandLineParser::String, "Algorithm:", "which algorithm to use (Peaks, DetTensor, ProbTensor, DetODF, ProbODF, DetRF, ProbRF)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output fiberbundle/probability map", us::Any(), false); parser.endGroup(); parser.beginGroup("2. Seeding:"); parser.addArgument("seeds", "", mitkCommandLineParser::Int, "Seeds per voxel:", "number of seed points per voxel", 1); parser.addArgument("seed_image", "", mitkCommandLineParser::String, "Seed image:", "mask image defining seed voxels", us::Any()); parser.addArgument("trials_per_seed", "", mitkCommandLineParser::Int, "Max. trials per seed:", "try each seed N times until a valid streamline is obtained (only for probabilistic tractography)", 10); parser.addArgument("max_tracts", "", mitkCommandLineParser::Int, "Max. number of tracts:", "tractography is stopped if the reconstructed number of tracts is exceeded", -1); parser.endGroup(); parser.beginGroup("3. Tractography constraints:"); parser.addArgument("tracking_mask", "", mitkCommandLineParser::String, "Mask image:", "streamlines leaving the mask will stop immediately", us::Any()); parser.addArgument("stop_image", "", mitkCommandLineParser::String, "Stop ROI image:", "streamlines entering the mask will stop immediately", us::Any()); parser.addArgument("exclusion_image", "", mitkCommandLineParser::String, "Exclusion ROI image:", "streamlines entering the mask will be discarded", us::Any()); parser.addArgument("ep_constraint", "", mitkCommandLineParser::String, "Endpoint constraint:", "determines which fibers are accepted based on their endpoint location - options are NONE, EPS_IN_TARGET, EPS_IN_TARGET_LABELDIFF, EPS_IN_SEED_AND_TARGET, MIN_ONE_EP_IN_TARGET, ONE_EP_IN_TARGET and NO_EP_IN_TARGET", us::Any()); parser.addArgument("target_image", "", mitkCommandLineParser::String, "Target ROI image:", "effact depends on the chosen endpoint constraint (option ep_constraint)", us::Any()); parser.endGroup(); parser.beginGroup("4. Streamline integration parameters:"); parser.addArgument("sharpen_odfs", "", mitkCommandLineParser::Bool, "SHarpen ODFs:", "if you are using dODF images as input, it is advisable to sharpen the ODFs (min-max normalize and raise to the power of 4). this is not necessary for CSD fODFs, since they are narurally much sharper."); parser.addArgument("cutoff", "", mitkCommandLineParser::Float, "Cutoff:", "set the FA, GFA or Peak amplitude cutoff for terminating tracks", 0.1); parser.addArgument("odf_cutoff", "", mitkCommandLineParser::Float, "ODF Cutoff:", "threshold on the ODF magnitude. this is useful in case of CSD fODF tractography.", 0.0); parser.addArgument("step_size", "", mitkCommandLineParser::Float, "Step size:", "step size (in voxels)", 0.5); parser.addArgument("min_tract_length", "", mitkCommandLineParser::Float, "Min. tract length:", "minimum fiber length (in mm)", 20); parser.addArgument("angular_threshold", "", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold between two successive steps, (default: 90° * step_size, minimum 15°)"); parser.addArgument("loop_check", "", mitkCommandLineParser::Float, "Check for loops:", "threshold on angular stdev over the last 4 voxel lengths"); parser.endGroup(); parser.beginGroup("5. Tractography prior:"); parser.addArgument("prior_image", "", mitkCommandLineParser::String, "Peak prior:", "tractography prior in thr for of a peak image", us::Any()); parser.addArgument("prior_weight", "", mitkCommandLineParser::Float, "Prior weight", "weighting factor between prior and data.", 0.5); parser.addArgument("restrict_to_prior", "", mitkCommandLineParser::Bool, "Restrict to prior:", "restrict tractography to regions where the prior is valid."); parser.addArgument("new_directions_from_prior", "", mitkCommandLineParser::Bool, "New directios from prior:", "the prior can create directions where there are none in the data."); parser.endGroup(); parser.beginGroup("6. Neighborhood sampling:"); parser.addArgument("num_samples", "", mitkCommandLineParser::Int, "Num. neighborhood samples:", "number of neighborhood samples that are use to determine the next progression direction", 0); parser.addArgument("sampling_distance", "", mitkCommandLineParser::Float, "Sampling distance:", "distance of neighborhood sampling points (in voxels)", 0.25); parser.addArgument("use_stop_votes", "", mitkCommandLineParser::Bool, "Use stop votes:", "use stop votes"); parser.addArgument("use_only_forward_samples", "", mitkCommandLineParser::Bool, "Use only forward samples:", "use only forward samples"); parser.endGroup(); parser.beginGroup("7. Tensor tractography specific:"); parser.addArgument("tend_f", "", mitkCommandLineParser::Float, "Weight f", "weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0); parser.addArgument("tend_g", "", mitkCommandLineParser::Float, "Weight g", "weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0); parser.endGroup(); parser.beginGroup("8. Random forest tractography specific:"); parser.addArgument("forest", "", mitkCommandLineParser::String, "Forest:", "input random forest (HDF5 file)", us::Any()); parser.addArgument("use_sh_features", "", mitkCommandLineParser::Bool, "Use SH features:", "use SH features"); parser.endGroup(); parser.beginGroup("9. Additional input:"); parser.addArgument("additional_images", "", mitkCommandLineParser::StringList, "Additional images:", "specify a list of float images that hold additional information (FA, GFA, additional features for RF tractography)", us::Any()); parser.endGroup(); parser.beginGroup("10. Misc:"); parser.addArgument("flip_x", "", mitkCommandLineParser::Bool, "Flip X:", "multiply x-coordinate of direction proposal by -1"); parser.addArgument("flip_y", "", mitkCommandLineParser::Bool, "Flip Y:", "multiply y-coordinate of direction proposal by -1"); parser.addArgument("flip_z", "", mitkCommandLineParser::Bool, "Flip Z:", "multiply z-coordinate of direction proposal by -1"); parser.addArgument("no_data_interpolation", "", mitkCommandLineParser::Bool, "Don't interpolate input data:", "don't interpolate input image values"); parser.addArgument("no_mask_interpolation", "", mitkCommandLineParser::Bool, "Don't interpolate masks:", "don't interpolate mask image values"); parser.addArgument("compress", "", mitkCommandLineParser::Float, "Compress:", "compress output fibers using the given error threshold (in mm)"); parser.endGroup(); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType input_files = us::any_cast(parsedArgs["input"]); std::string outFile = us::any_cast(parsedArgs["out"]); std::string algorithm = us::any_cast(parsedArgs["algorithm"]); std::string prior_image = ""; if (parsedArgs.count("prior_image")) prior_image = us::any_cast(parsedArgs["prior_image"]); float prior_weight = 0.5; if (parsedArgs.count("prior_weight")) prior_weight = us::any_cast(parsedArgs["prior_weight"]); bool restrict_to_prior = false; if (parsedArgs.count("restrict_to_prior")) restrict_to_prior = us::any_cast(parsedArgs["restrict_to_prior"]); bool new_directions_from_prior = false; if (parsedArgs.count("new_directions_from_prior")) new_directions_from_prior = us::any_cast(parsedArgs["new_directions_from_prior"]); bool sharpen_odfs = false; if (parsedArgs.count("sharpen_odfs")) sharpen_odfs = us::any_cast(parsedArgs["sharpen_odfs"]); bool interpolate = true; if (parsedArgs.count("no_data_interpolation")) interpolate = !us::any_cast(parsedArgs["no_data_interpolation"]); bool mask_interpolation = true; if (parsedArgs.count("no_mask_interpolation")) interpolate = !us::any_cast(parsedArgs["no_mask_interpolation"]); bool use_sh_features = false; if (parsedArgs.count("use_sh_features")) use_sh_features = us::any_cast(parsedArgs["use_sh_features"]); bool use_stop_votes = false; if (parsedArgs.count("use_stop_votes")) use_stop_votes = us::any_cast(parsedArgs["use_stop_votes"]); bool use_only_forward_samples = false; if (parsedArgs.count("use_only_forward_samples")) use_only_forward_samples = us::any_cast(parsedArgs["use_only_forward_samples"]); bool flip_x = false; if (parsedArgs.count("flip_x")) flip_x = us::any_cast(parsedArgs["flip_x"]); bool flip_y = false; if (parsedArgs.count("flip_y")) flip_y = us::any_cast(parsedArgs["flip_y"]); bool flip_z = false; if (parsedArgs.count("flip_z")) flip_z = us::any_cast(parsedArgs["flip_z"]); bool apply_image_rotation = false; if (parsedArgs.count("apply_image_rotation")) apply_image_rotation = us::any_cast(parsedArgs["apply_image_rotation"]); float compress = -1; if (parsedArgs.count("compress")) compress = us::any_cast(parsedArgs["compress"]); float min_tract_length = 20; if (parsedArgs.count("min_tract_length")) min_tract_length = us::any_cast(parsedArgs["min_tract_length"]); float loop_check = -1; if (parsedArgs.count("loop_check")) loop_check = us::any_cast(parsedArgs["loop_check"]); std::string forestFile; if (parsedArgs.count("forest")) forestFile = us::any_cast(parsedArgs["forest"]); std::string maskFile = ""; if (parsedArgs.count("tracking_mask")) maskFile = us::any_cast(parsedArgs["tracking_mask"]); std::string seedFile = ""; if (parsedArgs.count("seed_image")) seedFile = us::any_cast(parsedArgs["seed_image"]); std::string targetFile = ""; if (parsedArgs.count("target_image")) targetFile = us::any_cast(parsedArgs["target_image"]); std::string exclusionFile = ""; if (parsedArgs.count("exclusion_image")) exclusionFile = us::any_cast(parsedArgs["exclusion_image"]); std::string stopFile = ""; if (parsedArgs.count("stop_image")) stopFile = us::any_cast(parsedArgs["stop_image"]); std::string ep_constraint = "NONE"; if (parsedArgs.count("ep_constraint")) ep_constraint = us::any_cast(parsedArgs["ep_constraint"]); float cutoff = 0.1; if (parsedArgs.count("cutoff")) cutoff = us::any_cast(parsedArgs["cutoff"]); float odf_cutoff = 0.0; if (parsedArgs.count("odf_cutoff")) odf_cutoff = us::any_cast(parsedArgs["odf_cutoff"]); float stepsize = -1; if (parsedArgs.count("step_size")) stepsize = us::any_cast(parsedArgs["step_size"]); float sampling_distance = -1; if (parsedArgs.count("sampling_distance")) sampling_distance = us::any_cast(parsedArgs["sampling_distance"]); int num_samples = 0; if (parsedArgs.count("num_samples")) num_samples = us::any_cast(parsedArgs["num_samples"]); int num_seeds = 1; if (parsedArgs.count("seeds")) num_seeds = us::any_cast(parsedArgs["seeds"]); unsigned int trials_per_seed = 10; if (parsedArgs.count("trials_per_seed")) trials_per_seed = us::any_cast(parsedArgs["trials_per_seed"]); float tend_f = 1; if (parsedArgs.count("tend_f")) tend_f = us::any_cast(parsedArgs["tend_f"]); float tend_g = 0; if (parsedArgs.count("tend_g")) tend_g = us::any_cast(parsedArgs["tend_g"]); float angular_threshold = -1; if (parsedArgs.count("angular_threshold")) angular_threshold = us::any_cast(parsedArgs["angular_threshold"]); unsigned int max_tracts = -1; if (parsedArgs.count("max_tracts")) max_tracts = us::any_cast(parsedArgs["max_tracts"]); std::string ext = itksys::SystemTools::GetFilenameExtension(outFile); if (ext != ".fib" && ext != ".trk") { MITK_INFO << "Output file format not supported. Use one of .fib, .trk, .nii, .nii.gz, .nrrd"; return EXIT_FAILURE; } // LOAD DATASETS mitkCommandLineParser::StringContainerType addFiles; if (parsedArgs.count("additional_images")) addFiles = us::any_cast(parsedArgs["additional_images"]); typedef itk::Image ItkFloatImgType; MITK_INFO << "loading input"; std::vector< mitk::Image::Pointer > input_images; for (unsigned int i=0; i(mitk::IOUtil::Load(input_files.at(i))[0].GetPointer()); + mitk::Image::Pointer mitkImage = mitk::IOUtil::Load(input_files.at(i)); input_images.push_back(mitkImage); } ItkFloatImgType::Pointer mask = nullptr; if (!maskFile.empty()) { MITK_INFO << "loading mask image"; - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(maskFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(maskFile); mask = ItkFloatImgType::New(); mitk::CastToItkImage(img, mask); } ItkFloatImgType::Pointer seed = nullptr; if (!seedFile.empty()) { MITK_INFO << "loading seed ROI image"; - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(seedFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(seedFile); seed = ItkFloatImgType::New(); mitk::CastToItkImage(img, seed); } ItkFloatImgType::Pointer stop = nullptr; if (!stopFile.empty()) { MITK_INFO << "loading stop ROI image"; - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(stopFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(stopFile); stop = ItkFloatImgType::New(); mitk::CastToItkImage(img, stop); } ItkFloatImgType::Pointer target = nullptr; if (!targetFile.empty()) { MITK_INFO << "loading target ROI image"; - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(targetFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(targetFile); target = ItkFloatImgType::New(); mitk::CastToItkImage(img, target); } ItkFloatImgType::Pointer exclusion = nullptr; if (!exclusionFile.empty()) { MITK_INFO << "loading exclusion ROI image"; - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(exclusionFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(exclusionFile); exclusion = ItkFloatImgType::New(); mitk::CastToItkImage(img, exclusion); } MITK_INFO << "loading additional images"; std::vector< std::vector< ItkFloatImgType::Pointer > > addImages; addImages.push_back(std::vector< ItkFloatImgType::Pointer >()); for (auto file : addFiles) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(file)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(file); ItkFloatImgType::Pointer itkimg = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkimg); addImages.at(0).push_back(itkimg); } // ////////////////////////////////////////////////////////////////// // omp_set_num_threads(1); if (algorithm == "ProbTensor") { typedef mitk::ImageToItk< mitk::TrackingHandlerTensor::ItkTensorImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(input_images.at(0)); caster->Update(); mitk::TrackingHandlerTensor::ItkTensorImageType::Pointer itkTensorImg = caster->GetOutput(); typedef itk::TensorImageToOdfImageFilter< float, float > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkTensorImg ); filter->Update(); mitk::Image::Pointer image = mitk::Image::New(); FilterType::OutputImageType::Pointer outimg = filter->GetOutput(); image->InitializeByItk( outimg.GetPointer() ); image->SetVolume( outimg->GetBufferPointer() ); input_images.clear(); input_images.push_back(image); sharpen_odfs = true; odf_cutoff = 0; } typedef itk::StreamlineTrackingFilter TrackerType; TrackerType::Pointer tracker = TrackerType::New(); if (!prior_image.empty()) { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image"}, {}); - mitk::PeakImage::Pointer priorImage = dynamic_cast(mitk::IOUtil::Load(prior_image, &functor)[0].GetPointer()); + mitk::PeakImage::Pointer priorImage = mitk::IOUtil::Load(prior_image, &functor); if (priorImage.IsNull()) { MITK_INFO << "Only peak images are supported as prior at the moment!"; return EXIT_FAILURE; } mitk::TrackingDataHandler* priorhandler = new mitk::TrackingHandlerPeaks(); typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(priorImage); caster->Update(); mitk::TrackingHandlerPeaks::PeakImgType::Pointer itkImg = caster->GetOutput(); dynamic_cast(priorhandler)->SetPeakImage(itkImg); dynamic_cast(priorhandler)->SetPeakThreshold(0.0); dynamic_cast(priorhandler)->SetInterpolate(interpolate); dynamic_cast(priorhandler)->SetMode(mitk::TrackingDataHandler::MODE::DETERMINISTIC); tracker->SetTrackingPriorHandler(priorhandler); tracker->SetTrackingPriorWeight(prior_weight); tracker->SetTrackingPriorAsMask(restrict_to_prior); tracker->SetIntroduceDirectionsFromPrior(new_directions_from_prior); } mitk::TrackingDataHandler* handler; if (algorithm == "DetRF" || algorithm == "ProbRF") { - mitk::TractographyForest::Pointer forest = dynamic_cast(mitk::IOUtil::Load(forestFile)[0].GetPointer()); + mitk::TractographyForest::Pointer forest = mitk::IOUtil::Load(forestFile); if (forest.IsNull()) mitkThrow() << "Forest file " << forestFile << " could not be read."; if (use_sh_features) { handler = new mitk::TrackingHandlerRandomForest<6,28>(); dynamic_cast*>(handler)->SetForest(forest); dynamic_cast*>(handler)->AddDwi(input_images.at(0)); dynamic_cast*>(handler)->SetAdditionalFeatureImages(addImages); } else { handler = new mitk::TrackingHandlerRandomForest<6,100>(); dynamic_cast*>(handler)->SetForest(forest); dynamic_cast*>(handler)->AddDwi(input_images.at(0)); dynamic_cast*>(handler)->SetAdditionalFeatureImages(addImages); } if (algorithm == "ProbRF") handler->SetMode(mitk::TrackingDataHandler::MODE::PROBABILISTIC); } else if (algorithm == "Peaks") { handler = new mitk::TrackingHandlerPeaks(); typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(input_images.at(0)); caster->Update(); mitk::TrackingHandlerPeaks::PeakImgType::Pointer itkImg = caster->GetOutput(); dynamic_cast(handler)->SetPeakImage(itkImg); dynamic_cast(handler)->SetApplyDirectionMatrix(apply_image_rotation); dynamic_cast(handler)->SetPeakThreshold(cutoff); } else if (algorithm == "DetTensor") { handler = new mitk::TrackingHandlerTensor(); for (auto input_image : input_images) { typedef mitk::ImageToItk< mitk::TrackingHandlerTensor::ItkTensorImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(input_image); caster->Update(); mitk::TrackingHandlerTensor::ItkTensorImageType::ConstPointer itkImg = caster->GetOutput(); dynamic_cast(handler)->AddTensorImage(itkImg); } dynamic_cast(handler)->SetFaThreshold(cutoff); dynamic_cast(handler)->SetF(tend_f); dynamic_cast(handler)->SetG(tend_g); if (addImages.at(0).size()>0) dynamic_cast(handler)->SetFaImage(addImages.at(0).at(0)); } else if (algorithm == "DetODF" || algorithm == "ProbODF" || algorithm == "ProbTensor") { handler = new mitk::TrackingHandlerOdf(); typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(input_images.at(0)); caster->Update(); mitk::TrackingHandlerOdf::ItkOdfImageType::Pointer itkImg = caster->GetOutput(); dynamic_cast(handler)->SetOdfImage(itkImg); dynamic_cast(handler)->SetGfaThreshold(cutoff); dynamic_cast(handler)->SetOdfThreshold(odf_cutoff); dynamic_cast(handler)->SetSharpenOdfs(sharpen_odfs); if (algorithm == "ProbODF" || algorithm == "ProbTensor") dynamic_cast(handler)->SetMode(mitk::TrackingHandlerOdf::MODE::PROBABILISTIC); if (algorithm == "ProbTensor") dynamic_cast(handler)->SetIsOdfFromTensor(true); if (addImages.at(0).size()>0) dynamic_cast(handler)->SetGfaImage(addImages.at(0).at(0)); } else { MITK_INFO << "Unknown tractography algorithm (" + algorithm+"). Known types are Peaks, DetTensor, ProbTensor, DetODF, ProbODF, DetRF, ProbRF."; return EXIT_FAILURE; } handler->SetInterpolate(interpolate); handler->SetFlipX(flip_x); handler->SetFlipY(flip_y); handler->SetFlipZ(flip_z); if (ep_constraint=="NONE") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::NONE); else if (ep_constraint=="EPS_IN_TARGET") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::EPS_IN_TARGET); else if (ep_constraint=="EPS_IN_TARGET_LABELDIFF") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::EPS_IN_TARGET_LABELDIFF); else if (ep_constraint=="EPS_IN_SEED_AND_TARGET") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::EPS_IN_SEED_AND_TARGET); else if (ep_constraint=="MIN_ONE_EP_IN_TARGET") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::MIN_ONE_EP_IN_TARGET); else if (ep_constraint=="ONE_EP_IN_TARGET") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::ONE_EP_IN_TARGET); else if (ep_constraint=="NO_EP_IN_TARGET") tracker->SetEndpointConstraint(itk::StreamlineTrackingFilter::EndpointConstraints::NO_EP_IN_TARGET); MITK_INFO << "Tractography algorithm: " << algorithm; tracker->SetInterpolateMasks(mask_interpolation); tracker->SetNumberOfSamples(num_samples); tracker->SetAngularThreshold(angular_threshold); tracker->SetMaskImage(mask); tracker->SetSeedImage(seed); tracker->SetStoppingRegions(stop); tracker->SetTargetRegions(target); tracker->SetExclusionRegions(exclusion); tracker->SetSeedsPerVoxel(num_seeds); tracker->SetStepSize(stepsize); tracker->SetSamplingDistance(sampling_distance); tracker->SetUseStopVotes(use_stop_votes); tracker->SetOnlyForwardSamples(use_only_forward_samples); tracker->SetLoopCheck(loop_check); tracker->SetMaxNumTracts(max_tracts); tracker->SetTrialsPerSeed(trials_per_seed); tracker->SetTrackingHandler(handler); if (ext != ".fib" && ext != ".trk") tracker->SetUseOutputProbabilityMap(true); tracker->SetMinTractLength(min_tract_length); tracker->Update(); if (ext == ".fib" || ext == ".trk") { vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData(); mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly); if (compress > 0) outFib->Compress(compress); mitk::IOUtil::Save(outFib, outFile); } else { TrackerType::ItkDoubleImgType::Pointer outImg = tracker->GetOutputProbabilityMap(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); if (ext != ".nii" && ext != ".nii.gz" && ext != ".nrrd") outFile += ".nii.gz"; mitk::IOUtil::Save(img, outFile); } delete handler; return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/AnchorBasedScoring.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/AnchorBasedScoring.cpp index a5a42ddcec..2fe1fa5134 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/AnchorBasedScoring.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/AnchorBasedScoring.cpp @@ -1,473 +1,473 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Point PointType4; typedef itk::Image< float, 4 > PeakImgType; typedef itk::Image< unsigned char, 3 > ItkUcharImageType; std::vector< mitk::FiberBundle::Pointer > CombineTractograms(std::vector< mitk::FiberBundle::Pointer > reference, std::vector< mitk::FiberBundle::Pointer > candidates, int skip=-1) { std::vector< mitk::FiberBundle::Pointer > fib; for (auto f : reference) fib.push_back(f); int c = 0; for (auto f : candidates) { if (c!=skip) fib.push_back(f); ++c; } return fib; } std::vector< std::string > get_file_list(const std::string& path, std::vector< std::string > extensions={".fib", ".trk"}) { std::vector< std::string > file_list; itk::Directory::Pointer dir = itk::Directory::New(); if (dir->Load(path.c_str())) { int n = dir->GetNumberOfFiles(); for (int r = 0; r < n; r++) { const char *filename = dir->GetFile(r); std::string ext = ist::GetFilenameExtension(filename); for (auto e : extensions) { if (ext==e) { file_list.push_back(path + '/' + filename); break; } } } } return file_list; } /*! \brief Fits the tractogram to the input peak image by assigning a weight to each fiber (similar to https://doi.org/10.1016/j.neuroimage.2015.06.092). */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Anchor Based Scoring"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "a", mitkCommandLineParser::InputFile, "Anchor tractogram:", "anchor tracts in one tractogram file", us::Any(), false); parser.addArgument("", "p", mitkCommandLineParser::InputFile, "Input peaks:", "input peak image", us::Any(), false); parser.addArgument("", "c", mitkCommandLineParser::InputDirectory, "Candidates folder:", "folder containing candidate tracts", us::Any(), false); parser.addArgument("", "o", mitkCommandLineParser::OutputDirectory, "Output folder:", "output folder", us::Any(), false); parser.addArgument("anchor_masks", "", mitkCommandLineParser::StringList, "Reference Masks:", "reference tract masks for accuracy evaluation"); parser.addArgument("mask", "", mitkCommandLineParser::InputFile, "Mask image:", "scoring is only performed inside the mask image"); parser.addArgument("greedy_add", "", mitkCommandLineParser::Bool, "Greedy:", "if enabled, the candidate tracts are not jointly fitted to the residual image but one after the other employing a greedy scheme", false); parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "modifier for regularization", 0.1); parser.addArgument("filter_outliers", "", mitkCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false); parser.addArgument("regu", "", mitkCommandLineParser::String, "Regularization:", "MSM, Variance, VoxelVariance, Lasso, GroupLasso, GroupVariance, NONE (default)"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string anchors_file = us::any_cast(parsedArgs["a"]); std::string peak_file_name = us::any_cast(parsedArgs["p"]); std::string candidate_tract_folder = us::any_cast(parsedArgs["c"]); std::string out_folder = us::any_cast(parsedArgs["o"]); bool greedy_add = false; if (parsedArgs.count("greedy_add")) greedy_add = us::any_cast(parsedArgs["greedy_add"]); float lambda = 0.1; if (parsedArgs.count("lambda")) lambda = us::any_cast(parsedArgs["lambda"]); bool filter_outliers = false; if (parsedArgs.count("filter_outliers")) filter_outliers = us::any_cast(parsedArgs["filter_outliers"]); std::string mask_file = ""; if (parsedArgs.count("mask")) mask_file = us::any_cast(parsedArgs["mask"]); mitkCommandLineParser::StringContainerType anchor_mask_files; if (parsedArgs.count("anchor_masks")) anchor_mask_files = us::any_cast(parsedArgs["anchor_masks"]); std::string regu = "NONE"; if (parsedArgs.count("regu")) regu = us::any_cast(parsedArgs["regu"]); try { itk::TimeProbe clock; clock.Start(); if (!ist::PathExists(out_folder)) { MITK_INFO << "Creating output directory"; ist::MakeDirectory(out_folder); } MITK_INFO << "Loading data"; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect ofstream logfile; logfile.open (out_folder + "log.txt"); itk::ImageFileWriter< PeakImgType >::Pointer peak_image_writer = itk::ImageFileWriter< PeakImgType >::New(); mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image", "Fiberbundles"}, {}); - mitk::Image::Pointer inputImage = dynamic_cast(mitk::IOUtil::Load(peak_file_name, &functor)[0].GetPointer()); + mitk::Image::Pointer inputImage = mitk::IOUtil::Load(peak_file_name, &functor); float minSpacing = 1; if(inputImage->GetGeometry()->GetSpacing()[0]GetGeometry()->GetSpacing()[1] && inputImage->GetGeometry()->GetSpacing()[0]GetGeometry()->GetSpacing()[2]) minSpacing = inputImage->GetGeometry()->GetSpacing()[0]; else if (inputImage->GetGeometry()->GetSpacing()[1] < inputImage->GetGeometry()->GetSpacing()[2]) minSpacing = inputImage->GetGeometry()->GetSpacing()[1]; else minSpacing = inputImage->GetGeometry()->GetSpacing()[2]; // Load mask file. Fit is only performed inside the mask itk::FitFibersToImageFilter::UcharImgType::Pointer mask = nullptr; if (mask_file.compare("")!=0) { - mitk::Image::Pointer mitk_mask = dynamic_cast(mitk::IOUtil::Load(mask_file)[0].GetPointer()); + mitk::Image::Pointer mitk_mask = mitk::IOUtil::Load(mask_file); mitk::CastToItkImage(mitk_mask, mask); } // Load masks covering the true positives for evaluation purposes std::vector< itk::FitFibersToImageFilter::UcharImgType::Pointer > reference_masks; for (auto filename : anchor_mask_files) { itk::FitFibersToImageFilter::UcharImgType::Pointer ref_mask = nullptr; - mitk::Image::Pointer ref_mitk_mask = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer ref_mitk_mask = mitk::IOUtil::Load(filename); mitk::CastToItkImage(ref_mitk_mask, ref_mask); reference_masks.push_back(ref_mask); } // Load peak image typedef mitk::ImageToItk< PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(inputImage); caster->Update(); PeakImgType::Pointer peak_image = caster->GetOutput(); // Load all candidate tracts std::vector< std::string > candidate_tract_files = get_file_list(candidate_tract_folder); std::vector< mitk::FiberBundle::Pointer > input_candidates; for (std::string f : candidate_tract_files) { - mitk::FiberBundle::Pointer fib = dynamic_cast(mitk::IOUtil::Load(f)[0].GetPointer()); + mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(f); if (fib.IsNull()) continue; if (fib->GetNumFibers()<=0) continue; fib->ResampleLinear(minSpacing/10.0); input_candidates.push_back(fib); } std::cout.rdbuf (old); // <-- restore MITK_INFO << "Loaded " << candidate_tract_files.size() << " candidate tracts."; double rmse = 0.0; int iteration = 0; std::string name = "NOANCHOR"; // Load reference tractogram consisting of all known tracts std::vector< mitk::FiberBundle::Pointer > input_reference; - mitk::FiberBundle::Pointer anchor_tractogram = dynamic_cast(mitk::IOUtil::Load(anchors_file)[0].GetPointer()); + mitk::FiberBundle::Pointer anchor_tractogram = mitk::IOUtil::Load(anchors_file); if ( !(anchor_tractogram.IsNull() || anchor_tractogram->GetNumFibers()==0) ) { std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect anchor_tractogram->ResampleLinear(minSpacing/10.0); std::cout.rdbuf (old); // <-- restore input_reference.push_back(anchor_tractogram); // Fit known tracts to peak image to obtain underexplained image MITK_INFO << "Fit anchor tracts"; itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); fitter->SetTractograms(input_reference); fitter->SetLambda(lambda); fitter->SetFilterOutliers(filter_outliers); fitter->SetPeakImage(peak_image); fitter->SetVerbose(true); fitter->SetResampleFibers(false); fitter->SetMaskImage(mask); fitter->SetRegularization(VnlCostFunction::REGU::NONE); fitter->Update(); rmse = fitter->GetRMSE(); vnl_vector rms_diff = fitter->GetRmsDiffPerBundle(); logfile << "RMS_DIFF: " << setprecision(5) << rms_diff[0] << " " << name << " RMSE: " << rmse << "\n"; name = ist::GetFilenameWithoutExtension(anchors_file); mitk::FiberBundle::Pointer anchor_tracts = fitter->GetTractograms().at(0); anchor_tracts->SetFiberColors(255,255,255); mitk::IOUtil::Save(anchor_tracts, out_folder + boost::lexical_cast((int)(100000*rms_diff[0])) + "_" + name + ".fib"); peak_image = fitter->GetUnderexplainedImage(); peak_image_writer->SetInput(peak_image); peak_image_writer->SetFileName(out_folder + "Residual_" + name + ".nii.gz"); peak_image_writer->Update(); } if (!greedy_add) { MITK_INFO << "Fit candidate tracts"; itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); fitter->SetLambda(lambda); fitter->SetFilterOutliers(filter_outliers); fitter->SetVerbose(true); fitter->SetPeakImage(peak_image); fitter->SetResampleFibers(false); fitter->SetMaskImage(mask); fitter->SetTractograms(input_candidates); fitter->SetFitIndividualFibers(true); if (regu=="MSM") fitter->SetRegularization(VnlCostFunction::REGU::MSM); else if (regu=="Variance") fitter->SetRegularization(VnlCostFunction::REGU::VARIANCE); else if (regu=="Lasso") fitter->SetRegularization(VnlCostFunction::REGU::LASSO); else if (regu=="VoxelVariance") fitter->SetRegularization(VnlCostFunction::REGU::VOXEL_VARIANCE); else if (regu=="GroupLasso") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_LASSO); else if (regu=="GroupVariance") fitter->SetRegularization(VnlCostFunction::REGU::GROUP_VARIANCE); else if (regu=="NONE") fitter->SetRegularization(VnlCostFunction::REGU::NONE); fitter->Update(); vnl_vector rms_diff = fitter->GetRmsDiffPerBundle(); vnl_vector log_rms_diff = rms_diff-rms_diff.min_value() + 1; log_rms_diff = log_rms_diff.apply(std::log); log_rms_diff /= log_rms_diff.max_value(); int c = 0; for (auto fib : input_candidates) { fib->SetFiberWeights( log_rms_diff[c] ); fib->ColorFibersByOrientation(); std::string bundle_name = ist::GetFilenameWithoutExtension(candidate_tract_files.at(c)); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect mitk::IOUtil::Save(fib, out_folder + boost::lexical_cast((int)(100000*rms_diff[c])) + "_" + bundle_name + ".fib"); float best_overlap = 0; int best_overlap_index = -1; int m_idx = 0; for (auto ref_mask : reference_masks) { float overlap = fib->GetOverlap(ref_mask, false); if (overlap>best_overlap) { best_overlap = overlap; best_overlap_index = m_idx; } ++m_idx; } unsigned int num_voxels = 0; { itk::TractDensityImageFilter< ItkUcharImageType >::Pointer masks_filter = itk::TractDensityImageFilter< ItkUcharImageType >::New(); masks_filter->SetInputImage(mask); masks_filter->SetBinaryOutput(true); masks_filter->SetFiberBundle(fib); masks_filter->SetUseImageGeometry(true); masks_filter->Update(); num_voxels = masks_filter->GetNumCoveredVoxels(); } double weight_sum = 0; for (int i=0; iGetNumFibers(); i++) weight_sum += fib->GetFiberWeight(i); std::cout.rdbuf (old); // <-- restore logfile << "RMS_DIFF: " << setprecision(5) << rms_diff[c] << " " << bundle_name << " " << num_voxels << " " << fib->GetNumFibers() << " " << weight_sum << "\n"; if (best_overlap_index>=0) logfile << "Best_overlap: " << setprecision(5) << best_overlap << " " << ist::GetFilenameWithoutExtension(anchor_mask_files.at(best_overlap_index)) << "\n"; else logfile << "No_overlap\n"; ++c; } mitk::FiberBundle::Pointer out_fib = mitk::FiberBundle::New(); out_fib = out_fib->AddBundles(input_candidates); out_fib->ColorFibersByFiberWeights(false, true); mitk::IOUtil::Save(out_fib, out_folder + "AllCandidates.fib"); peak_image = fitter->GetUnderexplainedImage(); peak_image_writer->SetInput(peak_image); peak_image_writer->SetFileName(out_folder + "Residual_AllCandidates.nii.gz"); peak_image_writer->Update(); } else { MITK_INFO << "RMSE: " << setprecision(5) << rmse; // fitter->SetPeakImage(peak_image); // Iteratively add candidate bundles in a greedy manner while (!input_candidates.empty()) { double next_rmse = rmse; double num_peaks = 0; mitk::FiberBundle::Pointer best_candidate = nullptr; PeakImgType::Pointer best_candidate_peak_image = nullptr; for (int i=0; i<(int)input_candidates.size(); ++i) { // WHY NECESSARY AGAIN?? itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New(); fitter->SetLambda(lambda); fitter->SetFilterOutliers(filter_outliers); fitter->SetVerbose(false); fitter->SetPeakImage(peak_image); fitter->SetResampleFibers(false); fitter->SetMaskImage(mask); // ****************************** fitter->SetTractograms({input_candidates.at(i)}); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect fitter->Update(); std::cout.rdbuf (old); // <-- restore double candidate_rmse = fitter->GetRMSE(); if (candidate_rmseGetNumCoveredDirections(); best_candidate = fitter->GetTractograms().at(0); best_candidate_peak_image = fitter->GetUnderexplainedImage(); } } if (best_candidate.IsNull()) break; // fitter->SetPeakImage(peak_image); peak_image = best_candidate_peak_image; int i=0; std::vector< mitk::FiberBundle::Pointer > remaining_candidates; std::vector< std::string > remaining_candidate_files; for (auto fib : input_candidates) { if (fib!=best_candidate) { remaining_candidates.push_back(fib); remaining_candidate_files.push_back(candidate_tract_files.at(i)); } else name = ist::GetFilenameWithoutExtension(candidate_tract_files.at(i)); ++i; } input_candidates = remaining_candidates; candidate_tract_files = remaining_candidate_files; iteration++; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect // Save winning candidate mitk::IOUtil::Save(best_candidate, out_folder + boost::lexical_cast(iteration) + "_" + name + ".fib"); peak_image_writer->SetInput(peak_image); peak_image_writer->SetFileName(out_folder + boost::lexical_cast(iteration) + "_" + name + ".nrrd"); peak_image_writer->Update(); // Calculate best overlap with reference masks for evaluation purposes float best_overlap = 0; int best_overlap_index = -1; i = 0; for (auto ref_mask : reference_masks) { float overlap = best_candidate->GetOverlap(ref_mask, false); if (overlap>best_overlap) { best_overlap = overlap; best_overlap_index = i; } ++i; } std::cout.rdbuf (old); // <-- restore logfile << "RMSE: " << setprecision(5) << rmse << " " << name << " " << num_peaks << "\n"; if (best_overlap_index>=0) logfile << "Best_overlap: " << setprecision(5) << best_overlap << " " << ist::GetFilenameWithoutExtension(anchor_mask_files.at(best_overlap_index)) << "\n"; else logfile << "No_overlap\n"; } } clock.Stop(); int h = clock.GetTotal()/3600; int m = ((int)clock.GetTotal()%3600)/60; int s = (int)clock.GetTotal()%60; MITK_INFO << "Plausibility estimation took " << h << "h, " << m << "m and " << s << "s"; logfile.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/EvaluateLiFE.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/EvaluateLiFE.cpp index 2bc531941f..07ecbbd06a 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/EvaluateLiFE.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/EvaluateLiFE.cpp @@ -1,248 +1,248 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; typedef std::tuple< ItkFloatImgType::Pointer, std::string > MaskType; ItkFloatImgType::Pointer LoadItkImage(const std::string& filename) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(filename); ItkFloatImgType::Pointer itkMask = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkMask); return itkMask; } std::vector< MaskType > get_file_list(const std::string& path) { std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); std::srand(ms.count()); std::vector< MaskType > mask_list; itk::Directory::Pointer dir = itk::Directory::New(); if (dir->Load(path.c_str())) { int n = dir->GetNumberOfFiles(); int num_images = 0; std::vector< int > im_indices; for (int r = 0; r < n; r++) { const char *filename = dir->GetFile(r); std::string ext = ist::GetFilenameExtension(filename); if (ext==".nii" || ext==".nii.gz" || ext==".nrrd") { ++num_images; im_indices.push_back(r); } } int c = -1; for (int r : im_indices) { c++; const char *filename = dir->GetFile(r); MITK_INFO << "Loading " << ist::GetFilenameWithoutExtension(filename); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect MaskType m(LoadItkImage(path + '/' + filename), ist::GetFilenameName(filename)); mask_list.push_back(m); std::cout.rdbuf (old); // <-- restore } } return mask_list; } /*! \brief */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Evaluate LiFE results"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output folder", us::Any(), false); parser.addArgument("reference_mask_folder", "m", mitkCommandLineParser::String, "Reference Mask Folder:", "reference masks of known bundles", false); parser.addArgument("overlap", "", mitkCommandLineParser::Float, "Overlap threshold:", "Overlap threshold used to identify true positives", 0.8); parser.addArgument("steps", "", mitkCommandLineParser::Int, "Threshold steps:", "number of weight thresholds used to calculate the ROC curve", 100); parser.addArgument("pre_filter_zeros", "", mitkCommandLineParser::Bool, "Remove zero weights:", "remove fibers with zero weights before starting the evaluation"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string fibFile = us::any_cast(parsedArgs["input"]); std::string reference_mask_folder = us::any_cast(parsedArgs["reference_mask_folder"]); std::string out_folder = us::any_cast(parsedArgs["out"]); float overlap = 0.8; if (parsedArgs.count("overlap")) overlap = us::any_cast(parsedArgs["overlap"]); int steps = 10; if (parsedArgs.count("steps")) steps = us::any_cast(parsedArgs["steps"]); bool pre_filter_zeros = false; if (parsedArgs.count("pre_filter_zeros")) pre_filter_zeros = us::any_cast(parsedArgs["pre_filter_zeros"]); try { std::vector< MaskType > known_tract_masks = get_file_list(reference_mask_folder); if (known_tract_masks.empty()) return EXIT_FAILURE; - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(fibFile)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); // resample fibers float minSpacing = 1; if(std::get<0>(known_tract_masks.at(0))->GetSpacing()[0](known_tract_masks.at(0))->GetSpacing()[1] && std::get<0>(known_tract_masks.at(0))->GetSpacing()[0](known_tract_masks.at(0))->GetSpacing()[2]) minSpacing = std::get<0>(known_tract_masks.at(0))->GetSpacing()[0]; else if (std::get<0>(known_tract_masks.at(0))->GetSpacing()[1] < std::get<0>(known_tract_masks.at(0))->GetSpacing()[2]) minSpacing = std::get<0>(known_tract_masks.at(0))->GetSpacing()[1]; else minSpacing = std::get<0>(known_tract_masks.at(0))->GetSpacing()[2]; inputTractogram->ResampleLinear(minSpacing/5); std::vector< float > weights; for (int i=0; iGetNumFibers(); ++i) weights.push_back(inputTractogram->GetFiberWeight(i)); std::sort(weights.begin(), weights.end()); if (pre_filter_zeros) inputTractogram = inputTractogram->FilterByWeights(0.0); mitk::FiberBundle::Pointer pred_positives = inputTractogram->GetDeepCopy(); mitk::FiberBundle::Pointer pred_negatives = mitk::FiberBundle::New(nullptr); ofstream logfile; logfile.open (out_folder + "LiFE_ROC.txt"); float fpr = 1.0; float tpr = 1.0; float step = weights.back()/steps; float w = 0; if (!pre_filter_zeros) w -= step; while (pred_positives->GetNumFibers()>0 && fpr>0.001 && tpr>0.001) { w += step; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect mitk::FiberBundle::Pointer tp_tracts = mitk::FiberBundle::New(nullptr); mitk::FiberBundle::Pointer fn_tracts = mitk::FiberBundle::New(nullptr); for ( MaskType mask : known_tract_masks ) { ItkFloatImgType::Pointer mask_image = std::get<0>(mask); mitk::FiberBundle::Pointer a; { itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(pred_positives); extractor->SetRoiImages({mask_image}); extractor->SetOverlapFraction(overlap); extractor->SetDontResampleFibers(true); extractor->SetMode(itk::FiberExtractionFilter::MODE::OVERLAP); extractor->Update(); a = extractor->GetPositives().at(0); } tp_tracts = tp_tracts->AddBundle(a); mitk::FiberBundle::Pointer b; { itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(pred_negatives); extractor->SetRoiImages({mask_image}); extractor->SetOverlapFraction(overlap); extractor->SetDontResampleFibers(true); extractor->SetMode(itk::FiberExtractionFilter::MODE::OVERLAP); extractor->Update(); b = extractor->GetPositives().at(0); } fn_tracts = fn_tracts->AddBundle(b); } mitk::FiberBundle::Pointer fp_tracts = pred_positives->SubtractBundle(tp_tracts); mitk::FiberBundle::Pointer tn_tracts = pred_negatives->SubtractBundle(fn_tracts); std::cout.rdbuf (old); // <-- restore float positives = tp_tracts->GetNumFibers() + fn_tracts->GetNumFibers(); float negatives = tn_tracts->GetNumFibers() + fp_tracts->GetNumFibers(); fpr = (float)fp_tracts->GetNumFibers() / negatives; tpr = (float)tp_tracts->GetNumFibers() / positives; float accuracy = 1.0; if (pred_positives->GetNumFibers()>0) accuracy = (float)tp_tracts->GetNumFibers()/pred_positives->GetNumFibers(); logfile << w << " " << fpr << " " << tpr << " " << accuracy << " \n"; MITK_INFO << "#Fibers: " << pred_positives->GetNumFibers(); MITK_INFO << "FPR/TPR: " << fpr << "/" << tpr; MITK_INFO << "Acc: " << accuracy; pred_positives = inputTractogram->FilterByWeights(w); pred_negatives = inputTractogram->FilterByWeights(w, true); } logfile.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractAnchorTracts.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractAnchorTracts.cpp index c67164b7d1..02b545cf70 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractAnchorTracts.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractAnchorTracts.cpp @@ -1,277 +1,277 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; typedef std::tuple< ItkFloatImgType::Pointer, std::string > MaskType; void CreateFolderStructure(const std::string& path) { if (ist::PathExists(path)) ist::RemoveADirectory(path); ist::MakeDirectory(path); ist::MakeDirectory(path + "/anchor_tracts/"); ist::MakeDirectory(path + "/candidate_tracts/"); ist::MakeDirectory(path + "/skipped_masks/"); } ItkFloatImgType::Pointer LoadItkImage(const std::string& filename) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(filename); ItkFloatImgType::Pointer itkMask = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkMask); return itkMask; } std::vector< MaskType > get_file_list(const std::string& path, float anchor_fraction, const std::string& skipped_path, int random_seed) { if (anchor_fraction<0) anchor_fraction = 0; else if (anchor_fraction>1.0) anchor_fraction = 1.0; std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); if (random_seed<0) std::srand(ms.count()); else std::srand(random_seed); MITK_INFO << "random_seed: " << random_seed; std::vector< MaskType > mask_list; itk::Directory::Pointer dir = itk::Directory::New(); int skipped = 0; if (dir->Load(path.c_str())) { int n = dir->GetNumberOfFiles(); int num_images = 0; std::vector< int > im_indices; for (int r = 0; r < n; r++) { const char *filename = dir->GetFile(r); std::string ext = ist::GetFilenameExtension(filename); if (ext==".nii" || ext==".nii.gz" || ext==".nrrd") { ++num_images; im_indices.push_back(r); } } int skipping_num = num_images * (1.0 - anchor_fraction); std::random_shuffle(im_indices.begin(), im_indices.end()); MITK_INFO << "Skipping " << skipping_num << " images"; MITK_INFO << "Number of anchors: " << num_images-skipping_num; int c = -1; for (int r : im_indices) { c++; const char *filename = dir->GetFile(r); if (c matrix = vtkSmartPointer< vtkMatrix4x4 >::New(); matrix->Identity(); matrix->SetElement(0,0,-matrix->GetElement(0,0)); matrix->SetElement(1,1,-matrix->GetElement(1,1)); geometry->SetIndexToWorldTransformByVtkMatrix(matrix); vtkSmartPointer transformFilter = vtkSmartPointer::New(); transformFilter->SetInputData(fib->GetFiberPolyData()); transformFilter->SetTransform(geometry->GetVtkTransform()); transformFilter->Update(); mitk::FiberBundle::Pointer transformed_fib = mitk::FiberBundle::New(transformFilter->GetOutput()); return transformed_fib; } /*! \brief */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Extract Overlapping Tracts"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output folder", us::Any(), false); parser.addArgument("reference_mask_folder", "m", mitkCommandLineParser::String, "Reference Mask Folder:", "reference masks of known bundles", us::Any(), false); parser.addArgument("gray_matter_mask", "gm", mitkCommandLineParser::String, "GM mask:", "remove fibers not ending in the gray matter"); parser.addArgument("anchor_fraction", "", mitkCommandLineParser::Float, "Anchor fraction:", "Fraction of tracts used as anchors", 0.5); parser.addArgument("overlap", "", mitkCommandLineParser::Float, "Overlap threshold:", "Overlap threshold used to identify the anchor tracts", 0.8); parser.addArgument("subsample", "", mitkCommandLineParser::Float, "Subsampling factor:", "Only use specified fraction of input fibers for the analysis", 1.0); parser.addArgument("random_seed", "", mitkCommandLineParser::Int, ":", "", -1); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string fibFile = us::any_cast(parsedArgs["input"]); std::string reference_mask_folder = us::any_cast(parsedArgs["reference_mask_folder"]); std::string out_folder = us::any_cast(parsedArgs["out"]); std::string gray_matter_mask = ""; if (parsedArgs.count("gray_matter_mask")) gray_matter_mask = us::any_cast(parsedArgs["gray_matter_mask"]); float anchor_fraction = 0.5; if (parsedArgs.count("anchor_fraction")) anchor_fraction = us::any_cast(parsedArgs["anchor_fraction"]); int random_seed = -1; if (parsedArgs.count("random_seed")) random_seed = us::any_cast(parsedArgs["random_seed"]); float overlap = 0.8; if (parsedArgs.count("overlap")) overlap = us::any_cast(parsedArgs["overlap"]); float subsample = 1.0; if (parsedArgs.count("subsample")) subsample = us::any_cast(parsedArgs["subsample"]); try { CreateFolderStructure(out_folder); std::vector< MaskType > known_tract_masks = get_file_list(reference_mask_folder, anchor_fraction, out_folder + "/skipped_masks/", random_seed); - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(fibFile)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); if (gray_matter_mask.compare("")!=0) { MITK_INFO << "Removing fibers not ending inside of GM"; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect ItkFloatImgType::Pointer gm_image = LoadItkImage(gray_matter_mask); std::cout.rdbuf (old); // <-- restore itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(inputTractogram); extractor->SetRoiImages({gm_image}); extractor->SetBothEnds(true); extractor->SetNoNegatives(true); extractor->SetMode(itk::FiberExtractionFilter::MODE::ENDPOINTS); extractor->Update(); inputTractogram = extractor->GetPositives().at(0); } std::srand(0); if (subsample<1.0) inputTractogram = inputTractogram->SubsampleFibers(subsample); mitk::FiberBundle::Pointer anchor_tractogram = mitk::FiberBundle::New(nullptr); mitk::FiberBundle::Pointer candidate_tractogram = mitk::FiberBundle::New(nullptr); if (!known_tract_masks.empty()) { MITK_INFO << "Find known tracts via overlap match"; std::vector< ItkFloatImgType::Pointer > mask_images; for (auto mask : known_tract_masks) mask_images.push_back(std::get<0>(mask)); std::vector< ItkFloatImgType* > roi_images2; for (auto roi : mask_images) roi_images2.push_back(roi); itk::FiberExtractionFilter::Pointer extractor = itk::FiberExtractionFilter::New(); extractor->SetInputFiberBundle(inputTractogram); extractor->SetRoiImages(roi_images2); extractor->SetOverlapFraction(overlap); extractor->SetMode(itk::FiberExtractionFilter::MODE::OVERLAP); extractor->Update(); std::vector< mitk::FiberBundle::Pointer > positives = extractor->GetPositives(); candidate_tractogram = extractor->GetNegatives().at(0); for ( unsigned int i=0; i(known_tract_masks.at(i)); mitk::IOUtil::Save(positives.at(i), out_folder + "/anchor_tracts/" + mask_name + ".trk"); std::cout.rdbuf (old); // <-- restore } anchor_tractogram = anchor_tractogram->AddBundles(positives); } mitk::IOUtil::Save(anchor_tractogram, out_folder + "/anchor_tracts/anchor_tractogram.trk"); mitk::IOUtil::Save(candidate_tractogram, out_folder + "/candidate_tracts/candidate_tractogram.trk"); mitk::IOUtil::Save(inputTractogram, out_folder + "/filtered_tractogram.trk"); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractSimilarTracts.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractSimilarTracts.cpp index 810fa2fb1c..ff78daa2a9 100644 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractSimilarTracts.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/ExtractSimilarTracts.cpp @@ -1,237 +1,237 @@ /*=================================================================== 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 #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; mitk::FiberBundle::Pointer LoadFib(std::string filename) { std::vector fibInfile = mitk::IOUtil::Load(filename); if( fibInfile.empty() ) std::cout << "File " << filename << " could not be read!"; mitk::BaseData::Pointer baseData = fibInfile.at(0); return dynamic_cast(baseData.GetPointer()); } ItkFloatImgType::Pointer LoadItkImage(const std::string& filename) { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(filename); ItkFloatImgType::Pointer itkMask = ItkFloatImgType::New(); mitk::CastToItkImage(img, itkMask); return itkMask; } /*! \brief Spatially cluster fibers */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Extract Similar Tracts"); parser.setCategory("Fiber Tracking Evaluation"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("", "i", mitkCommandLineParser::InputFile, "Input:", "input fiber bundle (.fib, .trk, .tck)", us::Any(), false); parser.addArgument("ref_tracts", "", mitkCommandLineParser::StringList, "Ref. Tracts:", "reference tracts (.fib, .trk, .tck)", us::Any(), false); parser.addArgument("ref_masks", "", mitkCommandLineParser::StringList, "Ref. Masks:", "reference bundle masks", us::Any()); parser.addArgument("", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("distance", "", mitkCommandLineParser::Int, "Distance:", "", 10); parser.addArgument("metric", "", mitkCommandLineParser::String, "Metric:", ""); parser.addArgument("subsample", "", mitkCommandLineParser::Float, "Subsampling factor:", "Only use specified fraction of input fibers", 1.0); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string in_fib = us::any_cast(parsedArgs["i"]); std::string out_root = us::any_cast(parsedArgs["o"]); mitkCommandLineParser::StringContainerType ref_bundle_files = us::any_cast(parsedArgs["ref_tracts"]); mitkCommandLineParser::StringContainerType ref_mask_files; if (parsedArgs.count("ref_masks")) ref_mask_files = us::any_cast(parsedArgs["ref_masks"]); if (ref_mask_files.size()>0 && ref_mask_files.size()!=ref_bundle_files.size()) { MITK_INFO << "If reference masks are used, there has to be one mask per reference tract."; return EXIT_FAILURE; } int distance = 10; if (parsedArgs.count("distance")) distance = us::any_cast(parsedArgs["distance"]); std::string metric = "EU_MEAN"; if (parsedArgs.count("metric")) metric = us::any_cast(parsedArgs["metric"]); float subsample = 1.0; if (parsedArgs.count("subsample")) subsample = us::any_cast(parsedArgs["subsample"]); try { mitk::FiberBundle::Pointer fib = LoadFib(in_fib); std::srand(0); if (subsample<1.0) fib = fib->SubsampleFibers(subsample); mitk::FiberBundle::Pointer resampled_fib = fib->GetDeepCopy(); resampled_fib->ResampleToNumPoints(12); std::vector< mitk::FiberBundle::Pointer > ref_fibs; std::vector< ItkFloatImgType::Pointer > ref_masks; for (std::size_t i=0; i distances; distances.push_back(distance); mitk::FiberBundle::Pointer anchor_tractogram = mitk::FiberBundle::New(nullptr); unsigned int c = 0; for (auto ref_fib : ref_fibs) { MITK_INFO << "Extracting " << ist::GetFilenameName(ref_bundle_files.at(c)); std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect try { itk::TractClusteringFilter::Pointer segmenter = itk::TractClusteringFilter::New(); // calculate centroids from reference bundle { itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New(); clusterer->SetDistances({10,20,30}); clusterer->SetTractogram(ref_fib); clusterer->SetMetrics({new mitk::ClusteringMetricEuclideanStd()}); clusterer->SetMergeDuplicateThreshold(0.0); clusterer->Update(); std::vector tracts = clusterer->GetOutCentroids(); ref_fib = mitk::FiberBundle::New(nullptr); ref_fib = ref_fib->AddBundles(tracts); mitk::IOUtil::Save(ref_fib, out_root + "centroids_" + ist::GetFilenameName(ref_bundle_files.at(c))); segmenter->SetInCentroids(ref_fib); } // segment tract segmenter->SetFilterMask(ref_masks.at(c)); segmenter->SetOverlapThreshold(0.8); segmenter->SetDistances(distances); segmenter->SetTractogram(resampled_fib); segmenter->SetMergeDuplicateThreshold(0.0); segmenter->SetDoResampling(false); if (metric=="EU_MEAN") segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanMean()}); else if (metric=="EU_STD") segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanStd()}); else if (metric=="EU_MAX") segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanMax()}); segmenter->Update(); std::vector< std::vector< long > > clusters = segmenter->GetOutFiberIndices(); if (clusters.size()>0) { vtkSmartPointer weights = vtkSmartPointer::New(); mitk::FiberBundle::Pointer result = mitk::FiberBundle::New(nullptr); std::vector< mitk::FiberBundle::Pointer > result_fibs; for (unsigned int cluster_index=0; cluster_indexGeneratePolyDataByIds(clusters.at(cluster_index), weights))); result = result->AddBundles(result_fibs); anchor_tractogram = anchor_tractogram->AddBundle(result); mitk::IOUtil::Save(result, out_root + "anchor_" + ist::GetFilenameName(ref_bundle_files.at(c))); fib = mitk::FiberBundle::New(fib->GeneratePolyDataByIds(clusters.back(), weights)); resampled_fib = mitk::FiberBundle::New(resampled_fib->GeneratePolyDataByIds(clusters.back(), weights)); } } catch(itk::ExceptionObject& excpt) { MITK_INFO << "Exception while processing " << ist::GetFilenameName(ref_bundle_files.at(c)); MITK_INFO << excpt.GetDescription(); } catch(std::exception& excpt) { MITK_INFO << "Exception while processing " << ist::GetFilenameName(ref_bundle_files.at(c)); MITK_INFO << excpt.what(); } std::cout.rdbuf (old); // <-- restore if (fib->GetNumFibers()==0) break; ++c; } MITK_INFO << "Streamlines in anchor tractogram: " << anchor_tractogram->GetNumFibers(); mitk::IOUtil::Save(anchor_tractogram, out_root + "anchor_tractogram.trk"); MITK_INFO << "Streamlines remaining in candidate tractogram: " << fib->GetNumFibers(); mitk::IOUtil::Save(fib, out_root + "candidate_tractogram.trk"); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp index e9643af29b..b47893d07e 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/LocalDirectionalFiberPlausibility.cpp @@ -1,315 +1,315 @@ /*=================================================================== 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 #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include /*! \brief Calculate angular error of a tractogram with respect to the input reference directions. */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Local Directional Fiber Plausibility"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription("Calculate angular error of a tractogram with respect to the input reference directions."); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images:", "reference direction images", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::StringList, "Masks:", "mask images"); parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true); parser.addArgument("sthresh", "s", mitkCommandLineParser::Float, "Size threshold:", "Relative peak size threshold per voxel.", 0.0, true); parser.addArgument("maxdirs", "md", mitkCommandLineParser::Int, "Max. Clusters:", "Maximum number of fiber clusters.", 0, true); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results"); parser.addArgument("ignore", "n", mitkCommandLineParser::Bool, "Ignore:", "don't increase error for missing or too many directions"); parser.addArgument("empty", "e", mitkCommandLineParser::Bool, "Empty Voxels:", "don't increase error for empty voxels"); parser.addArgument("fileID", "id", mitkCommandLineParser::String, "ID:", "optional ID field"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); mitkCommandLineParser::StringContainerType maskImages; if (parsedArgs.count("mask")) maskImages = us::any_cast(parsedArgs["mask"]); string fibFile = us::any_cast(parsedArgs["input"]); float angularThreshold = 25; if (parsedArgs.count("athresh")) angularThreshold = us::any_cast(parsedArgs["athresh"]); float sizeThreshold = 0; if (parsedArgs.count("sthresh")) sizeThreshold = us::any_cast(parsedArgs["sthresh"]); int maxDirs = 0; if (parsedArgs.count("maxdirs")) maxDirs = us::any_cast(parsedArgs["maxdirs"]); string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool ignoreMissing = false; if (parsedArgs.count("ignore")) ignoreMissing = us::any_cast(parsedArgs["ignore"]); bool ignoreEmpty = false; if (parsedArgs.count("empty")) ignoreEmpty = us::any_cast(parsedArgs["empty"]); string fileID = ""; if (parsedArgs.count("fileID")) fileID = us::any_cast(parsedArgs["fileID"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType; // load fiber bundle mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::LoadData(fibFile)[0].GetPointer()); // load reference directions ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::Load(referenceImages.at(i))[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(referenceImages.at(i)); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg); } catch(...){ std::cout << "could not load: " << referenceImages.at(i); } } ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0); itkMaskImage->SetSpacing( dirImg->GetSpacing() ); itkMaskImage->SetOrigin( dirImg->GetOrigin() ); itkMaskImage->SetDirection( dirImg->GetDirection() ); itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->Allocate(); itkMaskImage->FillBuffer(1); // extract directions from fiber bundle itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetMaskImage(itkMaskImage); fOdfFilter->SetAngularThreshold(cos(angularThreshold*itk::Math::pi/180)); fOdfFilter->SetNormalizeVectors(true); fOdfFilter->SetUseWorkingCopy(false); fOdfFilter->SetSizeThreshold(sizeThreshold); fOdfFilter->SetMaxNumDirections(maxDirs); fOdfFilter->Update(); if (verbose) { // write vector field mitk::FiberBundle::Pointer directions = fOdfFilter->GetOutputFiberBundle(); string outfilename = outRoot; outfilename.append("_VECTOR_FIELD.fib"); mitk::IOUtil::Save(directions.GetPointer(), outfilename ); // write direction images { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = fOdfFilter->GetDirectionImage(); typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter::ItkDirectionImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_DIRECTIONS.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(itkImg); writer->Update(); } // write num direction image { ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage(); typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_NUM_DIRECTIONS.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(numDirImage); writer->Update(); } } string logFile = outRoot; logFile.append("_ANGULAR_ERROR.csv"); ofstream file; file.open (logFile.c_str()); if (maskImages.size()>0) { for (unsigned int i=0; i(mitk::IOUtil::Load(maskImages.at(i))[0].GetPointer()); + mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::Load(maskImages.at(i)); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); //evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignoreMissing); evaluationFilter->SetIgnoreEmptyVoxels(ignoreEmpty); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string maskFileName = itksys::SystemTools::GetFilenameWithoutExtension(maskImages.at(i)); unsigned found = maskFileName.find_last_of("_"); string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile); if (!fileID.empty()) sens = fileID; sens.append(","); sens.append(maskFileName.substr(found+1)); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; } } else { // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); //evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignoreMissing); evaluationFilter->SetIgnoreEmptyVoxels(ignoreEmpty); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile); if (!fileID.empty()) sens = fileID; sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; } file.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/MergeOverlappingTracts.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/MergeOverlappingTracts.cpp index 2dcd23c2b8..56df393e72 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/MergeOverlappingTracts.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/MergeOverlappingTracts.cpp @@ -1,250 +1,250 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef itksys::SystemTools ist; typedef itk::Image ItkFloatImgType; typedef itk::Image ItkUIntImgType; std::vector< std::string > get_file_list(const std::string& path, std::vector< std::string > extensions={".fib", ".trk"}) { std::vector< std::string > file_list; itk::Directory::Pointer dir = itk::Directory::New(); if (dir->Load(path.c_str())) { int n = dir->GetNumberOfFiles(); for (int r = 0; r < n; r++) { const char *filename = dir->GetFile(r); std::string ext = ist::GetFilenameExtension(filename); for (auto e : extensions) { if (ext==e) { file_list.push_back(path + '/' + filename); break; } } } } return file_list; } /*! \brief */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Merge Overlapping Tracts"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input Folder:", "input folder", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output Folder:", "output folder", us::Any(), false); parser.addArgument("overlap", "", mitkCommandLineParser::Float, "Overlap threshold:", "Tracts with overlap larger than this threshold are merged", 0.8, false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string input_folder = us::any_cast(parsedArgs["in"]); std::string out_folder = us::any_cast(parsedArgs["out"]); float overlap = 0.8; if (parsedArgs.count("overlap")) overlap = us::any_cast(parsedArgs["overlap"]); try { if (!ist::PathExists(out_folder)) ist::MakeDirectory(out_folder); std::vector< std::string > fib_files = get_file_list(input_folder, {".fib", ".trk", ".tck"}); if (fib_files.empty()) return EXIT_FAILURE; std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect std::vector< mitk::FiberBundle::Pointer > fibs; for (std::string f : fib_files) { - mitk::FiberBundle::Pointer fib = dynamic_cast(mitk::IOUtil::Load(f)[0].GetPointer()); + mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load(f); fibs.push_back(fib); } mitk::FiberBundle::Pointer combined = mitk::FiberBundle::New(); combined = combined->AddBundles(fibs); itk::TractsToFiberEndingsImageFilter< ItkFloatImgType >::Pointer endings = itk::TractsToFiberEndingsImageFilter< ItkFloatImgType >::New(); endings->SetFiberBundle(combined); endings->SetUpsamplingFactor(0.25); endings->Update(); ItkFloatImgType::Pointer ref_image = endings->GetOutput(); std::cout.rdbuf (old); // <-- restore for (int its = 0; its<3; its++) { std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect std::vector< ItkFloatImgType::Pointer > mask_images; for (auto fib : fibs) { itk::TractDensityImageFilter< ItkFloatImgType >::Pointer masks = itk::TractDensityImageFilter< ItkFloatImgType >::New(); masks->SetInputImage(ref_image); masks->SetBinaryOutput(true); masks->SetFiberBundle(fib); masks->SetUseImageGeometry(true); masks->Update(); mask_images.push_back(masks->GetOutput()); } int r=0; vnl_matrix< int > mat; mat.set_size(mask_images.size(), mask_images.size()); mat.fill(0); for (auto m1 : mask_images) { float max_overlap = overlap; int c = 0; for (auto m2 : mask_images) { if (c<=r) { ++c; continue; } itk::ImageRegionConstIterator it1(m1, m1->GetLargestPossibleRegion()); itk::ImageRegionConstIterator it2(m2, m2->GetLargestPossibleRegion()); unsigned int c1 = 0; unsigned int c2 = 0; unsigned int intersect = 0; while( !it1.IsAtEnd() ) { if( it1.Get()>0 && it2.Get()>0) ++intersect; if(it1.Get()>0) ++c1; if(it2.Get()>0) ++c2; ++it1; ++it2; } if ( (float)intersect/c1>max_overlap ) { max_overlap = (float)intersect/c1; mat.put(r,c, 1); } if ( (float)intersect/c2>max_overlap ) { max_overlap = (float)intersect/c2; mat.put(r,c, 1); } ++c; } ++r; } std::vector< mitk::FiberBundle::Pointer > out_fibs; std::vector< bool > used; for (unsigned int i=0; i0) { fib = fib->AddBundle(fibs.at(c)); MITK_INFO << c; used[c] = true; } } out_fibs.push_back(fib); } std::cout.rdbuf (old); // <-- restore MITK_INFO << fibs.size() << " --> " << out_fibs.size(); if (fibs.size()==out_fibs.size()) break; fibs = out_fibs; } int c = 0; for (auto fib : fibs) { std::streambuf *old = cout.rdbuf(); // <-- save std::stringstream ss; std::cout.rdbuf (ss.rdbuf()); // <-- redirect mitk::IOUtil::Save(fib, out_folder + "/bundle_" + boost::lexical_cast(c) + ".trk"); std::cout.rdbuf (old); // <-- restore ++c; } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp index 6ddf817ab4..3c6d23ce7a 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/PeaksAngularError.cpp @@ -1,207 +1,207 @@ /*=================================================================== 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 #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Calculate angular error between two sets of directions stored in multiple 3D vector images where each pixel corresponds to a vector (itk::Image< itk::Vector< float, 3>, 3 >) */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("test", "t", mitkCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false); parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false); parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image"); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose", "output optional and intermediate calculation results"); parser.addArgument("ignore", "i", mitkCommandLineParser::Bool, "Ignore", "don't increase error for missing or too many directions"); parser.setCategory("Fiber Tracking Evaluation"); parser.setTitle("Peaks Angular Error"); parser.setDescription("Calculate angular error between two sets of directions stored in multiple 3D vector images where each pixel corresponds to a vector (itk::Image< itk::Vector< float, 3>, 3 >)"); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType testImages = us::any_cast(parsedArgs["test"]); mitkCommandLineParser::StringContainerType referenceImages = us::any_cast(parsedArgs["reference"]); std::string maskImage(""); if (parsedArgs.count("mask")) maskImage = us::any_cast(parsedArgs["mask"]); std::string outRoot = us::any_cast(parsedArgs["out"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); bool ignore = false; if (parsedArgs.count("ignore")) ignore = us::any_cast(parsedArgs["ignore"]); try { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType; ItkDirectionImageContainerType::Pointer directionImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::Load(testImages.at(i))[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(testImages.at(i)); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); directionImageContainer->InsertElement(directionImageContainer->Size(),itkImg); } catch(...){ std::cout << "could not load: " << referenceImages.at(i); } } // load reference directions ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New(); for (unsigned int i=0; i(mitk::IOUtil::Load(referenceImages.at(i))[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(referenceImages.at(i)); typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput(); referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg); } catch(...){ std::cout << "could not load: " << referenceImages.at(i); } } // load/create mask image ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); if (maskImage.compare("")==0) { ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0); itkMaskImage->SetSpacing( dirImg->GetSpacing() ); itkMaskImage->SetOrigin( dirImg->GetOrigin() ); itkMaskImage->SetDirection( dirImg->GetDirection() ); itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() ); itkMaskImage->Allocate(); itkMaskImage->FillBuffer(1); } else { - mitk::Image::Pointer mitkMaskImage = dynamic_cast(mitk::IOUtil::Load(maskImage)[0].GetPointer()); + mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::Load(maskImage); mitk::CastToItkImage(mitkMaskImage, itkMaskImage); } // evaluate directions EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New(); evaluationFilter->SetImageSet(directionImageContainer); evaluationFilter->SetReferenceImageSet(referenceImageContainer); evaluationFilter->SetMaskImage(itkMaskImage); evaluationFilter->SetIgnoreMissingDirections(ignore); evaluationFilter->Update(); if (verbose) { EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0); typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); std::string outfilename = outRoot; outfilename.append("_ERROR_IMAGE.nrrd"); writer->SetFileName(outfilename.c_str()); writer->SetInput(angularErrorImage); writer->Update(); } std::string logFile = outRoot; logFile.append("_ANGULAR_ERROR.csv"); ofstream file; file.open (logFile.c_str()); std::string sens = "Mean:"; sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMeanAngularError())); sens.append(";\n"); sens.append("Median:"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMedianAngularError())); sens.append(";\n"); sens.append("Maximum:"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMaxAngularError())); sens.append(";\n"); sens.append("Minimum:"); sens.append(","); sens.append(boost::lexical_cast(evaluationFilter->GetMinAngularError())); sens.append(";\n"); sens.append("STDEV:"); sens.append(","); sens.append(boost::lexical_cast(std::sqrt(evaluationFilter->GetVarAngularError()))); sens.append(";\n"); file << sens; file.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp index 864e58a084..d64eeb5420 100755 --- a/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp +++ b/Modules/DiffusionImaging/FiberTracking/cmdapps/TractographyEvaluation/TractometerMetrics.cpp @@ -1,415 +1,415 @@ /*=================================================================== 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 #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include /*! \brief Calculates the Tractometer evaluation metrics for tractograms (http://www.tractometer.org/) */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Tractometer Metrics"); parser.setCategory("Fiber Tracking Evaluation"); parser.setDescription("Calculates the Tractometer evaluation metrics for tractograms (http://www.tractometer.org/)"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false); parser.addArgument("labels", "l", mitkCommandLineParser::StringList, "Label pairs:", "label pairs", false); parser.addArgument("labelimage", "li", mitkCommandLineParser::String, "Label image:", "label image", false); parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output valid, invalid and no connections as fiber bundles"); parser.addArgument("fileID", "id", mitkCommandLineParser::String, "ID:", "optional ID field"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; mitkCommandLineParser::StringContainerType labelpairs = us::any_cast(parsedArgs["labels"]); std::string fibFile = us::any_cast(parsedArgs["input"]); std::string labelImageFile = us::any_cast(parsedArgs["labelimage"]); std::string outRoot = us::any_cast(parsedArgs["out"]); std::string fileID = ""; if (parsedArgs.count("fileID")) fileID = us::any_cast(parsedArgs["fileID"]); bool verbose = false; if (parsedArgs.count("verbose")) verbose = us::any_cast(parsedArgs["verbose"]); try { typedef itk::Image ItkShortImgType; typedef itk::Image ItkUcharImgType; // load fiber bundle - mitk::FiberBundle::Pointer inputTractogram = dynamic_cast(mitk::IOUtil::Load(fibFile)[0].GetPointer()); + mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load(fibFile); - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(labelImageFile)[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(labelImageFile); typedef mitk::ImageToItk< ItkShortImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkShortImgType::Pointer labelImage = caster->GetOutput(); std::string path = itksys::SystemTools::GetFilenamePath(labelImageFile); std::vector< bool > detected; std::vector< std::pair< int, int > > labelsvector; std::vector< ItkUcharImgType::Pointer > bundleMasks; std::vector< ItkUcharImgType::Pointer > bundleMasksCoverage; short max = 0; for (unsigned int i=0; i l; l.first = boost::lexical_cast(labelpairs.at(i)); l.second = boost::lexical_cast(labelpairs.at(i+1)); std::cout << labelpairs.at(i); std::cout << labelpairs.at(i+1); if (l.first>max) max=l.first; if (l.second>max) max=l.second; labelsvector.push_back(l); detected.push_back(false); { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(path+"/Bundle"+boost::lexical_cast(labelsvector.size())+"_MASK.nrrd")[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(path+"/Bundle"+boost::lexical_cast(labelsvector.size())+"_MASK.nrrd"); typedef mitk::ImageToItk< ItkUcharImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkUcharImgType::Pointer bundle = caster->GetOutput(); bundleMasks.push_back(bundle); } { - mitk::Image::Pointer img = dynamic_cast(mitk::IOUtil::Load(path+"/Bundle"+boost::lexical_cast(labelsvector.size())+"_MASK_COVERAGE.nrrd")[0].GetPointer()); + mitk::Image::Pointer img = mitk::IOUtil::Load(path+"/Bundle"+boost::lexical_cast(labelsvector.size())+"_MASK_COVERAGE.nrrd"); typedef mitk::ImageToItk< ItkUcharImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(img); caster->Update(); ItkUcharImgType::Pointer bundle = caster->GetOutput(); bundleMasksCoverage.push_back(bundle); } } vnl_matrix< unsigned char > matrix; matrix.set_size(max, max); matrix.fill(0); vtkSmartPointer polyData = inputTractogram->GetFiberPolyData(); int validConnections = 0; int noConnection = 0; int validBundles = 0; int invalidBundles = 0; int invalidConnections = 0; ItkUcharImgType::Pointer coverage = ItkUcharImgType::New(); coverage->SetSpacing(labelImage->GetSpacing()); coverage->SetOrigin(labelImage->GetOrigin()); coverage->SetDirection(labelImage->GetDirection()); coverage->SetLargestPossibleRegion(labelImage->GetLargestPossibleRegion()); coverage->SetBufferedRegion( labelImage->GetLargestPossibleRegion() ); coverage->SetRequestedRegion( labelImage->GetLargestPossibleRegion() ); coverage->Allocate(); coverage->FillBuffer(0); vtkSmartPointer noConnPoints = vtkSmartPointer::New(); vtkSmartPointer noConnCells = vtkSmartPointer::New(); vtkSmartPointer invalidPoints = vtkSmartPointer::New(); vtkSmartPointer invalidCells = vtkSmartPointer::New(); vtkSmartPointer validPoints = vtkSmartPointer::New(); vtkSmartPointer validCells = vtkSmartPointer::New(); boost::progress_display disp(inputTractogram->GetNumFibers()); for (int i=0; iGetNumFibers(); i++) { ++disp; vtkCell* cell = polyData->GetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (numPoints>1) { double* start = points->GetPoint(0); itk::Point itkStart; itkStart[0] = start[0]; itkStart[1] = start[1]; itkStart[2] = start[2]; itk::Index<3> idxStart; labelImage->TransformPhysicalPointToIndex(itkStart, idxStart); double* end = points->GetPoint(numPoints-1); itk::Point itkEnd; itkEnd[0] = end[0]; itkEnd[1] = end[1]; itkEnd[2] = end[2]; itk::Index<3> idxEnd; labelImage->TransformPhysicalPointToIndex(itkEnd, idxEnd); if ( labelImage->GetPixel(idxStart)==0 || labelImage->GetPixel(idxEnd)==0 ) { noConnection++; if (verbose) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = noConnPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } noConnCells->InsertNextCell(container); } } else { bool invalid = true; for (unsigned int i=0; i l = labelsvector.at(i); if ( (labelImage->GetPixel(idxStart)==l.first && labelImage->GetPixel(idxEnd)==l.second) || (labelImage->GetPixel(idxStart)==l.second && labelImage->GetPixel(idxEnd)==l.first) ) { for (int j=0; jGetPoint(j); itk::Point itkP; itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2]; itk::Index<3> idx; bundle->TransformPhysicalPointToIndex(itkP, idx); if ( bundle->GetPixel(idx) == 0 && bundle->GetLargestPossibleRegion().IsInside(idx) ) { outside=true; } } if (!outside) { validConnections++; if (detected.at(i)==false) validBundles++; detected.at(i) = true; invalid = false; vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = validPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); itk::Point itkP; itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2]; itk::Index<3> idx; coverage->TransformPhysicalPointToIndex(itkP, idx); if ( coverage->GetLargestPossibleRegion().IsInside(idx) ) coverage->SetPixel(idx, 1); } validCells->InsertNextCell(container); } break; } } if (invalid==true) { invalidConnections++; int x = labelImage->GetPixel(idxStart)-1; int y = labelImage->GetPixel(idxEnd)-1; if (x>=0 && y>0 && x(matrix.cols()) && y(matrix.rows()) && (matrix[x][y]==0 || matrix[y][x]==0) ) { invalidBundles++; matrix[x][y]=1; matrix[y][x]=1; } if (verbose) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = invalidPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } invalidCells->InsertNextCell(container); } } } } } if (verbose) { vtkSmartPointer noConnPolyData = vtkSmartPointer::New(); noConnPolyData->SetPoints(noConnPoints); noConnPolyData->SetLines(noConnCells); mitk::FiberBundle::Pointer noConnFib = mitk::FiberBundle::New(noConnPolyData); std::string ncfilename = outRoot; ncfilename.append("_NC.fib"); mitk::IOUtil::Save(noConnFib.GetPointer(), ncfilename ); vtkSmartPointer invalidPolyData = vtkSmartPointer::New(); invalidPolyData->SetPoints(invalidPoints); invalidPolyData->SetLines(invalidCells); mitk::FiberBundle::Pointer invalidFib = mitk::FiberBundle::New(invalidPolyData); std::string icfilename = outRoot; icfilename.append("_IC.fib"); mitk::IOUtil::Save(invalidFib.GetPointer(), icfilename ); vtkSmartPointer validPolyData = vtkSmartPointer::New(); validPolyData->SetPoints(validPoints); validPolyData->SetLines(validCells); mitk::FiberBundle::Pointer validFib = mitk::FiberBundle::New(validPolyData); std::string vcfilename = outRoot; vcfilename.append("_VC.fib"); mitk::IOUtil::Save(validFib.GetPointer(), vcfilename ); { typedef itk::ImageFileWriter< ItkUcharImgType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outRoot+"_ABC.nrrd"); writer->SetInput(coverage); writer->Update(); } } // calculate coverage int wmVoxels = 0; int coveredVoxels = 0; itk::ImageRegionIterator it (coverage, coverage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { bool wm = false; for (unsigned int i=0; iGetPixel(it.GetIndex())>0) { wm = true; wmVoxels++; break; } } if (wm && it.Get()>0) coveredVoxels++; ++it; } int numFibers = inputTractogram->GetNumFibers(); double nc = (double)noConnection/numFibers; double vc = (double)validConnections/numFibers; double ic = (double)invalidConnections/numFibers; if (numFibers==0) { nc = 0.0; vc = 0.0; ic = 0.0; } int vb = validBundles; int ib = invalidBundles; double abc = (double)coveredVoxels/wmVoxels; std::cout << "NC: " << nc; std::cout << "VC: " << vc; std::cout << "IC: " << ic; std::cout << "VB: " << vb; std::cout << "IB: " << ib; std::cout << "ABC: " << abc; std::string logFile = outRoot; logFile.append("_TRACTOMETER.csv"); ofstream file; file.open (logFile.c_str()); { std::string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile); if (!fileID.empty()) sens = fileID; sens.append(","); sens.append(boost::lexical_cast(nc)); sens.append(","); sens.append(boost::lexical_cast(vc)); sens.append(","); sens.append(boost::lexical_cast(ic)); sens.append(","); sens.append(boost::lexical_cast(validBundles)); sens.append(","); sens.append(boost::lexical_cast(invalidBundles)); sens.append(","); sens.append(boost::lexical_cast(abc)); sens.append(";\n"); file << sens; } file.close(); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/MiniApps/ExtractAllGradients.cpp b/Modules/DiffusionImaging/MiniApps/ExtractAllGradients.cpp index b878cb2075..848d857171 100644 --- a/Modules/DiffusionImaging/MiniApps/ExtractAllGradients.cpp +++ b/Modules/DiffusionImaging/MiniApps/ExtractAllGradients.cpp @@ -1,86 +1,86 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include using namespace mitk; using namespace std; /*! \brief Copies transformation matrix of one image to another */ int main(int argc, char* argv[]) { typedef itk::VectorImage< short, 3 > ItkDwiType; mitkCommandLineParser parser; parser.setTitle("Extract all gradients"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Extract all gradients from an diffusion image"); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false); //parser.addArgument("extension", "e", mitkCommandLineParser::String, "File Extension:", "Extension of the output file", us::Any(), false); //parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) return EXIT_FAILURE; MITK_INFO << "Extract parameter"; // mandatory arguments /*string inputName = us::any_cast(parsedArgs["in"]); string extensionName = us::any_cast(parsedArgs["extension"]); string ouputName = us::any_cast(parsedArgs["out"]);*/ string in = us::any_cast(parsedArgs["in"]); string inputName = "E:\\Kollektive\\R02-Lebertumore-Diffusion\\01-Extrahierte-Daten\\" + in + "\\" + in + "-DWI.dwi"; string extensionName = ".nrrd"; string ouputName = "E:\\Kollektive\\R02-Lebertumore-Diffusion\\01-Extrahierte-Daten\\" + in + "\\" + in + "-"; MITK_INFO << "Load Image: "; - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(inputName); + mitk::Image::Pointer image = mitk::IOUtil::Load(inputName); //bool isDiffusionImage(mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image)); //if (!isDiffusionImage) //{ // MITK_INFO << "Input file is not of type diffusion image"; // return; //} ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(image, itkVectorImagePointer); unsigned int channel = 0; for (unsigned int channel = 0; channel < itkVectorImagePointer->GetVectorLength(); ++channel) { itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput(itkVectorImagePointer); filter->SetChannelIndex(channel); filter->Update(); mitk::Image::Pointer newImage = mitk::Image::New(); newImage->InitializeByItk(filter->GetOutput()); newImage->SetImportChannel(filter->GetOutput()->GetBufferPointer()); mitk::IOUtil::SaveImage(newImage, ouputName + to_string(channel) + extensionName); } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/Quantification/Testing/mitkTractAnalyzerTest.cpp b/Modules/DiffusionImaging/Quantification/Testing/mitkTractAnalyzerTest.cpp index e4ef88bf3b..e913d84fe9 100644 --- a/Modules/DiffusionImaging/Quantification/Testing/mitkTractAnalyzerTest.cpp +++ b/Modules/DiffusionImaging/Quantification/Testing/mitkTractAnalyzerTest.cpp @@ -1,82 +1,82 @@ /*=================================================================== 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 #include /**Documentation * test for the class "mitkTractAnalyzer". */ int mitkTractAnalyzerTest(int, char* argv[]) { MITK_TEST_BEGIN("TractAnalyzer"); // Load image typedef itk::Image FloatImageType; typedef itk::ImageFileReader ImageReaderType; ImageReaderType::Pointer reader = ImageReaderType::New(); reader->SetFileName(argv[1]); reader->Update(); FloatImageType::Pointer itkImage = reader->GetOutput(); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitk::CastToMitkImage(itkImage, mitkImage); // load point set - mitk::PointSet::Pointer pointSet = dynamic_cast(mitk::IOUtil::Load(argv[2])[0].GetPointer()); + mitk::PointSet::Pointer pointSet = mitk::IOUtil::Load(argv[2]); mitk::TractAnalyzer analyzer; analyzer.SetInputImage(mitkImage); analyzer.SetThreshold(0.2); analyzer.SetPointSet(pointSet); analyzer.MakeRoi(); mitk::TbssRoiImage::Pointer tbssRoi = analyzer.GetRoiImage(); std::vector< itk::Index<3> > roi = tbssRoi->GetRoi(); // Output roi for debug purposes std::cout << "ROI\n"; for(unsigned int t=0; t ix = roi.at(t); std::cout << ix[0] << ", " << ix[1] << ", " << ix[2] << "\n"; } std::cout << std::endl; // check the cost of the roi double cost = analyzer.GetCostSum(); std::cout << "Cost: " << cost << std::endl; bool equal = mitk::Equal(cost, 5162.854, 0.001); MITK_TEST_CONDITION(equal, "Checking cost of found ROI"); MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp index c24bae762b..c4a3104452 100644 --- a/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/DiffusionKurtosisFit.cpp @@ -1,254 +1,254 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include #include #include #include #include "mitkImage.h" #include #include #include #include "mitkIOUtil.h" #include #include //vnl_includes #include "vnl/vnl_math.h" #include "vnl/vnl_cost_function.h" #include "vnl/vnl_least_squares_function.h" #include "vnl/algo/vnl_lbfgsb.h" #include "vnl/algo/vnl_lbfgs.h" #include "vnl/algo/vnl_levenberg_marquardt.h" typedef mitk::DiffusionPropertyHelper DPH; #include #include #include #include #include #include #include DPH::ImageType::Pointer GetBlurredVectorImage( DPH::ImageType::Pointer vectorImage, double sigma) { typedef itk::DiscreteGaussianImageFilter< itk::Image, itk::Image > GaussianFilterType; typedef itk::VectorIndexSelectionCastImageFilter< DPH::ImageType, itk::Image > IndexSelectionType; IndexSelectionType::Pointer indexSelectionFilter = IndexSelectionType::New(); indexSelectionFilter->SetInput( vectorImage ); typedef itk::ComposeImageFilter< itk::Image, DPH::ImageType > ComposeFilterType; ComposeFilterType::Pointer vec_composer = ComposeFilterType::New(); for( unsigned int i=0; iGetVectorLength(); ++i) { GaussianFilterType::Pointer gaussian_filter = GaussianFilterType::New(); indexSelectionFilter->SetIndex( i ); gaussian_filter->SetInput( indexSelectionFilter->GetOutput() ); gaussian_filter->SetVariance( sigma ); vec_composer->SetInput(i, gaussian_filter->GetOutput() ); gaussian_filter->Update(); } try { vec_composer->Update(); } catch(const itk::ExceptionObject &e) { mitkThrow() << "[VectorImage.GaussianSmoothing] !! Failed with ITK Exception: " << e.what(); } DPH::ImageType::Pointer smoothed_vector = vec_composer->GetOutput(); /* itk::ImageFileWriter< DPH::ImageType >::Pointer writer = itk::ImageFileWriter< DPH::ImageType >::New(); writer->SetInput( smoothed_vector ); writer->SetFileName( "/tmp/itk_smoothed_vector.nrrd"); writer->Update();*/ return smoothed_vector; } void KurtosisMapComputation( mitk::Image::Pointer input, std::string output_prefix , std::string output_type, std::string maskPath, bool omitBZero, double lower, double upper ) { DPH::ImageType::Pointer vectorImage = DPH::ImageType::New(); mitk::CastToItkImage( input, vectorImage ); typedef itk::DiffusionKurtosisReconstructionImageFilter< short, double > KurtosisFilterType; KurtosisFilterType::Pointer kurtosis_filter = KurtosisFilterType::New(); kurtosis_filter->SetInput( GetBlurredVectorImage( vectorImage, 1.5 ) ); kurtosis_filter->SetReferenceBValue( DPH::GetReferenceBValue( input.GetPointer() ) ); kurtosis_filter->SetGradientDirections( DPH::GetGradientContainer( input.GetPointer() ) ); // kurtosis_filter->SetNumberOfThreads(1); kurtosis_filter->SetOmitUnweightedValue(omitBZero); kurtosis_filter->SetBoundariesForKurtosis(-lower,upper); // kurtosis_filter->SetInitialSolution(const vnl_vector& x0 ); if(maskPath != "") { mitk::Image::Pointer segmentation; - segmentation = dynamic_cast(mitk::IOUtil::Load(maskPath)[0].GetPointer()); + segmentation = mitk::IOUtil::Load(maskPath); typedef itk::Image< short , 3> MaskImageType; MaskImageType::Pointer vectorSeg = MaskImageType::New() ; mitk::CastToItkImage( segmentation, vectorSeg ); kurtosis_filter->SetImageMask(vectorSeg) ; } try { kurtosis_filter->Update(); } catch( const itk::ExceptionObject& e) { mitkThrow() << "Kurtosis fit failed with an ITK Exception: " << e.what(); } mitk::Image::Pointer d_image = mitk::Image::New(); d_image->InitializeByItk( kurtosis_filter->GetOutput(0) ); d_image->SetVolume( kurtosis_filter->GetOutput(0)->GetBufferPointer() ); mitk::Image::Pointer k_image = mitk::Image::New(); k_image->InitializeByItk( kurtosis_filter->GetOutput(1) ); k_image->SetVolume( kurtosis_filter->GetOutput(1)->GetBufferPointer() ); std::string outputD_FileName = output_prefix + "_ADC_map." + output_type; std::string outputK_FileName = output_prefix + "_AKC_map." + output_type; try { mitk::IOUtil::Save( d_image, outputD_FileName ); mitk::IOUtil::Save( k_image, outputK_FileName ); } catch( const itk::ExceptionObject& e) { mitkThrow() << "Failed to save the KurtosisFit Results due to exception: " << e.what(); } } int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setTitle("Diffusion Kurtosis Fit"); parser.setCategory("Diffusion Related Measures"); parser.setContributor("MIC"); parser.setDescription("Fitting Kurtosis"); parser.setArgumentPrefix("--","-"); // mandatory arguments parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input: ", "input image (DWI)", us::Any(), false); parser.addArgument("output", "o", mitkCommandLineParser::String, "Output Preifx: ", "Prefix for the output images, will append _f, _K, _D accordingly ", us::Any(), false); parser.addArgument("output_type", "ot", mitkCommandLineParser::String, "Output Type: ", "choose data type of output image, e.g. '.nii' or '.nrrd' ", us::Any(), false); // optional arguments parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Masking Image: ", "ROI (segmentation)", us::Any()); parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help", "Show this help text"); parser.addArgument("omitbzero", "om", mitkCommandLineParser::Bool, "Omit b0:", "Omit b0 value during fit (default = false)", us::Any()); parser.addArgument("lowerkbound", "kl", mitkCommandLineParser::Float, "lower Kbound:", "Set (unsigned) lower boundary for Kurtosis parameter (default = -1000)", us::Any()); parser.addArgument("upperkbound", "ku", mitkCommandLineParser::Float, "upper Kbound:", "Set upper boundary for Kurtosis parameter (default = 1000)", us::Any()); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")){ std::cout << parser.helpText(); return EXIT_SUCCESS; } // mandatory arguments std::string inFileName = us::any_cast(parsedArgs["input"]); std::string out_prefix = us::any_cast(parsedArgs["output"]); std::string maskPath = ""; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inFileName, &functor); + mitk::Image::Pointer inputImage = mitk::IOUtil::Load(inFileName, &functor); bool omitBZero = false; double lower = -1000; double upper = 1000; std::string out_type = "nrrd"; if (parsedArgs.count("mask") || parsedArgs.count("m")) { maskPath = us::any_cast(parsedArgs["mask"]); } if (parsedArgs.count("output_type") || parsedArgs.count("ot")) { out_type = us::any_cast(parsedArgs["output_type"]); } if (parsedArgs.count("omitbzero") || parsedArgs.count("om")) { omitBZero = us::any_cast(parsedArgs["omitbzero"]); } if (parsedArgs.count("lowerkbound") || parsedArgs.count("kl")) { lower = us::any_cast(parsedArgs["lowerkbound"]); } if (parsedArgs.count("upperkbound") || parsedArgs.count("ku")) { upper = us::any_cast(parsedArgs["upperkbound"]); } if( !DPH::IsDiffusionWeightedImage( inputImage ) ) { MITK_ERROR("DiffusionIVIMFit.Input") << "No valid diffusion-weighted image provided, failed to load " << inFileName << " as DW Image. Aborting..."; return EXIT_FAILURE; } KurtosisMapComputation( inputImage, out_prefix , out_type, maskPath, omitBZero, lower, upper); } diff --git a/Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp index 231410751c..3dc5a4d61b 100644 --- a/Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/MultishellMethods.cpp @@ -1,216 +1,216 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Multishell Methods"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false); parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false); parser.addArgument("adc", "D", mitkCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false); parser.addArgument("akc", "K", mitkCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false); parser.addArgument("biexp", "B", mitkCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false); parser.addArgument("targetbvalue", "b", mitkCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string inName = us::any_cast(parsedArgs["in"]); std::string outName = us::any_cast(parsedArgs["out"]); bool applyADC = us::any_cast(parsedArgs["adc"]); bool applyAKC = us::any_cast(parsedArgs["akc"]); bool applyBiExp = us::any_cast(parsedArgs["biexp"]); std::string targetType = us::any_cast(parsedArgs["targetbvalue"]); try { std::cout << "Loading " << inName; mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); - mitk::Image::Pointer dwi = mitk::IOUtil::LoadImage(inName, &functor); + mitk::Image::Pointer dwi = mitk::IOUtil::Load(inName, &functor); if ( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dwi ) ) { typedef itk::RadialMultishellToSingleshellImageFilter FilterType; typedef itk::DwiGradientLengthCorrectionFilter CorrectionFilterType; CorrectionFilterType::Pointer roundfilter = CorrectionFilterType::New(); roundfilter->SetRoundingValue( 1000 ); roundfilter->SetReferenceBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi )); roundfilter->SetReferenceGradientDirectionContainer(mitk::DiffusionPropertyHelper::GetGradientContainer(dwi)); roundfilter->Update(); dwi->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( roundfilter->GetNewBValue() ) ); dwi->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( roundfilter->GetOutputGradientDirectionContainer() ) ); // filter input parameter const mitk::DiffusionPropertyHelper::BValueMapType &originalShellMap = mitk::DiffusionPropertyHelper::GetBValueMap(dwi); mitk::DiffusionPropertyHelper::ImageType::Pointer vectorImage = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, vectorImage); const mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainer = mitk::DiffusionPropertyHelper::GetGradientContainer(dwi); const unsigned int &bValue = mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi ); // filter call vnl_vector bValueList(originalShellMap.size()-1); double targetBValue = bValueList.mean(); mitk::DiffusionPropertyHelper::BValueMapType::const_iterator it = originalShellMap.begin(); ++it; int i = 0 ; for(; it != originalShellMap.end(); ++it) bValueList.put(i++,it->first); if( targetType == "mean" ) targetBValue = bValueList.mean(); else if( targetType == "min" ) targetBValue = bValueList.min_value(); else if( targetType == "max" ) targetBValue = bValueList.max_value(); if(applyADC) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( targetBValue ) ); outImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, (outName + "_ADC.dwi").c_str()); } if(applyAKC) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( targetBValue ) ); outImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, (std::string(outName) + "_AKC.dwi").c_str()); } if(applyBiExp) { FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( targetBValue ) ); outImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); mitk::IOUtil::Save(outImage, (std::string(outName) + "_BiExp.dwi").c_str()); } } } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp index 26c3538bc4..0a8b7dc7ac 100644 --- a/Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/TensorDerivedMapsExtraction.cpp @@ -1,179 +1,179 @@ /*=================================================================== 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 "mitkImage.h" #include #include "mitkITKImageImport.h" #include #include #include #include #include #include "itkTensorDerivedMeasurementsFilter.h" #include "itkDiffusionTensor3DReconstructionImageFilter.h" #include "mitkCommandLineParser.h" #include #include #include typedef short DiffusionPixelType; typedef double TTensorPixelType; static void ExtractMapsAndSave(mitk::TensorImage::Pointer tensorImage, std::string filename, std::string postfix = "") { mitk::Image* image = dynamic_cast (tensorImage.GetPointer()); typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; TensorImageType::Pointer itkvol = TensorImageType::New(); mitk::CastToItkImage(image, itkvol); typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); mitk::Image::Pointer map = mitk::Image::New(); // FA measurementsCalculator->SetMeasure(MeasurementsType::FA); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_FA" + postfix + ".nrrd"); // MD measurementsCalculator->SetMeasure(MeasurementsType::MD); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_MD" + postfix + ".nrrd"); // AD measurementsCalculator->SetMeasure(MeasurementsType::AD); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_AD" + postfix + ".nrrd"); // CA measurementsCalculator->SetMeasure(MeasurementsType::CA); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_CA" + postfix + ".nrrd"); // RA measurementsCalculator->SetMeasure(MeasurementsType::RA); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_RA" + postfix + ".nrrd"); // RD measurementsCalculator->SetMeasure(MeasurementsType::RD); measurementsCalculator->Update(); map->InitializeByItk( measurementsCalculator->GetOutput() ); map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() ); mitk::IOUtil::Save(map, filename + "_RD" + postfix + ".nrrd"); } int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("help", "h", mitkCommandLineParser::String, "Help", "Show this help text"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input dwi file", us::Any(),false); parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output folder", "output folder and base name, e.g. /tmp/outPatient1 ", us::Any(),false); parser.setTitle("Tensor Derived Maps Extraction"); parser.setCategory("Diffusion Related Measures"); parser.setDescription(""); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string inputFile = us::any_cast(parsedArgs["input"]); std::string baseFileName = us::any_cast(parsedArgs["out"]); std::string dtiFileName = "_dti.dti"; - mitk::Image::Pointer diffusionImage = dynamic_cast(mitk::IOUtil::Load(inputFile)[0].GetPointer()); + mitk::Image::Pointer diffusionImage = mitk::IOUtil::Load(inputFile); if (diffusionImage.IsNull() || !mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(diffusionImage)) // does nullptr pointer check make sense after static cast ? { MITK_ERROR << "Invalid Input Image. Must be DWI. Aborting."; return -1; } typedef itk::DiffusionTensor3DReconstructionImageFilter< DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New(); mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainerCopy = mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::New(); for( mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::ConstIterator it = mitk::DiffusionPropertyHelper::GetGradientContainer(diffusionImage)->Begin(); it != mitk::DiffusionPropertyHelper::GetGradientContainer(diffusionImage)->End(); it++) { gradientContainerCopy->push_back(it.Value()); } mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(diffusionImage, itkVectorImagePointer); tensorReconstructionFilter->SetGradientImage( gradientContainerCopy, itkVectorImagePointer ); tensorReconstructionFilter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue( diffusionImage ) ); tensorReconstructionFilter->SetThreshold(50); tensorReconstructionFilter->Update(); typedef itk::Image, 3> TensorImageType; TensorImageType::Pointer tensorImage = tensorReconstructionFilter->GetOutput(); tensorImage->SetDirection( itkVectorImagePointer->GetDirection() ); mitk::TensorImage::Pointer tensorImageMitk = mitk::TensorImage::New(); tensorImageMitk->InitializeByItk(tensorImage.GetPointer()); tensorImageMitk->SetVolume( tensorImage->GetBufferPointer() ); itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< double >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< double >, 3 > >::New(); writer->SetInput(tensorReconstructionFilter->GetOutput()); writer->SetFileName(baseFileName + dtiFileName); writer->SetImageIO(io); writer->UseCompressionOn(); writer->Update(); ExtractMapsAndSave(tensorImageMitk,baseFileName); return EXIT_SUCCESS; } diff --git a/Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp b/Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp index 06f82a4903..95061f6614 100644 --- a/Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp +++ b/Modules/DiffusionImaging/Quantification/cmdapps/TensorReconstruction.cpp @@ -1,99 +1,99 @@ /*=================================================================== 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 #include "mitkBaseData.h" #include #include #include #include #include #include "mitkCommandLineParser.h" #include #include /** * Convert files from one ending to the other */ int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false); parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false); parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true); parser.setCategory("Signal Modelling"); parser.setTitle("Tensor Reconstruction"); parser.setDescription(""); parser.setContributor("MIC"); std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; std::string inFileName = us::any_cast(parsedArgs["input"]); std::string outfilename = us::any_cast(parsedArgs["outFile"]); outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename); outfilename += ".dti"; int threshold = 0; if (parsedArgs.count("b0Threshold")) threshold = us::any_cast(parsedArgs["b0Threshold"]); try { - mitk::Image::Pointer dwi = dynamic_cast(mitk::IOUtil::Load(inFileName)[0].GetPointer()); + mitk::Image::Pointer dwi = mitk::IOUtil::Load(inFileName); mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer ); filter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi )); filter->SetThreshold(threshold); filter->Update(); // Save tensor image itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New(); writer->SetInput(filter->GetOutput()); writer->SetFileName(outfilename); writer->SetImageIO(io); writer->UseCompressionOn(); writer->Update(); } catch ( itk::ExceptionObject &err) { std::cout << "Exception: " << err; } catch ( std::exception err) { std::cout << "Exception: " << err.what(); } catch ( ... ) { std::cout << "Exception!"; } return EXIT_SUCCESS; } diff --git a/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp b/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp index faefa746f0..e36113465b 100644 --- a/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp @@ -1,132 +1,132 @@ /*=================================================================== 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. ===================================================================*/ //testing headers //#include #include #include #include #include #include #include #include #include #include #include #include #include //for exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" class mitkNavigationDataSetReaderWriterCSVTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkNavigationDataSetReaderWriterCSVTestSuite); // MITK_TEST(TestCompareFunction); MITK_TEST(TestReadWrite); CPPUNIT_TEST_SUITE_END(); private: std::string pathRead; std::string pathWrite; std::string pathWrong; mitk::NavigationDataSet::Pointer set; public: void setUp() override { pathRead = GetTestDataFilePath("IGT-Data/RecordedNavigationData.xml"); pathWrong = GetTestDataFilePath("IGT-Data/NavigationDataTestData.CSV"); pathWrite="C:\\test.csv"; } void tearDown() override { } void TestReadWrite() { // Aim is to read an CSV into a pointset, write that CSV again, and compare the output - set = dynamic_cast(mitk::IOUtil::Load(pathRead)[0].GetPointer() ); + set = mitk::IOUtil::Load(pathRead); CPPUNIT_ASSERT_MESSAGE("Testing whether something was read at all", set != nullptr); mitk::IOUtil::Save(set, pathWrite); //FIXME: Commented out, because test fails under linux. binary comparison of files is probably not the wa to go // See Bug 17775 //CPPUNIT_ASSERT_MESSAGE( "Testing if read/write cycle creates identical files", CompareFiles(pathRead, pathWrite)); //remove(pathWrite.c_str()); } bool CompareFiles(std::string file) { - set = dynamic_cast(mitk::IOUtil::Load(file)[0].GetPointer()); + set = mitk::IOUtil::Load(file); double sample[2][30] ={ {5134019.44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5134019.44, 0, 1, 101.2300034, -62.63999939, -203.2400055, -0.3059000075, 0.5752000213, 0, 0.7585999966, 5134019.44, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {5134082.84, 5134073.64, 1, -172.6100006, 12.60999966, -299.4500122, -0.1588999927, 0.4370000064, 0, 0.8852000237, 5134082.84, 5134073.64, 1, 101.2300034, -62.63999939, -203.2400055, -0.3059000075, 0.5752000213, 0, 0.7585999966, 5134082.84, 5134073.64, 0, 0, 0, 0, 0, 0, 0, 0} }; bool returnValue = true; for(int line = 0 ; line < 2; line++) { for (int tool =0; tool < 3; tool ++) { mitk::NavigationData::Pointer testline = set->GetNavigationDataForIndex(line,tool) ; returnValue = returnValue && mitk::Equal( testline->GetIGTTimeStamp() , sample [line] [(tool*10)] ); returnValue = returnValue && mitk::Equal( testline->IsDataValid() , sample [line] [(tool*10)+1] ); mitk::NavigationData::PositionType pos = testline->GetPosition(); returnValue = returnValue && mitk::Equal( pos[0] , sample [line] [(tool*10)+2] ); returnValue = returnValue && mitk::Equal( pos[1] , sample [line] [(tool*10)+3] ); returnValue = returnValue && mitk::Equal( pos[2] , sample [line] [(tool*10)+4] ); mitk::NavigationData::OrientationType ori = testline->GetOrientation(); returnValue = returnValue && mitk::Equal( ori[0] , sample [line] [(tool*10)+5] ); returnValue = returnValue && mitk::Equal( ori[1] , sample [line] [(tool*10)+6] ); returnValue = returnValue && mitk::Equal( ori[2] , sample [line] [(tool*10)+7] ); returnValue = returnValue && mitk::Equal( ori[3] , sample [line] [(tool*10)+8] ); } } return returnValue; } void TestCompareFunction() { CPPUNIT_ASSERT_MESSAGE("Checking if csv-file reader is working properly", CompareFiles(pathRead)); //CPPUNIT_ASSERT_MESSAGE("Asserting that compare function for files works correctly - Negative Test", ! CompareFiles(pathWrong) ); } }; MITK_TEST_SUITE_REGISTRATION(mitkNavigationDataSetReaderWriterCSV) diff --git a/Modules/IGT/Testing/mitkNavigationToolReaderAndWriterTest.cpp b/Modules/IGT/Testing/mitkNavigationToolReaderAndWriterTest.cpp index 8150cbdf15..cf8eee3eb8 100644 --- a/Modules/IGT/Testing/mitkNavigationToolReaderAndWriterTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationToolReaderAndWriterTest.cpp @@ -1,231 +1,231 @@ /*=================================================================== 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. ===================================================================*/ //Poco headers #include "Poco/Path.h" //mitk headers #include "mitkNavigationToolWriter.h" #include "mitkCommon.h" #include "mitkTestingMacros.h" #include "mitkNavigationTool.h" #include "mitkBaseData.h" #include "mitkDataNode.h" #include "mitkSurface.h" #include "mitkStandaloneDataStorage.h" #include "mitkDataStorage.h" #include "mitkNavigationToolReader.h" #include "mitkIGTConfig.h" #include #include #include #include "mitkNDIAuroraTypeInformation.h" #include "mitkMicronTrackerTypeInformation.h" mitk::Surface::Pointer m_testSurface; static void TestInstantiation() { // let's create an object of our class mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); MITK_TEST_CONDITION_REQUIRED(myWriter.IsNotNull(),"Testing instantiation") } static void TestWrite() { //testcase with first test tool: a claron tool //create a NavigationTool which we can write on the harddisc std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/ClaronTool"); mitk::NavigationTool::Pointer myNavigationTool = mitk::NavigationTool::New(); myNavigationTool->SetCalibrationFile(toolFileName); mitk::DataNode::Pointer myNode = mitk::DataNode::New(); myNode->SetName("ClaronTool"); std::string surfaceFileName(MITK_IGT_DATA_DIR); surfaceFileName.append("/ClaronTool.stl"); - m_testSurface = dynamic_cast(mitk::IOUtil::Load( surfaceFileName )[0].GetPointer()); + m_testSurface = mitk::IOUtil::Load( surfaceFileName ); myNode->SetData(m_testSurface); myNavigationTool->SetDataNode(myNode); myNavigationTool->SetIdentifier("ClaronTool#1"); myNavigationTool->SetSerialNumber("0815"); myNavigationTool->SetTrackingDeviceType(mitk::MicronTrackerTypeInformation::GetTrackingDeviceName()); myNavigationTool->SetType(mitk::NavigationTool::Fiducial); //now create a writer and write it to the harddisc mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); std::string filename = mitk::IOUtil::GetTempPath() + "TestTool.tool"; MITK_TEST_OUTPUT(<<"---- Testing navigation tool writer with first test tool (claron tool) ----"); bool test = myWriter->DoWrite(filename,myNavigationTool); MITK_TEST_CONDITION_REQUIRED(test,"OK"); } static void TestRead() { mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(); std::string filename = mitk::IOUtil::GetTempPath() + "TestTool.tool"; mitk::NavigationTool::Pointer readTool = myReader->DoRead(filename); MITK_TEST_OUTPUT(<<"---- Testing navigation tool reader with first test tool (claron tool) ----"); //Test if the surfaces do have the same number of vertexes (it would be better to test for real equality of the surfaces!) MITK_TEST_CONDITION_REQUIRED(dynamic_cast(readTool->GetDataNode()->GetData())->GetSizeOfPolyDataSeries()==m_testSurface->GetSizeOfPolyDataSeries(),"Test if surface was restored correctly ..."); MITK_TEST_CONDITION_REQUIRED(readTool->GetType()==mitk::NavigationTool::Fiducial,"Testing Tool Type"); MITK_TEST_CONDITION_REQUIRED(readTool->GetTrackingDeviceType() == mitk::MicronTrackerTypeInformation::GetTrackingDeviceName(), "Testing Tracking Device Type"); MITK_TEST_CONDITION_REQUIRED(readTool->GetSerialNumber()=="0815","Testing Serial Number"); std::ifstream TestFile(readTool->GetCalibrationFile().c_str()); MITK_TEST_CONDITION_REQUIRED(TestFile,"Testing If Calibration File Exists"); } static void TestWrite2() { //testcase with second test tool: an aurora tool //create a NavigationTool which we can write on the harddisc mitk::NavigationTool::Pointer myNavigationTool = mitk::NavigationTool::New(); mitk::DataNode::Pointer myNode = mitk::DataNode::New(); myNode->SetName("AuroraTool"); std::string surfaceFileName(MITK_IGT_DATA_DIR); surfaceFileName.append("/EMTool.stl"); - m_testSurface = dynamic_cast(mitk::IOUtil::Load( surfaceFileName )[0].GetPointer()); + m_testSurface = mitk::IOUtil::Load( surfaceFileName ); myNode->SetData(m_testSurface); myNavigationTool->SetDataNode(myNode); myNavigationTool->SetIdentifier("AuroraTool#1"); myNavigationTool->SetSerialNumber("0816"); myNavigationTool->SetTrackingDeviceType(mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()); myNavigationTool->SetType(mitk::NavigationTool::Instrument); //now create a writer and write it to the harddisc mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); std::string filename = mitk::IOUtil::GetTempPath() + "TestTool2.tool"; MITK_TEST_OUTPUT(<<"---- Testing navigation tool writer with second tool (aurora tool) ----"); bool test = myWriter->DoWrite(filename,myNavigationTool); MITK_TEST_CONDITION_REQUIRED(test,"OK"); } static void TestRead2() { mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(); std::string filename = mitk::IOUtil::GetTempPath() + "TestTool2.tool"; mitk::NavigationTool::Pointer readTool = myReader->DoRead(filename); MITK_TEST_OUTPUT(<<"---- Testing navigation tool reader with second tool (aurora tool) ----"); //Test if the surfaces do have the same number of vertexes (it would be better to test for real equality of the surfaces!) MITK_TEST_CONDITION_REQUIRED(dynamic_cast(readTool->GetDataNode()->GetData())->GetSizeOfPolyDataSeries()==m_testSurface->GetSizeOfPolyDataSeries(),"Test if surface was restored correctly ..."); //Test if the tool type is the same MITK_TEST_CONDITION_REQUIRED(readTool->GetType()==mitk::NavigationTool::Instrument,"Testing Tool Type"); MITK_TEST_CONDITION_REQUIRED(readTool->GetTrackingDeviceType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName(), "Testing Tracking Device Type"); MITK_TEST_CONDITION_REQUIRED(readTool->GetSerialNumber()=="0816","Testing Serial Number"); MITK_TEST_CONDITION_REQUIRED(readTool->GetCalibrationFile()=="none","Testing Calibration File"); } static void CleanUp() { std::string tempFile1 = mitk::IOUtil::GetTempPath() + "TestTool.tool"; std::remove(tempFile1.c_str()); std::string tempFile2 = mitk::IOUtil::GetTempPath() + "TestTool2.tool"; std::remove(tempFile2.c_str()); } static void TestReadInvalidData() { mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(); mitk::NavigationTool::Pointer readTool = myReader->DoRead("invalidTool"); MITK_TEST_CONDITION_REQUIRED(readTool.IsNull(), "Testing return value if filename is invalid"); MITK_TEST_CONDITION_REQUIRED(myReader->GetErrorMessage() == "Cannot open 'invalidTool' for reading", "Testing error message in this case"); } static void TestWriteInvalidFilename() { //create a test navigation tool mitk::NavigationTool::Pointer myNavigationTool = mitk::NavigationTool::New(); mitk::DataNode::Pointer myNode = mitk::DataNode::New(); myNode->SetName("AuroraTool"); std::string surfaceFileName(MITK_IGT_DATA_DIR); surfaceFileName.append("/EMTool.stl"); - m_testSurface = dynamic_cast(mitk::IOUtil::Load( surfaceFileName )[0].GetPointer()); + m_testSurface = mitk::IOUtil::Load( surfaceFileName ); myNode->SetData(m_testSurface); myNavigationTool->SetDataNode(myNode); myNavigationTool->SetIdentifier("AuroraTool#1"); myNavigationTool->SetSerialNumber("0816"); myNavigationTool->SetTrackingDeviceType(mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()); myNavigationTool->SetType(mitk::NavigationTool::Instrument); //now create a writer and write it to the harddisc mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); std::string filename = "NH:/sfdsfsdsf.&%%%"; MITK_TEST_OUTPUT(<<"---- Testing write invalid file ----"); bool test = myWriter->DoWrite(filename,myNavigationTool); MITK_TEST_CONDITION_REQUIRED(!test,"testing write"); MITK_TEST_CONDITION_REQUIRED(myWriter->GetErrorMessage() == "Could not open a zip file for writing: 'NH:/sfdsfsdsf.&%%%'","testing error message"); } static void TestWriteInvalidData() { mitk::NavigationTool::Pointer myNavigationTool; //tool is invalid because no data note is created //now create a writer and write it to the harddisc mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); std::string filename = "NH:/sfdsfsdsf.&%%%"; MITK_TEST_OUTPUT(<<"---- Testing write invalid tool ----"); bool test = myWriter->DoWrite(filename,myNavigationTool); MITK_TEST_CONDITION_REQUIRED(!test,"testing write"); MITK_TEST_CONDITION_REQUIRED(myWriter->GetErrorMessage() == "Cannot write a navigation tool containing invalid tool data, aborting!","testing error message"); } /** This function is testing the TrackingVolume class. */ int mitkNavigationToolReaderAndWriterTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationToolWriter") TestInstantiation(); TestWrite(); TestRead(); TestWrite2(); TestRead2(); TestReadInvalidData(); TestWriteInvalidData(); TestWriteInvalidFilename(); CleanUp(); MITK_TEST_END() } diff --git a/Modules/IGT/TestingHelper/mitkNavigationToolStorageTestHelper.cpp b/Modules/IGT/TestingHelper/mitkNavigationToolStorageTestHelper.cpp index fc5bd5613c..c76d8881f5 100644 --- a/Modules/IGT/TestingHelper/mitkNavigationToolStorageTestHelper.cpp +++ b/Modules/IGT/TestingHelper/mitkNavigationToolStorageTestHelper.cpp @@ -1,108 +1,108 @@ /*=================================================================== 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 "mitkNavigationToolStorageTestHelper.h" #include "mitkNDIAuroraTypeInformation.h" #include "mitkMicronTrackerTypeInformation.h" mitk::NavigationToolStorage::Pointer mitk::NavigationToolStorageTestHelper::CreateTestData_SimpleStorage() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); myStorage->AddTool(myTool1); //second tool mitk::NavigationTool::Pointer myTool2 = mitk::NavigationTool::New(); myTool2->SetIdentifier("002"); myStorage->AddTool(myTool2); //third tool mitk::NavigationTool::Pointer myTool3 = mitk::NavigationTool::New(); myTool3->SetIdentifier("003"); myStorage->AddTool(myTool3); return myStorage; } mitk::NavigationToolStorage::Pointer mitk::NavigationToolStorageTestHelper::CreateTestData_StorageWithOneTool() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); mitk::PointSet::Pointer CalLandmarks1 = mitk::PointSet::New(); mitk::Point3D testPt1; mitk::FillVector3D(testPt1,1,2,3); CalLandmarks1->SetPoint(0,testPt1); mitk::PointSet::Pointer RegLandmarks1 = mitk::PointSet::New(); mitk::Point3D testPt2; mitk::FillVector3D(testPt2,4,5,6); RegLandmarks1->SetPoint(5,testPt2); myTool1->SetToolControlPoints(CalLandmarks1); myTool1->SetToolLandmarks(RegLandmarks1); mitk::Point3D toolTipPos; mitk::FillVector3D(toolTipPos,1.3423,2.323,4.332); mitk::Quaternion toolTipRot = mitk::Quaternion(0.1,0.2,0.3,0.4); myTool1->SetToolTipPosition(toolTipPos); myTool1->SetToolAxisOrientation(toolTipRot); myStorage->AddTool(myTool1); return myStorage; } mitk::NavigationToolStorage::Pointer mitk::NavigationToolStorageTestHelper::CreateTestData_ComplexStorage(std::string toolFilePath, std::string toolSurfacePath1, std::string toolSurfacePath2) { //create first tool mitk::NavigationTool::Pointer myNavigationTool = mitk::NavigationTool::New(); myNavigationTool->SetCalibrationFile(toolFilePath); mitk::DataNode::Pointer myNode = mitk::DataNode::New(); myNode->SetName("ClaronTool"); - myNode->SetData(dynamic_cast(mitk::IOUtil::Load(toolSurfacePath1)[0].GetPointer())); //load an stl File + myNode->SetData(mitk::IOUtil::Load(toolSurfacePath1)); //load an stl File myNavigationTool->SetDataNode(myNode); myNavigationTool->SetIdentifier("ClaronTool#1"); myNavigationTool->SetSerialNumber("0815"); myNavigationTool->SetTrackingDeviceType(mitk::MicronTrackerTypeInformation::GetTrackingDeviceName()); myNavigationTool->SetType(mitk::NavigationTool::Fiducial); //create second tool mitk::NavigationTool::Pointer myNavigationTool2 = mitk::NavigationTool::New(); mitk::Surface::Pointer testSurface2; mitk::DataNode::Pointer myNode2 = mitk::DataNode::New(); myNode2->SetName("AuroraTool"); //load an stl File - testSurface2 = dynamic_cast(mitk::IOUtil::Load(toolSurfacePath2)[0].GetPointer()); + testSurface2 = mitk::IOUtil::Load(toolSurfacePath2); myNode2->SetData(testSurface2); myNavigationTool2->SetDataNode(myNode2); myNavigationTool2->SetIdentifier("AuroraTool#1"); myNavigationTool2->SetSerialNumber("0816"); myNavigationTool2->SetTrackingDeviceType(mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()); myNavigationTool2->SetType(mitk::NavigationTool::Instrument); //create navigation tool storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); myStorage->AddTool(myNavigationTool); myStorage->AddTool(myNavigationTool2); return myStorage; } diff --git a/Modules/IGTUI/Qmitk/QmitkNDIConfigurationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNDIConfigurationWidget.cpp index c7ef549ccf..8cf7c86059 100644 --- a/Modules/IGTUI/Qmitk/QmitkNDIConfigurationWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkNDIConfigurationWidget.cpp @@ -1,895 +1,895 @@ /*=================================================================== 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. ===================================================================*/ #define MITK_NO_DEPRECATED_WARNINGS #include "QmitkNDIConfigurationWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include "QmitkCustomVariants.h" //#include #include "QmitkNDIToolDelegate.h" #include "mitkNDIAuroraTypeInformation.h" #include "mitkNDIPolarisTypeInformation.h" /* VIEW MANAGEMENT */ QmitkNDIConfigurationWidget::QmitkNDIConfigurationWidget(QWidget* parent) : QWidget(parent), m_Controls(nullptr), m_Tracker(nullptr), m_Source(nullptr), m_Delegate(nullptr), m_SROMCellDefaultText(""), m_RepresentatonCellDefaultText("") { this->CreateQtPartControl(this); } QmitkNDIConfigurationWidget::~QmitkNDIConfigurationWidget() { m_Controls = nullptr; m_Tracker = nullptr; m_Source = nullptr; } void QmitkNDIConfigurationWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkNDIConfigurationWidget; m_Controls->setupUi(parent); QStringList comPorts; #ifdef WIN32 comPorts << "COM1" << "COM2" << "COM3" << "COM4" << "COM5" << "COM6" << "COM7" << "COM8" << "COM9"; #else comPorts << "/dev/ttyS1" << "/dev/ttyS2" << "/dev/ttyS3" << "/dev/ttyS4" << "/dev/ttyS5" << "/dev/ttyUSB0" << "/dev/ttyUSB1" << "/dev/ttyUSB2" << "/dev/ttyUSB3"; #endif m_Controls->m_ComPortSelector->addItems(comPorts); m_Delegate = new QmitkNDIToolDelegate(m_Controls->m_ToolTable); m_Delegate->SetDataStorage(nullptr); //needs to be set later using the setter methods m_Delegate->SetPredicate(nullptr); m_Delegate->SetTypes(QStringList()); m_Controls->m_ToolTable->setItemDelegate(m_Delegate); this->CreateConnections(); this->HidePolarisOptionsGroupbox(true); this->HideAuroraOptionsGroupbox(true); } } void QmitkNDIConfigurationWidget::CreateConnections() { connect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnConnect())); connect(m_Controls->m_DiscoverToolsBtn, SIGNAL(clicked()), this, SLOT(OnDiscoverTools())); connect(m_Controls->m_AddToolBtn, SIGNAL(clicked()), this, SLOT(OnAddPassiveTool())); connect(m_Controls->m_DisoverDevicesBtn, SIGNAL(clicked()), this, SLOT(OnDiscoverDevices())); connect(m_Controls->m_ToolTable->model(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(UpdateTrackerFromToolTable(const QModelIndex &, const QModelIndex &))); connect(m_Controls->m_DisoverDevicesBtnInfo, SIGNAL(clicked()), this, SLOT(OnDisoverDevicesBtnInfo())); connect(m_Controls->m_SaveToolPushButton, SIGNAL(clicked()), this, SLOT(OnSaveTool()) ); connect(m_Controls->m_LoadToolPushButton, SIGNAL(clicked()), this, SLOT(OnLoadTool()) ); } void QmitkNDIConfigurationWidget::OnConnect() { if (m_Tracker.IsNotNull()) { m_Tracker->CloseConnection(); m_Tracker = nullptr; } this->CreateTracker(); this->SetupTracker(); bool okay = false; try { okay = m_Tracker->OpenConnection(); } catch(mitk::IGTException &e) { QMessageBox::warning(nullptr, "Error", QString("Connection failed, error message: ") + e.GetDescription()); m_Tracker->CloseConnection(); this->m_Tracker = nullptr; } if (okay) { // show/hide options according to connected device if(m_Tracker->GetType() == mitk::NDIPolarisTypeInformation::GetTrackingDeviceName()) { this->HideAuroraOptionsGroupbox(true); this->HidePolarisOptionsGroupbox(false); } else if (m_Tracker->GetType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) { this->HidePolarisOptionsGroupbox(true); this->HideAuroraOptionsGroupbox(false); } this->UpdateWidgets(); this->UpdateToolTable(); connect(m_Controls->m_ToolTable, SIGNAL(cellChanged(int,int)), this, SLOT(OnTableCellChanged(int,int))); emit ToolsAdded(this->GetToolNamesList()); emit Connected(); } else { QMessageBox::warning(nullptr, "Error", QString("Connection failed due to an unknown reason!")); m_Tracker->CloseConnection(); this->m_Tracker = nullptr; } } void QmitkNDIConfigurationWidget::OnDisconnect() { if (m_Tracker.IsNull()) return; m_Tracker->CloseConnection(); m_Tracker = nullptr; disconnect(m_Controls->m_ToolTable, SIGNAL(cellChanged(int,int)), this, SLOT(OnTableCellChanged(int,int))); m_Controls->m_ToolSelectionComboBox->clear(); this->UpdateToolTable(); this->UpdateWidgets(); emit ToolsAdded(this->GetToolNamesList()); emit Disconnected(); this->HidePolarisOptionsGroupbox(true); this->HideAuroraOptionsGroupbox(true); } void QmitkNDIConfigurationWidget::UpdateWidgets() { m_Controls->m_DeviceStatus->setText(this->GetStatusText()); if (m_Tracker.IsNull()) // not connected to tracker { m_Controls->m_Connect->setText("Connect"); m_Controls->m_lConnection->setText("III. Enable connection to device "); disconnect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnDisconnect())); connect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnConnect())); m_Controls->m_DiscoverToolsBtn->setDisabled(true); m_Controls->m_AddToolBtn->setDisabled(true); return; } if (m_Tracker->GetState() == mitk::TrackingDevice::Setup) { m_Controls->m_Connect->setText("Connect"); m_Controls->m_lConnection->setText("III. Enable connection to device "); disconnect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnDisconnect())); connect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnConnect())); m_Controls->m_DiscoverToolsBtn->setDisabled(true); m_Controls->m_AddToolBtn->setDisabled(true); return; } if ((m_Tracker->GetState() == mitk::TrackingDevice::Ready) || (m_Tracker->GetState() == mitk::TrackingDevice::Tracking)) { m_Controls->m_Connect->setText("Disconnect"); m_Controls->m_lConnection->setText("III. Disable connection to device "); disconnect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnConnect())); connect(m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnDisconnect())); m_Controls->m_DiscoverToolsBtn->setEnabled(true); m_Controls->m_AddToolBtn->setEnabled(true); } } QString QmitkNDIConfigurationWidget::GetStatusText() { if (m_Tracker.IsNull()) return QString("Not connected"); QString devName = QString::fromStdString(m_Tracker->GetType()); if (m_Tracker->GetState() == mitk::TrackingDevice::Ready) return QString("Connected to %1 on %2. Device is ready.").arg(devName).arg(m_Tracker->GetDeviceName()); if (m_Tracker->GetState() == mitk::TrackingDevice::Tracking) return QString("%1 is tracking.").arg(devName); return QString(""); } void QmitkNDIConfigurationWidget::OnDiscoverTools() { if (m_Tracker.IsNull()) { QMessageBox::warning(nullptr, "Error", QString("Connection failed. No tracking device found.")); return; } m_Tracker->DiscoverWiredTools(); this->UpdateToolTable(); emit ToolsAdded(this->GetToolNamesList()); } void QmitkNDIConfigurationWidget::OnAddPassiveTool() { if (m_Tracker.IsNull()) this->CreateTracker(); QStringList filenames = QFileDialog::getOpenFileNames(this, "Select NDI SROM file", QmitkIGTCommonHelper::GetLastFileLoadPath(),"NDI SROM files (*.rom)"); if (filenames.isEmpty()) { this->m_Tracker = nullptr; return; } QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(filenames.at(0)); foreach(QString fileName, filenames) { //QString toolName = QInputDialog::getText(this, "Enter a name for the tool", "Name of the tool: ", QLineEdit::Normal, QFileInfo(filename).baseName(), &ok); //if (ok == false || toolName.isEmpty()) // return; m_Tracker->AddTool(QFileInfo(fileName).baseName().toLatin1(), fileName.toLatin1()); m_Tracker->Modified(); } emit ToolsAdded(this->GetToolNamesList()); this->UpdateToolTable(); } void QmitkNDIConfigurationWidget::CreateTracker() { m_Tracker = mitk::NDITrackingDevice::New(); } void QmitkNDIConfigurationWidget::SetupTracker() { if (m_Tracker.IsNull()) return; m_Tracker->SetDeviceName(this->GetDeviceName()); m_Tracker->SetBaudRate(mitk::SerialCommunication::BaudRate115200); } std::string QmitkNDIConfigurationWidget::GetDeviceName() const { if (m_Controls == nullptr) return nullptr; QString deviceName = m_Controls->m_ComPortSelector->currentText(); #if WIN32 deviceName.prepend("\\\\.\\"); // always prepend "\\.\ to all COM ports, to be able to connect to ports > 9" #endif return deviceName.toStdString(); } void QmitkNDIConfigurationWidget::SetDeviceName( const char* dev ) { if (m_Controls == nullptr) return; m_Controls->m_ComPortSelector->setCurrentIndex(m_Controls->m_ComPortSelector->findText(dev)); } void QmitkNDIConfigurationWidget::UpdateToolTable() { //disconnect(m_Controls->m_ToolTable, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(OnTableItemChanged(QTableWidgetItem*))); // stop listening to table changes disconnect(m_Controls->m_ToolTable->model(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(UpdateTrackerFromToolTable(const QModelIndex &, const QModelIndex &))); disconnect(m_Controls->m_ToolTable, SIGNAL( clicked ( const QModelIndex & )), this, SLOT ( OnTableItemClicked( const QModelIndex & ))); m_Controls->m_ToolTable->clearContents(); m_Controls->m_ToolTable->setRowCount(0); if (m_Tracker.IsNull() || (m_Controls == nullptr)) return; m_Controls->m_ToolSelectionComboBox->clear(); m_Controls->m_ToolTable->setRowCount(m_Tracker->GetToolCount()); for (unsigned int i = 0; i < m_Tracker->GetToolCount(); ++i) { mitk::TrackingTool* t = m_Tracker->GetTool(i); if (t == nullptr) { m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::IndexCol, new QTableWidgetItem("INVALID")); // Index continue; } m_Controls->m_ToolSelectionComboBox->addItem(m_Tracker->GetTool(i)->GetToolName()); m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::IndexCol, new QTableWidgetItem(QString::number(i))); // Index m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::NameCol, new QTableWidgetItem(t->GetToolName())); // Name if (dynamic_cast(t)->GetSROMDataLength() > 0) m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::SROMCol, new QTableWidgetItem("SROM file loaded")); // SROM file else m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::SROMCol, new QTableWidgetItem(m_SROMCellDefaultText)); // SROM file m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::TypeCol, new QTableWidgetItem("")); // Type if (t->IsEnabled()) m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::StatusCol, new QTableWidgetItem("Enabled")); // Status else m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::StatusCol, new QTableWidgetItem("Disabled")); // Status m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::NodeCol, new QTableWidgetItem("")); // Node m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::RepCol, new QTableWidgetItem(m_RepresentatonCellDefaultText)); // Representation /* set read-only/editable flags */ m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::IndexCol)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled); // Index m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::NodeCol)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled); // Name m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::SROMCol)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled); // SROM file m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::TypeCol)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled); // Type m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::StatusCol)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled); // Status m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::NodeCol)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled); // Node m_Controls->m_ToolTable->item(i, QmitkNDIToolDelegate::RepCol)->setFlags(Qt::NoItemFlags); // Representation surface file } m_Controls->m_ToolTable->resizeColumnsToContents(); //connect(m_Controls->m_ToolTable, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(OnTableItemChanged(QTableWidgetItem*))); // listen to table changes again connect(m_Controls->m_ToolTable->model(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(UpdateTrackerFromToolTable(const QModelIndex &, const QModelIndex &))); connect(m_Controls->m_ToolTable, SIGNAL( clicked ( const QModelIndex & )), this, SLOT ( OnTableItemClicked( const QModelIndex & ))); } void QmitkNDIConfigurationWidget::OnDiscoverDevices() { PortDeviceMap portsAndDevices; QString status = "Scanning "; #ifdef WIN32 QString devName; for (unsigned int i = 1; i < 40; ++i) { if (i<10) devName = QString("COM%1").arg(i); else devName = QString("\\\\.\\COM%1").arg(i); // prepend "\\.\ to COM ports >9, to be able to allow connection" portsAndDevices[devName]; status += QString("COM%1").arg(i) + ", "; } #else //linux/posix systems for(unsigned int i = 1; i < 6; ++i) { QString devName = QString("/dev/ttyS%1").arg(i); portsAndDevices[devName]; status += devName + ", "; } for(unsigned int i = 0; i <7; ++i) { QString devName = QString("/dev/ttyUSB%1").arg(i); portsAndDevices[devName]; status += devName + ", "; } #endif status.chop(2); // remove last ", " status += " for NDI tracking devices..."; m_Controls->m_DeviceStatus->setText(status); ScanPortsForNDITrackingDevices(portsAndDevices); m_Controls->m_ComPortSelector->clear(); QString result = "The following tracking devices were found:
\n"; for (PortDeviceMap::const_iterator it = portsAndDevices.begin(); it != portsAndDevices.end(); ++it) { QString tmpComPort = it.key(); if (tmpComPort.startsWith("\\")) { tmpComPort.remove(0,4); // remove "\\.\" for nice ui visualisation } result += tmpComPort + ": "; if (mitk::NDIPolarisTypeInformation::GetTrackingDeviceName() == it.value() || mitk::NDIAuroraTypeInformation::GetTrackingDeviceName() == it.value()) { result += QString::fromStdString(it.value()); result += "
\n"; m_Controls->m_ComPortSelector->addItem(tmpComPort); } else { result += "No NDI tracking device found
\n"; } } //QMessageBox::information(nullptr, "Tracking Device Discovery", result); m_Controls->m_DeviceStatus->setText(result); } mitk::TrackingDeviceType QmitkNDIConfigurationWidget::ScanPort(QString port) { mitk::NDITrackingDevice::Pointer tracker = mitk::NDITrackingDevice::New(); tracker->SetDeviceName(port.toStdString()); return tracker->TestConnection(); } void QmitkNDIConfigurationWidget::ScanPortsForNDITrackingDevices( PortDeviceMap& portsAndDevices ) { // Iterative scanning: for (PortDeviceMap::iterator it = portsAndDevices.begin(); it != portsAndDevices.end(); ++it) it.value() = this->ScanPort(it.key()); // \Todo: use parallel scanning //QtConcurrent::blockingMap( portsAndDevices.begin(), portsAndDevices.end(), ScanPort ); //MITK_INFO << portsAndDevices; } QStringList QmitkNDIConfigurationWidget::GetToolNamesList() { QStringList toolNames; if (m_Tracker.IsNull()) return toolNames; for (unsigned int i = 0; i < m_Tracker->GetToolCount(); ++i) { mitk::TrackingTool* t = m_Tracker->GetTool(i); if (t == nullptr) continue; toolNames << t->GetToolName(); } return toolNames; } mitk::NDITrackingDevice* QmitkNDIConfigurationWidget::GetTracker() const { return m_Tracker.GetPointer(); } void QmitkNDIConfigurationWidget::SetToolTypes(const QStringList& types) { m_Delegate->SetTypes(types); } void QmitkNDIConfigurationWidget::SetDataStorage(mitk::DataStorage* ds) { m_Delegate->SetDataStorage(ds); } void QmitkNDIConfigurationWidget::SetPredicate(mitk::NodePredicateBase::Pointer p) { m_Delegate->SetPredicate(p); } void QmitkNDIConfigurationWidget::SetTagPropertyName( const std::string& name ) { m_Delegate->SetTagPropertyName(name); } void QmitkNDIConfigurationWidget::SetTagProperty( mitk::BaseProperty::Pointer prop ) { m_Delegate->SetTagProperty(prop); } void QmitkNDIConfigurationWidget::OnTableItemClicked(const QModelIndex & topLeft ) { QString filename; QTableWidgetItem* filenameItem; switch (topLeft.column()) { case QmitkNDIToolDelegate::RepCol: filename = QFileDialog::getOpenFileName(this, "Select Surface File", QmitkIGTCommonHelper::GetLastFileLoadPath(),"STL files (*.stl)"); QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(filename); filenameItem = new QTableWidgetItem(filename); m_Controls->m_ToolTable->setItem( topLeft.row(), topLeft.column(), filenameItem ); if(QFileInfo(filename).exists()) { mitk::Surface::Pointer surface = this->LoadSurfaceFromSTLFile(filename); if(surface.IsNotNull()) emit RepresentationChanged( topLeft.row(), surface); } break; default: break; } } void QmitkNDIConfigurationWidget::UpdateTrackerFromToolTable(const QModelIndex & topLeft, const QModelIndex & /*bottomRight*/) { //Colums ID doesn't have to be processed. if (topLeft.column()<1) return; if (m_Tracker.IsNull()) return; if (topLeft.row() >= (int) m_Tracker->GetToolCount()) return; QAbstractItemModel* model = m_Controls->m_ToolTable->model(); //define topleft contains row and column; row 0 is tool 0; column is index =0, Name =1, SROMFileName = 2; Type = 3; Status = 4; Node (?) = 5 //only update the changed item mitk::NDIPassiveTool* tool = dynamic_cast (m_Tracker->GetTool(topLeft.row())); if (tool == nullptr) return; switch (topLeft.column()) { case QmitkNDIToolDelegate::IndexCol: //index break; case QmitkNDIToolDelegate::NameCol: //name tool->SetToolName(model->data(model->index(topLeft.row(), 1)).toString().toLatin1()); emit ToolsChanged(); break; case QmitkNDIToolDelegate::SROMCol: //SROM File Name { QString romfile = model->data(model->index(topLeft.row(), QmitkNDIToolDelegate::SROMCol)).toString(); if (QFileInfo(romfile).exists()) tool->LoadSROMFile(romfile.toLatin1()); m_Tracker->UpdateTool(tool); break; } //TODO: Add Node Status and Type here as well default: break; } } const QString QmitkNDIConfigurationWidget::GetToolType( unsigned int index ) const { if (m_Controls == nullptr) return QString(""); QAbstractItemModel* model = m_Controls->m_ToolTable->model(); QModelIndex modelIndex = model->index(index, QmitkNDIToolDelegate::TypeCol); if (modelIndex.isValid() == false) return QString(""); return model->data(modelIndex).toString(); } const QString QmitkNDIConfigurationWidget::GetToolName( unsigned int index ) const { if (m_Controls == nullptr) return QString(""); QAbstractItemModel* model = m_Controls->m_ToolTable->model(); QModelIndex modelIndex = model->index(index, QmitkNDIToolDelegate::NameCol); if (modelIndex.isValid() == false) return QString(""); return model->data(modelIndex).toString(); } QMap QmitkNDIConfigurationWidget::GetToolAndTypes() const { QMap map; if (m_Controls == nullptr) return map; QAbstractItemModel* model = m_Controls->m_ToolTable->model(); for (int i = 0; i < model->rowCount(); ++i) { QModelIndex indexIndex = model->index(i, QmitkNDIToolDelegate::IndexCol); QModelIndex typeIndex = model->index(i, QmitkNDIToolDelegate::TypeCol); if ((indexIndex.isValid() == false) || (typeIndex.isValid() == false)) continue; map.insert(model->data(typeIndex).toString(), model->data(indexIndex).toUInt()); } return map; } QList QmitkNDIConfigurationWidget::GetToolsByToolType( QString toolType ) const { QList list; if (m_Controls == nullptr) return list; QAbstractItemModel* model = m_Controls->m_ToolTable->model(); for (int i = 0; i < model->rowCount(); ++i) { QModelIndex indexIndex = model->index(i, QmitkNDIToolDelegate::IndexCol); QModelIndex typeIndex = model->index(i, QmitkNDIToolDelegate::TypeCol); if ((indexIndex.isValid() == false) || (typeIndex.isValid() == false)) continue; if (model->data(typeIndex).toString() == toolType) list.append(model->data(indexIndex).toUInt()); } return list; } mitk::DataNode* QmitkNDIConfigurationWidget::GetNode( unsigned int index ) const { if (m_Controls == nullptr) return nullptr; QAbstractItemModel* model = m_Controls->m_ToolTable->model(); QVariant data = model->data(model->index(index, QmitkNDIToolDelegate::NodeCol), QmitkNDIToolDelegate::OrganNodeRole); return data.value(); } void QmitkNDIConfigurationWidget::HidePolarisOptionsGroupbox( bool on ) { m_Controls->m_gbPolarisOptions->setHidden(on); } void QmitkNDIConfigurationWidget::HideAuroraOptionsGroupbox( bool on ) { m_Controls->m_gbAuroraOptions->setHidden(on); } void QmitkNDIConfigurationWidget::ShowToolRepresentationColumn() { int cols = m_Controls->m_ToolTable->columnCount(); //checking if representation column is inserted at right index if(cols != QmitkNDIToolDelegate::RepCol) { //throw std::exception("Representation Column is not inserted at it's designated index!"); return; } m_Controls->m_ToolTable->insertColumn(cols); // insert new column at end of table m_Controls->m_ToolTable->setHorizontalHeaderItem(QmitkNDIToolDelegate::RepCol, new QTableWidgetItem(QString("Representation"))); // inser column header for new colum //m_Controls->m_ToolTable->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers); int rows = m_Controls->m_ToolTable->rowCount(); // make all representation colum items not editable for(int i=0; i < rows; ++i) { m_Controls->m_ToolTable->setItem(i, QmitkNDIToolDelegate::RepCol, new QTableWidgetItem("")); // Representation m_Controls->m_ToolTable->item(i,QmitkNDIToolDelegate::RepCol)->setFlags(Qt::NoItemFlags); } //connect(m_Controls->m_ToolTable, SIGNAL( clicked ( const QModelIndex & )), this, SLOT ( OnTableItemClicked( const QModelIndex & ))); } void QmitkNDIConfigurationWidget::OnDisoverDevicesBtnInfo() { QMessageBox *infoBox = new QMessageBox(this); infoBox->setText("Click \"Scan Ports\" to get a list of all connected NDI tracking devices. This will clear the selection menu below and add the ports for discovered NDI tracking devices. Use this function, if a port is not listed."); infoBox->exec(); delete infoBox; } void QmitkNDIConfigurationWidget::OnTableCellChanged(int row, int column) { if(m_Tracker.IsNull()) return; QString toolName; switch (column) { case QmitkNDIToolDelegate::NameCol: toolName = m_Controls->m_ToolTable->item(row,column)->text(); m_Controls->m_ToolSelectionComboBox->setItemText(row, toolName); emit SignalToolNameChanged(row, toolName); break; default: break; } } void QmitkNDIConfigurationWidget::OnSaveTool() { if(m_Tracker.IsNull() || m_Tracker->GetToolCount() <= 0) return; int currId = m_Controls->m_ToolSelectionComboBox->currentIndex(); QString filename = QFileDialog::getSaveFileName(nullptr, "Save NDI-Tool", QString(QString(m_Tracker->GetTool(currId)->GetToolName())),"NDI Tracking Tool file(*.ntf)"); mitk::TrackingTool* selectedTool = m_Tracker->GetTool(currId); if(filename.isEmpty()) return; mitk::NavigationTool::Pointer navTool = mitk::NavigationTool::New(); mitk::NavigationToolWriter::Pointer toolWriter = mitk::NavigationToolWriter::New(); try { toolWriter->DoWrite(filename.toStdString(), this->GenerateNavigationTool(selectedTool)); } catch( ... ) { QMessageBox::warning(nullptr, "Saving Tool Error", QString("An error occured! Could not save tool!\n\n")); MBI_ERROR<<"Could not save tool surface!"; MBI_ERROR<< toolWriter->GetErrorMessage(); QFile maybeCorruptFile(filename); if(maybeCorruptFile.exists()) maybeCorruptFile.remove(); } emit SignalSavedTool(currId, filename); } void QmitkNDIConfigurationWidget::OnLoadTool() { if(m_Tracker.IsNull() || m_Tracker->GetToolCount() <= 0) return; QString filename = QFileDialog::getOpenFileName(nullptr, "Load NDI-Tools", QmitkIGTCommonHelper::GetLastFileLoadPath(),"NDI Tracking Tool file(*.ntf)"); int currId = m_Controls->m_ToolSelectionComboBox->currentIndex(); if(filename.isEmpty()) return; QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(filename); mitk::DataNode::Pointer toolNode; mitk::NavigationToolReader::Pointer toolReader = mitk::NavigationToolReader::New(); mitk::NavigationTool::Pointer navTool; try { navTool = toolReader->DoRead(filename.toStdString()); } catch( ... ) { QMessageBox::warning(nullptr, "Loading Tool Error", QString("An error occured! Could not load tool!\n\n")); MBI_ERROR<<"Could not load tool surface!"; MBI_ERROR<< toolReader->GetErrorMessage(); } int currSelectedToolID = m_Controls->m_ToolSelectionComboBox->currentIndex(); // name m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::NameCol)->setText(navTool->GetToolName().c_str()); dynamic_cast(m_Tracker->GetTool(currSelectedToolID))->SetToolName(navTool->GetToolName().c_str()); // also setting name to tool directly //calibration file (.srom) filename m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::SROMCol)->setText(navTool->GetCalibrationFile().c_str()); //type if(navTool->GetType() == mitk::NavigationTool::Instrument) m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::TypeCol)->setText("Instrument"); else if(navTool->GetType() == mitk::NavigationTool::Fiducial) m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::TypeCol)->setText("Fiducial"); else if(navTool->GetType() == mitk::NavigationTool::Skinmarker) m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::TypeCol)->setText("Skinmarker"); else m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::TypeCol)->setText("Unknown"); //representation m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::SROMCol)->setText(m_RepresentatonCellDefaultText); emit SignalLoadTool(currId, navTool->GetDataNode()); } mitk::NavigationTool::Pointer QmitkNDIConfigurationWidget::GenerateNavigationTool(mitk::TrackingTool* tool) { mitk::NavigationTool::Pointer navTool = mitk::NavigationTool::New(); mitk::NDIPassiveTool::Pointer passiveTool = dynamic_cast(tool); if(passiveTool.IsNull()) throw std::runtime_error("Could not cast TrackingTool to PassiveTool"); int currSelectedToolID = m_Controls->m_ToolSelectionComboBox->currentIndex(); QString sromFileName = m_Controls->m_ToolTable->item(currSelectedToolID, QmitkNDIToolDelegate::SROMCol)->text(); QString surfaceFileName = m_Controls->m_ToolTable->item(currSelectedToolID, QmitkNDIToolDelegate::RepCol)->text(); //calibration file (.srom) filename QFile sromFile(sromFileName); if(sromFile.exists()) navTool->SetCalibrationFile(sromFileName.toStdString()); //serial number navTool->SetSerialNumber(passiveTool->GetSerialNumber()); // name and surface as dataNode mitk::DataNode::Pointer node = mitk::DataNode::New(); mitk::Surface::Pointer toolSurface; try{ toolSurface = this->LoadSurfaceFromSTLFile(surfaceFileName); } catch( ... ) { QMessageBox::warning(nullptr, "Loading Surface Error", QString("An error occured! Could not load surface from .stl file!\n\n")); MBI_ERROR<<"Could not load .stl tool surface!"; } if(toolSurface.IsNotNull()) { node->SetData(toolSurface); node->SetName(tool->GetToolName()); } navTool->SetDataNode(node); // type mitk::NavigationTool::NavigationToolType type; QString currentToolType = m_Controls->m_ToolTable->item(currSelectedToolID,QmitkNDIToolDelegate::TypeCol)->text(); if(currentToolType.compare("Instrument") == 0) type = mitk::NavigationTool::Instrument; else if(currentToolType.compare("Fiducial") == 0) type = mitk::NavigationTool::Fiducial; else if(currentToolType.compare("Skinmarker") == 0) type = mitk::NavigationTool::Skinmarker; else type = mitk::NavigationTool::Unknown; navTool->SetType(type); return navTool; } mitk::Surface::Pointer QmitkNDIConfigurationWidget::LoadSurfaceFromSTLFile(QString surfaceFilename) { mitk::Surface::Pointer toolSurface; QFile surfaceFile(surfaceFilename); if(surfaceFile.exists()) { try{ - toolSurface = dynamic_cast(mitk::IOUtil::Load(surfaceFilename.toStdString().c_str())[0].GetPointer()); + toolSurface = mitk::IOUtil::Load(surfaceFilename.toStdString().c_str()); } catch(std::exception& e ) { MBI_ERROR<<"Could not load surface for tool!"; MBI_ERROR<< e.what(); throw e; } } return toolSurface; } void QmitkNDIConfigurationWidget::EnableAddToolsButton(bool enable) { m_Controls->m_AddToolBtn->setEnabled(enable); } void QmitkNDIConfigurationWidget::EnableDiscoverNewToolsButton(bool enable) { m_Controls->m_DiscoverToolsBtn->setEnabled(enable); } diff --git a/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp index be876ca23e..1dc7d01eaa 100644 --- a/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp @@ -1,397 +1,397 @@ /*=================================================================== 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 "QmitkNavigationToolCreationWidget.h" //mitk headers #include #include #include #include #include "mitkTrackingDeviceTypeCollection.h" //qt headers #include #include #include #include #include //poco headers #include const std::string QmitkNavigationToolCreationWidget::VIEW_ID = "org.mitk.views.navigationtoolcreationwizardwidget"; QmitkNavigationToolCreationWidget::QmitkNavigationToolCreationWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = nullptr; m_ToolToBeEdited = mitk::NavigationTool::New(); m_FinalTool = mitk::NavigationTool::New(); m_ToolTransformationWidget = new QmitkInteractiveTransformationWidget(); m_Controls = nullptr; CreateQtPartControl(this); CreateConnections(); this->InitializeUIToolLandmarkLists(); Initialize(nullptr, ""); //Default values, which are not stored in tool m_Controls->m_CalibrationFileName->setText("none"); m_Controls->m_Surface_Use_Sphere->setChecked(true); m_Controls->m_CalibrationLandmarksList->EnableEditButton(false); m_Controls->m_RegistrationLandmarksList->EnableEditButton(false); RefreshTrackingDeviceCollection(); OnSurfaceUseToggled(); } QmitkNavigationToolCreationWidget::~QmitkNavigationToolCreationWidget() { m_Controls->m_CalibrationLandmarksList->SetPointSetNode(nullptr); m_Controls->m_RegistrationLandmarksList->SetPointSetNode(nullptr); delete m_ToolTransformationWidget; } void QmitkNavigationToolCreationWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkNavigationToolCreationWidgetControls; m_Controls->setupUi(parent); } } void QmitkNavigationToolCreationWidget::CreateConnections() { if (m_Controls) { connect((QObject*)(m_Controls->m_TrackingDeviceTypeChooser), SIGNAL(currentIndexChanged(int)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_ToolNameEdit), SIGNAL(textChanged(const QString)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_ToolTypeChooser), SIGNAL(currentIndexChanged(int)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_IdentifierEdit), SIGNAL(textChanged(const QString)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_SerialNumberEdit), SIGNAL(textChanged(const QString)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_ToolAxisX), SIGNAL(valueChanged(int)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_ToolAxisY), SIGNAL(valueChanged(int)), this, SLOT(GetValuesFromGuiElements())); connect((QObject*)(m_Controls->m_ToolAxisZ), SIGNAL(valueChanged(int)), this, SLOT(GetValuesFromGuiElements())); //Buttons connect((QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile())); connect(m_Controls->m_Surface_Use_Other, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceUseToggled())); connect(m_Controls->m_Surface_Load_File, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceUseToggled())); connect((QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface())); connect((QObject*)(m_Controls->m_EditToolTip), SIGNAL(clicked()), this, SLOT(OnEditToolTip())); connect((QObject*)(m_ToolTransformationWidget), SIGNAL(EditToolTipFinished(mitk::AffineTransform3D::Pointer)), this, SLOT(OnEditToolTipFinished(mitk::AffineTransform3D::Pointer))); connect((QObject*)(m_Controls->m_cancel), SIGNAL(clicked()), this, SLOT(OnCancel())); connect((QObject*)(m_Controls->m_finished), SIGNAL(clicked()), this, SLOT(OnFinished())); } } void QmitkNavigationToolCreationWidget::Initialize(mitk::DataStorage* dataStorage, const std::string& supposedIdentifier, const std::string& supposedName) { m_DataStorage = dataStorage; //initialize UI components m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage); m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true); m_Controls->m_SurfaceChooser->SetPredicate(mitk::NodePredicateDataType::New("Surface")); //Create new tool, which should be edited/created m_ToolToBeEdited = nullptr;//Reset m_ToolToBeEdited = mitk::NavigationTool::New();//Reinitialize m_ToolToBeEdited->SetIdentifier(supposedIdentifier); m_ToolToBeEdited->GetDataNode()->SetName(supposedName); this->SetDefaultData(m_ToolToBeEdited); } void QmitkNavigationToolCreationWidget::ShowToolPreview(std::string _name) { m_DataStorage->Add(m_ToolToBeEdited->GetDataNode()); m_ToolToBeEdited->GetDataNode()->SetName(_name); //change color to blue m_ToolToBeEdited->GetDataNode()->SetProperty("color", mitk::ColorProperty::New(0, 0, 1)); //Global Reinit to show new tool mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); } void QmitkNavigationToolCreationWidget::SetDefaultData(mitk::NavigationTool::Pointer DefaultTool) { //Set Members. This can either be the new initialized tool from call of Initialize() or a tool which already exists in the toolStorage m_ToolToBeEdited = DefaultTool->Clone(); //Set all gui variables SetGuiElements(); } void QmitkNavigationToolCreationWidget::SetGuiElements() { //Block signals, so that we don't call SetGuiElements again. This is undone at the end of this function! m_Controls->m_TrackingDeviceTypeChooser->blockSignals(true); m_Controls->m_ToolNameEdit->blockSignals(true); m_Controls->m_ToolTypeChooser->blockSignals(true); m_Controls->m_IdentifierEdit->blockSignals(true); m_Controls->m_SerialNumberEdit->blockSignals(true); m_Controls->m_ToolAxisX->blockSignals(true); m_Controls->m_ToolAxisY->blockSignals(true); m_Controls->m_ToolAxisZ->blockSignals(true); //DeviceType int index = m_Controls->m_TrackingDeviceTypeChooser->findText(QString::fromStdString(m_ToolToBeEdited->GetTrackingDeviceType())); if (index >= 0) { m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(index); } m_Controls->m_ToolNameEdit->setText(QString(m_ToolToBeEdited->GetToolName().c_str())); m_Controls->m_CalibrationFileName->setText(QString(m_ToolToBeEdited->GetCalibrationFile().c_str())); FillUIToolLandmarkLists(m_ToolToBeEdited->GetToolControlPoints(), m_ToolToBeEdited->GetToolLandmarks()); switch (m_ToolToBeEdited->GetType()) { case mitk::NavigationTool::Instrument: m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break; case mitk::NavigationTool::Fiducial: m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break; case mitk::NavigationTool::Skinmarker: m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break; case mitk::NavigationTool::Unknown: m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break; } m_Controls->m_IdentifierEdit->setText(QString(m_ToolToBeEdited->GetIdentifier().c_str())); m_Controls->m_SerialNumberEdit->setText(QString(m_ToolToBeEdited->GetSerialNumber().c_str())); QString _label = "(" + QString::number(m_ToolToBeEdited->GetToolTipPosition()[0], 'f', 1) + ", " + QString::number(m_ToolToBeEdited->GetToolTipPosition()[1], 'f', 1) + ", " + QString::number(m_ToolToBeEdited->GetToolTipPosition()[2], 'f', 1) + "), quat: [" + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[0], 'f', 2) + ", " + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[1], 'f', 2) + ", " + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[2], 'f', 2) + ", " + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[3], 'f', 2) + "]"; m_Controls->m_ToolTipLabel->setText(_label); //Undo block signals. Don't remove it, if signals are still blocked at the beginning of this function! m_Controls->m_TrackingDeviceTypeChooser->blockSignals(false); m_Controls->m_ToolNameEdit->blockSignals(false); m_Controls->m_ToolTypeChooser->blockSignals(false); m_Controls->m_IdentifierEdit->blockSignals(false); m_Controls->m_SerialNumberEdit->blockSignals(false); m_Controls->m_ToolAxisX->blockSignals(false); m_Controls->m_ToolAxisY->blockSignals(false); m_Controls->m_ToolAxisZ->blockSignals(false); } void QmitkNavigationToolCreationWidget::OnSurfaceUseToggled() { if (m_Controls->m_Surface_Use_Sphere->isChecked()) m_ToolToBeEdited->SetDefaultSurface(); m_Controls->m_SurfaceChooser->setEnabled(m_Controls->m_Surface_Use_Other->isChecked()); m_Controls->m_LoadSurface->setEnabled(m_Controls->m_Surface_Load_File->isChecked()); //Global Reinit to show tool surface preview mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); } void QmitkNavigationToolCreationWidget::OnLoadSurface() { std::string filename = QFileDialog::getOpenFileName(nullptr, tr("Open Surface"), QmitkIGTCommonHelper::GetLastFileLoadPath(), tr("STL (*.stl)")).toLatin1().data(); QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(QString::fromStdString(filename)); mitk::Surface::Pointer surface; try { - surface = mitk::IOUtil::LoadSurface(filename.c_str()); + surface = mitk::IOUtil::Load(filename.c_str()); } catch (mitk::Exception &e) { MITK_ERROR << "Exception occured: " << e.what(); return; } m_ToolToBeEdited->GetDataNode()->SetData(surface); //Global Reinit to show tool surface or preview mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); } void QmitkNavigationToolCreationWidget::OnLoadCalibrationFile() { QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open Calibration File"), QmitkIGTCommonHelper::GetLastFileLoadPath(), "*.*"); QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(fileName); m_Controls->m_CalibrationFileName->setText(fileName); m_ToolToBeEdited->SetCalibrationFile(fileName.toStdString()); } void QmitkNavigationToolCreationWidget::GetValuesFromGuiElements() { //Tracking Device m_ToolToBeEdited->SetTrackingDeviceType(m_Controls->m_TrackingDeviceTypeChooser->currentText().toStdString()); //m_ToolToBeEdited->GetDataNode()->SetName(m_Controls->m_ToolNameEdit->text().toStdString()); //Tool Landmarks mitk::PointSet::Pointer toolCalLandmarks, toolRegLandmarks; GetUIToolLandmarksLists(toolCalLandmarks, toolRegLandmarks); m_ToolToBeEdited->SetToolControlPoints(toolCalLandmarks); m_ToolToBeEdited->SetToolLandmarks(toolRegLandmarks); //Advanced if (m_Controls->m_ToolTypeChooser->currentText() == "Instrument") m_ToolToBeEdited->SetType(mitk::NavigationTool::Instrument); else if (m_Controls->m_ToolTypeChooser->currentText() == "Fiducial") m_ToolToBeEdited->SetType(mitk::NavigationTool::Fiducial); else if (m_Controls->m_ToolTypeChooser->currentText() == "Skinmarker") m_ToolToBeEdited->SetType(mitk::NavigationTool::Skinmarker); else m_FinalTool->SetType(mitk::NavigationTool::Unknown); m_ToolToBeEdited->SetIdentifier(m_Controls->m_IdentifierEdit->text().toLatin1().data()); m_ToolToBeEdited->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toLatin1().data()); ////Tool Axis //mitk::Point3D toolAxis; //toolAxis.SetElement(0, (m_Controls->m_ToolAxisX->value())); //toolAxis.SetElement(1, (m_Controls->m_ToolAxisY->value())); //toolAxis.SetElement(2, (m_Controls->m_ToolAxisZ->value())); //m_ToolToBeEdited->SetToolAxis(toolAxis); } mitk::NavigationTool::Pointer QmitkNavigationToolCreationWidget::GetCreatedTool() { return m_FinalTool; } void QmitkNavigationToolCreationWidget::OnFinished() { if (m_Controls->m_Surface_Use_Other->isChecked()) m_ToolToBeEdited->GetDataNode()->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData()); //here we create a new tool m_FinalTool = m_ToolToBeEdited->Clone(); //Set the correct name of data node, cause the m_ToolToBeEdited was called "Tool preview" m_FinalTool->GetDataNode()->SetName(m_Controls->m_ToolNameEdit->text().toStdString()); emit NavigationToolFinished(); } void QmitkNavigationToolCreationWidget::OnCancel() { Initialize(nullptr, "");//Reset everything to a fresh tool, like it was done in the constructor emit Canceled(); } void QmitkNavigationToolCreationWidget::SetTrackingDeviceType(mitk::TrackingDeviceType type, bool changeable /*= true*/) { //Adapt Gui int index = m_Controls->m_TrackingDeviceTypeChooser->findText(QString::fromStdString(type)); if (index >= 0) { m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(index); } m_Controls->m_TrackingDeviceTypeChooser->setEditable(changeable); //Set data to member m_ToolToBeEdited->SetTrackingDeviceType(type); } //################################################################################## //############################## internal help methods ############################# //################################################################################## void QmitkNavigationToolCreationWidget::MessageBox(std::string s) { QMessageBox msgBox; msgBox.setText(s.c_str()); msgBox.exec(); } void QmitkNavigationToolCreationWidget::OnEditToolTip() { m_ToolTransformationWidget->SetToolToEdit(m_ToolToBeEdited); m_ToolTransformationWidget->SetDefaultRotation(m_ToolToBeEdited->GetToolAxisOrientation()); m_ToolTransformationWidget->SetDefaultOffset(m_ToolToBeEdited->GetToolTipPosition()); m_ToolTransformationWidget->open(); } void QmitkNavigationToolCreationWidget::OnEditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip) { //if user pressed cancle, nullptr is returned. Do nothing. Else, set values. if (toolTip) { m_ToolToBeEdited->SetToolTipPosition(toolTip->GetOffset()); mitk::NavigationData::Pointer tempND = mitk::NavigationData::New(toolTip);//Convert to Navigation data for simple transversion to quaternion m_ToolToBeEdited->SetToolAxisOrientation(tempND->GetOrientation()); //Update Label QString _label = "(" + QString::number(m_ToolToBeEdited->GetToolTipPosition()[0], 'f', 1) + ", " + QString::number(m_ToolToBeEdited->GetToolTipPosition()[1], 'f', 1) + ", " + QString::number(m_ToolToBeEdited->GetToolTipPosition()[2], 'f', 1) + "), quat: [" + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[0], 'f', 2) + ", " + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[1], 'f', 2) + ", " + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[2], 'f', 2) + ", " + QString::number(m_ToolToBeEdited->GetToolAxisOrientation()[3], 'f', 2) + "]"; m_Controls->m_ToolTipLabel->setText(_label); } } void QmitkNavigationToolCreationWidget::FillUIToolLandmarkLists(mitk::PointSet::Pointer calLandmarks, mitk::PointSet::Pointer regLandmarks) { m_calLandmarkNode->SetData(calLandmarks); m_regLandmarkNode->SetData(regLandmarks); m_Controls->m_CalibrationLandmarksList->SetPointSetNode(m_calLandmarkNode); m_Controls->m_RegistrationLandmarksList->SetPointSetNode(m_regLandmarkNode); } void QmitkNavigationToolCreationWidget::GetUIToolLandmarksLists(mitk::PointSet::Pointer& calLandmarks, mitk::PointSet::Pointer& regLandmarks) { calLandmarks = dynamic_cast(m_calLandmarkNode->GetData()); regLandmarks = dynamic_cast(m_regLandmarkNode->GetData()); } void QmitkNavigationToolCreationWidget::InitializeUIToolLandmarkLists() { m_calLandmarkNode = mitk::DataNode::New(); m_regLandmarkNode = mitk::DataNode::New(); FillUIToolLandmarkLists(mitk::PointSet::New(), mitk::PointSet::New()); } void QmitkNavigationToolCreationWidget::RefreshTrackingDeviceCollection() { us::ModuleContext* context = us::GetModuleContext(); std::vector > refs = context->GetServiceReferences(); if (refs.empty()) { MITK_WARN << "No tracking device service found!"; return; } mitk::TrackingDeviceTypeCollection* _DeviceTypeCollection = context->GetService(refs.front()); for (auto name : _DeviceTypeCollection->GetTrackingDeviceTypeNames()) { //if the device is not included yet, add name to comboBox and widget to stackedWidget if (m_Controls->m_TrackingDeviceTypeChooser->findText(QString::fromStdString(name)) == -1) { m_Controls->m_TrackingDeviceTypeChooser->addItem(QString::fromStdString(name)); } } } \ No newline at end of file diff --git a/Modules/IOExt/Internal/mitkStlVolumeTimeSeriesReader.cpp b/Modules/IOExt/Internal/mitkStlVolumeTimeSeriesReader.cpp index 07e1c8514b..d05562844a 100644 --- a/Modules/IOExt/Internal/mitkStlVolumeTimeSeriesReader.cpp +++ b/Modules/IOExt/Internal/mitkStlVolumeTimeSeriesReader.cpp @@ -1,80 +1,80 @@ /*=================================================================== 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 "mitkStlVolumeTimeSeriesReader.h" #include "mitkSurface.h" #include "vtkPolyData.h" #include void mitk::StlVolumeTimeSeriesReader::GenerateData() { if (!this->GenerateFileList()) { itkWarningMacro(<< "Sorry, file list could not be determined..."); return; } mitk::Surface::Pointer result = this->GetOutput(); MITK_INFO << "prefix: " << m_FilePrefix << ", pattern: " << m_FilePattern << std::endl; result->Expand(m_MatchedFileNames.size()); for (unsigned int i = 0; i < m_MatchedFileNames.size(); ++i) { std::string fileName = m_MatchedFileNames[i]; MITK_INFO << "Loading " << fileName << " as stl..." << std::endl; - mitk::Surface::Pointer timestepSurface = dynamic_cast(IOUtil::Load(fileName.c_str())[0].GetPointer()); + auto timestepSurface = IOUtil::Load(fileName.c_str()); if (timestepSurface.IsNull()) { itkWarningMacro(<< "stlReader returned nullptr while reading " << fileName << ". Trying to continue with empty vtkPolyData..."); result->SetVtkPolyData(vtkPolyData::New(), i); return; } result->SetVtkPolyData(timestepSurface->GetVtkPolyData(), i); } } bool mitk::StlVolumeTimeSeriesReader::CanReadFile(const std::string /*filename*/, const std::string filePrefix, const std::string filePattern) { if (filePattern != "" && filePrefix != "") return false; bool extensionFound = false; std::string::size_type STLPos = filePattern.rfind(".stl"); if ((STLPos != std::string::npos) && (STLPos == filePattern.length() - 4)) extensionFound = true; STLPos = filePattern.rfind(".STL"); if ((STLPos != std::string::npos) && (STLPos == filePattern.length() - 4)) extensionFound = true; if (!extensionFound) return false; return true; } mitk::StlVolumeTimeSeriesReader::StlVolumeTimeSeriesReader() { } mitk::StlVolumeTimeSeriesReader::~StlVolumeTimeSeriesReader() { } diff --git a/Modules/ImageStatistics/Testing/mitkImageStatisticsCalculatorTest.cpp b/Modules/ImageStatistics/Testing/mitkImageStatisticsCalculatorTest.cpp index 5854cd3d83..4efe996173 100644 --- a/Modules/ImageStatistics/Testing/mitkImageStatisticsCalculatorTest.cpp +++ b/Modules/ImageStatistics/Testing/mitkImageStatisticsCalculatorTest.cpp @@ -1,1767 +1,1767 @@ /*=================================================================== 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 "mitkImageStatisticsCalculator.h" #include #include #include #include #include #include #include #include #include #include #include /** * \brief Test class for mitkImageStatisticsCalculator * * This test covers: * - instantiation of an ImageStatisticsCalculator class * - correctness of statistics when using PlanarFigures for masking */ class mitkImageStatisticsCalculatorTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageStatisticsCalculatorTestSuite); MITK_TEST(TestUninitializedImage); MITK_TEST(TestCase1); MITK_TEST(TestCase2); MITK_TEST(TestCase3); MITK_TEST(TestCase4); MITK_TEST(TestCase5); MITK_TEST(TestCase6); MITK_TEST(TestCase7); MITK_TEST(TestCase8); MITK_TEST(TestCase9); MITK_TEST(TestCase10); MITK_TEST(TestCase11); MITK_TEST(TestCase12); MITK_TEST(TestImageMaskingEmpty); MITK_TEST(TestImageMaskingNonEmpty); MITK_TEST(TestRecomputeOnModifiedMask); MITK_TEST(TestPic3DStatistics); MITK_TEST(TestPic3DAxialPlanarFigureMaskStatistics); MITK_TEST(TestPic3DSagittalPlanarFigureMaskStatistics); MITK_TEST(TestPic3DCoronalPlanarFigureMaskStatistics); MITK_TEST(TestPic3DImageMaskStatistics_label1); MITK_TEST(TestPic3DImageMaskStatistics_label2); MITK_TEST(TestPic3DIgnorePixelValueMaskStatistics); MITK_TEST(TestPic3DSecondaryMaskStatistics); MITK_TEST(TestUS4DCylStatistics_time1); MITK_TEST(TestUS4DCylAxialPlanarFigureMaskStatistics_time1); MITK_TEST(TestUS4DCylSagittalPlanarFigureMaskStatistics_time1); MITK_TEST(TestUS4DCylCoronalPlanarFigureMaskStatistics_time1); MITK_TEST(TestUS4DCylImageMaskStatistics_time1_label_1); MITK_TEST(TestUS4DCylImageMaskStatistics_time2_label_1); MITK_TEST(TestUS4DCylImageMaskStatistics_time1_label_2); MITK_TEST(TestUS4DCylIgnorePixelValueMaskStatistics_time1); MITK_TEST(TestUS4DCylSecondaryMaskStatistics_time1); CPPUNIT_TEST_SUITE_END(); public: void setUp() override; void tearDown() override; void TestUninitializedImage(); void TestCase1(); void TestCase2(); void TestCase3(); void TestCase4(); void TestCase5(); void TestCase6(); void TestCase7(); void TestCase8(); void TestCase9(); void TestCase10(); void TestCase11(); void TestCase12(); void TestImageMaskingEmpty(); void TestImageMaskingNonEmpty(); void TestRecomputeOnModifiedMask(); void TestPic3DStatistics(); void TestPic3DAxialPlanarFigureMaskStatistics(); void TestPic3DSagittalPlanarFigureMaskStatistics(); void TestPic3DCoronalPlanarFigureMaskStatistics(); void TestPic3DImageMaskStatistics_label1(); void TestPic3DImageMaskStatistics_label2(); void TestPic3DIgnorePixelValueMaskStatistics(); void TestPic3DSecondaryMaskStatistics(); void TestUS4DCylStatistics_time1(); void TestUS4DCylAxialPlanarFigureMaskStatistics_time1(); void TestUS4DCylSagittalPlanarFigureMaskStatistics_time1(); void TestUS4DCylCoronalPlanarFigureMaskStatistics_time1(); void TestUS4DCylImageMaskStatistics_time1_label_1(); void TestUS4DCylImageMaskStatistics_time2_label_1(); void TestUS4DCylImageMaskStatistics_time1_label_2(); void TestUS4DCylIgnorePixelValueMaskStatistics_time1(); void TestUS4DCylSecondaryMaskStatistics_time1(); void TestDifferentNBinsForHistogramStatistics(); void TestDifferentBinSizeForHistogramStatistic(); void TestSwitchFromBinSizeToNBins(); void TestSwitchFromNBinsToBinSize(); private: mitk::Image::Pointer m_TestImage; mitk::Image::Pointer m_Pic3DImage; mitk::Image::Pointer m_Pic3DImageMask; mitk::Image::Pointer m_Pic3DImageMask2; mitk::PlanarFigure::Pointer m_Pic3DPlanarFigureAxial; mitk::PlanarFigure::Pointer m_Pic3DPlanarFigureSagittal; mitk::PlanarFigure::Pointer m_Pic3DPlanarFigureCoronal; mitk::Image::Pointer m_US4DImage; mitk::Image::Pointer m_US4DImageMask; mitk::Image::Pointer m_US4DImageMask2; mitk::PlanarFigure::Pointer m_US4DPlanarFigureAxial; mitk::PlanarFigure::Pointer m_US4DPlanarFigureSagittal; mitk::PlanarFigure::Pointer m_US4DPlanarFigureCoronal; mitk::PlaneGeometry::Pointer m_Geometry; // calculate statistics for the given image and planarpolygon const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer ComputeStatistics( mitk::Image::Pointer image, mitk::PlanarFigure::Pointer polygon ); // calculate statistics for the given image and mask const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer ComputeStatistics( mitk::Image::Pointer image, mitk::Image::Pointer image_mask ); // universal function to calculate statistics const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer ComputeStatisticsNew(mitk::Image::Pointer image, int timeStep=0, mitk::MaskGenerator::Pointer maskGen=nullptr, mitk::MaskGenerator::Pointer secondardMaskGen=nullptr, unsigned short label=1); void VerifyStatistics(mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer stats, double testMean, double testSD, double testMedian=0); void VerifyStatistics(mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer stats, long N, double mean, double MPP, double median, double skewness, double kurtosis, double uniformity, double UPP, double variance, double stdev, double min, double max, double RMS, double entropy, vnl_vector minIndex, vnl_vector maxIndex); }; void mitkImageStatisticsCalculatorTestSuite::tearDown() { m_TestImage = nullptr; m_Pic3DImage = nullptr; m_Pic3DImageMask = nullptr; m_Pic3DImageMask2 = nullptr; m_Pic3DPlanarFigureAxial = nullptr; m_Pic3DPlanarFigureSagittal = nullptr; m_Pic3DPlanarFigureCoronal = nullptr; m_US4DImage = nullptr; m_US4DImageMask = nullptr; m_US4DImageMask2 = nullptr; m_US4DPlanarFigureAxial = nullptr; m_US4DPlanarFigureSagittal = nullptr; m_US4DPlanarFigureCoronal = nullptr; m_Geometry = nullptr; } void mitkImageStatisticsCalculatorTestSuite::setUp() { std::string filename = this->GetTestDataFilePath("ImageStatisticsTestData/testimage.dcm"); std::string Pic3DFile = this->GetTestDataFilePath("Pic3D.nrrd"); std::string Pic3DImageMaskFile = this->GetTestDataFilePath("ImageStatisticsTestData/Pic3D-labels.nrrd"); std::string Pic3DImageMaskFile2 = this->GetTestDataFilePath("ImageStatisticsTestData/Pic3D-labels2.nrrd"); std::string Pic3DAxialPlanarFigureFile = this->GetTestDataFilePath("ImageStatisticsTestData/Pic3DAxialPlanarFigure.pf"); std::string Pic3DSagittalPlanarFigureFile = this->GetTestDataFilePath("ImageStatisticsTestData/Pic3DSagittalPlanarFigure.pf"); std::string Pic3DCoronalPlanarFigureFile = this->GetTestDataFilePath("ImageStatisticsTestData/Pic3DCoronalPlanarFigure.pf"); std::string US4DFile = this->GetTestDataFilePath("US4DCyl.nrrd"); std::string US4DImageMaskFile = this->GetTestDataFilePath("ImageStatisticsTestData/US4D-labels.nrrd"); std::string US4DImageMaskFile2 = this->GetTestDataFilePath("ImageStatisticsTestData/US4D-labels2.nrrd"); std::string US4DAxialPlanarFigureFile = this->GetTestDataFilePath("ImageStatisticsTestData/US4DAxialPlanarFigure.pf"); std::string US4DSagittalPlanarFigureFile = this->GetTestDataFilePath("ImageStatisticsTestData/US4DSagittalPlanarFigure.pf"); std::string US4DCoronalPlanarFigureFile = this->GetTestDataFilePath("ImageStatisticsTestData/US4DCoronalPlanarFigure.pf"); if (filename.empty() || Pic3DFile.empty() || Pic3DImageMaskFile.empty() || Pic3DAxialPlanarFigureFile.empty() || Pic3DSagittalPlanarFigureFile.empty() || Pic3DCoronalPlanarFigureFile.empty() || US4DFile.empty() || US4DImageMaskFile.empty() || US4DAxialPlanarFigureFile.empty() || US4DSagittalPlanarFigureFile.empty() || US4DCoronalPlanarFigureFile.empty()) { MITK_TEST_FAILED_MSG( << "Could not find test file" ) } MITK_TEST_OUTPUT(<< "Loading test image '" << filename << "'") - m_TestImage = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + m_TestImage = mitk::IOUtil::Load(filename); MITK_TEST_CONDITION_REQUIRED( m_TestImage.IsNotNull(), "Loaded an mitk::Image" ); m_Geometry = m_TestImage->GetSlicedGeometry()->GetPlaneGeometry(0); MITK_TEST_CONDITION_REQUIRED( m_Geometry.IsNotNull(), "Getting image geometry" ); - m_Pic3DImage = dynamic_cast(mitk::IOUtil::Load(Pic3DFile)[0].GetPointer()); + m_Pic3DImage = mitk::IOUtil::Load(Pic3DFile); MITK_TEST_CONDITION_REQUIRED( m_Pic3DImage.IsNotNull(), "Loaded Pic3D" ); - m_Pic3DImageMask = dynamic_cast(mitk::IOUtil::Load(Pic3DImageMaskFile)[0].GetPointer()); + m_Pic3DImageMask = mitk::IOUtil::Load(Pic3DImageMaskFile); MITK_TEST_CONDITION_REQUIRED( m_Pic3DImageMask.IsNotNull(), "Loaded Pic3D image mask" ); - m_Pic3DImageMask2 = dynamic_cast(mitk::IOUtil::Load(Pic3DImageMaskFile2)[0].GetPointer()); + m_Pic3DImageMask2 = mitk::IOUtil::Load(Pic3DImageMaskFile2); MITK_TEST_CONDITION_REQUIRED( m_Pic3DImageMask2.IsNotNull(), "Loaded Pic3D image secondary mask" ); - m_Pic3DPlanarFigureAxial = dynamic_cast(mitk::IOUtil::Load(Pic3DAxialPlanarFigureFile)[0].GetPointer()); + m_Pic3DPlanarFigureAxial = mitk::IOUtil::Load(Pic3DAxialPlanarFigureFile); MITK_TEST_CONDITION_REQUIRED( m_Pic3DPlanarFigureAxial.IsNotNull(), "Loaded Pic3D axial planarFigure" ); - m_Pic3DPlanarFigureSagittal = dynamic_cast(mitk::IOUtil::Load(Pic3DSagittalPlanarFigureFile)[0].GetPointer()); + m_Pic3DPlanarFigureSagittal = mitk::IOUtil::Load(Pic3DSagittalPlanarFigureFile); MITK_TEST_CONDITION_REQUIRED( m_Pic3DPlanarFigureSagittal.IsNotNull(), "Loaded Pic3D sagittal planarFigure" ); - m_Pic3DPlanarFigureCoronal = dynamic_cast(mitk::IOUtil::Load(Pic3DCoronalPlanarFigureFile)[0].GetPointer()); + m_Pic3DPlanarFigureCoronal = mitk::IOUtil::Load(Pic3DCoronalPlanarFigureFile); MITK_TEST_CONDITION_REQUIRED( m_Pic3DPlanarFigureCoronal.IsNotNull(), "Loaded Pic3D coronal planarFigure" ); - m_US4DImage = dynamic_cast(mitk::IOUtil::Load(US4DFile)[0].GetPointer()); + m_US4DImage = mitk::IOUtil::Load(US4DFile); MITK_TEST_CONDITION_REQUIRED( m_US4DImage.IsNotNull(), "Loaded US4D" ); - m_US4DImageMask = dynamic_cast(mitk::IOUtil::Load(US4DImageMaskFile)[0].GetPointer()); + m_US4DImageMask = mitk::IOUtil::Load(US4DImageMaskFile); MITK_TEST_CONDITION_REQUIRED( m_US4DImageMask.IsNotNull(), "Loaded US4D image mask" ); - m_US4DImageMask2 = dynamic_cast(mitk::IOUtil::Load(US4DImageMaskFile2)[0].GetPointer()); + m_US4DImageMask2 = mitk::IOUtil::Load(US4DImageMaskFile2); MITK_TEST_CONDITION_REQUIRED( m_US4DImageMask2.IsNotNull(), "Loaded US4D image mask2" ); - m_US4DPlanarFigureAxial = dynamic_cast(mitk::IOUtil::Load(US4DAxialPlanarFigureFile)[0].GetPointer()); + m_US4DPlanarFigureAxial = mitk::IOUtil::Load(US4DAxialPlanarFigureFile); MITK_TEST_CONDITION_REQUIRED( m_US4DPlanarFigureAxial.IsNotNull(), "Loaded US4D axial planarFigure" ); - m_US4DPlanarFigureSagittal = dynamic_cast(mitk::IOUtil::Load(US4DSagittalPlanarFigureFile)[0].GetPointer()); + m_US4DPlanarFigureSagittal = mitk::IOUtil::Load(US4DSagittalPlanarFigureFile); MITK_TEST_CONDITION_REQUIRED( m_US4DPlanarFigureSagittal.IsNotNull(), "Loaded US4D sagittal planarFigure" ); - m_US4DPlanarFigureCoronal = dynamic_cast(mitk::IOUtil::Load(US4DCoronalPlanarFigureFile)[0].GetPointer()); + m_US4DPlanarFigureCoronal = mitk::IOUtil::Load(US4DCoronalPlanarFigureFile); MITK_TEST_CONDITION_REQUIRED( m_US4DPlanarFigureCoronal.IsNotNull(), "Loaded US4D coronal planarFigure" ); } void mitkImageStatisticsCalculatorTestSuite::TestCase1() { /***************************** * one whole white pixel * -> mean of 255 expected ******************************/ MITK_INFO << std::endl << "Test case 1:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 10.5 ; pnt1[1] = 3.5; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5; figure1->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 10.5; pnt4[1] = 4.5; figure1->SetControlPoint( 3, pnt4, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 255.0, 0.0, 255.0); } void mitkImageStatisticsCalculatorTestSuite::TestCase2() { /***************************** * half pixel in x-direction (white) * -> mean of 255 expected ******************************/ MITK_INFO << std::endl << "Test case 2:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 10.0 ; pnt1[1] = 3.5; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5; figure1->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 10.0; pnt4[1] = 4.5; figure1->SetControlPoint( 3, pnt4, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 255.0, 0.0, 255.0); } void mitkImageStatisticsCalculatorTestSuite::TestCase3() { /***************************** * half pixel in diagonal-direction (white) * -> mean of 255 expected ******************************/ MITK_INFO << std::endl << "Test case 3:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 10.5 ; pnt1[1] = 3.5; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5; figure1->SetControlPoint( 2, pnt3, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 255.0, 0.0, 255.0); } void mitkImageStatisticsCalculatorTestSuite::TestCase4() { /***************************** * one pixel (white) + 2 half pixels (white) + 1 half pixel (black) * -> mean of 191.25 expected ******************************/ MITK_INFO << std::endl << "Test case 4:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 1.1; pnt1[1] = 1.1; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 2.0; pnt2[1] = 2.0; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 3.0; pnt3[1] = 1.0; figure1->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 2.0; pnt4[1] = 0.0; figure1->SetControlPoint( 3, pnt4, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 191.25, 110.41, 242.250); } void mitkImageStatisticsCalculatorTestSuite::TestCase5() { /***************************** * whole pixel (white) + half pixel (gray) in x-direction * -> mean of 191.5 expected ******************************/ MITK_INFO << std::endl << "Test case 5:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 11.0; pnt1[1] = 3.5; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 3.5; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 9.5; pnt3[1] = 4.5; figure1->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 11.0; pnt4[1] = 4.5; figure1->SetControlPoint( 3, pnt4, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 191.50, 63.50, 134.340); } void mitkImageStatisticsCalculatorTestSuite::TestCase6() { /***************************** * quarter pixel (black) + whole pixel (white) + half pixel (gray) in x-direction * -> mean of 191.5 expected ******************************/ MITK_INFO << std::endl << "Test case 6:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 11.0; pnt1[1] = 3.5; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.25; pnt2[1] = 3.5; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 9.25; pnt3[1] = 4.5; figure1->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 11.0; pnt4[1] = 4.5; figure1->SetControlPoint( 3, pnt4, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 191.5, 63.50, 134.340); } void mitkImageStatisticsCalculatorTestSuite::TestCase7() { /***************************** * half pixel (black) + whole pixel (white) + half pixel (gray) in x-direction * -> mean of 127.66 expected ******************************/ MITK_INFO << std::endl << "Test case 7:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure1 = mitk::PlanarPolygon::New(); figure1->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 11.0; pnt1[1] = 3.5; figure1->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.0; pnt2[1] = 3.5; figure1->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 9.0; pnt3[1] = 4.0; figure1->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 11.0; pnt4[1] = 4.0; figure1->SetControlPoint( 3, pnt4, true ); figure1->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure1.GetPointer()), 127.66, 104.1, 140.250); } void mitkImageStatisticsCalculatorTestSuite::TestCase8() { /***************************** * whole pixel (gray) * -> mean of 128 expected ******************************/ MITK_INFO << std::endl << "Test case 8:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New(); figure2->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 11.5; pnt1[1] = 10.5; figure2->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 11.5; pnt2[1] = 11.5; figure2->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 12.5; pnt3[1] = 11.5; figure2->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 12.5; pnt4[1] = 10.5; figure2->SetControlPoint( 3, pnt4, true ); figure2->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure2.GetPointer()), 128.0, 0.0, 128.0); } void mitkImageStatisticsCalculatorTestSuite::TestCase9() { /***************************** * whole pixel (gray) + half pixel (white) in y-direction * -> mean of 191.5 expected ******************************/ MITK_INFO << std::endl << "Test case 9:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New(); figure2->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 11.5; pnt1[1] = 10.5; figure2->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 11.5; pnt2[1] = 12.0; figure2->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 12.5; pnt3[1] = 12.0; figure2->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 12.5; pnt4[1] = 10.5; figure2->SetControlPoint( 3, pnt4, true ); figure2->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure2.GetPointer()), 191.5, 63.50, 134.340); } void mitkImageStatisticsCalculatorTestSuite::TestCase10() { /***************************** * 2 whole pixel (white) + 2 whole pixel (black) in y-direction * -> mean of 127.66 expected ******************************/ MITK_INFO << std::endl << "Test case 10:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New(); figure2->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 11.5; pnt1[1] = 10.5; figure2->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 11.5; pnt2[1] = 13.5; figure2->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 12.5; pnt3[1] = 13.5; figure2->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 12.5; pnt4[1] = 10.5; figure2->SetControlPoint( 3, pnt4, true ); figure2->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure2.GetPointer()), 127.66, 104.1, 140.250); } void mitkImageStatisticsCalculatorTestSuite::TestCase11() { /***************************** * 9 whole pixels (white) + 3 half pixels (white) * + 3 whole pixel (black) [ + 3 slightly less than half pixels (black)] * -> mean of 204.0 expected ******************************/ MITK_INFO << std::endl << "Test case 11:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New(); figure2->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 0.5; pnt1[1] = 0.5; figure2->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 3.5; pnt2[1] = 3.5; figure2->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 8.4999; pnt3[1] = 3.5; figure2->SetControlPoint( 2, pnt3, true ); mitk::Point2D pnt4; pnt4[0] = 5.4999; pnt4[1] = 0.5; figure2->SetControlPoint( 3, pnt4, true ); figure2->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure2.GetPointer()), 204.0, 102.00, 242.250); } void mitkImageStatisticsCalculatorTestSuite::TestCase12() { /***************************** * half pixel (white) + whole pixel (white) + half pixel (black) * -> mean of 212.66 expected ******************************/ MITK_INFO << std::endl << "Test case 12:-----------------------------------------------------------------------------------"; mitk::PlanarPolygon::Pointer figure2 = mitk::PlanarPolygon::New(); figure2->SetPlaneGeometry( m_Geometry ); mitk::Point2D pnt1; pnt1[0] = 9.5; pnt1[1] = 0.5; figure2->PlaceFigure( pnt1 ); mitk::Point2D pnt2; pnt2[0] = 9.5; pnt2[1] = 2.5; figure2->SetControlPoint( 1, pnt2, true ); mitk::Point2D pnt3; pnt3[0] = 11.5; pnt3[1] = 2.5; figure2->SetControlPoint( 2, pnt3, true ); figure2->GetPolyLine(0); this->VerifyStatistics(ComputeStatistics(m_TestImage, figure2.GetPointer()), 212.66, 59.860, 248.640); } void mitkImageStatisticsCalculatorTestSuite::TestImageMaskingEmpty() { MITK_INFO << std::endl << "TestImageMaskingEmpty:-----------------------------------------------------------------------------------"; mitk::Image::Pointer mask_image = mitk::ImageGenerator::GenerateImageFromReference( m_TestImage, 0 ); this->VerifyStatistics( ComputeStatistics( m_TestImage, mask_image ), -21474836.480, -21474836.480, -21474836.480); // empty statisticsContainer (default values) } void mitkImageStatisticsCalculatorTestSuite::TestImageMaskingNonEmpty() { MITK_INFO << std::endl << "TestImageMaskingNonEmpty:-----------------------------------------------------------------------------------"; mitk::Image::Pointer mask_image = mitk::ImageGenerator::GenerateImageFromReference( m_TestImage, 0 ); // activate voxel in the mask image if (mask_image->GetDimension() == 3) { std::vector< itk::Index<3U> > activated_indices; itk::Index<3U> index = { { 10, 8, 0 } }; activated_indices.push_back(index); index[0] = 9; index[1] = 8; index[2] = 0; activated_indices.push_back(index); index[0] = 9; index[1] = 7; index[2] = 0; activated_indices.push_back(index); index[0] = 10; index[1] = 7; index[2] = 0; activated_indices.push_back(index); std::vector< itk::Index<3U> >::const_iterator indexIter = activated_indices.begin(); mitk::ImagePixelWriteAccessor< unsigned char, 3> writeAccess(mask_image); while (indexIter != activated_indices.end()) { writeAccess.SetPixelByIndex((*indexIter++), 1); } } if (mask_image->GetDimension() == 4) { std::vector< itk::Index<4U> > activated_indices; itk::Index<4U> index = { { 10, 8, 0, 0 } }; activated_indices.push_back(index); index[0] = 9; index[1] = 8; index[2] = 0; index[3] = 0; activated_indices.push_back(index); index[0] = 9; index[1] = 7; index[2] = 0; index[3] = 0; activated_indices.push_back(index); index[0] = 10; index[1] = 7; index[2] = 0; index[3] = 0; activated_indices.push_back(index); std::vector< itk::Index<4U> >::const_iterator indexIter = activated_indices.begin(); mitk::ImagePixelWriteAccessor< unsigned char, 4> writeAccess(mask_image); while (indexIter != activated_indices.end()) { writeAccess.SetPixelByIndex((*indexIter++), 1); } } this->VerifyStatistics( ComputeStatistics( m_TestImage, mask_image ), 127.5, 127.5, 12.750); } void mitkImageStatisticsCalculatorTestSuite::TestRecomputeOnModifiedMask() { MITK_INFO << std::endl << "TestRecomputeOnModifiedMask:-----------------------------------------------------------------------------------"; mitk::Image::Pointer mask_image = mitk::ImageGenerator::GenerateImageFromReference( m_TestImage, 0 ); mitk::ImageStatisticsCalculator::Pointer statisticsCalculator = mitk::ImageStatisticsCalculator::New(); statisticsCalculator->SetInputImage( m_TestImage ); mitk::ImageMaskGenerator::Pointer imgMaskGen = mitk::ImageMaskGenerator::New(); imgMaskGen->SetImageMask(mask_image); statisticsCalculator->SetMask(imgMaskGen.GetPointer()); this->VerifyStatistics( statisticsCalculator->GetStatistics(), -21474836.480, -21474836.480, -21474836.480); // activate voxel in the mask image if (mask_image->GetDimension() == 3) { itk::Index<3U> test_index = { { 11, 8, 0 } }; mitk::ImagePixelWriteAccessor< unsigned char, 3> writeAccess(mask_image); writeAccess.SetPixelByIndex(test_index, 1); } if (mask_image->GetDimension() == 4) { itk::Index<4U> test_index = { { 11, 8, 0, 0 } }; mitk::ImagePixelWriteAccessor< unsigned char, 4> writeAccess(mask_image); writeAccess.SetPixelByIndex(test_index, 1); } mask_image->Modified(); mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer stat = statisticsCalculator->GetStatistics(); this->VerifyStatistics( stat, 128.0, 0.0, 128.0); MITK_TEST_CONDITION( stat->GetN() == 1, "Calculated mask voxel count '" << stat->GetN() << "' is equal to the desired value '" << 1 << "'" ); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DStatistics() { MITK_INFO << std::endl << "Test plain Pic3D:-----------------------------------------------------------------------------------"; long expected_N = 3211264; double expected_mean = -365.80015345982144; double expected_MPP = 111.80226129535752; double expected_median = -105.16000366210938; double expected_skewness = -0.26976612134147004; double expected_kurtosis = 1.4655017209571437; double expected_uniformity = 0.06087994379480554; double expected_UPP = 0.011227934437026977; double expected_variance = 224036.80150510342; double expected_standarddev = 473.32525973700518; double expected_min = -1023; double expected_max = 1361; double expected_RMS = 598.20276978323352; double expected_entropy = 4.6727423654570357; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 0; expected_minIndex[1] = 0; expected_minIndex[2] = 0; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 139; expected_maxIndex[1] = 182; expected_maxIndex[2] = 43; const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DAxialPlanarFigureMaskStatistics() { MITK_INFO << std::endl << "Test Pic3D axial pf:-----------------------------------------------------------------------------------"; double expected_entropy = 5.6719817476387417; double expected_kurtosis = 5.8846935191205221; double expected_MPP = 230.43933685003768; double expected_max = 1206; double expected_mean = 182.30282131661443; double expected_median = 95.970001220703125; double expected_min = -156; long expected_N = 3190; double expected_RMS = 301.93844376702253; double expected_skewness = 1.6400489794326298; double expected_standarddev = 240.69172225993557; double expected_UPP = 0.024889790784288681; double expected_uniformity = 0.027579917650180332; double expected_variance = 57932.505164453964; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 156; expected_minIndex[1] = 133; expected_minIndex[2] = 24; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 125; expected_maxIndex[1] = 167; expected_maxIndex[2] = 24; mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_Pic3DImage); pfMaskGen->SetPlanarFigure(m_Pic3DPlanarFigureAxial); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, pfMaskGen.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DSagittalPlanarFigureMaskStatistics() { MITK_INFO << std::endl << "Test Pic3D sagittal pf:-----------------------------------------------------------------------------------"; double expected_entropy = 5.6051911962074286; double expected_kurtosis = 6.5814062739142338; double expected_MPP = 249.03202846975088; double expected_max = 1240; double expected_mean = 233.93602693602693; double expected_median = 174.9849853515625; double expected_min = -83; long expected_N = 1188; double expected_RMS = 332.03230188484594; double expected_skewness = 1.7489809015501814; double expected_standarddev = 235.62551813489128; double expected_UPP = 0.026837539253364174; double expected_uniformity = 0.027346982734188126; double expected_variance = 55519.384796335973; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 128; expected_minIndex[1] = 119; expected_minIndex[2] = 22; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 128; expected_maxIndex[1] = 167; expected_maxIndex[2] = 22; mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_Pic3DImage); pfMaskGen->SetPlanarFigure(m_Pic3DPlanarFigureSagittal); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, pfMaskGen.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DCoronalPlanarFigureMaskStatistics() { MITK_INFO << std::endl << "Test Pic3D coronal pf:-----------------------------------------------------------------------------------"; double expected_entropy = 6.0677398647867449; double expected_kurtosis = 1.6242929941303372; double expected_MPP = 76.649350649350652; double expected_max = 156; double expected_mean = -482.14807692307693; double expected_median = -660.07501220703125; double expected_min = -897; long expected_N = 520; double expected_RMS = 595.09446729069839; double expected_skewness = 0.51691492278851858; double expected_standarddev = 348.81321207686312; double expected_UPP = 0.0021560650887573964; double expected_uniformity = 0.020295857988165685; double expected_variance = 121670.6569193787; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 217; expected_minIndex[1] = 127; expected_minIndex[2] = 43; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 209; expected_maxIndex[1] = 127; expected_maxIndex[2] = 39; mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_Pic3DImage); pfMaskGen->SetPlanarFigure(m_Pic3DPlanarFigureCoronal); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, pfMaskGen.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DImageMaskStatistics_label1() { MITK_INFO << std::endl << "Test Pic3D image mask label 1 pf:-----------------------------------------------------------------------------------"; double expected_entropy = 5.695858251095868; double expected_kurtosis = 4.2728827997815717; double expected_MPP = 413.52408256880733; double expected_max = 1206; double expected_mean = 413.52408256880733; double expected_median = 324; double expected_min = 6; long expected_N = 872; double expected_RMS = 472.02024695145235; double expected_skewness = 1.3396074364415382; double expected_standarddev = 227.59821323493802; double expected_UPP = 0.029758648261930806; double expected_uniformity = 0.029758648261930806; double expected_variance = 51800.946667736309; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 135; expected_minIndex[1] = 158; expected_minIndex[2] = 24; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 125; expected_maxIndex[1] = 167; expected_maxIndex[2] = 24; mitk::ImageMaskGenerator::Pointer imgMaskGen = mitk::ImageMaskGenerator::New(); imgMaskGen->SetImageMask(m_Pic3DImageMask); imgMaskGen->SetInputImage(m_Pic3DImage); imgMaskGen->SetTimeStep(0); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, imgMaskGen.GetPointer(), nullptr, 1); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DImageMaskStatistics_label2() { MITK_INFO << std::endl << "Test Pic3D image mask label 2 pf:-----------------------------------------------------------------------------------"; double expected_entropy = 4.3685781901212764; double expected_kurtosis = 9.7999112757587934; double expected_MPP = -nan(""); double expected_max = -145; double expected_mean = -897.92833876221493; double expected_median = -969.16499900817871; double expected_min = -1008; long expected_N = 307; double expected_RMS = 913.01496468179471; double expected_skewness = 2.6658524648889736; double expected_standarddev = 165.29072623903585; double expected_UPP = 0; double expected_uniformity = 0.087544695434434425; double expected_variance = 27321.024180627897; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 170; expected_minIndex[1] = 60; expected_minIndex[2] = 24; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 173; expected_maxIndex[1] = 57; expected_maxIndex[2] = 24; mitk::ImageMaskGenerator::Pointer imgMaskGen = mitk::ImageMaskGenerator::New(); imgMaskGen->SetImageMask(m_Pic3DImageMask); imgMaskGen->SetInputImage(m_Pic3DImage); imgMaskGen->SetTimeStep(0); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, imgMaskGen.GetPointer(), nullptr, 2); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DIgnorePixelValueMaskStatistics() { MITK_INFO << std::endl << "Test Pic3D ignore zero pixels:-----------------------------------------------------------------------------------"; double expected_entropy = 4.671045011438645; double expected_kurtosis = 1.4638176488404484; double expected_MPP = 111.80226129535752; double expected_max = 1361; double expected_mean = -366.48547402877585; double expected_median = -105.16000366210938; double expected_min = -1023; long expected_N = 3205259; double expected_RMS = 598.76286909522139; double expected_skewness = -0.26648854845130782; double expected_standarddev = 473.50329537717545; double expected_UPP = 0.011270044547276429; double expected_uniformity = 0.061029773286547614; double expected_variance = 224205.37073304466; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 0; expected_minIndex[1] = 0; expected_minIndex[2] = 0; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 139; expected_maxIndex[1] = 182; expected_maxIndex[2] = 43; mitk::IgnorePixelMaskGenerator::Pointer ignPixelValMask = mitk::IgnorePixelMaskGenerator::New(); ignPixelValMask->SetInputImage(m_Pic3DImage); ignPixelValMask->SetIgnoredPixelValue(0); ignPixelValMask->SetTimeStep(0); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, ignPixelValMask.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestPic3DSecondaryMaskStatistics() { MITK_INFO << std::endl << "Test Pic3D ignore zero pixels AND Image mask 2:-----------------------------------------------------------------------------------"; double expected_entropy = 5.9741637167320176; double expected_kurtosis = 3.490663358061596; double expected_MPP = 332.43534482758622; double expected_max = 1206; double expected_mean = 320.63333333333333; double expected_median = 265.06500244140625; double expected_min = -57; long expected_N = 720; double expected_RMS = 433.57749531594055; double expected_skewness = 1.1047775627624981; double expected_standarddev = 291.86248474238687; double expected_UPP = 0.020628858024691339; double expected_uniformity = 0.021377314814814797; double expected_variance = 85183.710000000006; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 116; expected_minIndex[1] = 170; expected_minIndex[2] = 24; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 125; expected_maxIndex[1] = 167; expected_maxIndex[2] = 24; mitk::IgnorePixelMaskGenerator::Pointer ignPixelValMask = mitk::IgnorePixelMaskGenerator::New(); ignPixelValMask->SetInputImage(m_Pic3DImage); ignPixelValMask->SetIgnoredPixelValue(0); ignPixelValMask->SetTimeStep(0); mitk::ImageMaskGenerator::Pointer imgMaskGen2 = mitk::ImageMaskGenerator::New(); imgMaskGen2->SetImageMask(m_Pic3DImageMask2); imgMaskGen2->SetInputImage(m_Pic3DImage); imgMaskGen2->SetTimeStep(0); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_Pic3DImage, 0, imgMaskGen2.GetPointer(), ignPixelValMask.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylStatistics_time1() { MITK_INFO << std::endl << "Test plain US4D timeStep1:-----------------------------------------------------------------------------------"; double expected_entropy = 4.8272774900452502; double expected_kurtosis = 6.1336513352934432; double expected_MPP = 53.395358640738536; double expected_max = 199; double expected_mean = 35.771298153622375; double expected_median = 20.894999504089355; double expected_min = 0; long expected_N = 3409920; double expected_RMS = 59.244523377028408; double expected_skewness = 1.8734292240015058; double expected_standarddev = 47.226346233600559; double expected_UPP = 0.12098731125004937; double expected_uniformity = 0.12098731125004937; double expected_variance = 2230.3277785759178; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 0; expected_minIndex[1] = 0; expected_minIndex[2] = 0; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 268; expected_maxIndex[1] = 101; expected_maxIndex[2] = 0; const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylAxialPlanarFigureMaskStatistics_time1() { MITK_INFO << std::endl << "Test US4D axial pf timeStep1:-----------------------------------------------------------------------------------"; double expected_entropy = 6.218151288002292; double expected_kurtosis = 1.7322676370242023; double expected_MPP = 121.11663807890223; double expected_max = 199; double expected_mean = 121.11663807890223; double expected_median = 120.14999771118164; double expected_min = 9; long expected_N = 2332; double expected_RMS = 134.41895158590751; double expected_skewness = -0.1454808104597369; double expected_standarddev = 58.30278317472294; double expected_UPP = 0.021354765820606133; double expected_uniformity = 0.021354765820606133; double expected_variance = 3399.214525918756; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 129; expected_minIndex[1] = 131; expected_minIndex[2] = 19; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 126; expected_maxIndex[1] = 137; expected_maxIndex[2] = 19; mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_US4DImage); pfMaskGen->SetPlanarFigure(m_US4DPlanarFigureAxial); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, pfMaskGen.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylSagittalPlanarFigureMaskStatistics_time1() { MITK_INFO << std::endl << "Test US4D sagittal pf timeStep1:-----------------------------------------------------------------------------------"; double expected_entropy = 5.2003987046387508; double expected_kurtosis = 2.7574491062430142; double expected_MPP = 26.212534059945504; double expected_max = 59; double expected_mean = 26.176870748299319; double expected_median = 26.254999160766602; double expected_min = 0; long expected_N = 735; double expected_RMS = 28.084905283121476; double expected_skewness = 0.18245181360752327; double expected_standarddev = 10.175133541567705; double expected_UPP = 0.032921467906890628; double expected_uniformity = 0.032921467906890628; double expected_variance = 103.53334258873615; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 147; expected_minIndex[1] = 94; expected_minIndex[2] = 21; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 147; expected_maxIndex[1] = 77; expected_maxIndex[2] = 24; mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_US4DImage); pfMaskGen->SetPlanarFigure(m_US4DPlanarFigureSagittal); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, pfMaskGen.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylCoronalPlanarFigureMaskStatistics_time1() { MITK_INFO << std::endl << "Test US4D coronal pf timeStep1:-----------------------------------------------------------------------------------"; double expected_entropy = 5.8892941136639161; double expected_kurtosis = 4.6434920707409564; double expected_MPP = 55.486426346239433; double expected_max = 199; double expected_mean = 55.118479221927501; double expected_median = 36.815000534057617; double expected_min = 0; long expected_N = 2262; double expected_RMS = 71.98149752438627; double expected_skewness = 1.4988288344523237; double expected_standarddev = 46.29567187238105; double expected_UPP = 0.023286748110675673; double expected_uniformity = 0.023286748110675673; double expected_variance = 2143.2892341151742; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 214; expected_minIndex[1] = 169; expected_minIndex[2] = 10; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 99; expected_maxIndex[1] = 169; expected_maxIndex[2] = 17; mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_US4DImage); pfMaskGen->SetPlanarFigure(m_US4DPlanarFigureCoronal); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, pfMaskGen.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylImageMaskStatistics_time1_label_1() { MITK_INFO << std::endl << "Test US4D image mask time 1 label 1:-----------------------------------------------------------------------------------"; double expected_entropy = 5.0082903903398677; double expected_kurtosis = 3.6266994778237809; double expected_MPP = 169.58938547486034; double expected_max = 199; double expected_mean = 169.58938547486034; double expected_median = 187.44000244140625; double expected_min = 63; long expected_N = 716; double expected_RMS = 173.09843164831432; double expected_skewness = -1.2248969838579555; double expected_standarddev = 34.677188083311712; double expected_UPP = 0.076601073624418703; double expected_uniformity = 0.076601073624418703; double expected_variance = 1202.5073733653758; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 82; expected_minIndex[1] = 158; expected_minIndex[2] = 19; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 126; expected_maxIndex[1] = 140; expected_maxIndex[2] = 19; mitk::ImageMaskGenerator::Pointer imgMask1 = mitk::ImageMaskGenerator::New(); imgMask1->SetInputImage(m_US4DImage); imgMask1->SetImageMask(m_US4DImageMask); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, imgMask1.GetPointer(), nullptr, 1); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylImageMaskStatistics_time2_label_1() { MITK_INFO << std::endl << "Test US4D image mask time 2 label 1:-----------------------------------------------------------------------------------"; double expected_entropy = 5.1857604214916506; double expected_kurtosis = 3.0692303858330683; double expected_MPP = 167.97194163860831; double expected_max = 199; double expected_mean = 167.97194163860831; double expected_median = 184.39499664306641; double expected_min = 72; long expected_N = 891; double expected_RMS = 171.67986611998634; double expected_skewness = -1.1221651136259736; double expected_standarddev = 35.488071983870803; double expected_UPP = 0.063124070232188439; double expected_uniformity = 0.063124070232188439; double expected_variance = 1259.4032531323958; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 103; expected_minIndex[1] = 212; expected_minIndex[2] = 19; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 102; expected_maxIndex[1] = 168; expected_maxIndex[2] = 19; mitk::ImageMaskGenerator::Pointer imgMask1 = mitk::ImageMaskGenerator::New(); imgMask1->SetInputImage(m_US4DImage); imgMask1->SetImageMask(m_US4DImageMask); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 2, imgMask1.GetPointer(), nullptr, 1); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylImageMaskStatistics_time1_label_2() { MITK_INFO << std::endl << "Test US4D image mask time 1 label 2:-----------------------------------------------------------------------------------"; double expected_entropy = 5.0822234230119001; double expected_kurtosis = 2.4346603343623747; double expected_MPP = 20.733626373626375; double expected_max = 46; double expected_mean = 20.624836029733274; double expected_median = 20.010000228881836; double expected_min = 0; long expected_N = 2287; double expected_RMS = 22.508347574573804; double expected_skewness = 0.13837218490626488; double expected_standarddev = 9.0134260569684965; double expected_UPP = 0.034783970308787; double expected_uniformity = 0.034783970308787; double expected_variance = 81.241849284438644; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 178; expected_minIndex[1] = 76; expected_minIndex[2] = 19; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 198; expected_maxIndex[1] = 90; expected_maxIndex[2] = 19; mitk::ImageMaskGenerator::Pointer imgMask1 = mitk::ImageMaskGenerator::New(); imgMask1->SetInputImage(m_US4DImage); imgMask1->SetImageMask(m_US4DImageMask); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, imgMask1.GetPointer(), nullptr, 2); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylIgnorePixelValueMaskStatistics_time1() { MITK_INFO << std::endl << "Test US4D ignore zero pixels:-----------------------------------------------------------------------------------"; double expected_entropy = 5.8609813848087962; double expected_kurtosis = 4.7556214582883651; double expected_MPP = 53.395358640738536; double expected_max = 199; double expected_mean = 53.395358640738536; double expected_median = 35.649999618530273; double expected_min = 1; long expected_N = 2284417; double expected_RMS = 72.382339046507084; double expected_skewness = 1.588289859859108; double expected_standarddev = 48.868585834566694; double expected_UPP = 0.023927063695115193; double expected_uniformity = 0.023927063695115193; double expected_variance = 2388.1386814704128; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 187; expected_minIndex[1] = 19; expected_minIndex[2] = 0; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 268; expected_maxIndex[1] = 101; expected_maxIndex[2] = 0; mitk::IgnorePixelMaskGenerator::Pointer ignPixelValMask = mitk::IgnorePixelMaskGenerator::New(); ignPixelValMask->SetInputImage(m_US4DImage); ignPixelValMask->SetIgnoredPixelValue(0); ignPixelValMask->SetTimeStep(1); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, ignPixelValMask.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } void mitkImageStatisticsCalculatorTestSuite::TestUS4DCylSecondaryMaskStatistics_time1() { MITK_INFO << std::endl << "Test US4d ignore zero pixels AND Image mask 2:-----------------------------------------------------------------------------------"; double expected_entropy = 4.9955858614274558; double expected_kurtosis = 17.471042803365179; double expected_MPP = 32.791403286978507; double expected_max = 199; double expected_mean = 32.791403286978507; double expected_median = 25.75; double expected_min = 1; long expected_N = 17402; double expected_RMS = 42.776697859745241; double expected_skewness = 3.3991813038552596; double expected_standarddev = 27.469433016621732; double expected_UPP = 0.043040554251756687; double expected_uniformity = 0.043040554251756687; double expected_variance = 754.56975025466807; vnl_vector expected_minIndex; expected_minIndex.set_size(3); expected_minIndex[0] = 177; expected_minIndex[1] = 27; expected_minIndex[2] = 36; vnl_vector expected_maxIndex; expected_maxIndex.set_size(3); expected_maxIndex[0] = 109; expected_maxIndex[1] = 116; expected_maxIndex[2] = 36; mitk::IgnorePixelMaskGenerator::Pointer ignPixelValMask = mitk::IgnorePixelMaskGenerator::New(); ignPixelValMask->SetInputImage(m_US4DImage); ignPixelValMask->SetIgnoredPixelValue(0); mitk::ImageMaskGenerator::Pointer imgMaskGen2 = mitk::ImageMaskGenerator::New(); imgMaskGen2->SetImageMask(m_US4DImageMask2); imgMaskGen2->SetInputImage(m_US4DImage); const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer result = ComputeStatisticsNew(m_US4DImage, 1, imgMaskGen2.GetPointer(), ignPixelValMask.GetPointer()); //std::cout << result->GetAsString(); VerifyStatistics(result, expected_N, expected_mean, expected_MPP, expected_median, expected_skewness, expected_kurtosis, expected_uniformity, expected_UPP, expected_variance, expected_standarddev, expected_min, expected_max, expected_RMS, expected_entropy, expected_minIndex, expected_maxIndex); } const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer mitkImageStatisticsCalculatorTestSuite::ComputeStatistics( mitk::Image::Pointer image, mitk::PlanarFigure::Pointer polygon ) { mitk::ImageStatisticsCalculator::Pointer statisticsCalculator = mitk::ImageStatisticsCalculator::New(); statisticsCalculator->SetInputImage( image ); statisticsCalculator->SetNBinsForHistogramStatistics(10); mitk::PlanarFigureMaskGenerator::Pointer planFigMaskGen = mitk::PlanarFigureMaskGenerator::New(); planFigMaskGen->SetInputImage(image); planFigMaskGen->SetPlanarFigure(polygon); statisticsCalculator->SetMask(planFigMaskGen.GetPointer()); try { return statisticsCalculator->GetStatistics(); } catch( ... ) { } return mitk::ImageStatisticsCalculator::StatisticsContainer::New(); } const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer mitkImageStatisticsCalculatorTestSuite::ComputeStatistics(mitk::Image::Pointer image, mitk::Image::Pointer image_mask ) { mitk::ImageStatisticsCalculator::Pointer statisticsCalculator = mitk::ImageStatisticsCalculator::New(); statisticsCalculator->SetInputImage(image); statisticsCalculator->SetNBinsForHistogramStatistics(10); mitk::ImageMaskGenerator::Pointer imgMaskGen = mitk::ImageMaskGenerator::New(); imgMaskGen->SetImageMask(image_mask); statisticsCalculator->SetMask(imgMaskGen.GetPointer()); return statisticsCalculator->GetStatistics(); } const mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer mitkImageStatisticsCalculatorTestSuite::ComputeStatisticsNew(mitk::Image::Pointer image, int timeStep, mitk::MaskGenerator::Pointer maskGen, mitk::MaskGenerator::Pointer secondardMaskGen, unsigned short label) { mitk::ImageStatisticsCalculator::Pointer imgStatCalc = mitk::ImageStatisticsCalculator::New(); imgStatCalc->SetInputImage(image); if (maskGen.IsNotNull()) { imgStatCalc->SetMask(maskGen.GetPointer()); if (secondardMaskGen.IsNotNull()) { imgStatCalc->SetSecondaryMask(secondardMaskGen.GetPointer()); } } return imgStatCalc->GetStatistics(timeStep, label); } void mitkImageStatisticsCalculatorTestSuite::VerifyStatistics(mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer stats, double testMean, double testSD, double testMedian) { int tmpMean = stats->GetMean() * 100; double calculatedMean = tmpMean / 100.0; MITK_TEST_CONDITION( calculatedMean == testMean, "Calculated mean grayvalue '" << calculatedMean << "' is equal to the desired value '" << testMean << "'" ); int tmpSD = stats->GetStd() * 100; double calculatedSD = tmpSD / 100.0; MITK_TEST_CONDITION( calculatedSD == testSD, "Calculated grayvalue sd '" << calculatedSD << "' is equal to the desired value '" << testSD <<"'" ); int tmpMedian = stats->GetMedian() * 100; double calculatedMedian = tmpMedian / 100.0; MITK_TEST_CONDITION( testMedian == calculatedMedian, "Calculated median grayvalue '" << calculatedMedian << "' is equal to the desired value '" << testMedian << "'"); } void mitkImageStatisticsCalculatorTestSuite::VerifyStatistics(mitk::ImageStatisticsCalculator::StatisticsContainer::Pointer stats, long N, double mean, double MPP, double median, double skewness, double kurtosis, double uniformity, double UPP, double variance, double stdev, double min, double max, double RMS, double entropy, vnl_vector minIndex, vnl_vector maxIndex) { MITK_TEST_CONDITION(std::abs(stats->GetN() - N) < mitk::eps, "calculated N: " << stats->GetN() << " expected N: " << N); MITK_TEST_CONDITION(std::abs(stats->GetMean() - mean) < mitk::eps, "calculated mean: " << stats->GetMean() << " expected mean: " << mean); // in one test case MPP is None because the roi has no positive pixels if (!std::isnan(stats->GetMPP())) { MITK_TEST_CONDITION(std::abs(stats->GetMPP() - MPP) < mitk::eps, "calculated MPP: " << stats->GetMPP() << " expected MPP: " << MPP); } MITK_TEST_CONDITION(std::abs(stats->GetMedian() - median) < mitk::eps, "calculated median: " << stats->GetMedian() << " expected median: " << median); MITK_TEST_CONDITION(std::abs(stats->GetSkewness() - skewness) < mitk::eps, "calculated skewness: " << stats->GetSkewness() << " expected skewness: " << skewness); MITK_TEST_CONDITION(std::abs(stats->GetKurtosis() - kurtosis) < mitk::eps, "calculated kurtosis: " << stats->GetKurtosis() << " expected kurtosis: " << kurtosis); MITK_TEST_CONDITION(std::abs(stats->GetUniformity() - uniformity) < mitk::eps, "calculated uniformity: " << stats->GetUniformity() << " expected uniformity: " << uniformity); MITK_TEST_CONDITION(std::abs(stats->GetUPP() - UPP) < mitk::eps, "calculated UPP: " << stats->GetUPP() << " expected UPP: " << UPP); MITK_TEST_CONDITION(std::abs(stats->GetVariance() - variance) < mitk::eps, "calculated variance: " << stats->GetVariance() << " expected variance: " << variance); MITK_TEST_CONDITION(std::abs(stats->GetStd() - stdev) < mitk::eps, "calculated stdev: " << stats->GetStd() << " expected stdev: " << stdev); MITK_TEST_CONDITION(std::abs(stats->GetMin() - min) < mitk::eps, "calculated min: " << stats->GetMin() << " expected min: " << min); MITK_TEST_CONDITION(std::abs(stats->GetMax() - max) < mitk::eps, "calculated max: " << stats->GetMax() << " expected max: " << max); MITK_TEST_CONDITION(std::abs(stats->GetRMS() - RMS) < mitk::eps, "calculated RMS: " << stats->GetRMS() << " expected RMS: " << RMS); MITK_TEST_CONDITION(std::abs(stats->GetEntropy() - entropy) < mitk::eps, "calculated entropy: " << stats->GetEntropy() << " expected entropy: " << entropy); for (unsigned int i = 0; i < minIndex.size(); ++i) { MITK_TEST_CONDITION(std::abs(stats->GetMinIndex()[i] - minIndex[i]) < mitk::eps, "minIndex [" << i << "] = " << stats->GetMinIndex()[i] << " expected: " << minIndex[i]); } for (unsigned int i = 0; i < maxIndex.size(); ++i) { MITK_TEST_CONDITION(std::abs(stats->GetMaxIndex()[i] - maxIndex[i]) < mitk::eps, "maxIndex [" << i << "] = " << stats->GetMaxIndex()[i] << " expected: " << maxIndex[i]); } } void mitkImageStatisticsCalculatorTestSuite::TestUninitializedImage() { /***************************** * loading uninitialized image to datastorage ******************************/ MITK_INFO << std::endl << "Test uninitialized image: -----------------------------------------------------------------------------------"; MITK_TEST_FOR_EXCEPTION_BEGIN(mitk::Exception) mitk::Image::Pointer image = mitk::Image::New(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(image); mitk::ImageStatisticsCalculator::Pointer is = mitk::ImageStatisticsCalculator::New(); is->GetStatistics(); MITK_TEST_FOR_EXCEPTION_END(mitk::Exception) } MITK_TEST_SUITE_REGISTRATION(mitkImageStatisticsCalculator) diff --git a/Modules/Multilabel/Testing/mitkLabelSetImageIOTest.cpp b/Modules/Multilabel/Testing/mitkLabelSetImageIOTest.cpp index a8491085cb..5d24ec06ae 100644 --- a/Modules/Multilabel/Testing/mitkLabelSetImageIOTest.cpp +++ b/Modules/Multilabel/Testing/mitkLabelSetImageIOTest.cpp @@ -1,139 +1,139 @@ /*=================================================================== 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 std::string pathToImage; class mitkLabelSetImageIOTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkLabelSetImageIOTestSuite); MITK_TEST(TestReadWrite3DLabelSetImage); MITK_TEST(TestReadWrite3DplusTLabelSetImage); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer regularImage; mitk::LabelSetImage::Pointer multilabelImage; public: void setUp() override { regularImage = mitk::Image::New(); } void tearDown() override { regularImage = nullptr; multilabelImage = nullptr; } void TestReadWrite3DLabelSetImage() { unsigned int dimensions[3] = {256, 256, 312}; regularImage->Initialize(mitk::MakeScalarPixelType(), 3, dimensions); multilabelImage = mitk::LabelSetImage::New(); multilabelImage->Initialize(regularImage); mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); newlayer->SetLayer(1); mitk::Label::Pointer label0 = mitk::Label::New(); label0->SetName("Background"); label0->SetValue(0); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label0); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); multilabelImage->AddLayer(newlayer); pathToImage = mitk::IOUtil::CreateTemporaryDirectory(); pathToImage.append("/LabelSetTestImage3D.nrrd"); mitk::IOUtil::Save(multilabelImage, pathToImage); mitk::LabelSetImage::Pointer loadedImage = - dynamic_cast(mitk::IOUtil::Load(pathToImage)[0].GetPointer()); + mitk::IOUtil::Load(pathToImage); // This information is currently not serialized but also checked within the Equals function loadedImage->SetActiveLayer(multilabelImage->GetActiveLayer()); CPPUNIT_ASSERT_MESSAGE("Error reading label set image", loadedImage.IsNotNull()); CPPUNIT_ASSERT_MESSAGE("Error reading label set image", mitk::Equal(*multilabelImage, *loadedImage, 0.0001, true)); itksys::SystemTools::RemoveFile(pathToImage); } void TestReadWrite3DplusTLabelSetImage() { unsigned int dimensions[4] = {256, 256, 312, 10}; regularImage->Initialize(mitk::MakeScalarPixelType(), 4, dimensions); multilabelImage = mitk::LabelSetImage::New(); multilabelImage->Initialize(regularImage); mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); newlayer->SetLayer(1); mitk::Label::Pointer label0 = mitk::Label::New(); label0->SetName("Background"); label0->SetValue(0); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label0); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); multilabelImage->AddLayer(newlayer); pathToImage = mitk::IOUtil::CreateTemporaryDirectory(); pathToImage.append("/LabelSetTestImage3DplusT.nrrd"); mitk::IOUtil::Save(multilabelImage, pathToImage); mitk::LabelSetImage::Pointer loadedImage = - dynamic_cast(mitk::IOUtil::Load(pathToImage)[0].GetPointer()); + mitk::IOUtil::Load(pathToImage); // This information is currently not serialized but also checked within the Equals function loadedImage->SetActiveLayer(multilabelImage->GetActiveLayer()); CPPUNIT_ASSERT_MESSAGE("Error reading label set image", loadedImage.IsNotNull()); CPPUNIT_ASSERT_MESSAGE("Error reading label set image", mitk::Equal(*multilabelImage, *loadedImage, 0.0001, true)); itksys::SystemTools::RemoveFile(pathToImage); } }; MITK_TEST_SUITE_REGISTRATION(mitkLabelSetImageIO) diff --git a/Modules/Multilabel/Testing/mitkLabelSetImageSurfaceStampFilterTest.cpp b/Modules/Multilabel/Testing/mitkLabelSetImageSurfaceStampFilterTest.cpp index 64debf1156..a2aa55d867 100644 --- a/Modules/Multilabel/Testing/mitkLabelSetImageSurfaceStampFilterTest.cpp +++ b/Modules/Multilabel/Testing/mitkLabelSetImageSurfaceStampFilterTest.cpp @@ -1,88 +1,88 @@ /*=================================================================== 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 #include #include #include #include class mitkLabelSetImageSurfaceStampFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkLabelSetImageSurfaceStampFilterTestSuite); MITK_TEST(Result_Match_Expectation); CPPUNIT_TEST_SUITE_END(); private: mitk::LabelSetImage::Pointer m_LabelSetImage; mitk::Surface::Pointer m_Surface; public: void setUp() override { mitk::Image::Pointer regularImage = mitk::ImageGenerator::GenerateRandomImage(50, 50, 50, 1, 1, 1, 1, 0.3, 0.2); m_LabelSetImage = dynamic_cast( mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/EmptyMultiLabelSegmentation.nrrd"))[0].GetPointer()); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); mitk::Label::PixelType value1 = 1; label1->SetValue(value1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); mitk::Label::PixelType value2 = 2; label2->SetValue(value2); - m_Surface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30Reference.vtp"))[0].GetPointer()); + m_Surface = mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30Reference.vtp")); } void tearDown() override { // Delete LabelSetImage m_LabelSetImage = nullptr; } void Result_Match_Expectation() { mitk::LabelSetImageSurfaceStampFilter::Pointer filter = mitk::LabelSetImageSurfaceStampFilter::New(); filter->SetSurface(m_Surface); filter->SetForceOverwrite(true); filter->SetInput(m_LabelSetImage); filter->Update(); mitk::LabelSetImage::Pointer result = dynamic_cast( m_LabelSetImage.GetPointer()); // dynamic_cast(filter->GetOutput()); // result->DisconnectPipeline(); // mitk::LabelSetImage::Pointer result // =dynamic_cast(m_LabelSetImage->Clone().GetPointer());//dynamic_cast(filter->GetOutput()); mitk::LabelSetImage::Pointer expectedResult = dynamic_cast( mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/StampResultBasedOnEmptyML.nrrd"))[0].GetPointer()); MITK_ASSERT_EQUAL(result, expectedResult, "Result after stamping should be equal to the saved version"); } // Reduce contours with nth point void TestGetActiveLabel() {} }; MITK_TEST_SUITE_REGISTRATION(mitkLabelSetImageSurfaceStampFilter) diff --git a/Modules/Multilabel/Testing/mitkLabelSetImageTest.cpp b/Modules/Multilabel/Testing/mitkLabelSetImageTest.cpp index f585cbd720..aac87a554b 100644 --- a/Modules/Multilabel/Testing/mitkLabelSetImageTest.cpp +++ b/Modules/Multilabel/Testing/mitkLabelSetImageTest.cpp @@ -1,448 +1,448 @@ /*=================================================================== 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 #include class mitkLabelSetImageTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkLabelSetImageTestSuite); MITK_TEST(TestInitialize); MITK_TEST(TestAddLayer); MITK_TEST(TestGetActiveLabelSet); MITK_TEST(TestGetActiveLabel); MITK_TEST(TestInitializeByLabeledImage); MITK_TEST(TestGetLabelSet); MITK_TEST(TestGetLabel); MITK_TEST(TestSetExteriorLabel); MITK_TEST(TestGetTotalNumberOfLabels); MITK_TEST(TestExistsLabel); MITK_TEST(TestExistsLabelSet); MITK_TEST(TestSetActiveLayer); MITK_TEST(TestRemoveLayer); MITK_TEST(TestRemoveLabels); MITK_TEST(TestMergeLabel); // TODO check it these functionalities can be moved into a process object // MITK_TEST(TestMergeLabels); // MITK_TEST(TestConcatenate); // MITK_TEST(TestClearBuffer); // MITK_TEST(TestUpdateCenterOfMass); // MITK_TEST(TestGetVectorImage); // MITK_TEST(TestSetVectorImage); // MITK_TEST(TestGetLayerImage); CPPUNIT_TEST_SUITE_END(); private: mitk::LabelSetImage::Pointer m_LabelSetImage; public: void setUp() override { // Create a new labelset image m_LabelSetImage = mitk::LabelSetImage::New(); mitk::Image::Pointer regularImage = mitk::Image::New(); unsigned int dimensions[3] = {256, 256, 312}; regularImage->Initialize(mitk::MakeScalarPixelType(), 3, dimensions); m_LabelSetImage->Initialize(regularImage); } void tearDown() override { // Delete LabelSetImage m_LabelSetImage = nullptr; } // Reduce contours with nth point void TestInitialize() { // LabelSet image should always has the pixel type mitk::Label::PixelType CPPUNIT_ASSERT_MESSAGE("LabelSetImage has wrong pixel type", m_LabelSetImage->GetPixelType() == mitk::MakeScalarPixelType()); mitk::Image::Pointer regularImage = mitk::Image::New(); unsigned int dimensions[3] = {256, 256, 312}; regularImage->Initialize(mitk::MakeScalarPixelType(), 3, dimensions); mitk::BaseGeometry::Pointer regularImageGeo = regularImage->GetGeometry(); mitk::BaseGeometry::Pointer labelImageGeo = m_LabelSetImage->GetGeometry(); MITK_ASSERT_EQUAL(labelImageGeo, regularImageGeo, "LabelSetImage has wrong geometry"); // By default one layer containing the exterior label should be added CPPUNIT_ASSERT_MESSAGE("Image was not correctly initialized - number of layers is not one", m_LabelSetImage->GetNumberOfLayers() == 1); CPPUNIT_ASSERT_MESSAGE("Image was not correctly initialized - active layer has wrong ID", m_LabelSetImage->GetActiveLayer() == 0); CPPUNIT_ASSERT_MESSAGE("Image was not correctly initialized - active label is not the exterior label", m_LabelSetImage->GetActiveLabel()->GetValue() == 0); } void TestAddLayer() { CPPUNIT_ASSERT_MESSAGE("Number of layers is not zero", m_LabelSetImage->GetNumberOfLayers() == 1); m_LabelSetImage->AddLayer(); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - number of layers is not one", m_LabelSetImage->GetNumberOfLayers() == 2); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - active layer has wrong ID", m_LabelSetImage->GetActiveLayer() == 1); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - active label is not the exterior label", m_LabelSetImage->GetActiveLabel()->GetValue() == 0); mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); unsigned int layerID = m_LabelSetImage->AddLayer(newlayer); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - number of layers is not two", m_LabelSetImage->GetNumberOfLayers() == 3); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - active layer has wrong ID", m_LabelSetImage->GetActiveLayer() == layerID); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - active label is wrong", m_LabelSetImage->GetActiveLabel(layerID)->GetValue() == 200); } void TestGetActiveLabelSet() { mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); unsigned int layerID = m_LabelSetImage->AddLayer(newlayer); mitk::LabelSet::Pointer activeLayer = m_LabelSetImage->GetActiveLabelSet(); CPPUNIT_ASSERT_MESSAGE("Wrong layer ID was returned", layerID == 1); CPPUNIT_ASSERT_MESSAGE("Wrong active labelset returned", mitk::Equal(*newlayer, *activeLayer, 0.00001, true)); } void TestGetActiveLabel() { mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); mitk::Label::PixelType value1 = 1; label1->SetValue(value1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); mitk::Label::PixelType value2 = 200; label2->SetValue(value2); m_LabelSetImage->GetActiveLabelSet()->AddLabel(label1); m_LabelSetImage->GetActiveLabelSet()->AddLabel(label2); m_LabelSetImage->GetActiveLabelSet()->SetActiveLabel(1); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - active label is wrong", m_LabelSetImage->GetActiveLabel()->GetValue() == value1); m_LabelSetImage->GetActiveLabelSet()->SetActiveLabel(value2); CPPUNIT_ASSERT_MESSAGE("Layer was not added correctly to image - active label is wrong", m_LabelSetImage->GetActiveLabel()->GetValue() == value2); } void TestInitializeByLabeledImage() { mitk::Image::Pointer image = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/LabelSetTestInitializeImage.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/LabelSetTestInitializeImage.nrrd")); m_LabelSetImage->InitializeByLabeledImage(image); CPPUNIT_ASSERT_MESSAGE("Image - number of labels is not 6", m_LabelSetImage->GetNumberOfLabels() == 6); } void TestGetLabelSet() { // Test get non existing lset mitk::LabelSet::ConstPointer lset = m_LabelSetImage->GetLabelSet(10000); CPPUNIT_ASSERT_MESSAGE("Non existing labelset is not nullptr", lset.IsNull()); lset = m_LabelSetImage->GetLabelSet(0); CPPUNIT_ASSERT_MESSAGE("Existing labelset is nullptr", lset.IsNotNull()); } void TestGetLabel() { mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); mitk::Label::PixelType value1 = 1; label1->SetValue(value1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); mitk::Label::PixelType value2 = 200; label2->SetValue(value2); m_LabelSetImage->GetActiveLabelSet()->AddLabel(label1); m_LabelSetImage->AddLayer(); m_LabelSetImage->GetLabelSet(1)->AddLabel(label2); CPPUNIT_ASSERT_MESSAGE("Wrong label retrieved for active layer", mitk::Equal(*m_LabelSetImage->GetLabel(1), *label1, 0.0001, true)); CPPUNIT_ASSERT_MESSAGE("Wrong label retrieved for layer 1", mitk::Equal(*m_LabelSetImage->GetLabel(200, 1), *label2, 0.0001, true)); // Try to get a non existing label mitk::Label *label3 = m_LabelSetImage->GetLabel(1000); CPPUNIT_ASSERT_MESSAGE("Non existing label should be nullptr", label3 == nullptr); // Try to get a label from a non existing layer label3 = m_LabelSetImage->GetLabel(200, 1000); CPPUNIT_ASSERT_MESSAGE("Label from non existing layer should be nullptr", label3 == nullptr); } void TestSetExteriorLabel() { mitk::Label::Pointer exteriorLabel = mitk::Label::New(); exteriorLabel->SetName("MyExteriorSpecialLabel"); mitk::Label::PixelType value1 = 10000; exteriorLabel->SetValue(value1); m_LabelSetImage->SetExteriorLabel(exteriorLabel); CPPUNIT_ASSERT_MESSAGE("Wrong label retrieved for layer 1", mitk::Equal(*m_LabelSetImage->GetExteriorLabel(), *exteriorLabel, 0.0001, true)); // Exterior label should be set automatically for each new layer m_LabelSetImage->AddLayer(); CPPUNIT_ASSERT_MESSAGE("Wrong label retrieved for layer 1", mitk::Equal(*m_LabelSetImage->GetLabel(10000, 1), *exteriorLabel, 0.0001, true)); } void TestGetTotalNumberOfLabels() { mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); mitk::Label::PixelType value1 = 1; label1->SetValue(value1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); mitk::Label::PixelType value2 = 200; label2->SetValue(value2); m_LabelSetImage->GetActiveLabelSet()->AddLabel(label1); m_LabelSetImage->AddLayer(); m_LabelSetImage->GetLabelSet(1)->AddLabel(label2); CPPUNIT_ASSERT_MESSAGE( "Wrong total number of labels", m_LabelSetImage->GetTotalNumberOfLabels() == 4); // added 2 labels + 2 exterior default labels } void TestExistsLabel() { mitk::Label::Pointer label = mitk::Label::New(); label->SetName("Label2"); mitk::Label::PixelType value = 200; label->SetValue(value); m_LabelSetImage->AddLayer(); m_LabelSetImage->GetLabelSet(1)->AddLabel(label); m_LabelSetImage->SetActiveLayer(0); CPPUNIT_ASSERT_MESSAGE("Existing label was not found", m_LabelSetImage->ExistLabel(value) == true); CPPUNIT_ASSERT_MESSAGE("Non existing label was found", m_LabelSetImage->ExistLabel(10000) == false); } void TestExistsLabelSet() { // Cache active layer mitk::LabelSet::ConstPointer activeLayer = m_LabelSetImage->GetActiveLabelSet(); // Add new layer mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); m_LabelSetImage->AddLayer(newlayer); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(0) == true); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(1) == true); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(20) == false); } void TestSetActiveLayer() { // Cache active layer mitk::LabelSet::ConstPointer activeLayer = m_LabelSetImage->GetActiveLabelSet(); // Add new layer mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); unsigned int layerID = m_LabelSetImage->AddLayer(newlayer); // Set initial layer as active layer m_LabelSetImage->SetActiveLayer(0); CPPUNIT_ASSERT_MESSAGE("Wrong active labelset returned", mitk::Equal(*activeLayer, *m_LabelSetImage->GetActiveLabelSet(), 0.00001, true)); // Set previously added layer as active layer m_LabelSetImage->SetActiveLayer(layerID); CPPUNIT_ASSERT_MESSAGE("Wrong active labelset returned", mitk::Equal(*newlayer, *m_LabelSetImage->GetActiveLabelSet(), 0.00001, true)); // Set a non existing layer as active layer - nothing should change m_LabelSetImage->SetActiveLayer(10000); CPPUNIT_ASSERT_MESSAGE("Wrong active labelset returned", mitk::Equal(*newlayer, *m_LabelSetImage->GetActiveLabelSet(), 0.00001, true)); } void TestRemoveLayer() { // Cache active layer mitk::LabelSet::ConstPointer activeLayer = m_LabelSetImage->GetActiveLabelSet(); // Add new layers m_LabelSetImage->AddLayer(); mitk::LabelSet::Pointer newlayer = mitk::LabelSet::New(); mitk::Label::Pointer label1 = mitk::Label::New(); label1->SetName("Label1"); label1->SetValue(1); mitk::Label::Pointer label2 = mitk::Label::New(); label2->SetName("Label2"); label2->SetValue(200); newlayer->AddLabel(label1); newlayer->AddLabel(label2); newlayer->SetActiveLabel(200); m_LabelSetImage->AddLayer(newlayer); CPPUNIT_ASSERT_MESSAGE("Wrong active labelset returned", mitk::Equal(*newlayer, *m_LabelSetImage->GetActiveLabelSet(), 0.00001, true)); m_LabelSetImage->RemoveLayer(); CPPUNIT_ASSERT_MESSAGE("Wrong number of layers, after a layer was removed", m_LabelSetImage->GetNumberOfLayers() == 2); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(2) == false); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(1) == true); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(0) == true); m_LabelSetImage->RemoveLayer(); CPPUNIT_ASSERT_MESSAGE("Wrong number of layers, after a layer was removed", m_LabelSetImage->GetNumberOfLayers() == 1); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(1) == false); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(0) == true); CPPUNIT_ASSERT_MESSAGE("Wrong active layer", mitk::Equal(*activeLayer, *m_LabelSetImage->GetActiveLabelSet(), 0.00001, true)); m_LabelSetImage->RemoveLayer(); CPPUNIT_ASSERT_MESSAGE("Wrong number of layers, after a layer was removed", m_LabelSetImage->GetNumberOfLayers() == 0); CPPUNIT_ASSERT_MESSAGE("Check for existing layer failed", m_LabelSetImage->ExistLabelSet(0) == false); CPPUNIT_ASSERT_MESSAGE("Active layers is not nullptr although all layer have been removed", m_LabelSetImage->GetActiveLabelSet() == nullptr); } void TestRemoveLabels() { mitk::Image::Pointer image = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/LabelSetTestInitializeImage.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/LabelSetTestInitializeImage.nrrd")); m_LabelSetImage->InitializeByLabeledImage(image); CPPUNIT_ASSERT_MESSAGE("Image - number of labels is not 6", m_LabelSetImage->GetNumberOfLabels() == 6); // 2ndMin because of the exterior label = 0 CPPUNIT_ASSERT_MESSAGE("Labels with value 1 and 3 was not remove from the image", m_LabelSetImage->GetStatistics()->GetScalarValue2ndMin() == 1); CPPUNIT_ASSERT_MESSAGE("Label with value 7 was not remove from the image", m_LabelSetImage->GetStatistics()->GetScalarValueMax() == 7); CPPUNIT_ASSERT_MESSAGE("Label with ID 3 does not exists after initialization", m_LabelSetImage->ExistLabel(3) == true); CPPUNIT_ASSERT_MESSAGE("Label with ID 7 does not exists after initialization", m_LabelSetImage->ExistLabel(7) == true); std::vector labelsToBeRemoved; labelsToBeRemoved.push_back(1); labelsToBeRemoved.push_back(3); labelsToBeRemoved.push_back(7); m_LabelSetImage->RemoveLabels(labelsToBeRemoved); CPPUNIT_ASSERT_MESSAGE("Wrong number of labels after some have been removed", m_LabelSetImage->GetNumberOfLabels() == 3); // Values within the image are 0, 1, 3, 5, 6, 7 - New Min/Max value should be 5 / 6 // 2ndMin because of the exterior label = 0 CPPUNIT_ASSERT_MESSAGE("Labels with value 1 and 3 was not remove from the image", m_LabelSetImage->GetStatistics()->GetScalarValue2ndMin() == 5); CPPUNIT_ASSERT_MESSAGE("Label with value 7 was not remove from the image", m_LabelSetImage->GetStatistics()->GetScalarValueMax() == 6); } void TestMergeLabel() { - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/LabelSetTestInitializeImage.nrrd"))[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(GetTestDataFilePath("Multilabel/LabelSetTestInitializeImage.nrrd")); m_LabelSetImage = nullptr; m_LabelSetImage = mitk::LabelSetImage::New(); m_LabelSetImage->InitializeByLabeledImage(image); CPPUNIT_ASSERT_MESSAGE("Image - number of labels is not 6", m_LabelSetImage->GetNumberOfLabels() == 6); // 2ndMin because of the exterior label = 0 CPPUNIT_ASSERT_MESSAGE("Wrong MIN value", m_LabelSetImage->GetStatistics()->GetScalarValueMin() == 0); CPPUNIT_ASSERT_MESSAGE("Wrong MAX value", m_LabelSetImage->GetStatistics()->GetScalarValueMax() == 7); m_LabelSetImage->GetActiveLabelSet()->SetActiveLabel(6); // Merge label 7 with label 0. Result should be that label 7 is not present any more m_LabelSetImage->MergeLabel(6, 7); CPPUNIT_ASSERT_MESSAGE("Label with value 7 was not remove from the image", m_LabelSetImage->GetStatistics()->GetScalarValueMax() == 6); m_LabelSetImage->GetStatistics()->GetScalarValue2ndMax(); // Count all pixels with value 7 = 823 // Count all pixels with value 6 = 507 // Check if merge label has 507 + 823 = 1330 pixels CPPUNIT_ASSERT_MESSAGE("Label with value 7 was not remove from the image", m_LabelSetImage->GetStatistics()->GetCountOfMaxValuedVoxels() == 1330); } }; MITK_TEST_SUITE_REGISTRATION(mitkLabelSetImage) diff --git a/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp b/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp index 9be3143931..4e5bed14c2 100644 --- a/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp +++ b/Modules/OpenCVVideoSupport/Testing/mitkOpenCVMitkConversionTest.cpp @@ -1,290 +1,290 @@ /*=================================================================== 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. ===================================================================*/ // mitk includes #include "mitkImageToOpenCVImageFilter.h" #include "mitkOpenCVToMitkImageFilter.h" #include #include #include #include #include "mitkImageReadAccessor.h" #include "mitkImageSliceSelector.h" // itk includes #include #include #include // define test pixel indexes and intensities and other values typedef itk::RGBPixel< unsigned char > TestUCRGBPixelType; cv::Size testImageSize; cv::Point pos1; cv::Point pos2; cv::Point pos3; cv::Vec3b color1; cv::Vec3b color2; cv::Vec3b color3; uchar greyValue1; uchar greyValue2; uchar greyValue3; /*! Documentation * Test for image conversion of OpenCV images and mitk::Images. It tests the classes * OpenCVToMitkImageFilter and ImageToOpenCVImageFilter */ // Some declarations template void ComparePixels( itk::Image,VImageDimension>* image ); void ReadImageDataAndConvertForthAndBack(std::string imageFileName); void ConvertIplImageForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName); void ConvertCVMatForthAndBack(mitk::Image::Pointer inputForCVMat, std::string imageFileName); // Begin the test for mitkImage to OpenCV image conversion and back. int mitkOpenCVMitkConversionTest(int argc, char* argv[]) { MITK_TEST_BEGIN("ImageToOpenCVImageFilter") // the first part of this test checks the conversion of a cv::Mat style OpenCV image. // we build an cv::Mat image MITK_INFO << "setting test values"; testImageSize = cv::Size(11,11); pos1 = cv::Point(0,0); pos2 = cv::Point(5,5); pos3 = cv::Point(10,10); color1 = cv::Vec3b(50,0,0); color2 = cv::Vec3b(0,128,0); color3 = cv::Vec3b(0,0,255); greyValue1 = 0; greyValue2 = 128; greyValue3 = 255; MITK_INFO << "generating test OpenCV image (RGB)"; cv::Mat testRGBImage = cv::Mat::zeros( testImageSize, CV_8UC3 ); // generate some test intensity values testRGBImage.at(pos1)= color1; testRGBImage.at(pos2)= color2; testRGBImage.at(pos3)= color3; //cv::namedWindow("debug", CV_WINDOW_FREERATIO ); //cv::imshow("debug", testRGBImage.clone()); //cv::waitKey(0); // convert it to a mitk::Image MITK_INFO << "converting OpenCV test image to mitk image and comparing scalar rgb values"; mitk::OpenCVToMitkImageFilter::Pointer openCvToMitkFilter = mitk::OpenCVToMitkImageFilter::New(); openCvToMitkFilter->SetOpenCVMat( testRGBImage ); openCvToMitkFilter->Update(); mitk::Image::Pointer mitkImage = openCvToMitkFilter->GetOutput(); AccessFixedTypeByItk(mitkImage.GetPointer(), ComparePixels, (itk::RGBPixel), // rgb image (2) ); // convert it back to OpenCV image MITK_INFO << "converting mitk image to OpenCV image and comparing scalar rgb values"; mitk::ImageToOpenCVImageFilter::Pointer mitkToOpenCv = mitk::ImageToOpenCVImageFilter::New(); mitkToOpenCv->SetImage( mitkImage ); cv::Mat openCvImage = mitkToOpenCv->GetOpenCVMat(); // and test equality of the sentinel pixel cv::Vec3b convertedColor1 = openCvImage.at(pos1); cv::Vec3b convertedColor2 = openCvImage.at(pos2); cv::Vec3b convertedColor3 = openCvImage.at(pos3); MITK_TEST_CONDITION( color1 == convertedColor1, "Testing if initially created color values " << static_cast( color1[0] ) << ", " << static_cast( color1[1] ) << ", " << static_cast( color1[2] ) << " matches the color values " << static_cast( convertedColor1[0] ) << ", " << static_cast( convertedColor1[1] ) << ", " << static_cast( convertedColor1[2] ) << " at the same position " << pos1.x << ", " << pos1.y << " in the back converted OpenCV image" ) MITK_TEST_CONDITION( color2 == convertedColor2, "Testing if initially created color values " << static_cast( color2[0] ) << ", " << static_cast( color2[1] ) << ", " << static_cast( color2[2] ) << " matches the color values " << static_cast( convertedColor2[0] ) << ", " << static_cast( convertedColor2[1] ) << ", " << static_cast( convertedColor2[2] ) << " at the same position " << pos2.x << ", " << pos2.y << " in the back converted OpenCV image" ) MITK_TEST_CONDITION( color3 == convertedColor3, "Testing if initially created color values " << static_cast( color3[0] ) << ", " << static_cast( color3[1] ) << ", " << static_cast( color3[2] ) << " matches the color values " << static_cast( convertedColor3[0] ) << ", " << static_cast( convertedColor3[1] ) << ", " << static_cast( convertedColor3[2] ) << " at the same position " << pos3.x << ", " << pos3.y << " in the back converted OpenCV image" ) // the second part of this test checks the conversion of mitk::Images to Ipl images and cv::Mat and back. for (int i = 1; i < argc; ++i) { ReadImageDataAndConvertForthAndBack(argv[i]); } MITK_TEST_END(); } template void ComparePixels( itk::Image,VImageDimension>* image ) { typedef itk::RGBPixel PixelType; typedef itk::Image ImageType; typename ImageType::IndexType pixelIndex; pixelIndex[0] = pos1.x; pixelIndex[1] = pos1.y; PixelType onePixel = image->GetPixel( pixelIndex ); MITK_TEST_CONDITION( color1[0] == onePixel.GetBlue(), "Testing if blue value (= " << static_cast(color1[0]) << ") at postion " << pos1.x << ", " << pos1.y << " in OpenCV image is " << "equals the blue value (= " << static_cast(onePixel.GetBlue()) << ")" << " in the generated mitk image"); pixelIndex[0] = pos2.x; pixelIndex[1] = pos2.y; onePixel = image->GetPixel( pixelIndex ); MITK_TEST_CONDITION( color2[1] == onePixel.GetGreen(), "Testing if green value (= " << static_cast(color2[1]) << ") at postion " << pos2.x << ", " << pos2.y << " in OpenCV image is " << "equals the green value (= " << static_cast(onePixel.GetGreen()) << ")" << " in the generated mitk image"); pixelIndex[0] = pos3.x; pixelIndex[1] = pos3.y; onePixel = image->GetPixel( pixelIndex ); MITK_TEST_CONDITION( color3[2] == onePixel.GetRed(), "Testing if red value (= " << static_cast(color3[2]) << ") at postion " << pos3.x << ", " << pos3.y << " in OpenCV image is " << "equals the red value (= " << static_cast(onePixel.GetRed()) << ")" << " in the generated mitk image"); } void ReadImageDataAndConvertForthAndBack(std::string imageFileName) { // first we load an mitk::Image from the data repository - mitk::Image::Pointer mitkTestImage = dynamic_cast(mitk::IOUtil::Load(imageFileName)[0].GetPointer()); + mitk::Image::Pointer mitkTestImage = mitk::IOUtil::Load(imageFileName); // some format checking mitk::Image::Pointer resultImg = nullptr; if( mitkTestImage->GetDimension() <= 3 ) { if( mitkTestImage->GetDimension() > 2 && mitkTestImage->GetDimension(2) == 1 ) { mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New(); sliceSelector->SetInput(mitkTestImage); sliceSelector->SetSliceNr(0); sliceSelector->Update(); resultImg = sliceSelector->GetOutput()->Clone(); } else if(mitkTestImage->GetDimension() < 3) { resultImg = mitkTestImage; } else { return; // 3D images are not supported, except with just one slice. } } else { return; // 4D images are not supported! } ConvertIplImageForthAndBack(resultImg, imageFileName); ConvertCVMatForthAndBack(resultImg, imageFileName); } void ConvertCVMatForthAndBack(mitk::Image::Pointer inputForCVMat, std::string) { // now we convert it to OpenCV IplImage mitk::ImageToOpenCVImageFilter::Pointer toOCvConverter = mitk::ImageToOpenCVImageFilter::New(); toOCvConverter->SetImage(inputForCVMat); cv::Mat cvmatTestImage = toOCvConverter->GetOpenCVMat(); MITK_TEST_CONDITION_REQUIRED( !cvmatTestImage.empty(), "Conversion to cv::Mat successful!"); mitk::OpenCVToMitkImageFilter::Pointer toMitkConverter = mitk::OpenCVToMitkImageFilter::New(); toMitkConverter->SetOpenCVMat(cvmatTestImage); toMitkConverter->Update(); // initialize the image with the input image, since we want to test equality and OpenCV does not feature geometries and spacing mitk::Image::Pointer result = inputForCVMat->Clone(); mitk::ImageReadAccessor resultAcc(toMitkConverter->GetOutput(), toMitkConverter->GetOutput()->GetSliceData()); result->SetImportSlice(const_cast(resultAcc.GetData())); if( result->GetPixelType().GetNumberOfComponents() == 1 ) { MITK_ASSERT_EQUAL( result, inputForCVMat, "Testing equality of input and output image of cv::Mat conversion" ); } else if( result->GetPixelType().GetNumberOfComponents() == 3 ) { MITK_ASSERT_EQUAL( result, inputForCVMat, "Testing equality of input and output image of cv::Mat conversion" ); } else { MITK_WARN << "Unhandled number of components used to test equality, please enhance test!"; } // change OpenCV image to test if the filter gets updated cv::Mat changedcvmatTestImage = cvmatTestImage.clone(); if (result->GetPixelType().GetBitsPerComponent() == sizeof(char)*8) { changedcvmatTestImage.at(0,0) = cvmatTestImage.at(0,0) != 0 ? 0 : 1; } else if (result->GetPixelType().GetBitsPerComponent() == sizeof(float)*8) { changedcvmatTestImage.at(0,0) = cvmatTestImage.at(0,0) != 0 ? 0 : 1; } toMitkConverter->SetOpenCVMat(changedcvmatTestImage); toMitkConverter->Update(); MITK_TEST_NOT_EQUAL(toMitkConverter->GetOutput(), inputForCVMat, "Converted image must not be the same as before."); } void ConvertIplImageForthAndBack(mitk::Image::Pointer inputForIpl, std::string) { // now we convert it to OpenCV IplImage mitk::ImageToOpenCVImageFilter::Pointer toOCvConverter = mitk::ImageToOpenCVImageFilter::New(); toOCvConverter->SetImage(inputForIpl); IplImage* iplTestImage = toOCvConverter->GetOpenCVImage(); MITK_TEST_CONDITION_REQUIRED( iplTestImage != nullptr, "Conversion to OpenCv IplImage successful!"); mitk::OpenCVToMitkImageFilter::Pointer toMitkConverter = mitk::OpenCVToMitkImageFilter::New(); toMitkConverter->SetOpenCVImage(iplTestImage); toMitkConverter->Update(); // initialize the image with the input image, since we want to test equality and OpenCV does not feature geometries and spacing mitk::Image::Pointer result = inputForIpl->Clone(); mitk::ImageReadAccessor resultAcc(toMitkConverter->GetOutput(), toMitkConverter->GetOutput()->GetSliceData()); result->SetImportSlice(const_cast(resultAcc.GetData())); if( result->GetPixelType().GetNumberOfComponents() == 1 ) { MITK_ASSERT_EQUAL( result, inputForIpl, "Testing equality of input and output image of IplImage conversion" ); } else if( result->GetPixelType().GetNumberOfComponents() == 3 ) { MITK_ASSERT_EQUAL( result, inputForIpl, "Testing equality of input and output image of cv::Mat conversion" ); } else { MITK_WARN << "Unhandled number of components used to test equality, please enhance test!"; } } diff --git a/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp b/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp index 92e4008569..a557042cb0 100644 --- a/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp +++ b/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp @@ -1,1472 +1,1472 @@ /*=================================================================== 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. ===================================================================*/ // Please retain the following copyright notice /****************************************************************** * based on mcxyz.c Oct2014 * * mcxyz.c, in ANSI Standard C programing language * * created 2010, 2012 by * Steven L. JACQUES * Ting LI * Oregon Health & Science University * *******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "mitkImageCast.h" #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #include #endif #define ls 1.0E-7 /* Moving photon a little bit off the voxel face */ #define PI 3.1415926 #define ALIVE 1 /* if photon not yet terminated */ #define DEAD 0 /* if photon is to be terminated */ #define THRESHOLD 0.01 /* used in roulette */ #define CHANCE 0.1 /* used in roulette */ #define SQR(x) (x*x) #define SIGN(x) ((x)>=0 ? 1:-1) #define ONE_MINUS_COSZERO 1.0E-12 /* If 1-cos(theta) <= ONE_MINUS_COSZERO, fabs(theta) <= 1e-6 rad. */ /* If 1+cos(theta) <= ONE_MINUS_COSZERO, fabs(PI-theta) <= 1e-6 rad. */ /* Struct for storing x,y and z coordinates */ struct Location { int x, y, z; double absorb; }; struct Location initLocation(int x, int y, int z, double absorb) { struct Location loc; loc.x = x; loc.y = y; loc.z = z; loc.absorb = absorb; return loc; } class DetectorVoxel { public: Location location; std::vector* recordedPhotonRoute = new std::vector(); double* fluenceContribution; double m_PhotonNormalizationValue; long m_NumberPhotonsCurrent; DetectorVoxel(Location location, long totalNumberOfVoxels, double photonNormalizationValue) { this->location = location; this->fluenceContribution = (double *)malloc(totalNumberOfVoxels * sizeof(double)); for (int j = 0; j < totalNumberOfVoxels; j++) fluenceContribution[j] = 0; // ensure fluenceContribution[] starts empty. m_NumberPhotonsCurrent = 0; m_PhotonNormalizationValue = photonNormalizationValue; } }; bool verbose(false); class InputValues { private: std::string inputFilename; int tissueIterator; long long ix, iy, iz; public: int mcflag, launchflag, boundaryflag; double xfocus, yfocus, zfocus; double ux0, uy0, uz0; double radius; double waist; double xs, ys, zs; /* launch position */ int Nx, Ny, Nz, numberOfTissueTypes; /* # of bins */ char* tissueType; double* muaVector; double* musVector; double* gVector; double* normalizationVector; double xSpacing, ySpacing, zSpacing; double simulationTimeFromFile; long long Nphotons; long totalNumberOfVoxels; double* totalFluence; std::string myname; DetectorVoxel* detectorVoxel; mitk::Image::Pointer m_inputImage; mitk::Image::Pointer m_normalizationImage; InputValues() { tissueType = nullptr; muaVector = nullptr; musVector = nullptr; gVector = nullptr; detectorVoxel = nullptr; normalizationVector = nullptr; mcflag = 0; launchflag = 0; boundaryflag = 0; } double GetNormalizationValue(int x, int y, int z) { if (normalizationVector) return normalizationVector[z*Ny*Nx + x*Ny + y]; else return 1; } void LoadValues(std::string localInputFilename, float yOffset, std::string normalizationFilename, bool simulatePVFC) { inputFilename = localInputFilename; try { - m_inputImage = mitk::IOUtil::LoadImage(inputFilename); + m_inputImage = mitk::IOUtil::Load(inputFilename); } catch (...) { if (verbose) std::cout << "No .nrrd file found ... switching to legacy mode." << std::endl; } try { if (simulatePVFC && !normalizationFilename.empty()) - m_normalizationImage = mitk::IOUtil::LoadImage(normalizationFilename); + m_normalizationImage = mitk::IOUtil::Load(normalizationFilename); } catch (...) { if (verbose) std::cout << "No normalization .nrrd file found ... will not normalize PVFC" << std::endl; } if (m_normalizationImage.IsNotNull()) { mitk::ImageReadAccessor readAccess3(m_normalizationImage, m_normalizationImage->GetVolumeData(0)); normalizationVector = (double *)readAccess3.GetData(); } if (m_inputImage.IsNotNull()) // load stuff from nrrd file { simulationTimeFromFile = 0; Nx = m_inputImage->GetDimensions()[1]; Ny = m_inputImage->GetDimensions()[0]; Nz = m_inputImage->GetDimensions()[2]; xSpacing = m_inputImage->GetGeometry(0)->GetSpacing()[0]; ySpacing = m_inputImage->GetGeometry(0)->GetSpacing()[1]; zSpacing = m_inputImage->GetGeometry(0)->GetSpacing()[2]; mcflag = std::stoi(m_inputImage->GetProperty("mcflag")->GetValueAsString().c_str()); // mcflag, 0 = uniform, 1 = Gaussian, 2 = iso-pt, 4 = monospectral fraunhofer setup launchflag = std::stoi(m_inputImage->GetProperty("launchflag")->GetValueAsString().c_str());// 0 = let mcxyz calculate trajectory, 1 = manually set launch vector boundaryflag = std::stoi(m_inputImage->GetProperty("boundaryflag")->GetValueAsString().c_str());// 0 = no boundaries, 1 = escape at boundaries, 2 = escape at surface only xs = std::stod(m_inputImage->GetProperty("launchPointX")->GetValueAsString().c_str()); ys = std::stod(m_inputImage->GetProperty("launchPointY")->GetValueAsString().c_str()) + yOffset; zs = std::stod(m_inputImage->GetProperty("launchPointZ")->GetValueAsString().c_str()); xfocus = std::stod(m_inputImage->GetProperty("focusPointX")->GetValueAsString().c_str()); yfocus = std::stod(m_inputImage->GetProperty("focusPointY")->GetValueAsString().c_str()); zfocus = std::stod(m_inputImage->GetProperty("focusPointZ")->GetValueAsString().c_str()); ux0 = std::stod(m_inputImage->GetProperty("trajectoryVectorX")->GetValueAsString().c_str()); uy0 = std::stod(m_inputImage->GetProperty("trajectoryVectorY")->GetValueAsString().c_str()); uz0 = std::stod(m_inputImage->GetProperty("trajectoryVectorZ")->GetValueAsString().c_str()); radius = std::stod(m_inputImage->GetProperty("radius")->GetValueAsString().c_str()); waist = std::stod(m_inputImage->GetProperty("waist")->GetValueAsString().c_str()); totalNumberOfVoxels = Nx*Ny*Nz; if (verbose) std::cout << totalNumberOfVoxels << " = sizeof totalNumberOfVoxels" << std::endl; muaVector = (double *)malloc(totalNumberOfVoxels * sizeof(double)); /* tissue structure */ musVector = (double *)malloc(totalNumberOfVoxels * sizeof(double)); /* tissue structure */ gVector = (double *)malloc(totalNumberOfVoxels * sizeof(double)); /* tissue structure */ mitk::ImageReadAccessor readAccess0(m_inputImage, m_inputImage->GetVolumeData(0)); muaVector = (double *)readAccess0.GetData(); mitk::ImageReadAccessor readAccess1(m_inputImage, m_inputImage->GetVolumeData(1)); musVector = (double *)readAccess1.GetData(); mitk::ImageReadAccessor readAccess2(m_inputImage, m_inputImage->GetVolumeData(2)); gVector = (double *)readAccess2.GetData(); } else { mitkThrow() << "No longer support loading of binary tissue files."; } } }; class ReturnValues { private: long i1 = 0, i2 = 31; // used Random Generator long ma[56]; // used Random Generator /* ma[0] is not used. */ long mj, mk; short i, ii; public: long long Nphotons; double* totalFluence; std::string myname; DetectorVoxel* detectorVoxel; ReturnValues() { detectorVoxel = nullptr; Nphotons = 0; totalFluence = nullptr; } /* SUBROUTINES */ /************************************************************************** * RandomGen * A random number generator that generates uniformly * distributed random numbers between 0 and 1 inclusive. * The algorithm is based on: * W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. * Flannery, "Numerical Recipes in C," Cambridge University * Press, 2nd edition, (1992). * and * D.E. Knuth, "Seminumerical Algorithms," 2nd edition, vol. 2 * of "The Art of Computer Programming", Addison-Wesley, (1981). * * When Type is 0, sets Seed as the seed. Make sure 0 b) m = a; else m = b; return m; } /*********************************************************** * min2 ****/ double min2(double a, double b) { double m; if (a >= b) m = b; else m = a; return m; } /*********************************************************** * min3 ****/ double min3(double a, double b, double c) { double m; if (a <= min2(b, c)) m = a; else if (b <= min2(a, c)) m = b; else m = c; return m; } /******************** * my version of FindVoxelFace for no scattering. * s = ls + FindVoxelFace2(x,y,z, tempx, tempy, tempz, dx, dy, dz, ux, uy, uz); ****/ double FindVoxelFace2(double x1, double y1, double z1, double /*x2*/, double /*y2*/, double /*z2*/, double dx, double dy, double dz, double ux, double uy, double uz) { int ix1 = floor(x1 / dx); int iy1 = floor(y1 / dy); int iz1 = floor(z1 / dz); int ix2, iy2, iz2; if (ux >= 0) ix2 = ix1 + 1; else ix2 = ix1; if (uy >= 0) iy2 = iy1 + 1; else iy2 = iy1; if (uz >= 0) iz2 = iz1 + 1; else iz2 = iz1; double xs = fabs((ix2*dx - x1) / ux); double ys = fabs((iy2*dy - y1) / uy); double zs = fabs((iz2*dz - z1) / uz); double s = min3(xs, ys, zs); return s; } /*********************************************************** * FRESNEL REFLECTANCE * Computes reflectance as photon passes from medium 1 to * medium 2 with refractive indices n1,n2. Incident * angle a1 is specified by cosine value ca1 = cos(a1). * Program returns value of transmitted angle a1 as * value in *ca2_Ptr = cos(a2). ****/ double RFresnel(double n1, /* incident refractive index.*/ double n2, /* transmit refractive index.*/ double ca1, /* cosine of the incident */ /* angle a1, 00. */ { double r; if (n1 == n2) { /** matched boundary. **/ *ca2_Ptr = ca1; r = 0.0; } else if (ca1 > (1.0 - 1.0e-12)) { /** normal incidence. **/ *ca2_Ptr = ca1; r = (n2 - n1) / (n2 + n1); r *= r; } else if (ca1 < 1.0e-6) { /** very slanted. **/ *ca2_Ptr = 0.0; r = 1.0; } else { /** general. **/ double sa1, sa2; /* sine of incident and transmission angles. */ double ca2; /* cosine of transmission angle. */ sa1 = sqrt(1 - ca1*ca1); sa2 = n1*sa1 / n2; if (sa2 >= 1.0) { /* double check for total internal reflection. */ *ca2_Ptr = 0.0; r = 1.0; } else { double cap, cam; /* cosines of sum ap or diff am of the two */ /* angles: ap = a1 + a2, am = a1 - a2. */ double sap, sam; /* sines. */ *ca2_Ptr = ca2 = sqrt(1 - sa2*sa2); cap = ca1*ca2 - sa1*sa2; /* c+ = cc - ss. */ cam = ca1*ca2 + sa1*sa2; /* c- = cc + ss. */ sap = sa1*ca2 + ca1*sa2; /* s+ = sc + cs. */ sam = sa1*ca2 - ca1*sa2; /* s- = sc - cs. */ r = 0.5*sam*sam*(cam*cam + cap*cap) / (sap*sap*cam*cam); /* rearranged for speed. */ } } return(r); } /******** END SUBROUTINE **********/ /*********************************************************** * the boundary is the face of some voxel * find the the photon's hitting position on the nearest face of the voxel and update the step size. ****/ double FindVoxelFace(double x1, double y1, double z1, double x2, double y2, double z2, double dx, double dy, double dz, double ux, double uy, double uz) { double x_1 = x1 / dx; double y_1 = y1 / dy; double z_1 = z1 / dz; double x_2 = x2 / dx; double y_2 = y2 / dy; double z_2 = z2 / dz; double fx_1 = floor(x_1); double fy_1 = floor(y_1); double fz_1 = floor(z_1); double fx_2 = floor(x_2); double fy_2 = floor(y_2); double fz_2 = floor(z_2); double x = 0, y = 0, z = 0, x0 = 0, y0 = 0, z0 = 0, s = 0; if ((fx_1 != fx_2) && (fy_1 != fy_2) && (fz_1 != fz_2)) { //#10 fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added x = (max2(fx_1, fx_2) - x_1) / ux; y = (max2(fy_1, fy_2) - y_1) / uy; z = (max2(fz_1, fz_2) - z_1) / uz; if (x == min3(x, y, z)) { x0 = max2(fx_1, fx_2); y0 = (x0 - x_1) / ux*uy + y_1; z0 = (x0 - x_1) / ux*uz + z_1; } else if (y == min3(x, y, z)) { y0 = max2(fy_1, fy_2); x0 = (y0 - y_1) / uy*ux + x_1; z0 = (y0 - y_1) / uy*uz + z_1; } else { z0 = max2(fz_1, fz_2); y0 = (z0 - z_1) / uz*uy + y_1; x0 = (z0 - z_1) / uz*ux + x_1; } } else if ((fx_1 != fx_2) && (fy_1 != fy_2)) { //#2 fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added x = (max2(fx_1, fx_2) - x_1) / ux; y = (max2(fy_1, fy_2) - y_1) / uy; if (x == min2(x, y)) { x0 = max2(fx_1, fx_2); y0 = (x0 - x_1) / ux*uy + y_1; z0 = (x0 - x_1) / ux*uz + z_1; } else { y0 = max2(fy_1, fy_2); x0 = (y0 - y_1) / uy*ux + x_1; z0 = (y0 - y_1) / uy*uz + z_1; } } else if ((fy_1 != fy_2) && (fz_1 != fz_2)) { //#3 fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added y = (max2(fy_1, fy_2) - y_1) / uy; z = (max2(fz_1, fz_2) - z_1) / uz; if (y == min2(y, z)) { y0 = max2(fy_1, fy_2); x0 = (y0 - y_1) / uy*ux + x_1; z0 = (y0 - y_1) / uy*uz + z_1; } else { z0 = max2(fz_1, fz_2); x0 = (z0 - z_1) / uz*ux + x_1; y0 = (z0 - z_1) / uz*uy + y_1; } } else if ((fx_1 != fx_2) && (fz_1 != fz_2)) { //#4 fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added x = (max2(fx_1, fx_2) - x_1) / ux; z = (max2(fz_1, fz_2) - z_1) / uz; if (x == min2(x, z)) { x0 = max2(fx_1, fx_2); y0 = (x0 - x_1) / ux*uy + y_1; z0 = (x0 - x_1) / ux*uz + z_1; } else { z0 = max2(fz_1, fz_2); x0 = (z0 - z_1) / uz*ux + x_1; y0 = (z0 - z_1) / uz*uy + y_1; } } else if (fx_1 != fx_2) { //#5 fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added x0 = max2(fx_1, fx_2); y0 = (x0 - x_1) / ux*uy + y_1; z0 = (x0 - x_1) / ux*uz + z_1; } else if (fy_1 != fy_2) { //#6 fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added y0 = max2(fy_1, fy_2); x0 = (y0 - y_1) / uy*ux + x_1; z0 = (y0 - y_1) / uy*uz + z_1; } else { //#7 z0 = max2(fz_1, fz_2); fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added x0 = (z0 - z_1) / uz*ux + x_1; y0 = (z0 - z_1) / uz*uy + y_1; } //s = ( (x0-fx_1)*dx + (y0-fy_1)*dy + (z0-fz_1)*dz )/3; //s = sqrt( SQR((x0-x_1)*dx) + SQR((y0-y_1)*dy) + SQR((z0-z_1)*dz) ); //s = sqrt(SQR(x0-x_1)*SQR(dx) + SQR(y0-y_1)*SQR(dy) + SQR(z0-z_1)*SQR(dz)); s = sqrt(SQR((x0 - x_1)*dx) + SQR((y0 - y_1)*dy) + SQR((z0 - z_1)*dz)); return (s); } }; /* DECLARE FUNCTIONS */ void runMonteCarlo(InputValues* inputValues, ReturnValues* returnValue, int thread, mitk::pa::MonteCarloThreadHandler::Pointer threadHandler); int detector_x = -1; int detector_z = -1; bool interpretAsTime = true; bool simulatePVFC = false; int requestedNumberOfPhotons = 100000; float requestedSimulationTime = 0; // in minutes int concurentThreadsSupported = -1; float yOffset = 0; // in mm bool saveLegacy = false; std::string normalizationFilename; std::string inputFilename; std::string outputFilename; mitk::pa::Probe::Pointer m_PhotoacousticProbe; int main(int argc, char * argv[]) { mitkCommandLineParser parser; // set general information parser.setCategory("MITK-Photoacoustics"); parser.setTitle("Mitk MCxyz"); parser.setDescription("Runs Monte Carlo simulations on inputed tissues."); parser.setContributor("CAI, DKFZ based on code by Jacques and Li"); // how should arguments be prefixed parser.setArgumentPrefix("--", "-"); // add each argument, unless specified otherwise each argument is optional // see mitkCommandLineParser::addArgument for more information parser.beginGroup("Required I/O parameters"); parser.addArgument( "input", "i", mitkCommandLineParser::InputFile, "Input tissue file", "input tissue file (*.nrrd)", us::Any(), false); parser.addArgument( "output", "o", mitkCommandLineParser::OutputFile, "Output fluence file", "where to save the simulated fluence (*.nrrd)", us::Any(), false); parser.endGroup(); parser.beginGroup("Optional parameters"); parser.addArgument( "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose, or rather debug output"); parser.addArgument( "detector-x", "dx", mitkCommandLineParser::Int, "Detector voxel x position", "Determines the x position of the detector voxel (default: -1 = dont use detector voxel)", -1); parser.addArgument( "detector-z", "dz", mitkCommandLineParser::Int, "Detector voxel z position", "Determines the z position of the detector voxel (default: -1 = dont use detector voxel)", -1); parser.addArgument( "number-of-photons", "n", mitkCommandLineParser::Int, "Number of photons", "Specifies the number of photons (default: 100000). Simulation stops after that number. Use -t --timer to define a timer instead"); parser.addArgument( "timer", "t", mitkCommandLineParser::Float, "Simulation time in min", "Specifies the amount of time for simutation (default: 0). Simulation stops after that number of minutes. -n --number-of-photons is the override and default behavior and defines the maximum number of photons instead. If no simulation time or number of photons is specified the file time is taken."); parser.addArgument( "y-offset", "yo", mitkCommandLineParser::Float, "Probe Y-Offset in mm", "Specifies an offset of the photoacoustic probe in the y direction depending on the initial probe position (default: 0) in mm."); parser.addArgument( "jobs", "j", mitkCommandLineParser::Int, "Number of jobs", "Specifies the number of jobs for simutation (default: -1 which starts as many jobs as supported)."); parser.addArgument( "probe-xml", "p", mitkCommandLineParser::InputFile, "Xml definition of the probe", "Specifies the absolute path of the location of the xml definition file of the probe design."); parser.addArgument("normalization-file", "nf", mitkCommandLineParser::InputFile, "Input normalization file", "The input normalization file is used for normalization of the number of photons in the PVFC calculations."); parser.endGroup(); // parse arguments, this method returns a mapping of long argument names and their values std::map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) return EXIT_FAILURE; // parse, cast and set required arguments inputFilename = us::any_cast(parsedArgs["input"]); // strip ending inputFilename = inputFilename.substr(0, inputFilename.find("_H.mci")); inputFilename = inputFilename.substr(0, inputFilename.find("_T.bin")); outputFilename = us::any_cast(parsedArgs["output"]); // add .nrrd if not there std::string suffix = ".nrrd"; if (outputFilename.compare(outputFilename.size() - suffix.size(), suffix.size(), suffix) != 0) outputFilename = outputFilename + suffix; // default values for optional arguments // parse, cast and set optional arguments if given if (parsedArgs.count("verbose")) { verbose = us::any_cast(parsedArgs["verbose"]); } if (parsedArgs.count("detector-x")) { detector_x = us::any_cast(parsedArgs["detector-x"]); } if (parsedArgs.count("detector-z")) { detector_z = us::any_cast(parsedArgs["detector-z"]); } if (parsedArgs.count("timer")) { requestedSimulationTime = us::any_cast(parsedArgs["timer"]); if (requestedSimulationTime > 0) interpretAsTime = true; } if (parsedArgs.count("y-offset")) { yOffset = us::any_cast(parsedArgs["y-offset"]); } if (parsedArgs.count("number-of-photons")) { requestedNumberOfPhotons = us::any_cast(parsedArgs["number-of-photons"]); if (requestedNumberOfPhotons > 0) interpretAsTime = false; } if (parsedArgs.count("jobs")) { concurentThreadsSupported = us::any_cast(parsedArgs["jobs"]); } if (parsedArgs.count("probe-xml")) { std::string inputXmlProbeDesign = us::any_cast(parsedArgs["probe-xml"]); m_PhotoacousticProbe = mitk::pa::Probe::New(inputXmlProbeDesign, verbose); if (!m_PhotoacousticProbe->IsValid()) { std::cerr << "Xml File was not valid. Simulation failed." << std::endl; return EXIT_FAILURE; } } if (parsedArgs.count("normalization-file")) { normalizationFilename = us::any_cast(parsedArgs["normalization-file"]); } if (concurentThreadsSupported == 0 || concurentThreadsSupported == -1) { concurentThreadsSupported = std::thread::hardware_concurrency(); if (concurentThreadsSupported == 0) { std::cout << "Could not determine number of available threads. Launching only one." << std::endl; concurentThreadsSupported = 1; } } if (detector_x != -1 && detector_z != -1) { if (verbose) std::cout << "Performing PVFC calculation for x=" << detector_x << " and z=" << detector_z << std::endl; simulatePVFC = true; } else { if (verbose) std::cout << "Will not perform PVFC calculation due to x=" << detector_x << " and/or z=" << detector_z << std::endl; } InputValues allInput = InputValues(); allInput.LoadValues(inputFilename, yOffset, normalizationFilename, simulatePVFC); std::vector allValues(concurentThreadsSupported); auto* threads = new std::thread[concurentThreadsSupported]; for (long i = 0; i < concurentThreadsSupported; i++) { auto* tmp = new ReturnValues(); allValues.push_back(*tmp); } if (verbose) std::cout << "Initializing MonteCarloThreadHandler" << std::endl; long timeMetric; if (interpretAsTime) { if (requestedSimulationTime < mitk::eps) requestedSimulationTime = allInput.simulationTimeFromFile; timeMetric = requestedSimulationTime * 60 * 1000; } else { timeMetric = requestedNumberOfPhotons; } mitk::pa::MonteCarloThreadHandler::Pointer threadHandler = mitk::pa::MonteCarloThreadHandler::New(timeMetric, interpretAsTime); if (simulatePVFC) threadHandler->SetPackageSize(1000); if (verbose) std::cout << "\nStarting simulation ...\n" << std::endl; auto simulationStartTime = std::chrono::system_clock::now(); for (int i = 0; i < concurentThreadsSupported; i++) { threads[i] = std::thread(runMonteCarlo, &allInput, &allValues[i], (i + 1), threadHandler); } for (int i = 0; i < concurentThreadsSupported; i++) { threads[i].join(); } auto simulationFinishTime = std::chrono::system_clock::now(); auto simulationTimeElapsed = simulationFinishTime - simulationStartTime; if (verbose) std::cout << "\n\nFinished simulation\n\n" << std::endl; std::cout << "total time for simulation: " << (int)std::chrono::duration_cast(simulationTimeElapsed).count() << "sec " << std::endl; /**** SAVE Convert data to relative fluence rate [cm^-2] and save. *****/ if (!simulatePVFC) { if (verbose) std::cout << "Allocating memory for normal simulation result ... "; auto* finalTotalFluence = (double *)malloc(allInput.totalNumberOfVoxels * sizeof(double)); if (verbose) std::cout << "[OK]" << std::endl; if (verbose) std::cout << "Cleaning memory for normal simulation result ..."; for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { finalTotalFluence[i] = 0; } if (verbose) std::cout << "[OK]" << std::endl; if (verbose) std::cout << "Calculating resulting fluence ... "; double tdx = 0, tdy = 0, tdz = 0; long long tNphotons = 0; for (int t = 0; t < concurentThreadsSupported; t++) { tdx = allInput.xSpacing; tdy = allInput.ySpacing; tdz = allInput.zSpacing; tNphotons += allValues[t].Nphotons; for (int voxelNumber = 0; voxelNumber < allInput.totalNumberOfVoxels; voxelNumber++) { finalTotalFluence[voxelNumber] += allValues[t].totalFluence[voxelNumber]; } } if (verbose) std::cout << "[OK]" << std::endl; std::cout << "total number of photons simulated: " << tNphotons << std::endl; // Normalize deposition (A) to yield fluence rate (F). double temp = tdx*tdy*tdz*tNphotons; for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { finalTotalFluence[i] /= temp*allInput.muaVector[i]; } if (verbose) std::cout << "Saving normal simulated fluence result to " << outputFilename << " ... "; mitk::Image::Pointer resultImage = mitk::Image::New(); mitk::PixelType TPixel = mitk::MakeScalarPixelType(); auto* dimensionsOfImage = new unsigned int[3]; // Copy dimensions dimensionsOfImage[0] = allInput.Ny; dimensionsOfImage[1] = allInput.Nx; dimensionsOfImage[2] = allInput.Nz; resultImage->Initialize(TPixel, 3, dimensionsOfImage); mitk::Vector3D spacing; spacing[0] = allInput.ySpacing; spacing[1] = allInput.xSpacing; spacing[2] = allInput.zSpacing; resultImage->SetSpacing(spacing); resultImage->SetImportVolume(finalTotalFluence, 0, 0, mitk::Image::CopyMemory); resultImage->GetPropertyList()->SetFloatProperty("y-offset", yOffset); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("y-offset")); mitk::IOUtil::Save(resultImage, outputFilename); if (verbose) std::cout << "[OK]" << std::endl; if (verbose) { std::cout << "x spacing = " << tdx << std::endl; std::cout << "y spacing = " << tdy << std::endl; std::cout << "z spacing = " << tdz << std::endl; std::cout << "total number of voxels = " << allInput.totalNumberOfVoxels << std::endl; std::cout << "number of photons = " << (int)tNphotons << std::endl; } } else // if simulate PVFC { if (verbose) std::cout << "Allocating memory for PVFC simulation result ... "; double* detectorFluence = ((double*)malloc(allInput.totalNumberOfVoxels * sizeof(double))); if (verbose) std::cout << "[OK]" << std::endl; if (verbose) std::cout << "Cleaning memory for PVFC simulation result ..."; for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { detectorFluence[i] = 0; } if (verbose) std::cout << "[OK]" << std::endl; if (verbose) std::cout << "Calculating resulting PVFC fluence ... "; double tdx = 0, tdy = 0, tdz = 0; long long tNphotons = 0; long pvfcPhotons = 0; for (int t = 0; t < concurentThreadsSupported; t++) { tdx = allInput.xSpacing; tdy = allInput.ySpacing; tdz = allInput.zSpacing; tNphotons += allValues[t].Nphotons; pvfcPhotons += allValues[t].detectorVoxel->m_NumberPhotonsCurrent; for (int voxelNumber = 0; voxelNumber < allInput.totalNumberOfVoxels; voxelNumber++) { detectorFluence[voxelNumber] += allValues[t].detectorVoxel->fluenceContribution[voxelNumber]; } } if (verbose) std::cout << "[OK]" << std::endl; std::cout << "total number of photons simulated: " << tNphotons << std::endl; // Normalize deposition (A) to yield fluence rate (F). double temp = tdx*tdy*tdz*tNphotons; for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { detectorFluence[i] /= temp*allInput.muaVector[i]; } if (verbose) std::cout << "Saving PVFC ..."; std::stringstream detectorname(""); double detectorX = allValues[0].detectorVoxel->location.x; double detectorY = allValues[0].detectorVoxel->location.y; double detectorZ = allValues[0].detectorVoxel->location.z; detectorname << detectorX << "," << detectorY << "," << detectorZ << "FluenceContribution.nrrd"; // Save the binary file std::string outputFileBase = outputFilename.substr(0, outputFilename.find(".nrrd")); outputFilename = outputFileBase + "_p" + detectorname.str().c_str(); mitk::Image::Pointer pvfcImage = mitk::Image::New(); auto* dimensionsOfPvfcImage = new unsigned int[3]; // Copy dimensions dimensionsOfPvfcImage[0] = allInput.Ny; dimensionsOfPvfcImage[1] = allInput.Nx; dimensionsOfPvfcImage[2] = allInput.Nz; pvfcImage->Initialize(mitk::MakeScalarPixelType(), 3, dimensionsOfPvfcImage); mitk::Vector3D pvfcSpacing; pvfcSpacing[0] = allInput.ySpacing; pvfcSpacing[1] = allInput.xSpacing; pvfcSpacing[2] = allInput.zSpacing; pvfcImage->SetSpacing(pvfcSpacing); pvfcImage->SetImportVolume(detectorFluence, 0, 0, mitk::Image::CopyMemory); pvfcImage->GetPropertyList()->SetFloatProperty("detector-x", detectorX); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("detector-x")); pvfcImage->GetPropertyList()->SetFloatProperty("detector-y", detectorY); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("detector-y")); pvfcImage->GetPropertyList()->SetFloatProperty("detector-z", detectorZ); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("detector-z")); pvfcImage->GetPropertyList()->SetFloatProperty("normalization-factor", allValues[0].detectorVoxel->m_PhotonNormalizationValue); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("normalization-factor")); pvfcImage->GetPropertyList()->SetFloatProperty("simulated-photons", pvfcPhotons); mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("simulated-photons")); mitk::IOUtil::Save(pvfcImage, outputFilename); if (verbose) std::cout << "[OK]" << std::endl; if (verbose) { std::cout << "x spacing = " << tdx << std::endl; std::cout << "y spacing = " << tdy << std::endl; std::cout << "z spacing = " << tdz << std::endl; std::cout << "total number of voxels = " << allInput.totalNumberOfVoxels << std::endl; std::cout << "number of photons = " << (int)tNphotons << std::endl; } } exit(EXIT_SUCCESS); } /* end of main */ /* CORE FUNCTION */ void runMonteCarlo(InputValues* inputValues, ReturnValues* returnValue, int thread, mitk::pa::MonteCarloThreadHandler::Pointer threadHandler) { if (verbose) std::cout << "Thread " << thread << ": Locking Mutex ..." << std::endl; if (verbose) std::cout << "[OK]" << std::endl; if (verbose) std::cout << "Initializing ... "; /* Propagation parameters */ double x, y, z; /* photon position */ double ux, uy, uz; /* photon trajectory as cosines */ double uxx, uyy, uzz; /* temporary values used during SPIN */ double s; /* step sizes. s = -log(RND)/mus [cm] */ double sleft; /* dimensionless */ double costheta; /* cos(theta) */ double sintheta; /* sin(theta) */ double cospsi; /* cos(psi) */ double sinpsi; /* sin(psi) */ double psi; /* azimuthal angle */ long photonIterator = 0; /* current photon */ double W; /* photon weight */ double absorb; /* weighted deposited in a step due to absorption */ short photon_status; /* flag = ALIVE=1 or DEAD=0 */ bool sv; /* Are they in the same voxel? */ /* dummy variables */ double rnd; /* assigned random value 0-1 */ double r, phi; /* dummy values */ long i, j; /* dummy indices */ double tempx, tempy, tempz; /* temporary variables, used during photon step. */ int ix, iy, iz; /* Added. Used to track photons */ double temp; /* dummy variable */ int bflag; /* boundary flag: 0 = photon inside volume. 1 = outside volume */ int CNT = 0; returnValue->totalFluence = (double *)malloc(inputValues->totalNumberOfVoxels * sizeof(double)); /* relative fluence rate [W/cm^2/W.delivered] */ if (detector_x != -1 && detector_z != -1) { if (detector_x<0 || detector_x>inputValues->Nx) { std::cout << "Requested detector x position not valid. Needs to be >= 0 and <= " << inputValues->Nx << std::endl; exit(EXIT_FAILURE); } if (detector_z<1 || detector_z>inputValues->Nz) { std::cout << "Requested detector z position not valid. Needs to be > 0 and <= " << inputValues->Nz << std::endl; exit(EXIT_FAILURE); } double photonNormalizationValue = 1 / inputValues->GetNormalizationValue(detector_x, inputValues->Ny / 2, detector_z); returnValue->detectorVoxel = new DetectorVoxel(initLocation(detector_x, inputValues->Ny / 2, detector_z, 0), inputValues->totalNumberOfVoxels, photonNormalizationValue); } /**** ======================== MAJOR CYCLE ============================ *****/ auto duration = std::chrono::system_clock::now().time_since_epoch(); returnValue->RandomGen(0, (std::chrono::duration_cast(duration).count() + thread) % 32000, nullptr); /* initiate with seed = 1, or any long integer. */ for (j = 0; j < inputValues->totalNumberOfVoxels; j++) returnValue->totalFluence[j] = 0; // ensure F[] starts empty. /**** RUN Launch N photons, initializing each one before progation. *****/ long photonsToSimulate = 0; do { photonsToSimulate = threadHandler->GetNextWorkPackage(); if (returnValue->detectorVoxel != nullptr) { photonsToSimulate = photonsToSimulate * returnValue->detectorVoxel->m_PhotonNormalizationValue; } if (verbose) MITK_INFO << "Photons to simulate: " << photonsToSimulate; photonIterator = 0L; do { /**** LAUNCH Initialize photon position and trajectory. *****/ photonIterator += 1; /* increment photon count */ W = 1.0; /* set photon weight to one */ photon_status = ALIVE; /* Launch an ALIVE photon */ CNT = 0; /**** SET SOURCE* Launch collimated beam at x,y center.****/ /****************************/ /* Initial position. */ if (m_PhotoacousticProbe.IsNotNull()) { double rnd1 = -1; double rnd2 = -1; double rnd3 = -1; double rnd4 = -1; double rnd5 = -1; double rnd6 = -1; double rnd7 = -1; double rnd8 = -1; while ((rnd1 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd2 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd3 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd4 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd5 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd6 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd7 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); while ((rnd8 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); mitk::pa::LightSource::PhotonInformation info = m_PhotoacousticProbe->GetNextPhoton(rnd1, rnd2, rnd3, rnd4, rnd5, rnd6, rnd7, rnd8); x = info.xPosition; y = yOffset + info.yPosition; z = info.zPosition; ux = info.xAngle; uy = info.yAngle; uz = info.zAngle; if (verbose) std::cout << "Created photon at position (" << x << "|" << y << "|" << z << ") with angles (" << ux << "|" << uy << "|" << uz << ")." << std::endl; } else { /* trajectory */ if (inputValues->launchflag == 1) // manually set launch { x = inputValues->xs; y = inputValues->ys; z = inputValues->zs; ux = inputValues->ux0; uy = inputValues->uy0; uz = inputValues->uz0; } else // use mcflag { if (inputValues->mcflag == 0) // uniform beam { // set launch point and width of beam while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 r = inputValues->radius*sqrt(rnd); // radius of beam at launch point while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 phi = rnd*2.0*PI; x = inputValues->xs + r*cos(phi); y = inputValues->ys + r*sin(phi); z = inputValues->zs; // set trajectory toward focus while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 r = inputValues->waist*sqrt(rnd); // radius of beam at focus while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 phi = rnd*2.0*PI; // !!!!!!!!!!!!!!!!!!!!!!! setting input values will braek inputValues->xfocus = r*cos(phi); inputValues->yfocus = r*sin(phi); temp = sqrt((x - inputValues->xfocus)*(x - inputValues->xfocus) + (y - inputValues->yfocus)*(y - inputValues->yfocus) + inputValues->zfocus*inputValues->zfocus); ux = -(x - inputValues->xfocus) / temp; uy = -(y - inputValues->yfocus) / temp; uz = sqrt(1 - ux*ux + uy*uy); } else if (inputValues->mcflag == 5) // Multispectral DKFZ prototype { // set launch point and width of beam while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); //offset in x direction in cm (random) x = (rnd*2.5) - 1.25; while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); double b = ((rnd)-0.5); y = (b > 0 ? yOffset + 1.5 : yOffset - 1.5); z = 0.1; ux = 0; while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); //Angle of beam in y direction uy = sin((rnd*0.42) - 0.21 + (b < 0 ? 1.0 : -1.0) * 0.436); while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // angle of beam in x direction ux = sin((rnd*0.42) - 0.21); uz = sqrt(1 - ux*ux - uy*uy); } else if (inputValues->mcflag == 4) // Monospectral prototype DKFZ { // set launch point and width of beam while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); //offset in x direction in cm (random) x = (rnd*2.5) - 1.25; while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); double b = ((rnd)-0.5); y = (b > 0 ? yOffset + 0.83 : yOffset - 0.83); z = 0.1; ux = 0; while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); //Angle of beam in y direction uy = sin((rnd*0.42) - 0.21 + (b < 0 ? 1.0 : -1.0) * 0.375); while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // angle of beam in x direction ux = sin((rnd*0.42) - 0.21); uz = sqrt(1 - ux*ux - uy*uy); } else { // isotropic pt source costheta = 1.0 - 2.0 * returnValue->RandomGen(1, 0, nullptr); sintheta = sqrt(1.0 - costheta*costheta); psi = 2.0 * PI * returnValue->RandomGen(1, 0, nullptr); cospsi = cos(psi); if (psi < PI) sinpsi = sqrt(1.0 - cospsi*cospsi); else sinpsi = -sqrt(1.0 - cospsi*cospsi); x = inputValues->xs; y = inputValues->ys; z = inputValues->zs; ux = sintheta*cospsi; uy = sintheta*sinpsi; uz = costheta; } } // end use mcflag } /****************************/ /* Get tissue voxel properties of launchpoint. * If photon beyond outer edge of defined voxels, * the tissue equals properties of outermost voxels. * Therefore, set outermost voxels to infinite background value. */ ix = (int)(inputValues->Nx / 2 + x / inputValues->xSpacing); iy = (int)(inputValues->Ny / 2 + y / inputValues->ySpacing); iz = (int)(z / inputValues->zSpacing); if (ix >= inputValues->Nx) ix = inputValues->Nx - 1; if (iy >= inputValues->Ny) iy = inputValues->Ny - 1; if (iz >= inputValues->Nz) iz = inputValues->Nz - 1; if (ix < 0) ix = 0; if (iy < 0) iy = 0; if (iz < 0) iz = 0; /* Get the tissue type of located voxel */ i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); bflag = 1; // initialize as 1 = inside volume, but later check as photon propagates. if (returnValue->detectorVoxel != nullptr) returnValue->detectorVoxel->recordedPhotonRoute->clear(); /* HOP_DROP_SPIN_CHECK Propagate one photon until it dies as determined by ROULETTE. *******/ do { /**** HOP Take step to new position s = dimensionless stepsize x, uy, uz are cosines of current photon trajectory *****/ while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); /* yields 0 < rnd <= 1 */ sleft = -log(rnd); /* dimensionless step */ CNT += 1; do { // while sleft>0 s = sleft / inputValues->musVector[i]; /* Step size [cm].*/ tempx = x + s*ux; /* Update positions. [cm] */ tempy = y + s*uy; tempz = z + s*uz; sv = returnValue->SameVoxel(x, y, z, tempx, tempy, tempz, inputValues->xSpacing, inputValues->ySpacing, inputValues->zSpacing); if (sv) /* photon in same voxel */ { x = tempx; /* Update positions. */ y = tempy; z = tempz; /**** DROP Drop photon weight (W) into local bin. *****/ absorb = W*(1 - exp(-inputValues->muaVector[i] * s)); /* photon weight absorbed at this step */ W -= absorb; /* decrement WEIGHT by amount absorbed */ // If photon within volume of heterogeneity, deposit energy in F[]. // Normalize F[] later, when save output. if (bflag) { i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); returnValue->totalFluence[i] += absorb; // only save data if blag==1, i.e., photon inside simulation cube //For each detectorvoxel if (returnValue->detectorVoxel != nullptr) { //Add photon position to the recorded photon route returnValue->detectorVoxel->recordedPhotonRoute->push_back(initLocation(ix, iy, iz, absorb)); //If the photon is currently at the detector position if ((returnValue->detectorVoxel->location.x == ix) && ((returnValue->detectorVoxel->location.y == iy) || (returnValue->detectorVoxel->location.y - 1 == iy)) && (returnValue->detectorVoxel->location.z == iz)) { //For each voxel in the recorded photon route for (unsigned int routeIndex = 0; routeIndex < returnValue->detectorVoxel->recordedPhotonRoute->size(); routeIndex++) { //increment the fluence contribution at that particular position i = (long)(returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).z*inputValues->Ny*inputValues->Nx + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).x*inputValues->Ny + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).y); returnValue->detectorVoxel->fluenceContribution[i] += returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).absorb; } //Clear the recorded photon route returnValue->detectorVoxel->m_NumberPhotonsCurrent++; returnValue->detectorVoxel->recordedPhotonRoute->clear(); } } } /* Update sleft */ sleft = 0; /* dimensionless step remaining */ } else /* photon has crossed voxel boundary */ { /* step to voxel face + "littlest step" so just inside new voxel. */ s = ls + returnValue->FindVoxelFace2(x, y, z, tempx, tempy, tempz, inputValues->xSpacing, inputValues->ySpacing, inputValues->zSpacing, ux, uy, uz); /**** DROP Drop photon weight (W) into local bin. *****/ absorb = W*(1 - exp(-inputValues->muaVector[i] * s)); /* photon weight absorbed at this step */ W -= absorb; /* decrement WEIGHT by amount absorbed */ // If photon within volume of heterogeneity, deposit energy in F[]. // Normalize F[] later, when save output. if (bflag) { // only save data if bflag==1, i.e., photon inside simulation cube //For each detectorvoxel if (returnValue->detectorVoxel != nullptr) { //Add photon position to the recorded photon route returnValue->detectorVoxel->recordedPhotonRoute->push_back(initLocation(ix, iy, iz, absorb)); //If the photon is currently at the detector position if ((returnValue->detectorVoxel->location.x == ix) && ((returnValue->detectorVoxel->location.y == iy) || (returnValue->detectorVoxel->location.y - 1 == iy)) && (returnValue->detectorVoxel->location.z == iz)) { //For each voxel in the recorded photon route for (unsigned int routeIndex = 0; routeIndex < returnValue->detectorVoxel->recordedPhotonRoute->size(); routeIndex++) { //increment the fluence contribution at that particular position i = (long)(returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).z*inputValues->Ny*inputValues->Nx + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).x*inputValues->Ny + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).y); returnValue->detectorVoxel->fluenceContribution[i] += returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).absorb; } //Clear the recorded photon route returnValue->detectorVoxel->m_NumberPhotonsCurrent++; returnValue->detectorVoxel->recordedPhotonRoute->clear(); } } i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); returnValue->totalFluence[i] += absorb; } /* Update sleft */ sleft -= s*inputValues->musVector[i]; /* dimensionless step remaining */ if (sleft <= ls) sleft = 0; /* Update positions. */ x += s*ux; y += s*uy; z += s*uz; // pointers to voxel containing optical properties ix = (int)(inputValues->Nx / 2 + x / inputValues->xSpacing); iy = (int)(inputValues->Ny / 2 + y / inputValues->ySpacing); iz = (int)(z / inputValues->zSpacing); bflag = 1; // Boundary flag. Initialize as 1 = inside volume, then check. if (inputValues->boundaryflag == 0) { // Infinite medium. // Check if photon has wandered outside volume. // If so, set tissue type to boundary value, but let photon wander. // Set blag to zero, so DROP does not deposit energy. if (iz >= inputValues->Nz) { iz = inputValues->Nz - 1; bflag = 0; } if (ix >= inputValues->Nx) { ix = inputValues->Nx - 1; bflag = 0; } if (iy >= inputValues->Ny) { iy = inputValues->Ny - 1; bflag = 0; } if (iz < 0) { iz = 0; bflag = 0; } if (ix < 0) { ix = 0; bflag = 0; } if (iy < 0) { iy = 0; bflag = 0; } } else if (inputValues->boundaryflag == 1) { // Escape at boundaries if (iz >= inputValues->Nz) { iz = inputValues->Nz - 1; photon_status = DEAD; sleft = 0; } if (ix >= inputValues->Nx) { ix = inputValues->Nx - 1; photon_status = DEAD; sleft = 0; } if (iy >= inputValues->Ny) { iy = inputValues->Ny - 1; photon_status = DEAD; sleft = 0; } if (iz < 0) { iz = 0; photon_status = DEAD; sleft = 0; } if (ix < 0) { ix = 0; photon_status = DEAD; sleft = 0; } if (iy < 0) { iy = 0; photon_status = DEAD; sleft = 0; } } else if (inputValues->boundaryflag == 2) { // Escape at top surface, no x,y bottom z boundaries if (iz >= inputValues->Nz) { iz = inputValues->Nz - 1; bflag = 0; } if (ix >= inputValues->Nx) { ix = inputValues->Nx - 1; bflag = 0; } if (iy >= inputValues->Ny) { iy = inputValues->Ny - 1; bflag = 0; } if (iz < 0) { iz = 0; photon_status = DEAD; sleft = 0; } if (ix < 0) { ix = 0; bflag = 0; } if (iy < 0) { iy = 0; bflag = 0; } } // update pointer to tissue type i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); } //(sv) /* same voxel */ } while (sleft > 0); //do...while /**** SPIN Scatter photon into new trajectory defined by theta and psi. Theta is specified by cos(theta), which is determined based on the Henyey-Greenstein scattering function. Convert theta and psi into cosines ux, uy, uz. *****/ /* Sample for costheta */ while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); if (inputValues->gVector[i] == 0.0) { costheta = 2.0 * rnd - 1.0; } else { double temp = (1.0 - inputValues->gVector[i] * inputValues->gVector[i]) / (1.0 - inputValues->gVector[i] + 2 * inputValues->gVector[i] * rnd); costheta = (1.0 + inputValues->gVector[i] * inputValues->gVector[i] - temp*temp) / (2.0*inputValues->gVector[i]); } sintheta = sqrt(1.0 - costheta*costheta); /* sqrt() is faster than sin(). */ /* Sample psi. */ psi = 2.0*PI*returnValue->RandomGen(1, 0, nullptr); cospsi = cos(psi); if (psi < PI) sinpsi = sqrt(1.0 - cospsi*cospsi); /* sqrt() is faster than sin(). */ else sinpsi = -sqrt(1.0 - cospsi*cospsi); /* New trajectory. */ if (1 - fabs(uz) <= ONE_MINUS_COSZERO) { /* close to perpendicular. */ uxx = sintheta * cospsi; uyy = sintheta * sinpsi; uzz = costheta * SIGN(uz); /* SIGN() is faster than division. */ } else { /* usually use this option */ temp = sqrt(1.0 - uz * uz); uxx = sintheta * (ux * uz * cospsi - uy * sinpsi) / temp + ux * costheta; uyy = sintheta * (uy * uz * cospsi + ux * sinpsi) / temp + uy * costheta; uzz = -sintheta * cospsi * temp + uz * costheta; } /* Update trajectory */ ux = uxx; uy = uyy; uz = uzz; /**** CHECK ROULETTE If photon weight below THRESHOLD, then terminate photon using Roulette technique. Photon has CHANCE probability of having its weight increased by factor of 1/CHANCE, and 1-CHANCE probability of terminating. *****/ if (W < THRESHOLD) { if (returnValue->RandomGen(1, 0, nullptr) <= CHANCE) W /= CHANCE; else photon_status = DEAD; } } while (photon_status == ALIVE); /* end STEP_CHECK_HOP_SPIN */ /* if ALIVE, continue propagating */ /* If photon DEAD, then launch new photon. */ } while (photonIterator < photonsToSimulate); /* end RUN */ returnValue->Nphotons += photonsToSimulate; } while (photonsToSimulate > 0); if (verbose) std::cout << "------------------------------------------------------" << std::endl; if (verbose) std::cout << "Thread " << thread << " is finished." << std::endl; } diff --git a/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp b/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp index b5b97188fb..3da84124e7 100644 --- a/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp +++ b/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp @@ -1,258 +1,258 @@ #include "mitkPAIOUtil.h" #include "mitkIOUtil.h" #include "mitkImageReadAccessor.h" #include #include #include #include "mitkPAComposedVolume.h" #include "mitkPASlicedVolumeGenerator.h" #include "mitkPANoiseGenerator.h" #include "mitkPAVolumeManipulator.h" #include #include #include static std::vector splitString(const std::string &s, const char* delim) { std::vector elems; std::stringstream ss(s); std::string item; while (std::getline(ss, item, *delim)) { int numb; std::stringstream(item) >> numb; elems.push_back(numb); } return elems; } bool mitk::pa::IOUtil::DoesFileHaveEnding(std::string const &fullString, std::string const &ending) { if (fullString.length() == 0 || ending.length() == 0 || fullString.length() < ending.length()) return false; return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); } mitk::pa::IOUtil::IOUtil() {} mitk::pa::IOUtil::~IOUtil() {} mitk::pa::Volume::Pointer mitk::pa::IOUtil::LoadNrrd(std::string filename, double blur) { if (filename.empty() || filename == "") return nullptr; - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(filename); + auto inputImage = mitk::IOUtil::Load(filename); if (inputImage.IsNull()) return nullptr; int xDim = inputImage->GetDimensions()[1]; int yDim = inputImage->GetDimensions()[0]; int zDim = inputImage->GetDimensions()[2]; mitk::ImageReadAccessor readAccess(inputImage, inputImage->GetVolumeData(0)); auto* dataArray = new double[xDim*yDim*zDim]; const auto* srcData = (const double*)readAccess.GetData(); memcpy(dataArray, srcData, xDim*yDim*zDim * sizeof(double)); auto returnImage = mitk::pa::Volume::New(dataArray, xDim, yDim, zDim); mitk::pa::VolumeManipulator::GaussianBlur3D(returnImage, blur); return returnImage; } std::map mitk::pa::IOUtil::LoadFluenceContributionMaps(std::string foldername, double blur, int* progress, bool doLog10) { std::map resultMap; itk::Directory::Pointer directoryHandler = itk::Directory::New(); directoryHandler->Load(foldername.c_str()); for (unsigned int fileIndex = 0, numFiles = directoryHandler->GetNumberOfFiles(); fileIndex < numFiles; ++fileIndex) { std::string filename = std::string(directoryHandler->GetFile(fileIndex)); if (itksys::SystemTools::FileIsDirectory(filename)) continue; if (!DoesFileHaveEnding(filename, ".nrrd")) continue; size_t s = filename.find("_p"); size_t e = filename.find("Fluence", s); std::string sub = filename.substr(s + 2, e - s - 2); std::vector coords = splitString(sub, ","); if (coords.size() != 3) { MITK_ERROR << "Some of the data to read was corrupted or did not match the " << "naming pattern *_pN,N,NFluence*.nrrd"; mitkThrow() << "Some of the data to read was corrupted or did not match the" << " naming pattern *_pN,N,NFluence*.nrrd"; } else { MITK_DEBUG << "Extracted coords: " << coords[0] << "|" << coords[1] << "|" << coords[2] << " from string " << sub; Volume::Pointer nrrdFile = LoadNrrd(foldername + filename, blur); if (doLog10) VolumeManipulator::Log10Image(nrrdFile); resultMap[Position{ coords[0], coords[2] }] = nrrdFile; *progress = *progress + 1; } } return resultMap; } int mitk::pa::IOUtil::GetNumberOfNrrdFilesInDirectory(std::string directory) { return GetListOfAllNrrdFilesInDirectory(directory).size(); } std::vector mitk::pa::IOUtil::GetListOfAllNrrdFilesInDirectory(std::string directory, bool keepFileFormat) { std::vector filenames; itk::Directory::Pointer directoryHandler = itk::Directory::New(); directoryHandler->Load(directory.c_str()); for (unsigned int fileIndex = 0, numFiles = directoryHandler->GetNumberOfFiles(); fileIndex < numFiles; ++fileIndex) { std::string filename = std::string(directoryHandler->GetFile(fileIndex)); if (itksys::SystemTools::FileIsDirectory(filename)) continue; if (!DoesFileHaveEnding(filename, ".nrrd")) continue; if (keepFileFormat) { filenames.push_back(filename); } else { filenames.push_back(filename.substr(0, filename.size() - 5)); } } return filenames; } std::vector mitk::pa::IOUtil::GetAllChildfoldersFromFolder(std::string folderPath) { std::vector returnVector; itksys::Directory directoryHandler; directoryHandler.Load(folderPath.c_str()); for (unsigned int fileIndex = 0, numFiles = directoryHandler.GetNumberOfFiles(); fileIndex < numFiles; ++fileIndex) { std::string foldername = std::string(directoryHandler.GetFile(fileIndex)); std::string filename = folderPath + "/" + foldername; if (itksys::SystemTools::FileIsDirectory(filename)) { if (foldername != std::string(".") && foldername != std::string("..")) { MITK_INFO << filename; returnVector.push_back(filename); } continue; } //If there is a nrrd file in the directory we assume that a bottom level directory was chosen. if (DoesFileHaveEnding(filename, ".nrrd")) { returnVector.clear(); returnVector.push_back(folderPath); return returnVector; } } return returnVector; } mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::IOUtil::LoadInSilicoTissueVolumeFromNrrdFile(std::string nrrdFile) { MITK_INFO << "Initializing ComposedVolume by nrrd..."; - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(nrrdFile); + auto inputImage = mitk::IOUtil::Load(nrrdFile); auto tissueParameters = TissueGeneratorParameters::New(); unsigned int xDim = inputImage->GetDimensions()[1]; unsigned int yDim = inputImage->GetDimensions()[0]; unsigned int zDim = inputImage->GetDimensions()[2]; tissueParameters->SetXDim(xDim); tissueParameters->SetYDim(yDim); tissueParameters->SetZDim(zDim); double xSpacing = inputImage->GetGeometry(0)->GetSpacing()[1]; double ySpacing = inputImage->GetGeometry(0)->GetSpacing()[0]; double zSpacing = inputImage->GetGeometry(0)->GetSpacing()[2]; if ((xSpacing - ySpacing) > mitk::eps || (xSpacing - zSpacing) > mitk::eps || (ySpacing - zSpacing) > mitk::eps) { throw mitk::Exception("Cannot handle unequal spacing."); } tissueParameters->SetVoxelSpacingInCentimeters(xSpacing); mitk::PropertyList::Pointer propertyList = inputImage->GetPropertyList(); mitk::ImageReadAccessor readAccess0(inputImage, inputImage->GetVolumeData(0)); auto* m_AbsorptionArray = new double[xDim*yDim*zDim]; memcpy(m_AbsorptionArray, readAccess0.GetData(), xDim*yDim*zDim * sizeof(double)); auto absorptionVolume = Volume::New(m_AbsorptionArray, xDim, yDim, zDim); mitk::ImageReadAccessor readAccess1(inputImage, inputImage->GetVolumeData(1)); auto* m_ScatteringArray = new double[xDim*yDim*zDim]; memcpy(m_ScatteringArray, readAccess1.GetData(), xDim*yDim*zDim * sizeof(double)); auto scatteringVolume = Volume::New(m_ScatteringArray, xDim, yDim, zDim); mitk::ImageReadAccessor readAccess2(inputImage, inputImage->GetVolumeData(2)); auto* m_AnisotropyArray = new double[xDim*yDim*zDim]; memcpy(m_AnisotropyArray, readAccess2.GetData(), xDim*yDim*zDim * sizeof(double)); auto anisotropyVolume = Volume::New(m_AnisotropyArray, xDim, yDim, zDim); Volume::Pointer segmentationVolume; if (inputImage->GetDimension() == 4) { mitk::ImageReadAccessor readAccess3(inputImage, inputImage->GetVolumeData(3)); auto* m_SegmentationArray = new double[xDim*yDim*zDim]; memcpy(m_SegmentationArray, readAccess3.GetData(), xDim*yDim*zDim * sizeof(double)); segmentationVolume = Volume::New(m_SegmentationArray, xDim, yDim, zDim); } return mitk::pa::InSilicoTissueVolume::New(absorptionVolume, scatteringVolume, anisotropyVolume, segmentationVolume, tissueParameters, propertyList); } mitk::pa::FluenceYOffsetPair::Pointer mitk::pa::IOUtil::LoadFluenceSimulation(std::string fluenceSimulation) { MITK_INFO << "Adding slice..."; - mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(fluenceSimulation); + auto inputImage = mitk::IOUtil::Load(fluenceSimulation); mitk::ImageReadAccessor readAccess0(inputImage, inputImage->GetVolumeData(0)); unsigned int xDim = inputImage->GetDimensions()[1]; unsigned int yDim = inputImage->GetDimensions()[0]; unsigned int zDim = inputImage->GetDimensions()[2]; int size = xDim*yDim*zDim; auto* fluenceArray = new double[size]; memcpy(fluenceArray, readAccess0.GetData(), size * sizeof(double)); auto yOffsetProperty = inputImage->GetProperty("y-offset"); if (yOffsetProperty.IsNull()) mitkThrow() << "No \"y-offset\" property found in fluence file!"; std::string yOff = yOffsetProperty->GetValueAsString(); MITK_INFO << "Reading y Offset: " << yOff; #ifdef __linux__ std::replace(yOff.begin(), yOff.end(), '.', ','); #endif // __linux__ double yOffset = std::stod(yOff); MITK_INFO << "Converted offset " << yOffset; return mitk::pa::FluenceYOffsetPair::New(mitk::pa::Volume::New(fluenceArray, xDim, yDim, zDim), yOffset); } diff --git a/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp b/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp index 25812d1845..7f68db6cf1 100644 --- a/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp +++ b/Modules/PlanarFigure/test/mitkPlanarFigureInteractionTest.cpp @@ -1,206 +1,206 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "usModuleRegistry.h" class mitkPlanarFigureInteractionTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPlanarFigureInteractionTestSuite); MITK_TEST(AngleInteractionCreate); MITK_TEST(Angle2InteractionCreate); MITK_TEST(BezierCurveInteractionCreate); MITK_TEST(CircleInteractionCreate); MITK_TEST(DoubleEllipseInteractionCreate); MITK_TEST(PlanarFourPointAngleInteractionCreate); MITK_TEST(PlanarLineInteractionCreate); MITK_TEST(PlanarPolygonInteractionCreate); MITK_TEST(NonClosedPlanarPolygonInteractionCreate); MITK_TEST(RectangleInteractionCreate); // BUG 19304 // MITK_TEST(PlanarSubdivisionInteractionCreate); CPPUNIT_TEST_SUITE_END(); public: void setUp() { /// \todo Fix leaks of vtkObjects. Bug 18095. vtkDebugLeaks::SetExitError(0); } void tearDown() {} void RunTest(mitk::PlanarFigure::Pointer figure, std::string interactionXmlPath, std::string referenceFigurePath) { mitk::DataNode::Pointer node; mitk::PlanarFigureInteractor::Pointer figureInteractor; // Create DataNode as a container for our PlanarFigure node = mitk::DataNode::New(); node->SetData(figure); mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionXmlPath)); // Load a bounding image - mitk::Image::Pointer testImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + mitk::Image::Pointer testImage = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); figure->SetGeometry(testImage->GetGeometry()); mitk::DataNode::Pointer dn = mitk::DataNode::New(); dn->SetData(testImage); interactionTestHelper.AddNodeToStorage(dn); interactionTestHelper.GetDataStorage()->Add(node, dn); node->SetName("PLANAR FIGURE"); // set as selected node->SetSelected(true); node->AddProperty("selected", mitk::BoolProperty::New(true)); // Load state machine figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module *planarFigureModule = us::ModuleRegistry::GetModule("MitkPlanarFigure"); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule); figureInteractor->SetEventConfig("PlanarFigureConfig.xml", planarFigureModule); figureInteractor->SetDataNode(node); // Start Interaction interactionTestHelper.PlaybackInteraction(); // Load reference PlanarFigure mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New(); reader->SetFileName(GetTestDataFilePath(referenceFigurePath)); reader->Update(); mitk::PlanarFigure::Pointer reference = reader->GetOutput(0); // Compare figures MITK_ASSERT_EQUAL(figure, reference, "Compare figure with reference"); } void AngleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarAngle::New(); RunTest(figure, "InteractionTestData/Interactions/Angle1.xml", "InteractionTestData/ReferenceData/Angle1.pf"); } void Angle2InteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarAngle::New(); RunTest(figure, "InteractionTestData/Interactions/Angle2.xml", "InteractionTestData/ReferenceData/Angle2.pf"); } void BezierCurveInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarBezierCurve::New(); RunTest(figure, "InteractionTestData/Interactions/Bezier.xml", "InteractionTestData/ReferenceData/Bezier.pf"); } void CircleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarCircle::New(); RunTest(figure, "InteractionTestData/Interactions/Circle.xml", "InteractionTestData/ReferenceData/Circle.pf"); } void DoubleEllipseInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarDoubleEllipse::New(); RunTest(figure, "InteractionTestData/Interactions/DoubleEllipse.xml", "InteractionTestData/ReferenceData/DoubleEllipse.pf"); } void PlanarSubdivisionInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarSubdivisionPolygon::New(); RunTest(figure, "InteractionTestData/Interactions/SubdivisionPolygon.xml", "InteractionTestData/ReferenceData/SubDivision.pf"); } void PlanarFourPointAngleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarFourPointAngle::New(); RunTest(figure, "InteractionTestData/Interactions/Planar4PointAngle.xml", "InteractionTestData/ReferenceData/Planar4PointAngle.pf"); } void PlanarLineInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarLine::New(); RunTest(figure, "InteractionTestData/Interactions/Line.xml", "InteractionTestData/ReferenceData/Line.pf"); } void PlanarPolygonInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarPolygon::New(); RunTest(figure, "InteractionTestData/Interactions/Polygon.xml", "InteractionTestData/ReferenceData/Polygon.pf"); } void NonClosedPlanarPolygonInteractionCreate() { mitk::PlanarPolygon::Pointer figure; figure = mitk::PlanarPolygon::New(); figure->ClosedOff(); RunTest( figure.GetPointer(), "InteractionTestData/Interactions/Path.xml", "InteractionTestData/ReferenceData/Path.pf"); } void RectangleInteractionCreate() { mitk::PlanarFigure::Pointer figure; figure = mitk::PlanarRectangle::New(); RunTest(figure, "InteractionTestData/Interactions/Rectangle.xml", "InteractionTestData/ReferenceData/Rectangle.pf"); } // this is only for the OpenGL check mitkPlanarFigureInteractionTestSuite() : m_RenderingTestHelper(300, 300) {} private: mitk::RenderingTestHelper m_RenderingTestHelper; }; MITK_TEST_SUITE_REGISTRATION(mitkPlanarFigureInteraction) diff --git a/Modules/QtPython/Testing/mitkCommonPythonTest.h b/Modules/QtPython/Testing/mitkCommonPythonTest.h index a32375fbcb..2d72ed4881 100644 --- a/Modules/QtPython/Testing/mitkCommonPythonTest.h +++ b/Modules/QtPython/Testing/mitkCommonPythonTest.h @@ -1,73 +1,73 @@ /*=================================================================== 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 #include #include #include #include #include #include #include //#include #include //#include namespace mitk { class CommonPythonTestSuite : public mitk::TestFixture { protected: mitk::IPythonService* m_PythonService; mitk::Image::Pointer m_Image; mitk::Image::Pointer m_Image2D; mitk::Surface::Pointer m_Surface; //QMap m_Snippets; public: void setUp() { // Workaround to fix microservice loading issues!!! mitk::IPythonService::ForceLoadModule(); //get the context of the python module us::Module* module = us::ModuleRegistry::GetModule("MitkPythonService"); us::ModuleContext* context = module->GetModuleContext(); //get the service which is generated in the PythonModuleActivator us::ServiceReference serviceRef = context->GetServiceReference(); m_PythonService = dynamic_cast( context->GetService(serviceRef) ); - m_Image = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); - m_Image2D = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Png2D-bw.png"))[0].GetPointer()); - m_Surface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("binary.stl"))[0].GetPointer()); + m_Image = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); + m_Image2D = mitk::IOUtil::Load(GetTestDataFilePath("Png2D-bw.png")); + m_Surface = mitk::IOUtil::Load(GetTestDataFilePath("binary.stl")); //QmitkPythonSnippets::LoadStringMap(QmitkPythonSnippets::DEFAULT_SNIPPET_FILE,m_Snippets); } void tearDown() { m_Image = nullptr; m_Image2D = nullptr; m_Surface = nullptr; } }; } diff --git a/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp b/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp index 4a8b791cf5..f4b6a15e08 100644 --- a/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp @@ -1,488 +1,488 @@ /*=================================================================== 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 "QmitkPointListWidget.h" #include "QmitkPointListView.h" #include "QmitkPointListModel.h" #include #include #include #include #include #include #include #include #include QmitkPointListWidget::QmitkPointListWidget(QWidget *parent, int orientation) : QWidget(parent), m_PointListView(nullptr), m_PointSetNode(nullptr), m_Orientation(0), m_MovePointUpBtn(nullptr), m_MovePointDownBtn(nullptr), m_RemovePointBtn(nullptr), m_SavePointsBtn(nullptr), m_LoadPointsBtn(nullptr), m_ToggleAddPoint(nullptr), m_AddPoint(nullptr), m_TimeStepDisplay(nullptr), m_DataInteractor(nullptr), m_TimeStep(0), m_EditAllowed(true), m_NodeObserverTag(0) { m_PointListView = new QmitkPointListView(); if (orientation != 0) m_Orientation = orientation; SetupUi(); SetupConnections(); ObserveNewNode(nullptr); } QmitkPointListWidget::~QmitkPointListWidget() { m_DataInteractor = nullptr; if (m_PointSetNode && m_NodeObserverTag) { m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; } delete m_PointListView; } void QmitkPointListWidget::SetupConnections() { connect(this->m_LoadPointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnLoadPoints())); connect(this->m_SavePointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnSavePoints())); connect(this->m_MovePointUpBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointUp())); connect(this->m_MovePointDownBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointDown())); connect(this->m_RemovePointBtn, SIGNAL(clicked()), this, SLOT(RemoveSelectedPoint())); connect(this->m_ToggleAddPoint, SIGNAL(toggled(bool)), this, SLOT(OnBtnAddPoint(bool))); connect(this->m_AddPoint, SIGNAL(clicked()), this, SLOT(OnBtnAddPointManually())); connect(this->m_PointListView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnListDoubleClick())); connect(this->m_PointListView, SIGNAL(SignalPointSelectionChanged()), this, SLOT(OnPointSelectionChanged())); connect(this->m_PointListView, SIGNAL(SignalTimeStepChanged(int)), this, SLOT(OnTimeStepChanged(int))); } void QmitkPointListWidget::OnTimeStepChanged(int timeStep) { m_TimeStepLabel->setText(QString("%1").arg(timeStep)); } void QmitkPointListWidget::SetupUi() { // Setup the buttons m_ToggleAddPoint = new QPushButton(); m_ToggleAddPoint->setMaximumSize(25, 25); m_ToggleAddPoint->setCheckable(true); m_ToggleAddPoint->setToolTip("Toggle point editing (use SHIFT + Left Mouse Button to add Points)"); m_ToggleAddPoint->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/plus.svg"))); m_AddPoint = new QPushButton(); m_AddPoint->setMaximumSize(25, 25); m_AddPoint->setToolTip("Manually add point"); m_AddPoint->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/plus-xyz.svg"))); m_RemovePointBtn = new QPushButton(); m_RemovePointBtn->setMaximumSize(25, 25); m_RemovePointBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/eraser.svg"))); m_RemovePointBtn->setToolTip("Erase one point from list (Hotkey: DEL)"); m_MovePointUpBtn = new QPushButton(); m_MovePointUpBtn->setMaximumSize(25, 25); m_MovePointUpBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/arrow-up.svg"))); m_MovePointUpBtn->setToolTip("Swap selected point upwards (Hotkey: F2)"); m_MovePointDownBtn = new QPushButton(); m_MovePointDownBtn->setMaximumSize(25, 25); m_MovePointDownBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/arrow-down.svg"))); m_MovePointDownBtn->setToolTip("Swap selected point downwards (Hotkey: F3)"); m_SavePointsBtn = new QPushButton(); m_SavePointsBtn->setMaximumSize(25, 25); m_SavePointsBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/save.svg"))); m_SavePointsBtn->setToolTip("Save points to file"); m_LoadPointsBtn = new QPushButton(); m_LoadPointsBtn->setMaximumSize(25, 25); m_LoadPointsBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/folder-open.svg"))); m_LoadPointsBtn->setToolTip("Load list of points from file (REPLACES current content)"); int i; QBoxLayout *lay1; QBoxLayout *lay2; QBoxLayout *lay3; switch (m_Orientation) { case 0: lay1 = new QVBoxLayout(this); lay2 = new QHBoxLayout(); i = 0; break; case 1: lay1 = new QHBoxLayout(this); lay2 = new QVBoxLayout(); i = -1; break; case 2: lay1 = new QHBoxLayout(this); lay2 = new QVBoxLayout(); i = 0; break; default: lay1 = new QVBoxLayout(this); lay2 = new QHBoxLayout(); i = -1; break; } // setup Layouts this->setLayout(lay1); lay2->stretch(true); lay2->addWidget(m_ToggleAddPoint); lay2->addWidget(m_AddPoint); lay2->addWidget(m_RemovePointBtn); lay2->addWidget(m_MovePointUpBtn); lay2->addWidget(m_MovePointDownBtn); lay2->addWidget(m_SavePointsBtn); lay2->addWidget(m_LoadPointsBtn); // setup Labels m_TimeStepDisplay = new QLabel; m_TimeStepLabel = new QLabel; lay3 = new QHBoxLayout; m_TimeStepDisplay->setMaximumSize(200, 15); lay3->stretch(true); lay3->setAlignment(Qt::AlignLeft); lay3->addWidget(m_TimeStepDisplay); lay3->addWidget(m_TimeStepLabel); m_TimeStepDisplay->setText("Time Step: "); m_TimeStepLabel->setMaximumSize(10, 15); this->OnTimeStepChanged(0); //Add Layouts lay1->insertWidget(i, m_PointListView); this->setLayout(lay1); lay1->addLayout(lay2); lay1->addLayout(lay3); } void QmitkPointListWidget::SetPointSet(mitk::PointSet *newPs) { if (newPs == nullptr) return; this->m_PointSetNode->SetData(newPs); dynamic_cast(this->m_PointListView->model())->SetPointSetNode(m_PointSetNode); ObserveNewNode(m_PointSetNode); } void QmitkPointListWidget::SetPointSetNode(mitk::DataNode *newNode) { if (m_DataInteractor.IsNotNull()) m_DataInteractor->SetDataNode(newNode); ObserveNewNode(newNode); dynamic_cast(this->m_PointListView->model())->SetPointSetNode(newNode); } void QmitkPointListWidget::OnBtnSavePoints() { if ((dynamic_cast(m_PointSetNode->GetData())) == nullptr) return; // don't write empty point sets. If application logic requires something else then do something else. if ((dynamic_cast(m_PointSetNode->GetData()))->GetSize() == 0) return; // take the previously defined name of node as proposal for filename std::string nodeName = m_PointSetNode->GetName(); nodeName = "/" + nodeName + ".mps"; QString fileNameProposal = QString(); fileNameProposal.append(nodeName.c_str()); QString aFilename = QFileDialog::getSaveFileName( nullptr, "Save point set", QDir::currentPath() + fileNameProposal, "MITK Pointset (*.mps)"); if (aFilename.isEmpty()) return; try { mitk::IOUtil::Save(m_PointSetNode->GetData(), aFilename.toStdString()); } catch (...) { QMessageBox::warning(this, "Save point set", QString("File writer reported problems writing %1\n\n" "PLEASE CHECK output file!") .arg(aFilename)); } } void QmitkPointListWidget::OnBtnLoadPoints() { // get the name of the file to load QString filename = QFileDialog::getOpenFileName(nullptr, "Open MITK Pointset", "", "MITK Point Sets (*.mps)"); if (filename.isEmpty()) return; // attempt to load file try { - mitk::PointSet::Pointer pointSet = dynamic_cast(mitk::IOUtil::Load(filename.toStdString())[0].GetPointer()); + mitk::PointSet::Pointer pointSet = mitk::IOUtil::Load(filename.toStdString()); if (pointSet.IsNull()) { QMessageBox::warning(this, "Load point set", QString("File reader could not read %1").arg(filename)); return; } // loading successful this->SetPointSet(pointSet); } catch (...) { QMessageBox::warning(this, "Load point set", QString("File reader collapsed while reading %1").arg(filename)); } emit PointListChanged(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } mitk::PointSet *QmitkPointListWidget::GetPointSet() { return dynamic_cast(m_PointSetNode->GetData()); } mitk::DataNode *QmitkPointListWidget::GetPointSetNode() { return m_PointSetNode; } void QmitkPointListWidget::SetMultiWidget(QmitkStdMultiWidget *multiWidget) { m_PointListView->SetMultiWidget(multiWidget); } void QmitkPointListWidget::RemoveSelectedPoint() { if (!m_PointSetNode) return; mitk::PointSet *pointSet = dynamic_cast(m_PointSetNode->GetData()); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel *pointListModel = dynamic_cast(m_PointListView->model()); pointListModel->RemoveSelectedPoint(); emit PointListChanged(); } void QmitkPointListWidget::MoveSelectedPointDown() { if (!m_PointSetNode) return; mitk::PointSet *pointSet = dynamic_cast(m_PointSetNode->GetData()); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel *pointListModel = dynamic_cast(m_PointListView->model()); pointListModel->MoveSelectedPointDown(); emit PointListChanged(); } void QmitkPointListWidget::MoveSelectedPointUp() { if (!m_PointSetNode) return; mitk::PointSet *pointSet = dynamic_cast(m_PointSetNode->GetData()); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel *pointListModel = dynamic_cast(m_PointListView->model()); pointListModel->MoveSelectedPointUp(); emit PointListChanged(); } void QmitkPointListWidget::OnBtnAddPoint(bool checked) { if (m_PointSetNode.IsNotNull()) { if (checked) { m_DataInteractor = m_PointSetNode->GetDataInteractor(); // If no data Interactor is present create a new one if (m_DataInteractor.IsNull()) { // Create PointSetData Interactor m_DataInteractor = mitk::PointSetDataInteractor::New(); // Load the according state machine for regular point set interaction m_DataInteractor->LoadStateMachine("PointSet.xml"); // Set the configuration file that defines the triggers for the transitions m_DataInteractor->SetEventConfig("PointSetConfig.xml"); // set the DataNode (which already is added to the DataStorage m_DataInteractor->SetDataNode(m_PointSetNode); } } else { m_PointSetNode->SetDataInteractor(nullptr); m_DataInteractor = nullptr; } emit EditPointSets(checked); } } void QmitkPointListWidget::OnBtnAddPointManually() { mitk::PointSet *pointSet = this->GetPointSet(); QmitkEditPointDialog editPointDialog(this); if (this->GetPointSet()->IsEmpty()) { editPointDialog.SetPoint(pointSet, 0, m_TimeStep); } else { mitk::PointSet::PointsIterator maxIt = pointSet->GetMaxId(); mitk::PointSet::PointIdentifier maxId = maxIt->Index(); editPointDialog.SetPoint(pointSet, maxId + 1, m_TimeStep); } editPointDialog.exec(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointListWidget::OnListDoubleClick() { } void QmitkPointListWidget::OnPointSelectionChanged() { emit this->PointSelectionChanged(); } void QmitkPointListWidget::DeactivateInteractor(bool) { } void QmitkPointListWidget::EnableEditButton(bool enabled) { m_EditAllowed = enabled; if (enabled == false) m_ToggleAddPoint->setEnabled(false); else m_ToggleAddPoint->setEnabled(true); OnBtnAddPoint(enabled); } void QmitkPointListWidget::ObserveNewNode(mitk::DataNode *node) { if (m_DataInteractor.IsNotNull()) m_DataInteractor->SetDataNode(node); // remove old observer if (m_PointSetNode) { if (m_DataInteractor) { m_DataInteractor = nullptr; m_ToggleAddPoint->setChecked(false); } m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; } m_PointSetNode = node; // add new observer if necessary if (m_PointSetNode) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkPointListWidget::OnNodeDeleted); m_NodeObserverTag = m_PointSetNode->AddObserver(itk::DeleteEvent(), command); } else { m_NodeObserverTag = 0; } if (m_EditAllowed == true) m_ToggleAddPoint->setEnabled(m_PointSetNode); else m_ToggleAddPoint->setEnabled(false); m_RemovePointBtn->setEnabled(m_PointSetNode); m_LoadPointsBtn->setEnabled(m_PointSetNode); m_SavePointsBtn->setEnabled(m_PointSetNode); m_AddPoint->setEnabled(m_PointSetNode); } void QmitkPointListWidget::OnNodeDeleted(const itk::EventObject &) { if (m_PointSetNode.IsNotNull() && !m_NodeObserverTag) m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; m_PointSetNode = nullptr; m_PointListView->SetPointSetNode(nullptr); m_ToggleAddPoint->setEnabled(false); m_RemovePointBtn->setEnabled(false); m_LoadPointsBtn->setEnabled(false); m_SavePointsBtn->setEnabled(false); m_AddPoint->setEnabled(false); } void QmitkPointListWidget::AddSliceNavigationController(mitk::SliceNavigationController *snc) { m_PointListView->AddSliceNavigationController(snc); } void QmitkPointListWidget::RemoveSliceNavigationController(mitk::SliceNavigationController *snc) { m_PointListView->RemoveSliceNavigationController(snc); } void QmitkPointListWidget::UnselectEditButton() { m_ToggleAddPoint->setChecked(false); } diff --git a/Modules/Remeshing/Testing/mitkACVDTest.cpp b/Modules/Remeshing/Testing/mitkACVDTest.cpp index 27813ee294..0208444623 100644 --- a/Modules/Remeshing/Testing/mitkACVDTest.cpp +++ b/Modules/Remeshing/Testing/mitkACVDTest.cpp @@ -1,142 +1,142 @@ /*=================================================================== 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 #include #include #include #define _MITK_TEST_FOR_EXCEPTION(STATEMENT, EXCEPTION, MESSAGE) \ MITK_TEST_OUTPUT_NO_ENDL(<< MESSAGE) \ try \ { \ STATEMENT; \ MITK_TEST_OUTPUT(<< " [FAILED]") \ mitk::TestManager::GetInstance()->TestFailed(); \ } \ catch (const EXCEPTION &e) \ { \ MITK_TEST_OUTPUT(<< "\n " << e.GetDescription() << " [PASSED]") \ mitk::TestManager::GetInstance()->TestPassed(); \ } template static T lexical_cast(const std::string &string) { std::istringstream sstream(string); T value; sstream >> value; if (sstream.fail()) { MITK_ERROR << "Lexical cast failed for '" << string << "'!"; exit(EXIT_FAILURE); } return value; } static void Remesh_SurfaceIsNull_ThrowsException() { mitk::Surface::ConstPointer surface; _MITK_TEST_FOR_EXCEPTION( mitk::ACVD::Remesh(surface, 0, 100, 0.0), mitk::Exception, "Remesh_SurfaceIsNull_ThrowsException") } static void Remesh_PolyDataIsNull_ThrowsException() { mitk::Surface::ConstPointer surface = mitk::Surface::New().GetPointer(); _MITK_TEST_FOR_EXCEPTION( mitk::ACVD::Remesh(surface, 0, 100, 0.0), mitk::Exception, "Remesh_PolyDataIsNull_ThrowsException") } static void Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException() { mitk::Surface::ConstPointer surface = mitk::Surface::New().GetPointer(); _MITK_TEST_FOR_EXCEPTION(mitk::ACVD::Remesh(surface, 1, 100, 0.0), mitk::Exception, "Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException") } static void Remesh_SurfaceHasNoPolygons_ThrowsException() { mitk::Surface::Pointer surface = mitk::Surface::New(); vtkSmartPointer polyData = vtkSmartPointer::New(); surface->SetVtkPolyData(polyData); _MITK_TEST_FOR_EXCEPTION(mitk::ACVD::Remesh(surface.GetPointer(), 0, 100, 0.0), mitk::Exception, "Remesh_SurfaceHasNoPolygons_ThrowsException") } static void Remesh_SurfaceIsValid_ReturnsRemeshedSurface(const std::string &filename, unsigned int t, int numVertices, double gradation, int subsampling, double edgeSplitting, int optimizationLevel, bool forceManifold, bool boundaryFixing) { - mitk::Surface::ConstPointer surface = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Surface::ConstPointer surface = mitk::IOUtil::Load(filename); mitk::Surface::Pointer remeshedSurface = mitk::ACVD::Remesh( surface, t, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing); MITK_TEST_CONDITION(remeshedSurface.IsNotNull() && remeshedSurface->GetVtkPolyData() != nullptr && remeshedSurface->GetVtkPolyData()->GetNumberOfPolys() != 0, "Remesh_SurfaceIsValid_ReturnsRemeshedSurface") } int mitkACVDTest(int argc, char *argv[]) { if (argc != 10) { MITK_ERROR << "Invalid argument count!\n" << "Usage: mitkACVDTest \n" << " \n" << " \n" << " See MITK API documentation of mitk::ACVD::Remesh() for details."; return EXIT_FAILURE; } const std::string filename = argv[1]; const unsigned int t = lexical_cast(argv[2]); const int numVertices = lexical_cast(argv[3]); const double gradation = lexical_cast(argv[4]); const int subsampling = lexical_cast(argv[5]); const double edgeSplitting = lexical_cast(argv[6]); const int optimizationLevel = lexical_cast(argv[7]); const bool forceManifold = lexical_cast(argv[8]); const bool boundaryFixing = lexical_cast(argv[9]); MITK_TEST_BEGIN("mitkACVDTest") vtkDebugLeaks::SetExitError(0); Remesh_SurfaceIsNull_ThrowsException(); Remesh_PolyDataIsNull_ThrowsException(); Remesh_SurfaceDoesNotHaveDataAtTimeStep_ThrowsException(); Remesh_SurfaceHasNoPolygons_ThrowsException(); Remesh_SurfaceIsValid_ReturnsRemeshedSurface( filename, t, numVertices, gradation, subsampling, edgeSplitting, optimizationLevel, forceManifold, boundaryFixing); MITK_TEST_END() } diff --git a/Modules/SceneSerialization/test/mitkSceneIOTest.cpp b/Modules/SceneSerialization/test/mitkSceneIOTest.cpp index 346c522eff..684d20d7dc 100644 --- a/Modules/SceneSerialization/test/mitkSceneIOTest.cpp +++ b/Modules/SceneSerialization/test/mitkSceneIOTest.cpp @@ -1,377 +1,377 @@ /*=================================================================== 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 "mitkTestingConfig.h" #include "mitkTestingMacros.h" #include "mitkSceneIO.h" #include "Poco/File.h" #include "Poco/TemporaryFile.h" #include "mitkBaseData.h" #include "mitkCoreObjectFactory.h" #include "mitkGeometryData.h" #include "mitkIOUtil.h" #include "mitkImage.h" #include "mitkPointSet.h" #include "mitkStandaloneDataStorage.h" #include "mitkStandardFileLocations.h" #include "mitkSurface.h" #ifndef WIN32 #include #include #endif class SceneIOTestClass { public: static mitk::Image::Pointer LoadImage(const std::string &filename) { - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(filename); if (image.IsNull()) { MITK_TEST_FAILED_MSG(<< "Test image '" << filename << "' was not loaded as an mitk::Image"); } return image; } static mitk::Surface::Pointer LoadSurface(const std::string &filename) { - mitk::Surface::Pointer surface = dynamic_cast(mitk::IOUtil::Load(filename)[0].GetPointer()); + mitk::Surface::Pointer surface = mitk::IOUtil::Load(filename); if (surface.IsNull()) { MITK_TEST_FAILED_MSG(<< "Test surface '" << filename << "' was not loaded as an mitk::Surface"); } return surface; } static mitk::PointSet::Pointer CreatePointSet() { mitk::PointSet::Pointer ps = mitk::PointSet::New(); mitk::PointSet::PointType p; mitk::FillVector3D(p, 1.0, -2.0, 33.0); ps->SetPoint(0, p); mitk::FillVector3D(p, 100.0, -200.0, 3300.0); ps->SetPoint(1, p); mitk::FillVector3D(p, 2.0, -3.0, 22.0); ps->SetPoint(2, p, mitk::PTCORNER); // add point spec // mitk::FillVector3D(p, -2.0, -2.0, -2.22); // ps->SetPoint(0, p, 1); // ID 0 in timestep 1 // mitk::FillVector3D(p, -1.0, -1.0, -11.22); // ps->SetPoint(1, p, 1); // ID 1 in timestep 1 // mitk::FillVector3D(p, 1000.0, 1000.0, 1122.22); // ps->SetPoint(11, p, mitk::PTCORNER, 2); // ID 11, point spec, timestep 2 return ps; } static mitk::GeometryData::Pointer CreateGeometryDataObject() { mitk::GeometryData::Pointer gdata = mitk::GeometryData::New(); // define Geometry3D parameters mitk::AffineTransform3D::MatrixType matrix; matrix[0][0] = 1.1; matrix[1][1] = 2.2; matrix[2][2] = 3.3; mitk::AffineTransform3D::OffsetType offset; mitk::FillVector3D(offset, 0.1, 0.2, 0.3); bool isImageGeometry(false); unsigned int frameOfReferenceID(47); mitk::BaseGeometry::BoundsArrayType bounds; mitk::Point3D origin; mitk::FillVector3D(origin, 5.1, 5.2, 5.3); mitk::Vector3D spacing; mitk::FillVector3D(spacing, 2.1, 2.2, 2.3); // build GeometryData from matrix/offset/etc. mitk::AffineTransform3D::Pointer newTransform = mitk::AffineTransform3D::New(); newTransform->SetMatrix(matrix); newTransform->SetOffset(offset); mitk::Geometry3D::Pointer newGeometry = mitk::Geometry3D::New(); newGeometry->SetFrameOfReferenceID(frameOfReferenceID); newGeometry->SetImageGeometry(isImageGeometry); newGeometry->SetIndexToWorldTransform(newTransform); newGeometry->SetBounds(bounds); newGeometry->SetOrigin(origin); newGeometry->SetSpacing(spacing); mitk::GeometryData::Pointer newGeometryData = mitk::GeometryData::New(); gdata->SetGeometry(newGeometry); return gdata; } static void FillStorage(mitk::DataStorage *storage, std::string imageName, std::string surfaceName) { mitk::Image::Pointer image = LoadImage(imageName); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Loading test image" + imageName); image->SetProperty("image type", mitk::StringProperty::New("test image")); image->SetProperty("greetings", mitk::StringProperty::New("to mom")); image->SetProperty("test_float_property", mitk::FloatProperty::New(-2.57f)); mitk::DataNode::Pointer imagenode = mitk::DataNode::New(); imagenode->SetData(image); imagenode->SetName("Pic3D"); storage->Add(imagenode); mitk::DataNode::Pointer imagechildnode = mitk::DataNode::New(); imagechildnode->SetData(image); imagechildnode->SetName("Pic3D again"); storage->Add(imagechildnode, imagenode); mitk::Surface::Pointer surface = LoadSurface(surfaceName); MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(), "Loading test surface binary.stl"); surface->SetProperty("surface type", mitk::StringProperty::New("test surface")); surface->SetProperty("greetings", mitk::StringProperty::New("to dad")); mitk::DataNode::Pointer surfacenode = mitk::DataNode::New(); surfacenode->SetData(surface); surfacenode->SetName("binary"); storage->Add(surfacenode); mitk::PointSet::Pointer ps = CreatePointSet(); mitk::DataNode::Pointer psenode = mitk::DataNode::New(); psenode->SetData(ps); psenode->SetName("points"); storage->Add(psenode); mitk::GeometryData::Pointer gdo = CreateGeometryDataObject(); mitk::DataNode::Pointer geomNode = mitk::DataNode::New(); geomNode->SetData(gdo); geomNode->SetName("geometry3d"); storage->Add(geomNode); } static void VerifyStorage(mitk::DataStorage *storage) { mitk::DataNode::Pointer imagenode = storage->GetNamedNode("Pic3D"); MITK_TEST_CONDITION_REQUIRED(imagenode.IsNotNull(), "Get previously stored image node"); mitk::Image::Pointer image = dynamic_cast(imagenode->GetData()); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(), "Loading test image from Datastorage"); // Image std::string testString(""); float testFloatValue = 0.0f; mitk::PropertyList::Pointer imagePropList = image->GetPropertyList(); imagePropList->GetStringProperty("image type", testString); MITK_TEST_CONDITION(testString == "test image", "Get StringProperty from previously stored image"); imagePropList->GetStringProperty("greetings", testString); MITK_TEST_CONDITION(testString == "to mom", "Get another StringProperty from previously stored image"); imagePropList->GetFloatProperty("test_float_property", testFloatValue); MITK_TEST_CONDITION(testFloatValue == -2.57f, "Get FloatProperty from previously stored image.") // Get Image child node mitk::DataNode::Pointer imagechildnode = storage->GetNamedNode("Pic3D again"); mitk::DataStorage::SetOfObjects::ConstPointer objects = storage->GetSources(imagechildnode); MITK_TEST_CONDITION_REQUIRED(objects->Size() == 1, "Check size of image child nodes source list"); MITK_TEST_CONDITION_REQUIRED(objects->ElementAt(0) == imagenode, "Check for right parent node"); mitk::Image::Pointer imagechild = dynamic_cast(imagechildnode->GetData()); MITK_TEST_CONDITION_REQUIRED(imagechild.IsNotNull(), "Loading child test image from Datastorage"); // Surface mitk::DataNode::Pointer surfacenode = storage->GetNamedNode("binary"); MITK_TEST_CONDITION_REQUIRED(surfacenode.IsNotNull(), "Get previously stored surface node"); mitk::Surface::Pointer surface = dynamic_cast(surfacenode->GetData()); MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(), "Loading test surface from Datastorage"); // Get the property list and test the properties mitk::PropertyList::Pointer surfacePropList = surface->GetPropertyList(); surfacePropList->GetStringProperty("surface type", testString); MITK_TEST_CONDITION((testString.compare("test surface") == 0), "Get StringProperty from previously stored surface node"); surfacePropList->GetStringProperty("greetings", testString); MITK_TEST_CONDITION((testString.compare("to dad") == 0), "Get another StringProperty from previously stored surface node"); // PointSet mitk::DataNode::Pointer pointsnode = storage->GetNamedNode("points"); MITK_TEST_CONDITION_REQUIRED(pointsnode.IsNotNull(), "Get previously stored PointSet node"); mitk::PointSet::Pointer pointset = dynamic_cast(pointsnode->GetData()); MITK_TEST_CONDITION_REQUIRED(pointset.IsNotNull(), "Loading test PointSet from Datastorage"); mitk::PointSet::PointType p = pointset->GetPoint(0); MITK_TEST_CONDITION_REQUIRED(p[0] == 1.0 && p[1] == -2.0 && p[2] == 33.0, "Test Pointset entry 0 after loading"); p = pointset->GetPoint(1); MITK_TEST_CONDITION_REQUIRED(p[0] == 100.0 && p[1] == -200.0 && p[2] == 3300.0, "Test Pointset entry 1 after loading"); p = pointset->GetPoint(2); MITK_TEST_CONDITION_REQUIRED(p[0] == 2.0 && p[1] == -3.0 && p[2] == 22.0, "Test Pointset entry 2 after loading"); // GeometryData mitk::DataNode::Pointer geomnode = storage->GetNamedNode("geometry3d"); MITK_TEST_CONDITION_REQUIRED(geomnode.IsNotNull(), "Get previously stored GeometryData node"); mitk::GeometryData::Pointer gdata = dynamic_cast(geomnode->GetData()); MITK_TEST_CONDITION_REQUIRED(gdata.IsNotNull(), "Loading test GeometryData from Datastorage"); mitk::Geometry3D::Pointer geom3D = dynamic_cast(gdata->GetGeometry()); MITK_TEST_CONDITION_REQUIRED(geom3D.IsNotNull(), "Reconstructed a Geometry3D from serialization"); MITK_TEST_CONDITION(geom3D->GetImageGeometry() == false, "Reconstructed Geometry3D 'is image geometry'"); MITK_TEST_CONDITION(geom3D->GetFrameOfReferenceID() == 47, "Reconstructa Geometry3D has frame of reference '47'"); // TODO test other properties, BUT don't test too much, that shall be done in a reader/writer test! } }; // end test helper class int mitkSceneIOTest(int, char *argv[]) { MITK_TEST_BEGIN("SceneIO") std::string sceneFileName; for (unsigned int i = 0; i < 1; ++i) // TODO change to " < 2" to check cases where file system would be full { if (i == 1) { // call ulimit and restrict maximum file size to something small #ifndef WIN32 errno = 0; long int value = ulimit(UL_SETFSIZE, 1); MITK_TEST_CONDITION_REQUIRED(value != -1, "ulimit() returned with errno = " << errno); #else continue; #endif } // create a data storage and fill it with some test data mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); MITK_TEST_CONDITION_REQUIRED(sceneIO.IsNotNull(), "SceneIO instantiation") mitk::DataStorage::Pointer storage = mitk::StandaloneDataStorage::New().GetPointer(); MITK_TEST_CONDITION_REQUIRED(storage.IsNotNull(), "StandaloneDataStorage instantiation"); std::cout << "ImageName: " << argv[1] << std::endl; std::cout << "SurfaceName: " << argv[2] << std::endl; SceneIOTestClass::FillStorage(storage, argv[1], argv[2]); // attempt to save it Poco::Path newname(Poco::TemporaryFile::tempName()); sceneFileName = std::string(MITK_TEST_OUTPUT_DIR) + Poco::Path::separator() + newname.getFileName() + ".zip"; MITK_TEST_CONDITION_REQUIRED(sceneIO->SaveScene(storage->GetAll(), storage, sceneFileName), "Saving scene file '" << sceneFileName << "'"); // test if no errors were reported mitk::SceneIO::FailedBaseDataListType::ConstPointer failedNodes = sceneIO->GetFailedNodes(); if (failedNodes.IsNotNull() && !failedNodes->empty()) { MITK_TEST_OUTPUT(<< "The following nodes could not be serialized:"); for (auto iter = failedNodes->begin(); iter != failedNodes->end(); ++iter) { MITK_TEST_OUTPUT_NO_ENDL(<< " - "); if (mitk::BaseData *data = (*iter)->GetData()) { MITK_TEST_OUTPUT_NO_ENDL(<< data->GetNameOfClass()); } else { MITK_TEST_OUTPUT_NO_ENDL(<< "(nullptr)"); } MITK_TEST_OUTPUT(<< " contained in node '" << (*iter)->GetName() << "'"); // \TODO: should we fail the test case if failed properties exist? } } mitk::PropertyList::ConstPointer failedProperties = sceneIO->GetFailedProperties(); if (failedProperties.IsNotNull() && !failedProperties->IsEmpty()) { MITK_TEST_OUTPUT(<< "The following properties could not be serialized:"); const mitk::PropertyList::PropertyMap *propmap = failedProperties->GetMap(); for (auto iter = propmap->begin(); iter != propmap->end(); ++iter) { MITK_TEST_OUTPUT(<< " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'"); // \TODO: should we fail the test case if failed properties exist? } } MITK_TEST_CONDITION_REQUIRED(failedProperties.IsNotNull() && failedProperties->IsEmpty(), "Checking if all properties have been saved.") MITK_TEST_CONDITION_REQUIRED(failedNodes.IsNotNull() && failedNodes->empty(), "Checking if all nodes have been saved.") // Now do the loading part sceneIO = mitk::SceneIO::New(); // Load scene into the datastorage and clean the DS first MITK_TEST_OUTPUT(<< "Loading scene again"); storage = sceneIO->LoadScene(sceneFileName, storage, true); // test if no errors were reported failedNodes = sceneIO->GetFailedNodes(); if (failedNodes.IsNotNull() && !failedNodes->empty()) { MITK_TEST_OUTPUT(<< "The following nodes could not be serialized:"); for (auto iter = failedNodes->begin(); iter != failedNodes->end(); ++iter) { MITK_TEST_OUTPUT_NO_ENDL(<< " - "); if (mitk::BaseData *data = (*iter)->GetData()) { MITK_TEST_OUTPUT_NO_ENDL(<< data->GetNameOfClass()); } else { MITK_TEST_OUTPUT_NO_ENDL(<< "(nullptr)"); } MITK_TEST_OUTPUT(<< " contained in node '" << (*iter)->GetName() << "'"); // \TODO: should we fail the test case if failed properties exist? } } failedProperties = sceneIO->GetFailedProperties(); if (failedProperties.IsNotNull() && !failedProperties->IsEmpty()) { MITK_TEST_OUTPUT(<< "The following properties could not be serialized:"); const mitk::PropertyList::PropertyMap *propmap = failedProperties->GetMap(); for (auto iter = propmap->begin(); iter != propmap->end(); ++iter) { MITK_TEST_OUTPUT(<< " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'"); // \TODO: should we fail the test case if failed properties exist? } } // check if data storage content has been restored correctly SceneIOTestClass::VerifyStorage(storage); } // if no sub-test failed remove the scene file, otherwise it is kept for debugging purposes if (mitk::TestManager::GetInstance()->NumberOfFailedTests() == 0) { Poco::File pocoSceneFile(sceneFileName); MITK_TEST_CONDITION_REQUIRED(pocoSceneFile.exists(), "Checking if scene file still exists before cleaning up.") pocoSceneFile.remove(); } MITK_TEST_END(); } diff --git a/Modules/Segmentation/Testing/mitkContourModelSetToImageFilterTest.cpp b/Modules/Segmentation/Testing/mitkContourModelSetToImageFilterTest.cpp index f569cf73c4..e9092f40e1 100644 --- a/Modules/Segmentation/Testing/mitkContourModelSetToImageFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkContourModelSetToImageFilterTest.cpp @@ -1,60 +1,60 @@ /*=================================================================== 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 #include #include class mitkContourModelSetToImageFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkContourModelSetToImageFilterTestSuite); MITK_TEST(TestFillContourSetIntoImage); CPPUNIT_TEST_SUITE_END(); private: mitk::ContourModelSetToImageFilter::Pointer m_ContourFiller; public: void setUp() override { m_ContourFiller = mitk::ContourModelSetToImageFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ContourModelSetToImageFilter", m_ContourFiller.IsNotNull()); } void TestFillContourSetIntoImage() { - mitk::Image::Pointer refImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("ContourModel-Data/RefImage.nrrd"))[0].GetPointer()); + mitk::Image::Pointer refImage = mitk::IOUtil::Load(GetTestDataFilePath("ContourModel-Data/RefImage.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load reference image", refImage.IsNotNull()); std::vector> readerOutput; readerOutput = mitk::IOUtil::Load(GetTestDataFilePath("ContourModel-Data/Contours.cnt_set")); mitk::ContourModelSet::Pointer cnt_set = dynamic_cast(readerOutput.at(0).GetPointer()); CPPUNIT_ASSERT_MESSAGE("Failed to load contours", cnt_set.IsNotNull()); m_ContourFiller->SetImage(refImage); m_ContourFiller->SetInput(cnt_set); m_ContourFiller->Update(); mitk::Image::Pointer filledImage = m_ContourFiller->GetOutput(); filledImage->DisconnectPipeline(); MITK_ASSERT_EQUAL(refImage, filledImage, "Error filling contours into image"); } }; MITK_TEST_SUITE_REGISTRATION(mitkContourModelSetToImageFilter) diff --git a/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp b/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp index 3994af96e7..9b3de1e55d 100644 --- a/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp @@ -1,71 +1,71 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include class mitkFeatureBasedEdgeDetectionFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkFeatureBasedEdgeDetectionFilterTestSuite); MITK_TEST(testFeatureBasedEdgeDetectionFilterInitialization); MITK_TEST(testInput); MITK_TEST(testUnstructuredGridGeneration); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ mitk::Image::Pointer m_Pic3D; mitk::Image::Pointer m_Segmentation; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override { - m_Pic3D = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); - m_Segmentation = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("PlaneSuggestion/pic3D_segmentation.nrrd"))[0].GetPointer()); + m_Pic3D = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); + m_Segmentation = mitk::IOUtil::Load(GetTestDataFilePath("PlaneSuggestion/pic3D_segmentation.nrrd")); } void testFeatureBasedEdgeDetectionFilterInitialization() { mitk::FeatureBasedEdgeDetectionFilter::Pointer testFilter = mitk::FeatureBasedEdgeDetectionFilter::New(); CPPUNIT_ASSERT_MESSAGE("Testing instantiation of test object", testFilter.IsNotNull()); } void testInput() { mitk::FeatureBasedEdgeDetectionFilter::Pointer testFilter = mitk::FeatureBasedEdgeDetectionFilter::New(); testFilter->SetInput(m_Pic3D); CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", testFilter->GetInput() == m_Pic3D); } void testUnstructuredGridGeneration() { mitk::FeatureBasedEdgeDetectionFilter::Pointer testFilter = mitk::FeatureBasedEdgeDetectionFilter::New(); testFilter->SetInput(m_Pic3D); testFilter->SetSegmentationMask(m_Segmentation); testFilter->Update(); CPPUNIT_ASSERT_MESSAGE("Testing surface generation!", testFilter->GetOutput()->GetVtkUnstructuredGrid() != nullptr); } }; MITK_TEST_SUITE_REGISTRATION(mitkFeatureBasedEdgeDetectionFilter) diff --git a/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp b/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp index e85c083285..73ca01f75a 100644 --- a/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp @@ -1,121 +1,121 @@ /*=================================================================== 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 #include #include class mitkImageToContourFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageToContourFilterTestSuite); MITK_TEST(TestExtractContoursFromAnEmptySlice); MITK_TEST(TestExtractASingleContourFromASlice); MITK_TEST(TestExtractTwoContoursFromASingleSlice); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_EmptySlice; mitk::Image::Pointer m_SliceWithSingleContour; mitk::Image::Pointer m_SliceWithTwoContours; mitk::ImageToContourFilter::Pointer m_ContourExtractor; public: void setUp() override { // Load the image // TODO Move/create segmentation subfolder - m_EmptySlice = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/EmptySlice.nrrd"))[0].GetPointer()); + m_EmptySlice = mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/EmptySlice.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [EmptySlice.nrrd]", m_EmptySlice.IsNotNull()); m_SliceWithSingleContour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/SliceWithSingleContour.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/SliceWithSingleContour.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [SliceWithSingleContour.nrrd]", m_SliceWithSingleContour.IsNotNull()); m_SliceWithTwoContours = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/SliceWithTwoContours.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/SliceWithTwoContours.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [SliceWithTwoContours.nrrd]", m_SliceWithTwoContours.IsNotNull()); m_ContourExtractor = mitk::ImageToContourFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ImageToContourFilter", m_ContourExtractor.IsNotNull()); } // Extract contours from an empty slice void TestExtractContoursFromAnEmptySlice() { m_ContourExtractor->SetInput(m_EmptySlice); m_ContourExtractor->Update(); mitk::Surface::Pointer emptyContour = m_ContourExtractor->GetOutput(); CPPUNIT_ASSERT_MESSAGE("Extracted contour is not empty", emptyContour->GetVtkPolyData()->GetNumberOfPoints() == 0); } // Extract a single contour from a slice void TestExtractASingleContourFromASlice() { m_ContourExtractor->SetInput(m_SliceWithSingleContour); m_ContourExtractor->Update(); CPPUNIT_ASSERT_MESSAGE("ImageToContourFilter has wrong number of outputs!", m_ContourExtractor->GetNumberOfOutputs() == 1); mitk::Surface::Pointer contour = m_ContourExtractor->GetOutput(); mitk::Surface::Pointer referenceContour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); CPPUNIT_ASSERT_MESSAGE( "Extracted contour has wrong number of points!", contour->GetVtkPolyData()->GetNumberOfPoints() == referenceContour->GetVtkPolyData()->GetNumberOfPoints()); CPPUNIT_ASSERT_MESSAGE( "Unequal contours", mitk::Equal(*(contour->GetVtkPolyData()), *(referenceContour->GetVtkPolyData()), 0.000001, true)); } // Extract multiple contours from a single slice void TestExtractTwoContoursFromASingleSlice() { m_ContourExtractor->SetInput(m_SliceWithTwoContours); m_ContourExtractor->Update(); CPPUNIT_ASSERT_MESSAGE("ImageToContourFilter has wrong number of outputs!", m_ContourExtractor->GetNumberOfOutputs() == 1); mitk::Surface::Pointer contour = m_ContourExtractor->GetOutput(0); mitk::Surface::Pointer referenceContour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/TwoContours.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/TwoContours.vtk")); CPPUNIT_ASSERT_MESSAGE( "Extracted contour1 has wrong number of points!", contour->GetVtkPolyData()->GetNumberOfPoints() == referenceContour->GetVtkPolyData()->GetNumberOfPoints()); CPPUNIT_ASSERT_MESSAGE( "Extracted contour1 has wrong number of points!", contour->GetVtkPolyData()->GetNumberOfPolys() == referenceContour->GetVtkPolyData()->GetNumberOfPolys()); CPPUNIT_ASSERT_MESSAGE( "Unequal contours", mitk::Equal(*(contour->GetVtkPolyData()), *(referenceContour->GetVtkPolyData()), 0.000001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkImageToContourFilter) diff --git a/Modules/Segmentation/Testing/mitkManualSegmentationToSurfaceFilterTest.cpp b/Modules/Segmentation/Testing/mitkManualSegmentationToSurfaceFilterTest.cpp index e147efaeac..f3817fd6ed 100644 --- a/Modules/Segmentation/Testing/mitkManualSegmentationToSurfaceFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkManualSegmentationToSurfaceFilterTest.cpp @@ -1,90 +1,90 @@ /*=================================================================== 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 #include class mitkManualSegmentationToSurfaceFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkManualSegmentationToSurfaceFilterTestSuite); // Add tests with reference data. // For now I only add reference for BallBinary, since // other images do not really make sense. // Note: .stl consumes much more memory and even loses // some vertices and triangles during saving. Hence, //.vtp is preferred as reference format. MITK_PARAMETERIZED_TEST_2(Update_BallBinary_OutputEqualsReference, "BallBinary30x30x30.nrrd", "BallBinary30x30x30Reference.vtp"); MITK_PARAMETERIZED_TEST_2(Update_BallBinaryAndSmooth_OutputEqualsReference, "BallBinary30x30x30.nrrd", "BallBinary30x30x30SmoothReference.vtp"); CPPUNIT_TEST_SUITE_END(); private: mitk::ManualSegmentationToSurfaceFilter::Pointer m_Filter; mitk::Surface::Pointer m_ReferenceSurface; public: void setUp() override { std::vector parameter = GetTestParameter(); m_Filter = mitk::ManualSegmentationToSurfaceFilter::New(); if (parameter.size() == 2) { - m_Filter->SetInput(dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(parameter.at(0)))[0].GetPointer())); + m_Filter->SetInput(mitk::IOUtil::Load(GetTestDataFilePath(parameter.at(0)))); // For the tests which have reference data - m_ReferenceSurface = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(parameter.at(1)))[0].GetPointer()); + m_ReferenceSurface = mitk::IOUtil::Load(GetTestDataFilePath(parameter.at(1))); } else { MITK_WARN << "No test run for parameter for unknown parameter."; } } void tearDown() override { m_Filter = nullptr; m_ReferenceSurface = nullptr; } void Update_BallBinary_OutputEqualsReference() { m_Filter->Update(); mitk::Surface::Pointer computedOutput = m_Filter->GetOutput(); MITK_ASSERT_EQUAL(computedOutput, m_ReferenceSurface, "Computed equals the reference?"); } void Update_BallBinaryAndSmooth_OutputEqualsReference() { m_Filter->MedianFilter3DOn(); m_Filter->SetGaussianStandardDeviation(1.5); m_Filter->InterpolationOn(); m_Filter->UseGaussianImageSmoothOn(); m_Filter->SetThreshold(1); m_Filter->SetDecimate(mitk::ImageToSurfaceFilter::DecimatePro); m_Filter->SetTargetReduction(0.05f); m_Filter->SmoothOn(); m_Filter->Update(); mitk::Surface::Pointer computedOutput = m_Filter->GetOutput(); MITK_ASSERT_EQUAL(computedOutput, m_ReferenceSurface, "Computed equals the reference?"); } }; MITK_TEST_SUITE_REGISTRATION(mitkManualSegmentationToSurfaceFilter) diff --git a/Modules/Segmentation/Testing/mitkOverwriteSliceImageFilterTest.cpp b/Modules/Segmentation/Testing/mitkOverwriteSliceImageFilterTest.cpp index 52cf82b431..f7078e7959 100644 --- a/Modules/Segmentation/Testing/mitkOverwriteSliceImageFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkOverwriteSliceImageFilterTest.cpp @@ -1,370 +1,370 @@ /*=================================================================== 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 "mitkCompareImageSliceTestHelper.h" #include "mitkCoreObjectFactory.h" #include "mitkExtractImageFilter.h" #include "mitkOverwriteSliceImageFilter.h" #include unsigned int CompareImageSliceTestHelper::m_Dimension0 = 0; unsigned int CompareImageSliceTestHelper::m_Dimension1 = 0; unsigned int CompareImageSliceTestHelper::m_SliceDimension = 0; unsigned int CompareImageSliceTestHelper::m_SliceIndex = 0; bool CompareImageSliceTestHelper::m_ComparisonResult = false; mitk::Image *CompareImageSliceTestHelper::m_SliceImage = nullptr; class mitkOverwriteSliceImageFilterTestClass { public: static void Test3D(mitk::OverwriteSliceImageFilter *filter, mitk::Image *image, unsigned int &numberFailed) { assert(filter); assert(image); filter->SetInput(image); unsigned int initialNumberFailed = numberFailed; bool exception = false; // first extract slices and rewrite them for (unsigned int sliceDimension = 0; sliceDimension < 3; ++sliceDimension) { mitk::ExtractImageFilter::Pointer extractor = mitk::ExtractImageFilter::New(); extractor->SetInput(image); extractor->SetSliceDimension(sliceDimension); extractor->SetSliceIndex(2); // third slice in that direction try { extractor->Update(); } catch (...) { if (sliceDimension < 3) { // probably no sliceindex 2 there or extractor just doesn't work (check the corresponding test) std::cout << " (WW) Couldn't extract slice number 3 from a 3D image. This could be a problem if the image " "is not only two slices big." << std::endl; continue; } else { continue; // good } } mitk::Image::Pointer slice = extractor->GetOutput()->Clone(); filter->SetSliceDimension(sliceDimension); filter->SetSliceIndex(1); // second slice in that direction filter->SetSliceImage(slice); try { filter->Update(); // try to overwrite } catch (...) { if (sliceDimension < 3) { ++numberFailed; std::cerr << " (EE) Couln't overwrite a slice with data from a neigbor in a " << image->GetDimension() << "-dimensional image, sliceDimension " << sliceDimension << " sliceIndex 1-2." << "(l. " << __LINE__ << ")" << std::endl; } else { // this was expected and is nice to see continue; } } mitk::Image::Pointer output = filter->GetOutput(); if (output.IsNull()) { ++numberFailed; std::cerr << " (EE) Overwrite filter has output nullptr and gave no exception for an " << image->GetDimension() << "-dimensional image, sliceDimension " << sliceDimension << " sliceIndex 1-2." << "(l. " << __LINE__ << ")" << std::endl; continue; } if (!CompareImageSliceTestHelper::CompareSlice(image, sliceDimension, 1, slice)) { ++numberFailed; std::cerr << " (EE) Overwriting a slice seemed to work, but the pixels are not correct for an " << image->GetDimension() << "-dimensional image, sliceDimension " << sliceDimension << " sliceIndex 1-2." << "(l. " << __LINE__ << ")" << std::endl; } // try inserting at a position outside the image filter->SetSliceDimension(sliceDimension); filter->SetSliceIndex(image->GetDimension(sliceDimension)); // last possible slice index + 1 filter->SetSliceImage(slice); exception = false; try { filter->Update(); // try to overwrite } catch (...) { exception = true; } if (!exception) { ++numberFailed; std::cerr << " (EE) Inserting a slice outside the 3D volume did NOT throw an exception for an " << image->GetDimension() << "-dimensional image, sliceDimension " << sliceDimension << " sliceIndex 1-2." << "(l. " << __LINE__ << ")" << std::endl; } mitk::Image::Pointer originalSlice = slice; // now test slices that just don't fit (slice too big) { unsigned int dim[] = {slice->GetDimension(0) + 2, slice->GetDimension(1) + 2}; slice = mitk::Image::New(); slice->Initialize(mitk::MakeScalarPixelType(), 2, dim); unsigned int i; mitk::ImageWriteAccessor accessor(slice); auto *p = (signed int *)accessor.GetData(); unsigned int size = dim[0] * dim[1]; for (i = 0; i < size; ++i, ++p) *p = (signed int)i; // try to insert this bad slice filter->SetSliceImage(slice); exception = false; try { filter->Update(); // try to overwrite } catch (...) { exception = true; } if (!exception) { ++numberFailed; std::cerr << " (EE) Trying to insert a slice of bad dimensions (larger) did NOT throw an exception in an " << image->GetDimension() << "-dimensional image, sliceDimension " << sliceDimension << " sliceIndex 1-2." << "(l. " << __LINE__ << ")" << std::endl; } } // now test slices that just don't fit (slice too small) { slice = originalSlice; if ((slice->GetDimension(0) < 3) || (slice->GetDimension(1) < 3)) continue; // not possible shrink the image much further unsigned int dim[] = {slice->GetDimension(0) - 2, slice->GetDimension(1) - 2}; slice = mitk::Image::New(); slice->Initialize(mitk::MakeScalarPixelType(), 2, dim); unsigned int i; mitk::ImageWriteAccessor accessor(slice); auto *p = (signed int *)accessor.GetData(); unsigned int size = dim[0] * dim[1]; for (i = 0; i < size; ++i, ++p) *p = (signed int)i; // try to insert this bad slice filter->SetSliceImage(slice); exception = false; try { filter->Update(); // try to overwrite } catch (...) { exception = true; } if (!exception) { ++numberFailed; std::cerr << " (EE) Trying to insert a slice of bad dimensions (smaller) did NOT throw an exception in an " << image->GetDimension() << "-dimensional image, sliceDimension " << sliceDimension << " sliceIndex 1-2." << "(l. " << __LINE__ << ")" << std::endl; } } } if (numberFailed == initialNumberFailed) { std::cout << " (II) Overwriting works nicely (gives result, pixels are good) " << image->GetDimension() << "-dimensional image." << "(l. " << __LINE__ << ")" << std::endl; } } static void Test2D(mitk::OverwriteSliceImageFilter *filter, mitk::Image *image, unsigned int &numberFailed) { assert(filter); assert(image); filter->SetInput(image); filter->SetSliceImage(image); bool exception = false; try { filter->Update(); } catch (...) { exception = true; } if (!exception) { std::cerr << " (EE) Using OverwriteImageFilter for 2D -> 2D did not throw an exception " << "(l. " << __LINE__ << ")" << std::endl; } unsigned int initialNumberFailed = numberFailed; if (numberFailed == initialNumberFailed) { std::cout << " (II) Overwriting works nicely (gives result, pixels are good) " << image->GetDimension() << "-dimensional image." << "(l. " << __LINE__ << ")" << std::endl; } } static void TestOtherD(mitk::OverwriteSliceImageFilter *filter, mitk::Image *image, unsigned int &numberFailed) { assert(filter); assert(image); filter->SetInput(image); filter->SetSliceImage(image); bool exception = false; try { filter->Update(); } catch (...) { exception = true; } if (!exception) { std::cerr << " (EE) Using OverwriteImageFilter did not throw an exception " << "(l. " << __LINE__ << ")" << std::endl; } unsigned int initialNumberFailed = numberFailed; if (numberFailed == initialNumberFailed) { std::cout << " (II) Overwriting works nicely (gives result, pixels are good) " << image->GetDimension() << "-dimensional image." << "(l. " << __LINE__ << ")" << std::endl; } } }; /// ctest entry point int mitkOverwriteSliceImageFilterTest(int argc, char *argv[]) { // one big variable to tell if anything went wrong unsigned int numberFailed(0); // need one parameter (image filename) if (argc == 0) { std::cerr << "No file specified [FAILED]" << std::endl; return EXIT_FAILURE; } // load the image mitk::Image::Pointer image = nullptr; try { MITK_INFO << "Testing with parameter '" << argv[1] << "'"; std::string pathToImage(argv[1]); - image = dynamic_cast(mitk::IOUtil::Load(pathToImage)[0].GetPointer()); + image = mitk::IOUtil::Load(pathToImage); if (image.IsNull()) { MITK_INFO << "File not an image - test will not be applied"; return EXIT_FAILURE; } } catch (itk::ExceptionObject &ex) { ++numberFailed; std::cerr << "Exception: " << ex << "[FAILED]" << std::endl; return EXIT_FAILURE; } std::cout << " (II) Could load image." << std::endl; std::cout << "Testing filter instantiation" << std::endl; // instantiation mitk::OverwriteSliceImageFilter::Pointer filter = mitk::OverwriteSliceImageFilter::New(); if (filter.IsNotNull()) { std::cout << " (II) Instantiation works." << std::endl; } else { ++numberFailed; std::cout << "Test failed, and it's the ugliest one!" << std::endl; return EXIT_FAILURE; } // some real work if (image->GetDimension() == 2) { mitkOverwriteSliceImageFilterTestClass::Test2D(filter, image, numberFailed); } else if (image->GetDimension() == 3) { mitkOverwriteSliceImageFilterTestClass::Test3D(filter, image, numberFailed); } else { mitkOverwriteSliceImageFilterTestClass::TestOtherD(filter, image, numberFailed); } std::cout << "Testing filter destruction" << std::endl; // freeing filter = nullptr; std::cout << " (II) Freeing works." << std::endl; if (numberFailed > 0) { std::cerr << numberFailed << " tests failed." << std::endl; return EXIT_FAILURE; } else { std::cout << "PASSED all tests." << std::endl; return EXIT_SUCCESS; } } diff --git a/Modules/Segmentation/Testing/mitkSegmentationInterpolationTest.cpp b/Modules/Segmentation/Testing/mitkSegmentationInterpolationTest.cpp index 24ab4552e2..0dcde93a42 100644 --- a/Modules/Segmentation/Testing/mitkSegmentationInterpolationTest.cpp +++ b/Modules/Segmentation/Testing/mitkSegmentationInterpolationTest.cpp @@ -1,208 +1,208 @@ /*=================================================================== 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. ===================================================================*/ // Testing #include #include // other #include #include #include #include #include #include #include #include #include class mitkSegmentationInterpolationTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSegmentationInterpolationTestSuite); MITK_TEST(Equal_Axial_TestInterpolationAndReferenceInterpolation_ReturnsTrue); MITK_TEST(Equal_Frontal_TestInterpolationAndReferenceInterpolation_ReturnsTrue); MITK_TEST(Equal_Sagittal_TestInterpolationAndReferenceInterpolation_ReturnsTrue); CPPUNIT_TEST_SUITE_END(); private: // The tests all do the same, only in different directions void testRoutine(mitk::SliceNavigationController::ViewDirection viewDirection) { int dim; switch (viewDirection) { case (mitk::SliceNavigationController::Axial): dim = 2; break; case (mitk::SliceNavigationController::Frontal): dim = 1; break; case (mitk::SliceNavigationController::Sagittal): dim = 0; break; default: // mitk::SliceNavigationController::Original dim = -1; break; } /* Fill segmentation * * 1st slice: 3x3 square segmentation * 2nd slice: empty * 3rd slice: 1x1 square segmentation in corner * -> 2nd slice should become 2x2 square in corner * * put accessor in scope */ itk::Index<3> currentPoint; { mitk::ImagePixelWriteAccessor writeAccessor(m_SegmentationImage); // Fill 3x3 slice currentPoint[dim] = m_CenterPoint[dim] - 1; for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { currentPoint[(dim + 1) % 3] = m_CenterPoint[(dim + 1) % 3] + i; currentPoint[(dim + 2) % 3] = m_CenterPoint[(dim + 2) % 3] + j; writeAccessor.SetPixelByIndexSafe(currentPoint, 1); } } // Now i=j=1, set point two slices up currentPoint[dim] = m_CenterPoint[dim] + 1; writeAccessor.SetPixelByIndexSafe(currentPoint, 1); } // mitk::IOUtil::Save(m_SegmentationImage, "SOME PATH"); m_InterpolationController->SetSegmentationVolume(m_SegmentationImage); m_InterpolationController->SetReferenceVolume(m_ReferenceImage); // This could be easier... mitk::SliceNavigationController::Pointer navigationController = mitk::SliceNavigationController::New(); navigationController->SetInputWorldTimeGeometry(m_SegmentationImage->GetTimeGeometry()); navigationController->Update(viewDirection); mitk::Point3D pointMM; m_SegmentationImage->GetTimeGeometry()->GetGeometryForTimeStep(0)->IndexToWorld(m_CenterPoint, pointMM); navigationController->SelectSliceByPoint(pointMM); auto plane = navigationController->GetCurrentPlaneGeometry(); mitk::Image::Pointer interpolationResult = m_InterpolationController->Interpolate(dim, m_CenterPoint[dim], plane, 0); // mitk::IOUtil::Save(interpolationResult, "SOME PATH"); // Write result into segmentation image vtkSmartPointer reslicer = vtkSmartPointer::New(); reslicer->SetInputSlice( interpolationResult->GetSliceData()->GetVtkImageAccessor(interpolationResult)->GetVtkImageData()); reslicer->SetOverwriteMode(true); reslicer->Modified(); mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslicer); extractor->SetInput(m_SegmentationImage); extractor->SetTimeStep(0); extractor->SetWorldGeometry(plane); extractor->SetVtkOutputRequest(true); extractor->SetResliceTransformByGeometry(m_SegmentationImage->GetTimeGeometry()->GetGeometryForTimeStep(0)); extractor->Modified(); extractor->Update(); // mitk::IOUtil::Save(m_SegmentationImage, "SOME PATH"); // Check a 4x4 square, the center of which needs to be filled mitk::ImagePixelReadAccessor readAccess(m_SegmentationImage); currentPoint = m_CenterPoint; for (int i = -1; i <= 2; ++i) { for (int j = -1; j <= 2; ++j) { currentPoint[(dim + 1) % 3] = m_CenterPoint[(dim + 1) % 3] + i; currentPoint[(dim + 2) % 3] = m_CenterPoint[(dim + 2) % 3] + j; if (i == -1 || i == 2 || j == -1 || j == 2) { CPPUNIT_ASSERT_MESSAGE("Have false positive segmentation.", readAccess.GetPixelByIndexSafe(currentPoint) == 0); } else { CPPUNIT_ASSERT_MESSAGE("Have false negative segmentation.", readAccess.GetPixelByIndexSafe(currentPoint) == 1); } } } } mitk::Image::Pointer m_ReferenceImage; mitk::Image::Pointer m_SegmentationImage; itk::Index<3> m_CenterPoint; mitk::SegmentationInterpolationController::Pointer m_InterpolationController; public: void setUp() override { - m_ReferenceImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + m_ReferenceImage = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [Pic3D.nrrd]", m_ReferenceImage.IsNotNull()); m_InterpolationController = mitk::SegmentationInterpolationController::GetInstance(); // Create empty segmentation // Surely there must be a better way to get an image with all zeros? m_SegmentationImage = mitk::Image::New(); const mitk::PixelType pixelType(mitk::MakeScalarPixelType()); m_SegmentationImage->Initialize(pixelType, m_ReferenceImage->GetDimension(), m_ReferenceImage->GetDimensions()); m_SegmentationImage->SetClonedTimeGeometry(m_ReferenceImage->GetTimeGeometry()); unsigned int size = sizeof(mitk::Tool::DefaultSegmentationDataType); for (unsigned int dim = 0; dim < m_SegmentationImage->GetDimension(); ++dim) { size *= m_SegmentationImage->GetDimension(dim); } mitk::ImageWriteAccessor imageAccessor(m_SegmentationImage); memset(imageAccessor.GetData(), 0, size); // Work in the center of the image (Pic3D) m_CenterPoint = {{127, 127, 25}}; } void tearDown() override { m_ReferenceImage = nullptr; m_SegmentationImage = nullptr; m_CenterPoint = {{0, 0, 0}}; } void Equal_Axial_TestInterpolationAndReferenceInterpolation_ReturnsTrue() { mitk::SliceNavigationController::ViewDirection viewDirection = mitk::SliceNavigationController::Axial; testRoutine(viewDirection); } void Equal_Frontal_TestInterpolationAndReferenceInterpolation_ReturnsTrue() // Coronal { mitk::SliceNavigationController::ViewDirection viewDirection = mitk::SliceNavigationController::Frontal; testRoutine(viewDirection); } void Equal_Sagittal_TestInterpolationAndReferenceInterpolation_ReturnsTrue() { mitk::SliceNavigationController::ViewDirection viewDirection = mitk::SliceNavigationController::Sagittal; testRoutine(viewDirection); } }; MITK_TEST_SUITE_REGISTRATION(mitkSegmentationInterpolation) diff --git a/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp b/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp index d32eb322ef..9d67b01eb0 100644 --- a/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp +++ b/Modules/Segmentation/Testing/mitkToolInteractionTest.cpp @@ -1,241 +1,241 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include #include class mitkToolInteractionTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToolInteractionTestSuite); /// \todo Fix VTK memory leaks. Bug 18098. vtkDebugLeaks::SetExitError(0); /* ####### example ###### MITK_TEST(AddToolInteraction_4D_Test); #########################*/ /// \todo fix crash when wipe tool test is called after another test // MITK_TEST(WipeToolInteractionTest); // BUG 19274 - working if recorded again // MITK_TEST(AddToolInteractionTest); // MITK_TEST(SubtractToolInteractionTest); // MITK_TEST(PaintToolInteractionTest); // MITK_TEST(RegionGrowingToolInteractionTest); // MITK_TEST(CorrectionToolInteractionTest); // MITK_TEST(EraseToolInteractionTest); // MITK_TEST(FillToolInteractionTest); CPPUNIT_TEST_SUITE_END(); private: mitk::DataStorage::Pointer m_DataStorage; mitk::ToolManager::Pointer m_ToolManager; public: int GetToolIdByToolName(const std::string &toolName) { // find tool from toolname int numberOfTools = m_ToolManager->GetTools().size(); int toolId = 0; for (; toolId < numberOfTools; ++toolId) { mitk::Tool *currentTool = m_ToolManager->GetToolById(toolId); if (toolName.compare(currentTool->GetNameOfClass()) == 0) { return toolId; } } return -1; } void RunTestWithParameters(const std::string &patientImagePath, const std::string &referenceSegmentationImage, const std::string &toolName, const std::string &interactionPattern, unsigned int timestep = 0, const std::string &preSegmentationImagePath = std::string()) { // Create test helper to initialize all necessary objects for interaction mitk::InteractionTestHelper interactionTestHelper(GetTestDataFilePath(interactionPattern)); // Use data storage of test helper m_DataStorage = interactionTestHelper.GetDataStorage().GetPointer(); // create ToolManager m_ToolManager = mitk::ToolManager::New(m_DataStorage); m_ToolManager->InitializeTools(); m_ToolManager->RegisterClient(); // This is needed because there must be at least one registered. Otherwise tools // can't be activated. // Load patient image - mitk::Image::Pointer patientImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(patientImagePath))[0].GetPointer()); + mitk::Image::Pointer patientImage = mitk::IOUtil::Load(GetTestDataFilePath(patientImagePath)); CPPUNIT_ASSERT(patientImage.IsNotNull()); mitk::DataNode::Pointer patientImageNode = mitk::DataNode::New(); patientImageNode->SetData(patientImage); // Activate tool to work with int toolID = GetToolIdByToolName(toolName); mitk::Tool *tool = m_ToolManager->GetToolById(toolID); CPPUNIT_ASSERT(tool != nullptr); // Create empty segmentation working image mitk::DataNode::Pointer workingImageNode = mitk::DataNode::New(); const std::string organName = "test"; mitk::Color color; // actually it dosn't matter which color we are using color.SetRed(1); // but CreateEmptySegmentationNode expects a color parameter color.SetGreen(0); color.SetBlue(0); if (preSegmentationImagePath.empty()) { workingImageNode = tool->CreateEmptySegmentationNode(patientImage, organName, color); } else { - mitk::Image::Pointer preSegmentation = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(preSegmentationImagePath))[0].GetPointer()); + mitk::Image::Pointer preSegmentation = mitk::IOUtil::Load(GetTestDataFilePath(preSegmentationImagePath)); workingImageNode = tool->CreateSegmentationNode(preSegmentation, organName, color); } CPPUNIT_ASSERT(workingImageNode.IsNotNull()); CPPUNIT_ASSERT(workingImageNode->GetData() != nullptr); // add images to datastorage interactionTestHelper.AddNodeToStorage(patientImageNode); interactionTestHelper.AddNodeToStorage(workingImageNode); // set reference and working image m_ToolManager->SetWorkingData(workingImageNode); m_ToolManager->SetReferenceData(patientImageNode); // set time step interactionTestHelper.SetTimeStep(timestep); // load interaction events m_ToolManager->ActivateTool(toolID); CPPUNIT_ASSERT(m_ToolManager->GetActiveTool() != nullptr); // Start Interaction interactionTestHelper.PlaybackInteraction(); // load reference segmentation image mitk::Image::Pointer segmentationReferenceImage = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(referenceSegmentationImage))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath(referenceSegmentationImage)); mitk::Image::Pointer currentSegmentationImage = mitk::Image::New(); currentSegmentationImage = dynamic_cast(workingImageNode->GetData()); // compare reference with interaction result MITK_ASSERT_EQUAL(segmentationReferenceImage, currentSegmentationImage, "Reference equals interaction result."); } void setUp() {} void tearDown() { m_ToolManager->ActivateTool(-1); m_ToolManager = nullptr; } void AddToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_AddContourTool.nrrd", "AddContourTool", "InteractionTestData/Interactions/SegmentationInteractor_AddTool.xml"); } void SubtractToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_SubtractContourTool.nrrd", "SubtractContourTool", "InteractionTestData/Interactions/SegmentationInteractor_SubtractTool.xml"); } void PaintToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_DrawPaintbrushTool.nrrd", "DrawPaintbrushTool", "InteractionTestData/Interactions/SegmentationInteractor_PaintTool.xml"); } void WipeToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_ErasePaintbrushTool.nrrd", "ErasePaintbrushTool", "InteractionTestData/Interactions/SegmentationInteractor_WipeTool.xml"); } void RegionGrowingToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_RegionGrowingTool.nrrd", "RegionGrowingTool", "InteractionTestData/Interactions/SegmentationInteractor_RegionGrowingTool.xml"); } void CorrectionToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_CorrectorTool2D.nrrd", "CorrectorTool2D", "InteractionTestData/Interactions/SegmentationInteractor_CorrectionTool.xml"); } void EraseToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_EraseRegionTool.nrrd", "EraseRegionTool", "InteractionTestData/Interactions/SegmentationInteractor_EraseTool.xml", 0, "InteractionTestData/ReferenceData/SegmentationInteractor_AddContourTool.nrrd"); } void FillToolInteractionTest() { RunTestWithParameters("Pic3D.nrrd", "InteractionTestData/ReferenceData/SegmentationInteractor_FillRegionTool.nrrd", "FillRegionTool", "InteractionTestData/Interactions/SegmentationInteractor_FillTool.xml", 0, "InteractionTestData/InputData/SegmentationInteractor_FillTool_input.nrrd"); } /*############ example ################### void AddToolInteraction_4D_Test() { RunTestWithParameters("US4DCyl.nrrd", "Segmentation/ReferenceSegmentations/AddTool_4D.nrrd", "AddContourTool", "Segmentation/InteractionPatterns/AddTool_4D.xml", 1); } #########################################*/ }; MITK_TEST_SUITE_REGISTRATION(mitkToolInteraction) diff --git a/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp index 2b0abe8764..5b19b33362 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp @@ -1,1311 +1,1311 @@ /*=================================================================== 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 "QmitkLabelSetWidget.h" // mitk #include #include #include #include #include #include #include #include #include #include #include // Qmitk #include #include #include // Qt #include #include #include #include #include #include #include #include #include // itk #include // todo: // berry //#include QmitkLabelSetWidget::QmitkLabelSetWidget(QWidget *parent) : QWidget(parent), m_DataStorage(nullptr), m_Completer(nullptr), m_ToolManager(nullptr) { m_Controls.setupUi(this); m_ColorSequenceRainbow.GoToBegin(); m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); assert(m_ToolManager); m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(true); m_Controls.m_LabelSearchBox->setShowSearchIcon(true); QStringList completionList; completionList << ""; m_Completer = new QCompleter(completionList, this); m_Completer->setCaseSensitivity(Qt::CaseInsensitive); m_Controls.m_LabelSearchBox->setCompleter(m_Completer); connect(m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()), this, SLOT(OnSearchLabel())); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(labelListModified(const QStringList&)), this, SLOT( // OnLabelListModified(const QStringList&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(mergeLabel(int)), this, SLOT( OnMergeLabel(int)) ); QStringListModel *completeModel = static_cast(m_Completer->model()); completeModel->setStringList(GetLabelStringList()); m_Controls.m_LabelSearchBox->setEnabled(false); m_Controls.m_lblCaption->setText(""); InitializeTableWidget(); } QmitkLabelSetWidget::~QmitkLabelSetWidget() { } void QmitkLabelSetWidget::OnTableViewContextMenuRequested(const QPoint& /*pos*/) { int pixelValue = GetPixelValueOfSelectedItem(); QMenu *menu = new QMenu(m_Controls.m_LabelSetTableWidget); if (m_Controls.m_LabelSetTableWidget->selectedItems().size() > 1) { QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this); mergeAction->setEnabled(true); QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabels(bool))); menu->addAction(mergeAction); QAction *removeLabelsAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove selected labels", this); removeLabelsAction->setEnabled(true); QObject::connect(removeLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabels(bool))); menu->addAction(removeLabelsAction); QAction *eraseLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase selected labels", this); eraseLabelsAction->setEnabled(true); QObject::connect(eraseLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabels(bool))); menu->addAction(eraseLabelsAction); QAction *combineAndCreateSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Combine and create a surface", this); combineAndCreateSurfaceAction->setEnabled(true); QObject::connect( combineAndCreateSurfaceAction, SIGNAL(triggered(bool)), this, SLOT(OnCombineAndCreateSurface(bool))); // menu->addAction(combineAndCreateSurfaceAction); Not implemented QAction *createMasksAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create a mask for each selected label", this); createMasksAction->setEnabled(true); QObject::connect(createMasksAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMasks(bool))); // menu->addAction(createMasksAction); Not implemented QAction *combineAndCreateMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Combine and create a mask", this); combineAndCreateMaskAction->setEnabled(true); QObject::connect(combineAndCreateMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCombineAndCreateMask(bool))); // menu->addAction(combineAndCreateMaskAction); Not implemented } else { QAction *renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Rename...", this); renameAction->setEnabled(true); QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool))); menu->addAction(renameAction); QAction *removeAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove...", this); removeAction->setEnabled(true); QObject::connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabel(bool))); menu->addAction(removeAction); QAction *eraseAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase...", this); eraseAction->setEnabled(true); QObject::connect(eraseAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabel(bool))); menu->addAction(eraseAction); QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge...", this); mergeAction->setEnabled(true); QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabel(bool))); menu->addAction(mergeAction); QAction *randomColorAction = new QAction(QIcon(":/Qmitk/RandomColor.png"), "Random color", this); randomColorAction->setEnabled(true); QObject::connect(randomColorAction, SIGNAL(triggered(bool)), this, SLOT(OnRandomColor(bool))); menu->addAction(randomColorAction); QAction *viewOnlyAction = new QAction(QIcon(":/Qmitk/visible.png"), "View only", this); viewOnlyAction->setEnabled(true); QObject::connect(viewOnlyAction, SIGNAL(triggered(bool)), this, SLOT(OnSetOnlyActiveLabelVisible(bool))); menu->addAction(viewOnlyAction); QAction *viewAllAction = new QAction(QIcon(":/Qmitk/visible.png"), "View all", this); viewAllAction->setEnabled(true); QObject::connect(viewAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsVisible(bool))); menu->addAction(viewAllAction); QAction *hideAllAction = new QAction(QIcon(":/Qmitk/invisible.png"), "Hide all", this); hideAllAction->setEnabled(true); QObject::connect(hideAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsInvisible(bool))); menu->addAction(hideAllAction); QAction *lockAllAction = new QAction(QIcon(":/Qmitk/lock.png"), "Lock all", this); lockAllAction->setEnabled(true); QObject::connect(lockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnLockAllLabels(bool))); menu->addAction(lockAllAction); QAction *unlockAllAction = new QAction(QIcon(":/Qmitk/unlock.png"), "Unlock all", this); unlockAllAction->setEnabled(true); QObject::connect(unlockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnUnlockAllLabels(bool))); menu->addAction(unlockAllAction); QAction *createSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Create surface", this); createSurfaceAction->setEnabled(true); createSurfaceAction->setMenu(new QMenu()); QAction *tmp1 = createSurfaceAction->menu()->addAction(QString("Detailed")); QAction *tmp2 = createSurfaceAction->menu()->addAction(QString("Smoothed")); QObject::connect(tmp1, SIGNAL(triggered(bool)), this, SLOT(OnCreateDetailedSurface(bool))); QObject::connect(tmp2, SIGNAL(triggered(bool)), this, SLOT(OnCreateSmoothedSurface(bool))); menu->addAction(createSurfaceAction); QAction *createMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create mask", this); createMaskAction->setEnabled(true); QObject::connect(createMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMask(bool))); menu->addAction(createMaskAction); QAction *createCroppedMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create cropped mask", this); createCroppedMaskAction->setEnabled(true); QObject::connect(createCroppedMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateCroppedMask(bool))); // QAction* importAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Import...", this ); // importAction->setEnabled(true); // QObject::connect( importAction, SIGNAL( triggered(bool) ), this, SLOT( OnImportSegmentationSession(bool) ) ); // menu->addAction(importAction); menu->addAction(createCroppedMaskAction); QSlider *opacitySlider = new QSlider; opacitySlider->setMinimum(0); opacitySlider->setMaximum(100); opacitySlider->setOrientation(Qt::Horizontal); QObject::connect(opacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OnOpacityChanged(int))); QLabel *_OpacityLabel = new QLabel("Opacity: "); QVBoxLayout *_OpacityWidgetLayout = new QVBoxLayout; _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(opacitySlider); QWidget *_OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction *OpacityAction = new QWidgetAction(this); OpacityAction->setDefaultWidget(_OpacityWidget); // QObject::connect( m_OpacityAction, SIGNAL( changed() ), this, SLOT( OpacityActionChanged() ) ); opacitySlider->setValue(static_cast(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetOpacity() * 100)); menu->addAction(OpacityAction); } menu->popup(QCursor::pos()); } void QmitkLabelSetWidget::OnUnlockAllLabels(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(false); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnLockAllLabels(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnSetAllLabelsVisible(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(true); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetAllLabelsInvisible(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(false); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(bool /*value*/) { mitk::LabelSetImage* workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); workingImage->GetActiveLabelSet()->SetAllLabelsVisible(false); workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->SetVisible(true); workingImage->GetActiveLabelSet()->UpdateLookupTable(pixelValue); this->WaitCursorOn(); const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates(); this->WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnMergeLabel(bool /*value*/) { QmitkSearchLabelDialog dialog(this); dialog.setWindowTitle("Select a second label.."); dialog.SetLabelSuggestionList(GetLabelStringList()); int dialogReturnValue = dialog.exec(); if (dialogReturnValue == QDialog::Rejected) return; int sourcePixelValue = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); i++) { if (dialog.GetLabelSetWidgetTableCompleteWord() == QString(m_Controls.m_LabelSetTableWidget->item(i, 0)->text())) sourcePixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt(); } if (sourcePixelValue == -1) { MITK_INFO << "unknown label"; return; } int pixelValue = GetPixelValueOfSelectedItem(); GetWorkingImage()->MergeLabel(pixelValue, sourcePixelValue, GetWorkingImage()->GetActiveLayer()); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnEraseLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to erase the contents of label \""; question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question(this, "Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to remove label \""; question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question(this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->GetActiveLabelSet()->RemoveLabel(pixelValue); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); } ResetAllTableWidgetItems(); } void QmitkLabelSetWidget::OnRenameLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QmitkNewSegmentationDialog dialog(this); dialog.setWindowTitle("Rename Label"); dialog.SetSuggestionList(m_OrganColors); dialog.SetColor(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetColor()); dialog.SetSegmentationName(QString::fromStdString(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetName())); if (dialog.exec() == QDialog::Rejected) { return; } QString segmentationName = dialog.GetSegmentationName(); if (segmentationName.isEmpty()) { segmentationName = "Unnamed"; } GetWorkingImage()->GetActiveLabelSet()->RenameLabel(pixelValue, segmentationName.toStdString(), dialog.GetColor()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnCombineAndCreateMask(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ...to do... // } void QmitkLabelSetWidget::OnCreateMasks(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnCombineAndCreateSurface(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnEraseLabels(bool /*value*/) { QString question = "Do you really want to erase the selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) return; std::vector VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) for (int i = a.topRow(); i <= a.bottomRow(); i++) VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); this->WaitCursorOn(); GetWorkingImage()->EraseLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabels(bool /*value*/) { QString question = "Do you really want to remove selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) { return; } std::vector VectorOfLablePixelValues; foreach(QTableWidgetSelectionRange a, ranges) { for (int i = a.topRow(); i <= a.bottomRow(); ++i) { VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); } } this->WaitCursorOn(); GetWorkingImage()->RemoveLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); } ResetAllTableWidgetItems(); } void QmitkLabelSetWidget::OnMergeLabels(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to merge selected labels into \""; question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) { return; } std::vector vectorOfSourcePixelValues; foreach(QTableWidgetSelectionRange a, ranges) { for (int i = a.topRow(); i <= a.bottomRow(); ++i) { vectorOfSourcePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); } } this->WaitCursorOn(); GetWorkingImage()->MergeLabels(pixelValue, vectorOfSourcePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnLockedButtonClicked() { int row = -1; for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, LOCKED_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt(); GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetLocked(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetLocked()); } } void QmitkLabelSetWidget::OnVisibleButtonClicked() { int row = -1; for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, VISIBLE_COL)) { row = i; break; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { QTableWidgetItem *item = m_Controls.m_LabelSetTableWidget->item(row, 0); int pixelValue = item->data(Qt::UserRole).toInt(); GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetVisible(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetVisible()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } } void QmitkLabelSetWidget::OnColorButtonClicked() { int row = -1; for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, COLOR_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt(); const mitk::Color &color = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetColor(); QColor initial(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255); QColor qcolor = QColorDialog::getColor(initial, nullptr, QString("Change color")); if (!qcolor.isValid()) { return; } QPushButton *button = static_cast(m_Controls.m_LabelSetTableWidget->cellWidget(row, COLOR_COL)); if (!button) { return; } button->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(qcolor.red())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.green())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.blue())); styleSheet.append(")"); button->setStyleSheet(styleSheet); mitk::Color newColor; newColor.SetRed(qcolor.red() / 255.0); newColor.SetGreen(qcolor.green() / 255.0); newColor.SetBlue(qcolor.blue() / 255.0); GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(newColor); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } } void QmitkLabelSetWidget::OnRandomColor(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(m_ColorSequenceRainbow.GetNextColor()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::SetOrganColors(const QStringList &organColors) { m_OrganColors = organColors; } void QmitkLabelSetWidget::OnActiveLabelChanged(int pixelValue) { mitk::LabelSetImage *workingImage = GetWorkingImage(); assert(workingImage); workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue); // MITK_INFO << "Active Label set to << " << pixelValue; mitk::SurfaceBasedInterpolationController *interpolator = mitk::SurfaceBasedInterpolationController::GetInstance(); if (interpolator) { interpolator->SetActiveLabel(pixelValue); } workingImage->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (!ranges.empty() && ranges.back().rowCount() == 1) { SelectLabelByPixelValue(pixelValue); OnActiveLabelChanged(pixelValue); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); // OnItemClicked(item); <<-- Double click first call OnItemClicked WaitCursorOn(); mitk::LabelSetImage* workingImage = GetWorkingImage(); workingImage->UpdateCenterOfMass(pixelValue, workingImage->GetActiveLayer()); const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates(); WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } workingImage->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::SelectLabelByPixelValue(mitk::Label::PixelType pixelValue) { // MITK_INFO << "QmitkLabelSetWidget::SelectLabelByPixelValue " << pixelValue; if (!GetWorkingImage()->ExistLabel(pixelValue)) return; for (int row = 0; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++) { if (m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt() == pixelValue) { m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row, 0)); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); // SelectTableWidgetItem(m_Controls.m_LabelSetTableWidget->item(i,0)); // emit resetView(); // GetWorkingImage()->Modified(); return; } } } void QmitkLabelSetWidget::InsertTableWidgetItem(mitk::Label *label) { const mitk::Color &color = label->GetColor(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[1] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[2] * 255)); styleSheet.append(")"); QTableWidget* tableWidget = m_Controls.m_LabelSetTableWidget; int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); QTableWidgetItem *nameItem = new QTableWidgetItem(text); nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft); // ---!--- // IMPORTANT: ADD PIXELVALUE TO TABLEWIDGETITEM.DATA nameItem->setData(Qt::UserRole, QVariant(label->GetValue())); // ---!--- QPushButton *pbColor = new QPushButton(tableWidget); pbColor->setFixedSize(24, 24); pbColor->setCheckable(false); pbColor->setAutoFillBackground(true); pbColor->setToolTip("Change label color"); pbColor->setStyleSheet(styleSheet); connect(pbColor, SIGNAL(clicked()), this, SLOT(OnColorButtonClicked())); QPushButton *pbLocked = new QPushButton(tableWidget); pbLocked->setFixedSize(24, 24); QIcon *iconLocked = new QIcon(); iconLocked->addFile(QString::fromUtf8(":/Qmitk/lock.png"), QSize(), QIcon::Normal, QIcon::Off); iconLocked->addFile(QString::fromUtf8(":/Qmitk/unlock.png"), QSize(), QIcon::Normal, QIcon::On); pbLocked->setIcon(*iconLocked); pbLocked->setIconSize(QSize(24, 24)); pbLocked->setCheckable(true); pbLocked->setToolTip("Lock/unlock label"); pbLocked->setChecked(!label->GetLocked()); connect(pbLocked, SIGNAL(clicked()), this, SLOT(OnLockedButtonClicked())); QPushButton *pbVisible = new QPushButton(tableWidget); pbVisible->setFixedSize(24, 24); pbVisible->setAutoRepeat(false); QIcon *iconVisible = new QIcon(); iconVisible->addFile(QString::fromUtf8(":/Qmitk/visible.png"), QSize(), QIcon::Normal, QIcon::Off); iconVisible->addFile(QString::fromUtf8(":/Qmitk/invisible.png"), QSize(), QIcon::Normal, QIcon::On); pbVisible->setIcon(*iconVisible); pbVisible->setIconSize(QSize(24, 24)); pbVisible->setCheckable(true); pbVisible->setToolTip("Show/hide label"); pbVisible->setChecked(!label->GetVisible()); connect(pbVisible, SIGNAL(clicked()), this, SLOT(OnVisibleButtonClicked())); int row = tableWidget->rowCount(); tableWidget->insertRow(row); tableWidget->setRowHeight(row, 24); tableWidget->setItem(row, 0, nameItem); tableWidget->setCellWidget(row, 1, pbLocked); tableWidget->setCellWidget(row, 2, pbColor); tableWidget->setCellWidget(row, 3, pbVisible); tableWidget->selectRow(row); // m_LabelSetImage->SetActiveLabel(label->GetPixelValue()); // m_ToolManager->WorkingDataModified.Send(); // emit activeLabelChanged(label->GetPixelValue()); if (row == 0) { tableWidget->hideRow(row); // hide exterior label } } void QmitkLabelSetWidget::UpdateAllTableWidgetItems() { mitk::LabelSetImage *workingImage = GetWorkingImage(); if (!workingImage) return; // add all labels QTableWidget* tableWidget = m_Controls.m_LabelSetTableWidget; m_LabelStringList.clear(); for(int i = 0 ; i < tableWidget->rowCount(); ++i) { UpdateTableWidgetItem(tableWidget->item(i, 0)); m_LabelStringList.append(tableWidget->item(i, 0)->text()); } OnLabelListModified(m_LabelStringList); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item) { mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Label *label = workingImage->GetLabel(item->data(Qt::UserRole).toInt(), workingImage->GetActiveLayer()); const mitk::Color &color = label->GetColor(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[1] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[2] * 255)); styleSheet.append(")"); QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); item->setText(text); QPushButton *pbLocked = dynamic_cast(tableWidget->cellWidget(item->row(), 1)); pbLocked->setChecked(!label->GetLocked()); QPushButton *pbColor = dynamic_cast(tableWidget->cellWidget(item->row(), 2)); pbColor->setStyleSheet(styleSheet); QPushButton *pbVisible = dynamic_cast(tableWidget->cellWidget(item->row(), 3)); pbVisible->setChecked(!label->GetVisible()); if (item->row() == 0) { tableWidget->hideRow(item->row()); // hide exterior label } } void QmitkLabelSetWidget::ResetAllTableWidgetItems() { QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; // remove all rows while (tableWidget->rowCount()) { tableWidget->removeRow(0); } mitk::LabelSetImage *workingImage = GetWorkingImage(); if (!workingImage) return; // add all labels m_LabelStringList.clear(); mitk::LabelSet::LabelContainerConstIteratorType it = workingImage->GetActiveLabelSet()->IteratorConstBegin(); mitk::LabelSet::LabelContainerConstIteratorType end = workingImage->GetActiveLabelSet()->IteratorConstEnd(); int pixelValue = -1; while (it != end) { InsertTableWidgetItem(it->second); if (workingImage->GetActiveLabel() == it->second) // get active pixelValue = it->first; m_LabelStringList.append(QString(it->second->GetName().c_str())); it++; } SelectLabelByPixelValue(pixelValue); OnLabelListModified(m_LabelStringList); std::stringstream captionText; captionText << "Number of labels: " << workingImage->GetNumberOfLabels(workingImage->GetActiveLayer()) - 1; m_Controls.m_lblCaption->setText(captionText.str().c_str()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } int QmitkLabelSetWidget::GetPixelValueOfSelectedItem() { if (m_Controls.m_LabelSetTableWidget->currentItem()) { return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt(); } return -1; } QStringList &QmitkLabelSetWidget::GetLabelStringList() { return m_LabelStringList; } void QmitkLabelSetWidget::InitializeTableWidget() { QTableWidget *tableWidged = m_Controls.m_LabelSetTableWidget; tableWidged->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); tableWidged->setTabKeyNavigation(false); tableWidged->setAlternatingRowColors(false); tableWidged->setFocusPolicy(Qt::NoFocus); tableWidged->setColumnCount(4); tableWidged->resizeColumnToContents(NAME_COL); tableWidged->setColumnWidth(LOCKED_COL, 25); tableWidged->setColumnWidth(COLOR_COL, 25); tableWidged->setColumnWidth(VISIBLE_COL, 25); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) tableWidged->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); #else tableWidged->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); #endif tableWidged->setContextMenuPolicy(Qt::CustomContextMenu); tableWidged->horizontalHeader()->hide(); tableWidged->setSortingEnabled(false); tableWidged->verticalHeader()->hide(); tableWidged->setEditTriggers(QAbstractItemView::NoEditTriggers); tableWidged->setSelectionMode(QAbstractItemView::ExtendedSelection); tableWidged->setSelectionBehavior(QAbstractItemView::SelectRows); connect(tableWidged, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(OnItemClicked(QTableWidgetItem *))); connect( tableWidged, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(OnItemDoubleClicked(QTableWidgetItem *))); connect(tableWidged, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(OnTableViewContextMenuRequested(const QPoint &))); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(activeLabelChanged(int)), this, SLOT(OnActiveLabelChanged(int)) // ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importSegmentation()), this, SLOT( OnImportSegmentation()) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importLabeledImage()), this, SLOT( OnImportLabeledImage()) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(renameLabel(int, const mitk::Color&, const std::string&)), this, // SLOT(OnRenameLabel(int, const mitk::Color&, const std::string&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createSurface(int, bool)), this, SLOT(OnCreateSurface(int, bool)) // ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(toggleOutline(bool)), this, SLOT(OnToggleOutline(bool)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(goToLabel(const mitk::Point3D&)), this, SIGNAL(goToLabel(const // mitk::Point3D&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateSurface( const QList& // )), // this, SLOT(OnCombineAndCreateSurface( const QList&)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createMask(int)), this, SLOT(OnCreateMask(int)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createCroppedMask(int)), this, SLOT(OnCreateCroppedMask(int)) ); // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateMask( const QList& // )), // this, SLOT(OnCombineAndCreateMask( const QList&)) ); } void QmitkLabelSetWidget::OnOpacityChanged(int value) { int pixelValue = GetPixelValueOfSelectedItem(); float opacity = static_cast(value) / 100.0f; GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetOpacity(opacity); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } void QmitkLabelSetWidget::setEnabled(bool enabled) { QWidget::setEnabled(enabled); UpdateControls(); } void QmitkLabelSetWidget::SetDataStorage(mitk::DataStorage *storage) { m_DataStorage = storage; } void QmitkLabelSetWidget::OnSearchLabel() { std::string text = m_Controls.m_LabelSearchBox->text().toStdString(); int pixelValue = -1; int row = -1; for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if( m_Controls.m_LabelSetTableWidget->item(i, 0)->text().toStdString().compare(text) == 0) { pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt(); row = i; break; } } if (pixelValue == -1) { return; } GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); QTableWidgetItem *nameItem = m_Controls.m_LabelSetTableWidget->item(row, NAME_COL); if (!nameItem) { return; } m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); this->WaitCursorOn(); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates(); m_ToolManager->WorkingDataChanged(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } else { GetWorkingImage()->UpdateCenterOfMass(pixelValue, GetWorkingImage()->GetActiveLayer()); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates(); emit goToLabel(pos); } this->WaitCursorOff(); } void QmitkLabelSetWidget::OnLabelListModified(const QStringList &list) { QStringListModel *completeModel = static_cast(m_Completer->model()); completeModel->setStringList(list); } mitk::LabelSetImage *QmitkLabelSetWidget::GetWorkingImage() { mitk::DataNode *workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData()); assert(workingImage); return workingImage; } mitk::DataNode *QmitkLabelSetWidget::GetWorkingNode() { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); return workingNode; } void QmitkLabelSetWidget::UpdateControls() { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); bool hasWorkingData = (workingNode != nullptr); m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData); m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData); if (!hasWorkingData) return; QStringListModel *completeModel = static_cast(m_Completer->model()); completeModel->setStringList(GetLabelStringList()); } void QmitkLabelSetWidget::OnCreateCroppedMask(bool) { m_ToolManager->ActivateTool(-1); mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New(); cropFilter->SetInput(workingImage->CreateLabelMask(pixelValue)); cropFilter->SetBackgroundValue(0); cropFilter->SetMarginFactor(1.15); cropFilter->Update(); maskImage = cropFilter->GetOutput(); this->WaitCursorOff(); } catch (mitk::Exception &e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, GetWorkingNode()); } void QmitkLabelSetWidget::OnCreateMask(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); maskImage = workingImage->CreateLabelMask(pixelValue); this->WaitCursorOff(); } catch (mitk::Exception &e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, GetWorkingNode()); } void QmitkLabelSetWidget::OnToggleOutline(bool value) { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); workingNode->SetBoolProperty("labelset.contour.active", value); workingNode->GetData()->Modified(); // fixme: workaround to force data-type rendering (and not only property-type) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnCreateSmoothedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", true); surfaceFilter->SetDataStorage(*m_DataStorage); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch (mitk::Exception &e) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnCreateDetailedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", false); surfaceFilter->SetDataStorage(*m_DataStorage); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch (mitk::Exception &e) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnImportLabeledImage() { /* m_ToolManager->ActivateTool(-1); mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); assert(referenceNode); // Ask the user for a list of files to open QStringList fileNames = QFileDialog::getOpenFileNames( this, "Open Image", m_LastFileOpenPath, mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); if (fileNames.empty()) return; try { this->WaitCursorOn(); - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load( fileNames.front().toStdString() )[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load( fileNames.front().toStdString() ); if (image.IsNull()) { this->WaitCursorOff(); QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation.\n"); return; } mitk::LabelSetImage::Pointer newImage = mitk::LabelSetImage::New(); newImage->InitializeByLabeledImage(image); this->WaitCursorOff(); mitk::DataNode::Pointer newNode = mitk::DataNode::New(); std::string newName = referenceNode->GetName(); newName += "-labels"; newNode->SetName(newName); newNode->SetData(newImage); m_DataStorage->Add(newNode, referenceNode); } catch (mitk::Exception & e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation. See error log for details.\n"); return; } this->UpdateControls(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); */ } void QmitkLabelSetWidget::OnImportSegmentation() { /* m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); mitk::LabelSetImage* workingImage = dynamic_cast( workingNode->GetData() ); assert(workingImage); std::string fileExtensions("Segmentation files (*.lset);;"); QString qfileName = QFileDialog::getOpenFileName(this, "Import Segmentation", m_LastFileOpenPath, fileExtensions.c_str() ); if (qfileName.isEmpty() ) return; mitk::NrrdLabelSetImageReader::Pointer reader = mitk::NrrdLabelSetImageReader::New(); reader->SetFileName(qfileName.toLatin1()); try { this->WaitCursorOn(); reader->Update(); mitk::LabelSetImage::Pointer newImage = reader->GetOutput(); workingImage->Concatenate(newImage); this->WaitCursorOff(); } catch ( mitk::Exception& e ) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Import Segmentation", "Could not import the selected segmentation session.\n See error log for details.\n"); } */ mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::WaitCursorOn() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } void QmitkLabelSetWidget::WaitCursorOff() { this->RestoreOverrideCursor(); } void QmitkLabelSetWidget::RestoreOverrideCursor() { QApplication::restoreOverrideCursor(); } void QmitkLabelSetWidget::OnThreadedCalculationDone() { mitk::StatusBar::GetInstance()->Clear(); } diff --git a/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp index b3f4f82a23..4d851cff1d 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkComputeContourSetNormalsFilterTest.cpp @@ -1,103 +1,103 @@ /*=================================================================== 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 #include #include #include #include #include class mitkComputeContourSetNormalsFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkComputeContourSetNormalsFilterTestSuite); /// \todo Fix leaks of vtkObjects. Bug 18096. vtkDebugLeaks::SetExitError(0); MITK_TEST(TestComputeNormals); MITK_TEST(TestComputeNormalsWithHole); CPPUNIT_TEST_SUITE_END(); private: mitk::ComputeContourSetNormalsFilter::Pointer m_ContourNormalsFilter; public: void setUp() override { m_ContourNormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ReduceContourSetFilter", m_ContourNormalsFilter.IsNotNull()); } // Compute the normals for a regular contour void TestComputeNormals() { mitk::Surface::Pointer contour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); m_ContourNormalsFilter->SetInput(contour); m_ContourNormalsFilter->Update(); // Get the computed normals (basically lines) mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface(); // Get the actual surface object which has the contours stored as normals internally mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput(); mitk::Surface::Pointer referenceContour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithNormals.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithNormals.vtk")); mitk::Surface::Pointer referenceNormals = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourNormals.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourNormals.vtk")); CPPUNIT_ASSERT_MESSAGE( "Unequal contours", mitk::Equal(*(contourWithNormals->GetVtkPolyData()), *(referenceContour->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE( "Unequal contours", mitk::Equal(*(normals->GetVtkPolyData()), *(referenceNormals->GetVtkPolyData()), 0.000001, true)); } // Reduce contours with Douglas Peucker void TestComputeNormalsWithHole() { mitk::Image::Pointer segmentationImage = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd")); mitk::Surface::Pointer contour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ComputeNormals/ContourWithHoles.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/ComputeNormals/ContourWithHoles.vtk")); m_ContourNormalsFilter->SetInput(contour); m_ContourNormalsFilter->SetSegmentationBinaryImage(segmentationImage); m_ContourNormalsFilter->Update(); mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput(); mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface(); mitk::Surface::Pointer contourReference = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithHolesWithNormals.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithHolesWithNormals.vtk")); mitk::Surface::Pointer normalsReference = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/NormalsWithHoles.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/NormalsWithHoles.vtk")); CPPUNIT_ASSERT_MESSAGE( "Error computing normals", mitk::Equal(*(normals->GetVtkPolyData()), *(normalsReference->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Error computing normals", contourWithNormals->GetVtkPolyData()->GetCellData()->GetNormals()->GetNumberOfTuples() == contourReference->GetVtkPolyData()->GetNumberOfPoints()); } }; MITK_TEST_SUITE_REGISTRATION(mitkComputeContourSetNormalsFilter) diff --git a/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp index b505db843a..8ebdca88f2 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkCreateDistanceImageFromSurfaceFilterTest.cpp @@ -1,136 +1,136 @@ /*=================================================================== 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 #include #include #include class mitkCreateDistanceImageFromSurfaceFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkCreateDistanceImageFromSurfaceFilterTestSuite); vtkDebugLeaks::SetExitError(0); MITK_TEST(TestCreateDistanceImageForLiver); MITK_TEST(TestCreateDistanceImageForTube); CPPUNIT_TEST_SUITE_END(); private: std::vector contourList; public: void setUp() override {} template void GetImageBase(itk::Image *input, itk::ImageBase<3>::Pointer &result) { result->Graft(input); } // Interpolate the shape of a liver void TestCreateDistanceImageForLiver() { // That's the number of available liver contours in MITK-Data unsigned int NUMBER_OF_LIVER_CONTOURS = 18; for (unsigned int i = 0; i <= NUMBER_OF_LIVER_CONTOURS; ++i) { std::stringstream s; s << "SurfaceInterpolation/InterpolateLiver/LiverContourWithNormals_"; s << i; s << ".vtk"; - mitk::Surface::Pointer contour = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(s.str()))[0].GetPointer()); + mitk::Surface::Pointer contour = mitk::IOUtil::Load(GetTestDataFilePath(s.str())); contourList.push_back(contour); } mitk::Image::Pointer segmentationImage = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverSegmentation.nrrd")); mitk::ComputeContourSetNormalsFilter::Pointer m_NormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); mitk::CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter = mitk::CreateDistanceImageFromSurfaceFilter::New(); itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New(); AccessFixedDimensionByItk_1(segmentationImage, GetImageBase, 3, itkImage); m_InterpolateSurfaceFilter->SetReferenceImage(itkImage.GetPointer()); for (unsigned int j = 0; j < contourList.size(); j++) { m_NormalsFilter->SetInput(j, contourList.at(j)); m_InterpolateSurfaceFilter->SetInput(j, m_NormalsFilter->GetOutput(j)); } m_InterpolateSurfaceFilter->Update(); mitk::Image::Pointer liverDistanceImage = m_InterpolateSurfaceFilter->GetOutput(); CPPUNIT_ASSERT(liverDistanceImage.IsNotNull()); mitk::Image::Pointer liverDistanceImageReference = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverDistanceImage.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/LiverDistanceImage.nrrd")); CPPUNIT_ASSERT_MESSAGE("LiverDistanceImages are not equal!", mitk::Equal(*(liverDistanceImageReference), *(liverDistanceImage), 0.0001, true)); } void TestCreateDistanceImageForTube() { // That's the number of available contours with holes in MITK-Data unsigned int NUMBER_OF_TUBE_CONTOURS = 5; for (unsigned int i = 0; i < NUMBER_OF_TUBE_CONTOURS; ++i) { std::stringstream s; s << "SurfaceInterpolation/InterpolateWithHoles/ContourWithHoles_"; s << i; s << ".vtk"; - mitk::Surface::Pointer contour = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath(s.str()))[0].GetPointer()); + mitk::Surface::Pointer contour = mitk::IOUtil::Load(GetTestDataFilePath(s.str())); contourList.push_back(contour); } mitk::Image::Pointer segmentationImage = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SegmentationWithHoles.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SegmentationWithHoles.nrrd")); mitk::ComputeContourSetNormalsFilter::Pointer m_NormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); mitk::CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter = mitk::CreateDistanceImageFromSurfaceFilter::New(); m_NormalsFilter->SetSegmentationBinaryImage(segmentationImage); itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New(); AccessFixedDimensionByItk_1(segmentationImage, GetImageBase, 3, itkImage); m_InterpolateSurfaceFilter->SetReferenceImage(itkImage.GetPointer()); for (unsigned int j = 0; j < contourList.size(); j++) { m_NormalsFilter->SetInput(j, contourList.at(j)); m_InterpolateSurfaceFilter->SetInput(j, m_NormalsFilter->GetOutput(j)); } m_InterpolateSurfaceFilter->Update(); mitk::Image::Pointer holeDistanceImage = m_InterpolateSurfaceFilter->GetOutput(); CPPUNIT_ASSERT(holeDistanceImage.IsNotNull()); mitk::Image::Pointer holesDistanceImageReference = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/HolesDistanceImage.nrrd"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/HolesDistanceImage.nrrd")); CPPUNIT_ASSERT_MESSAGE("HolesDistanceImages are not equal!", mitk::Equal(*(holesDistanceImageReference), *(holeDistanceImage), 0.0001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkCreateDistanceImageFromSurfaceFilter) diff --git a/Modules/SurfaceInterpolation/Testing/mitkImageToPointCloudFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkImageToPointCloudFilterTest.cpp index 0124bc6e72..4b3c3ced4e 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkImageToPointCloudFilterTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkImageToPointCloudFilterTest.cpp @@ -1,82 +1,82 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include class mitkImageToPointCloudFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageToPointCloudFilterTestSuite); MITK_TEST(testImageToPointCloudFilterInitialization); MITK_TEST(testInput); MITK_TEST(testUnstructuredGridGeneration); MITK_TEST(testThreshold); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ mitk::Image::Pointer m_BallImage; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ - void setUp() override { m_BallImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30.nrrd"))[0].GetPointer()); } + void setUp() override { m_BallImage = mitk::IOUtil::Load(GetTestDataFilePath("BallBinary30x30x30.nrrd")); } void testImageToPointCloudFilterInitialization() { mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); CPPUNIT_ASSERT_MESSAGE("Testing instantiation of test object", testFilter.IsNotNull()); } void testInput() { mitk::ImageToPointCloudFilter::Pointer testFilter = mitk::ImageToPointCloudFilter::New(); testFilter->SetInput(m_BallImage); CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", testFilter->GetInput() == m_BallImage); } void testUnstructuredGridGeneration() { mitk::ImageToPointCloudFilter::Pointer testFilter = mitk::ImageToPointCloudFilter::New(); testFilter->SetInput(m_BallImage); testFilter->Update(); CPPUNIT_ASSERT_MESSAGE("Testing UnstructuredGrid generation!", testFilter->GetOutput() != nullptr); } void testThreshold() { mitk::ImageToPointCloudFilter::Pointer testFilter1 = mitk::ImageToPointCloudFilter::New(); testFilter1->SetInput(m_BallImage); testFilter1->Update(); int numberOfPoints1 = testFilter1->GetNumberOfExtractedPoints(); mitk::ImageToPointCloudFilter::Pointer testFilter2 = mitk::ImageToPointCloudFilter::New(); testFilter2->SetInput(m_BallImage); testFilter2->SetMethod(mitk::ImageToPointCloudFilter::LAPLACIAN_STD_DEV3); testFilter2->Update(); int numberOfPoints2 = testFilter2->GetNumberOfExtractedPoints(); CPPUNIT_ASSERT_MESSAGE("Testing Threshold", numberOfPoints1 > numberOfPoints2); } }; MITK_TEST_SUITE_REGISTRATION(mitkImageToPointCloudFilter) diff --git a/Modules/SurfaceInterpolation/Testing/mitkReduceContourSetFilterTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkReduceContourSetFilterTest.cpp index c1fb546cf5..a0f650ff20 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkReduceContourSetFilterTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkReduceContourSetFilterTest.cpp @@ -1,79 +1,79 @@ /*=================================================================== 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 #include #include class mitkReduceContourSetFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkReduceContourSetFilterTestSuite); MITK_TEST(TestReduceContourWithNthPoint); MITK_TEST(TestReduceContourWithDouglasPeuker); CPPUNIT_TEST_SUITE_END(); private: mitk::ReduceContourSetFilter::Pointer m_ContourReducer; public: void setUp() override { m_ContourReducer = mitk::ReduceContourSetFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ReduceContourSetFilter", m_ContourReducer.IsNotNull()); } // Reduce contours with nth point void TestReduceContourWithNthPoint() { mitk::Surface::Pointer contour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); m_ContourReducer->SetInput(contour); m_ContourReducer->SetReductionType(mitk::ReduceContourSetFilter::NTH_POINT); m_ContourReducer->SetStepSize(20); m_ContourReducer->Update(); mitk::Surface::Pointer reducedContour = m_ContourReducer->GetOutput(); mitk::Surface::Pointer reference = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ReducedContourNthPoint_20.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ReducedContourNthPoint_20.vtk")); CPPUNIT_ASSERT_MESSAGE( "Unequal contours", mitk::Equal(*(reducedContour->GetVtkPolyData()), *(reference->GetVtkPolyData()), 0.000001, true)); } // Reduce contours with Douglas Peucker void TestReduceContourWithDouglasPeuker() { mitk::Surface::Pointer contour = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/TwoContours.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/TwoContours.vtk")); m_ContourReducer->SetInput(contour); m_ContourReducer->SetReductionType(mitk::ReduceContourSetFilter::DOUGLAS_PEUCKER); m_ContourReducer->Update(); mitk::Surface::Pointer reducedContour = m_ContourReducer->GetOutput(); mitk::Surface::Pointer reference = - dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ReducedContourDouglasPeucker.vtk"))[0].GetPointer()); + mitk::IOUtil::Load(GetTestDataFilePath("SurfaceInterpolation/Reference/ReducedContourDouglasPeucker.vtk")); CPPUNIT_ASSERT_MESSAGE( "Unequal contours", mitk::Equal(*(reducedContour->GetVtkPolyData()), *(reference->GetVtkPolyData()), 0.000001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkReduceContourSetFilter) diff --git a/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerDeviceTest.cpp b/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerDeviceTest.cpp index 63d7065a2e..808b75258e 100644 --- a/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerDeviceTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFCameraMITKPlayerDeviceTest.cpp @@ -1,145 +1,145 @@ /*=================================================================== 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 "mitkToFCameraMITKPlayerDevice.h" #include "mitkIToFDeviceFactory.h" //MicroServices #include #include #include class mitkToFCameraMITKPlayerDeviceTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFCameraMITKPlayerDeviceTestSuite); MITK_TEST(DeviceNotConnected_NotActive); MITK_TEST(ConnectCamera_ValidData_ReturnsTrue); MITK_TEST(GetDistances_ValidData_ImagesEqual); MITK_TEST(StartCamera_ValidData_DeviceIsConnected); MITK_TEST(DisconnectCamera_ValidData_ReturnsTrue); CPPUNIT_TEST_SUITE_END(); private: mitk::ToFCameraMITKPlayerDevice* m_PlayerDevice; std::string m_PathToDepthData; float* m_DistanceArray; public: void setUp() override { us::ModuleContext* context = us::GetModuleContext(); //Filter all registered devices for an ToFCameraMITKPlayerDevice via device name std::string filter = "(ToFDeviceName=MITK Player)"; us::ServiceReference serviceRefDevice = context->GetServiceReferences(filter).front(); //Get the actual device m_PlayerDevice = dynamic_cast( context->GetService(serviceRefDevice) ); //during the tests here, we use one special test data set located in MITK-Data m_PathToDepthData = GetTestDataFilePath("ToF-Data/Kinect_Lego_Phantom_DistanceImage.nrrd"); m_PlayerDevice->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_PathToDepthData)); //initialize an array with the test data size unsigned int numberOfPixels = 640*480; m_DistanceArray = new float[numberOfPixels]; } void tearDown() override { //Wait some time to avoid threading issues. itksys::SystemTools::Delay(10); //Clean up if(m_PlayerDevice->IsCameraActive()) m_PlayerDevice->StopCamera(); if(m_PlayerDevice->IsCameraConnected()) m_PlayerDevice->DisconnectCamera(); delete[] m_DistanceArray; } void DeviceNotConnected_NotActive() { CPPUNIT_ASSERT_MESSAGE("The device (player) should not be active before starting.", m_PlayerDevice->IsCameraActive()==false); } void ConnectCamera_ValidData_ReturnsTrue() { CPPUNIT_ASSERT_MESSAGE("ConnectCamera() should return true in case of success.", m_PlayerDevice->ConnectCamera()==true); } void StartCamera_ValidData_DeviceIsConnected() { m_PlayerDevice->ConnectCamera(); m_PlayerDevice->StartCamera(); CPPUNIT_ASSERT_MESSAGE("After starting the device, the device should be active.", m_PlayerDevice->IsCameraActive()==true); } void GetDistances_ValidData_ImagesEqual() { try { m_PlayerDevice->ConnectCamera(); m_PlayerDevice->StartCamera(); unsigned int dimension[2]; dimension[0] = m_PlayerDevice->GetCaptureWidth(); dimension[1] = m_PlayerDevice->GetCaptureHeight(); int imageSequence = 0; //fill the array with the device output m_PlayerDevice->GetDistances(m_DistanceArray,imageSequence); //initialize an image and fill it with the array mitk::Image::Pointer resultDepthImage = mitk::Image::New(); resultDepthImage->Initialize(mitk::PixelType(mitk::MakeScalarPixelType()), 2, dimension,1); resultDepthImage->SetSlice(m_DistanceArray); - mitk::Image::Pointer expectedDepthImage = dynamic_cast(mitk::IOUtil::Load(m_PathToDepthData)[0].GetPointer()); + mitk::Image::Pointer expectedDepthImage = mitk::IOUtil::Load(m_PathToDepthData); MITK_ASSERT_EQUAL( expectedDepthImage, resultDepthImage, "Image from the player should be the same as loaded from the harddisk, because we just load one slice."); } catch(std::exception &e) { MITK_ERROR << "Unknown exception occured: " << e.what(); } } void DisconnectCamera_ValidData_ReturnsTrue() { try { int imageSequence = 0; m_PlayerDevice->ConnectCamera(); m_PlayerDevice->StartCamera(); m_PlayerDevice->GetDistances(m_DistanceArray,imageSequence); m_PlayerDevice->StopCamera(); CPPUNIT_ASSERT_MESSAGE("After stopping the device, the device should be inactive.", m_PlayerDevice->IsCameraActive()==false); CPPUNIT_ASSERT_MESSAGE("DisconnectCamera() should return true in case of success.", m_PlayerDevice->DisconnectCamera()==true); } catch(std::exception &e) { MITK_ERROR << "Unknown exception occured: " << e.what(); } } }; MITK_TEST_SUITE_REGISTRATION(mitkToFCameraMITKPlayerDevice) diff --git a/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp index e598da9b5d..9b190af3a0 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageGrabberTest.cpp @@ -1,190 +1,190 @@ /*=================================================================== 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 #include #include #include #include /** * @brief The mitkToFImageGrabberTestSuite class is a test-suite for mitkToFImageGrabber. * * Test data is retrieved from MITK-Data. */ class mitkToFImageGrabberTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFImageGrabberTestSuite); MITK_TEST(GetterAndSetterTests); MITK_TEST(ConnectCamera_InvalidFileName_ThrowsException); MITK_TEST(ConnectCamera_ValidFileName_ReturnsTrue); MITK_TEST(IsCameraActive_DifferentStates_ReturnsCorrectResult); MITK_TEST(Update_2DData_ImagesAreEqual); MITK_TEST(Update_CamCubeData_PropertiesAreTrue); CPPUNIT_TEST_SUITE_END(); private: std::string m_KinectDepthImagePath; std::string m_KinectColorImagePath; std::string m_CamCubeDepthImagePath; std::string m_CamCubeIntensityImagePath; std::string m_CamCubeAmplitudeImagePath; mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; public: void setUp() override { std::string dirName = MITK_TOF_DATA_DIR; std::string depthImagePath = dirName + "/" + "Kinect_Lego_Phantom_DistanceImage.nrrd"; std::string colorImagePath = dirName + "/" + "Kinect_Lego_Phantom_RGBImage.nrrd"; std::string distanceImageP = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_DistanceImage.pic"; std::string amplitudeImage = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_AmplitudeImage.pic"; std::string intensityImage = dirName + "/" + "PMDCamCube2_MF0_IT0_1Images_IntensityImage.pic"; m_KinectDepthImagePath = GetTestDataFilePath(depthImagePath); m_KinectColorImagePath = GetTestDataFilePath(colorImagePath); m_CamCubeDepthImagePath = GetTestDataFilePath(distanceImageP); m_CamCubeIntensityImagePath = GetTestDataFilePath(amplitudeImage); m_CamCubeAmplitudeImagePath = GetTestDataFilePath(intensityImage); m_ToFImageGrabber = mitk::ToFImageGrabber::New(); //The Grabber always needs a device mitk::ToFCameraMITKPlayerDevice::Pointer tofCameraMITKPlayerDevice = mitk::ToFCameraMITKPlayerDevice::New(); m_ToFImageGrabber->SetCameraDevice(tofCameraMITKPlayerDevice); } void tearDown() override { if(m_ToFImageGrabber->IsCameraActive()) { m_ToFImageGrabber->StopCamera(); m_ToFImageGrabber->DisconnectCamera(); } m_ToFImageGrabber = nullptr; } /** * @brief GetterAndSetterTests Testing getters and setters of mitkToFImageGrabber, because * they internally contain logic. */ void GetterAndSetterTests() { int modulationFrequency = 20; m_ToFImageGrabber->SetModulationFrequency(modulationFrequency); CPPUNIT_ASSERT(modulationFrequency==m_ToFImageGrabber->GetModulationFrequency()); int integrationTime = 500; m_ToFImageGrabber->SetIntegrationTime(integrationTime); CPPUNIT_ASSERT(integrationTime==m_ToFImageGrabber->GetIntegrationTime()); } void ConnectCamera_InvalidFileName_ThrowsException() { MITK_TEST_FOR_EXCEPTION(std::logic_error, m_ToFImageGrabber->ConnectCamera()); m_ToFImageGrabber->StartCamera(); m_ToFImageGrabber->StopCamera(); CPPUNIT_ASSERT_MESSAGE("Test DisconnectCamera() with no file name set", !m_ToFImageGrabber->DisconnectCamera()); } void ConnectCamera_ValidFileName_ReturnsTrue() { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_KinectDepthImagePath)); m_ToFImageGrabber->SetProperty("RGBImageFileName",mitk::StringProperty::New(m_KinectColorImagePath)); CPPUNIT_ASSERT(m_ToFImageGrabber->ConnectCamera() == true); } void Update_2DData_ImagesAreEqual() { try { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_KinectDepthImagePath)); m_ToFImageGrabber->ConnectCamera(); m_ToFImageGrabber->StartCamera(); - mitk::Image::Pointer expectedResultImage = dynamic_cast(mitk::IOUtil::Load(m_KinectDepthImagePath)[0].GetPointer()); + mitk::Image::Pointer expectedResultImage = mitk::IOUtil::Load(m_KinectDepthImagePath); m_ToFImageGrabber->Update(); //Select 2D slice to make it comparable in diminsion mitk::ImageSliceSelector::Pointer selector = mitk::ImageSliceSelector::New(); selector->SetSliceNr(0); selector->SetTimeNr(0); selector->SetInput( m_ToFImageGrabber->GetOutput(0) ); selector->Update(); mitk::Image::Pointer distanceImage = selector->GetOutput(0); MITK_ASSERT_EQUAL( expectedResultImage, distanceImage, "Test data is 2D. Results should be equal."); } catch(std::exception &e) { MITK_ERROR << e.what(); } } void IsCameraActive_DifferentStates_ReturnsCorrectResult() { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_KinectDepthImagePath)); m_ToFImageGrabber->SetProperty("RGBImageFileName",mitk::StringProperty::New(m_KinectColorImagePath)); m_ToFImageGrabber->ConnectCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); m_ToFImageGrabber->StartCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == true); m_ToFImageGrabber->StopCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); m_ToFImageGrabber->StartCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == true); m_ToFImageGrabber->StopCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); m_ToFImageGrabber->DisconnectCamera(); CPPUNIT_ASSERT(m_ToFImageGrabber->IsCameraActive() == false); } void Update_CamCubeData_PropertiesAreTrue() { m_ToFImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(m_CamCubeDepthImagePath)); m_ToFImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(m_CamCubeAmplitudeImagePath)); m_ToFImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(m_CamCubeIntensityImagePath)); m_ToFImageGrabber->ConnectCamera(); m_ToFImageGrabber->StartCamera(); m_ToFImageGrabber->Update(); CPPUNIT_ASSERT( m_ToFImageGrabber->GetBoolProperty("HasAmplitudeImage") == true); CPPUNIT_ASSERT( m_ToFImageGrabber->GetBoolProperty("HasIntensityImage") == true); CPPUNIT_ASSERT( m_ToFImageGrabber->GetOutput(1) != nullptr ); CPPUNIT_ASSERT( m_ToFImageGrabber->GetOutput(2) != nullptr ); } }; MITK_TEST_SUITE_REGISTRATION(mitkToFImageGrabber) diff --git a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp index abda1f3d02..bb8480a8bc 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp @@ -1,159 +1,159 @@ /*=================================================================== 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 #include #include #include #include class mitkToFImageRecorderTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFImageRecorderTestSuite); //See bug #12997 // MITK_TEST(StartRecording_ValidDepthImage_WritesImageToFile); // MITK_TEST(StartRecording_ValidAmplitudeImage_WritesImageToFile); // MITK_TEST(StartRecording_ValidIntensityImage_WritesImageToFile); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different (sub-)tests. All members are initialized via setUp(). * Every recorder needs a device. Here we use a player device. * The player device needs data to load. The ground truth is loaded via IOUtil. */ mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; mitk::ToFCameraMITKPlayerDevice::Pointer m_PlayerDevice; std::string m_DistanceImageName; std::string m_AmplitudeImageName; std::string m_IntensityImageName; mitk::Image::Pointer m_GroundTruthDepthImage; mitk::Image::Pointer m_GroundTruthIntensityImage; mitk::Image::Pointer m_GroundTruthAmplitudeImage; public: /** * @brief Setup a recorder including a device. Here, we use a player, because in an automatic test * hardware is not useful. */ void setUp() override { m_ToFImageRecorder = mitk::ToFImageRecorder::New(); m_DistanceImageName = mitk::IOUtil::CreateTemporaryFile(); m_AmplitudeImageName = mitk::IOUtil::CreateTemporaryFile(); m_IntensityImageName = mitk::IOUtil::CreateTemporaryFile(); //The recorder would automatically append the default extension ".nrrd" //but we have to append it here, because the data is later loaded with //IOUtil which does not know what kind of data to load/look for. m_DistanceImageName.append("Distance.nrrd"); m_AmplitudeImageName.append("Amplitude.nrrd"); m_IntensityImageName.append("Intensity.nrrd"); m_PlayerDevice = mitk::ToFCameraMITKPlayerDevice::New(); m_ToFImageRecorder->SetCameraDevice(m_PlayerDevice); //the test data set has 20 frames, so we record 20 per default m_ToFImageRecorder->SetNumOfFrames(20); m_ToFImageRecorder->SetRecordMode(mitk::ToFImageRecorder::PerFrames); std::string dirName = MITK_TOF_DATA_DIR; std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic"; std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic"; std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic"; m_PlayerDevice->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); m_PlayerDevice->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); m_PlayerDevice->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); //comparing against IOUtil seems fair enough - m_GroundTruthDepthImage = dynamic_cast(mitk::IOUtil::Load(distanceFileName)[0].GetPointer()); - m_GroundTruthAmplitudeImage = dynamic_cast(mitk::IOUtil::Load(amplitudeFileName)[0].GetPointer()); - m_GroundTruthIntensityImage = dynamic_cast(mitk::IOUtil::Load(intensityFileName)[0].GetPointer()); + m_GroundTruthDepthImage = mitk::IOUtil::Load(distanceFileName); + m_GroundTruthAmplitudeImage = mitk::IOUtil::Load(amplitudeFileName); + m_GroundTruthIntensityImage = mitk::IOUtil::Load(intensityFileName); m_PlayerDevice->ConnectCamera(); m_PlayerDevice->StartCamera(); } void tearDown() override { m_PlayerDevice->StopCamera(); m_PlayerDevice->DisconnectCamera(); } void StartRecording_ValidDepthImage_WritesImageToFile() { m_ToFImageRecorder->SetDistanceImageFileName(m_DistanceImageName); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); m_ToFImageRecorder->StopRecording(); - mitk::Image::Pointer recordedImage = dynamic_cast(mitk::IOUtil::Load(m_DistanceImageName)[0].GetPointer()); + mitk::Image::Pointer recordedImage = mitk::IOUtil::Load(m_DistanceImageName); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, recordedImage, "Recorded image should be equal to the test data."); //delete the tmp image if( remove( m_DistanceImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: "<< m_DistanceImageName << " not successfully deleted!"; } } void StartRecording_ValidAmplitudeImage_WritesImageToFile() { m_ToFImageRecorder->SetAmplitudeImageFileName(m_AmplitudeImageName); m_ToFImageRecorder->SetAmplitudeImageSelected(true); m_ToFImageRecorder->SetDistanceImageSelected(false); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); m_ToFImageRecorder->StopRecording(); - mitk::Image::Pointer recordedImage = dynamic_cast(mitk::IOUtil::Load(m_AmplitudeImageName)[0].GetPointer()); + mitk::Image::Pointer recordedImage = mitk::IOUtil::Load(m_AmplitudeImageName); MITK_ASSERT_EQUAL( m_GroundTruthAmplitudeImage, recordedImage, "Recorded image should be equal to the test data."); //delete the tmp image if( remove( m_AmplitudeImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: "<< m_AmplitudeImageName << " not successfully deleted!"; } } void StartRecording_ValidIntensityImage_WritesImageToFile() { m_ToFImageRecorder->SetIntensityImageFileName(m_IntensityImageName); m_ToFImageRecorder->SetIntensityImageSelected(true); m_ToFImageRecorder->SetDistanceImageSelected(false); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); m_ToFImageRecorder->StopRecording(); - mitk::Image::Pointer recordedImage = dynamic_cast(mitk::IOUtil::Load(m_IntensityImageName)[0].GetPointer()); + mitk::Image::Pointer recordedImage = mitk::IOUtil::Load(m_IntensityImageName); MITK_ASSERT_EQUAL( m_GroundTruthIntensityImage, recordedImage, "Recorded image should be equal to the test data."); //delete the tmp image if( remove( m_IntensityImageName.c_str() ) != 0 ) { MITK_ERROR<<"File: "<< m_IntensityImageName << " not successfully deleted!"; } } }; MITK_TEST_SUITE_REGISTRATION(mitkToFImageRecorder) diff --git a/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp b/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp index b5a2ed3559..be86c4ff1b 100644 --- a/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFNrrdImageWriterTest.cpp @@ -1,229 +1,229 @@ /*=================================================================== 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 #include #include #include #include class mitkToFNrrdImageWriterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFNrrdImageWriterTestSuite); MITK_TEST(GetExtension_DefaultValueIsNrrd); MITK_TEST(Add_WriteDistanceImage_OutputImageIsEqualToInput); //Work in progress: // MITK_TEST(Add_WriteDistanceAndAmplitudeImage_OutputImagesAreEqualToInput); // MITK_TEST(Add_WriteDistanceAndIntensityImage_OutputImagesAreEqualToInput); // MITK_TEST(Add_WriteDistanceAndIntensityAndAmplitudeImage_OutputImagesAreEqualToInput); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different (sub-)tests. All members are initialized via setUp(). * Every recorder needs a device. Here we use a player device. * The player device needs data to load. The ground truth is loaded via IOUtil. */ mitk::ToFNrrdImageWriter::Pointer m_ToFNrrdImageWriter; std::string m_DistanceImageName; std::string m_AmplitudeImageName; std::string m_IntensityImageName; mitk::Image::Pointer m_GroundTruthDepthImage; mitk::Image::Pointer m_GroundTruthIntensityImage; mitk::Image::Pointer m_GroundTruthAmplitudeImage; unsigned int m_NumberOfFrames; public: /** * @brief Setup a recorder including a device. Here, we use a player, because in an automatic test * hardware is not useful. */ void setUp() override { m_ToFNrrdImageWriter = mitk::ToFNrrdImageWriter::New(); m_ToFNrrdImageWriter->SetToFImageType(mitk::ToFNrrdImageWriter::ToFImageType3D); //we test the ToFImageType3D since 3D is deprecated? //Generate some random test data unsigned int dimX = 255; unsigned int dimY = 178; m_NumberOfFrames = 23; m_GroundTruthDepthImage= mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, m_NumberOfFrames,1.0, 1.0f, 1.0f); m_GroundTruthAmplitudeImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, m_NumberOfFrames,1.0, 1.0f, 2000.0f); m_GroundTruthIntensityImage = mitk::ImageGenerator::GenerateRandomImage(dimX, dimY, m_NumberOfFrames,1.0, 1.0f, 100000.0f); m_ToFNrrdImageWriter->SetToFCaptureWidth(dimX); m_ToFNrrdImageWriter->SetToFCaptureHeight(dimY); m_DistanceImageName = "test_DistanceImage.nrrd"; m_AmplitudeImageName = "test_AmplitudeImage.nrrd"; m_IntensityImageName = "test_IntensityImage.nrrd"; } void tearDown() override { } void GetExtension_DefaultValueIsNrrd() { MITK_TEST_CONDITION_REQUIRED(m_ToFNrrdImageWriter->GetExtension() == ".nrrd", "Is .nrrd the default extension?"); } void Add_WriteDistanceImage_OutputImageIsEqualToInput() { m_ToFNrrdImageWriter->SetDistanceImageFileName(m_DistanceImageName); //buffer for each slice float* distanceArray; m_ToFNrrdImageWriter->Open(); //open file/stream for(unsigned int i = 0; i < m_NumberOfFrames ; ++i) { mitk::ImageReadAccessor distAcc(m_GroundTruthDepthImage, m_GroundTruthDepthImage->GetSliceData(i, 0, 0)); distanceArray = (float*)distAcc.GetData(); //write (or add) the three slices to the file m_ToFNrrdImageWriter->Add(distanceArray, nullptr, nullptr); } m_ToFNrrdImageWriter->Close(); //close file - mitk::Image::Pointer writtenImage = dynamic_cast(mitk::IOUtil::Load( m_DistanceImageName )[0].GetPointer()); + mitk::Image::Pointer writtenImage = mitk::IOUtil::Load( m_DistanceImageName ); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, writtenImage, "Written image should be equal to the test data."); //clean up tmp written image remove( m_DistanceImageName.c_str() ); } void Add_WriteDistanceAndAmplitudeImage_OutputImagesAreEqualToInput() { m_ToFNrrdImageWriter->SetDistanceImageFileName(m_DistanceImageName); m_ToFNrrdImageWriter->SetAmplitudeImageFileName(m_AmplitudeImageName); m_ToFNrrdImageWriter->SetAmplitudeImageSelected(true); //buffer for each slice float* distanceArray; float* amplitudeArray; m_ToFNrrdImageWriter->Open(); //open file/stream for(unsigned int i = 0; i < m_NumberOfFrames ; ++i) { mitk::ImageReadAccessor distAcc(m_GroundTruthDepthImage, m_GroundTruthDepthImage->GetSliceData(i, 0, 0)); mitk::ImageReadAccessor amplAcc(m_GroundTruthAmplitudeImage, m_GroundTruthAmplitudeImage->GetSliceData(i, 0, 0)); distanceArray = (float*)distAcc.GetData(); amplitudeArray = (float*)amplAcc.GetData(); //write (or add) the three slices to the file m_ToFNrrdImageWriter->Add(distanceArray, amplitudeArray, nullptr); } m_ToFNrrdImageWriter->Close(); //close file - mitk::Image::Pointer writtenDepthImage = dynamic_cast(mitk::IOUtil::Load( m_DistanceImageName )[0].GetPointer()); - mitk::Image::Pointer writtenAmplitudeImage = dynamic_cast(mitk::IOUtil::Load( m_AmplitudeImageName )[0].GetPointer()); + mitk::Image::Pointer writtenDepthImage = mitk::IOUtil::Load( m_DistanceImageName ); + mitk::Image::Pointer writtenAmplitudeImage = mitk::IOUtil::Load( m_AmplitudeImageName ); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, writtenDepthImage, "Written depth image should be equal to the test data."); MITK_ASSERT_EQUAL( m_GroundTruthAmplitudeImage, writtenAmplitudeImage, "Written amplitude image should be equal to the test data."); //clean up tmp written image remove( m_DistanceImageName.c_str() ); remove( m_AmplitudeImageName.c_str() ); } void Add_WriteDistanceAndIntensityImage_OutputImagesAreEqualToInput() { m_ToFNrrdImageWriter->SetDistanceImageFileName(m_DistanceImageName); m_ToFNrrdImageWriter->SetIntensityImageFileName(m_IntensityImageName); m_ToFNrrdImageWriter->SetIntensityImageSelected(true); //buffer for each slice float* distanceArray; float* intensityArray; m_ToFNrrdImageWriter->Open(); //open file/stream for(unsigned int i = 0; i < m_NumberOfFrames ; ++i) { mitk::ImageReadAccessor distAcc(m_GroundTruthDepthImage, m_GroundTruthDepthImage->GetSliceData(i, 0, 0)); mitk::ImageReadAccessor intensityAcc(m_GroundTruthIntensityImage, m_GroundTruthIntensityImage->GetSliceData(i, 0, 0)); distanceArray = (float*)distAcc.GetData(); intensityArray = (float*)intensityAcc.GetData(); //write (or add) the three slices to the file m_ToFNrrdImageWriter->Add(distanceArray, nullptr, intensityArray); } m_ToFNrrdImageWriter->Close(); //close file - mitk::Image::Pointer writtenDepthImage = dynamic_cast(mitk::IOUtil::Load( m_DistanceImageName )[0].GetPointer()); - mitk::Image::Pointer writtenIntensityImage = dynamic_cast(mitk::IOUtil::Load( m_IntensityImageName )[0].GetPointer()); + mitk::Image::Pointer writtenDepthImage = mitk::IOUtil::Load( m_DistanceImageName ); + mitk::Image::Pointer writtenIntensityImage = mitk::IOUtil::Load( m_IntensityImageName ); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, writtenDepthImage, "Written depth image should be equal to the test data."); MITK_ASSERT_EQUAL( m_GroundTruthIntensityImage, writtenIntensityImage, "Written amplitude image should be equal to the test data."); //clean up tmp written image remove( m_DistanceImageName.c_str() ); remove( m_IntensityImageName.c_str() ); } void Add_WriteDistanceAndIntensityAndAmplitudeImage_OutputImagesAreEqualToInput() { m_ToFNrrdImageWriter->SetDistanceImageFileName(m_DistanceImageName); m_ToFNrrdImageWriter->SetIntensityImageFileName(m_IntensityImageName); m_ToFNrrdImageWriter->SetIntensityImageSelected(true); m_ToFNrrdImageWriter->SetAmplitudeImageFileName(m_AmplitudeImageName); m_ToFNrrdImageWriter->SetAmplitudeImageSelected(true); //buffer for each slice float* distanceArray; float* intensityArray; float* amplitudeArray; m_ToFNrrdImageWriter->Open(); //open file/stream for(unsigned int i = 0; i < m_NumberOfFrames ; ++i) { mitk::ImageReadAccessor distAcc(m_GroundTruthDepthImage, m_GroundTruthDepthImage->GetSliceData(i, 0, 0)); mitk::ImageReadAccessor intensityAcc(m_GroundTruthIntensityImage, m_GroundTruthIntensityImage->GetSliceData(i, 0, 0)); mitk::ImageReadAccessor amplAcc(m_GroundTruthAmplitudeImage, m_GroundTruthAmplitudeImage->GetSliceData(i, 0, 0)); distanceArray = (float*)distAcc.GetData(); intensityArray = (float*)intensityAcc.GetData(); amplitudeArray = (float*)amplAcc.GetData(); //write (or add) the three slices to the file m_ToFNrrdImageWriter->Add(distanceArray, amplitudeArray, intensityArray); } m_ToFNrrdImageWriter->Close(); //close file - mitk::Image::Pointer writtenDepthImage = dynamic_cast(mitk::IOUtil::Load( m_DistanceImageName )[0].GetPointer()); - mitk::Image::Pointer writtenIntensityImage = dynamic_cast(mitk::IOUtil::Load( m_IntensityImageName )[0].GetPointer()); - mitk::Image::Pointer writtenAmplitudeImage = dynamic_cast(mitk::IOUtil::Load( m_AmplitudeImageName )[0].GetPointer()); + mitk::Image::Pointer writtenDepthImage = mitk::IOUtil::Load( m_DistanceImageName ); + mitk::Image::Pointer writtenIntensityImage = mitk::IOUtil::Load( m_IntensityImageName ); + mitk::Image::Pointer writtenAmplitudeImage = mitk::IOUtil::Load( m_AmplitudeImageName ); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, writtenDepthImage, "Written depth image should be equal to the test data."); MITK_ASSERT_EQUAL( m_GroundTruthAmplitudeImage, writtenAmplitudeImage, "Written amplitude image should be equal to the test data."); MITK_ASSERT_EQUAL( m_GroundTruthIntensityImage, writtenIntensityImage, "Written amplitude image should be equal to the test data."); //clean up tmp written image remove( m_DistanceImageName.c_str() ); remove( m_IntensityImageName.c_str() ); remove( m_AmplitudeImageName.c_str() ); } }; MITK_TEST_SUITE_REGISTRATION(mitkToFNrrdImageWriter) diff --git a/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp b/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp index 35f23d6ffc..ab31e520b8 100644 --- a/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFOpenCVImageGrabberTest.cpp @@ -1,101 +1,101 @@ /*=================================================================== 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 #include #include #include static bool CompareImages(mitk::Image::Pointer mitkImage, cv::Mat openCVImage) { float equal = true; if (static_cast(mitkImage->GetDimension(0)) != openCVImage.cols || static_cast(mitkImage->GetDimension(1)) != openCVImage.rows) { equal = false; } mitk::ImagePixelReadAccessor imageAcces(mitkImage, mitkImage->GetSliceData(0)); for(int i=0; i currentIndex; currentIndex[0] = i; currentIndex[1] = j; float mitkImageValue = imageAcces.GetPixelByIndex(currentIndex); float openCVImageValue = openCVImage.at(j,i); if (!mitk::Equal(mitkImageValue,openCVImageValue)) { equal = false; } } } return equal; } /**Documentation * test for the class "ToFOpenCVImageGrabber". */ int mitkToFOpenCVImageGrabberTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("ToFOpenCVImageGrabber"); std::string dirName = MITK_TOF_DATA_DIR; mitk::ToFImageGrabber::Pointer tofImageGrabber = mitk::ToFImageGrabber::New(); tofImageGrabber->SetCameraDevice(mitk::ToFCameraMITKPlayerDevice::New()); std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_DistanceImage.pic"; tofImageGrabber->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_AmplitudeImage.pic"; tofImageGrabber->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_1Images_IntensityImage.pic"; tofImageGrabber->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); tofImageGrabber->Update(); - mitk::Image::Pointer image = dynamic_cast(mitk::IOUtil::Load(distanceFileName)[0].GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::Load(distanceFileName); try { mitk::ToFOpenCVImageGrabber::Pointer tofOpenCVImageGrabber = mitk::ToFOpenCVImageGrabber::New(); tofOpenCVImageGrabber->SetToFImageGrabber(tofImageGrabber); MITK_TEST_CONDITION_REQUIRED(tofImageGrabber==tofOpenCVImageGrabber->GetToFImageGrabber(),"Test Set/GetToFImageGrabber()"); MITK_TEST_OUTPUT(<<"Call StartCapturing()"); tofOpenCVImageGrabber->StartCapturing(); cv::Mat cvImage = tofOpenCVImageGrabber->GetImage(); MITK_TEST_CONDITION_REQUIRED(CompareImages(image,cvImage),"Test distance image"); - image = dynamic_cast(mitk::IOUtil::Load(amplitudeFileName)[0].GetPointer()); + image = mitk::IOUtil::Load(amplitudeFileName); tofOpenCVImageGrabber->SetImageType(1); cvImage = tofOpenCVImageGrabber->GetImage(); MITK_TEST_CONDITION_REQUIRED(CompareImages(image,cvImage),"Test amplitude image"); - image = dynamic_cast(mitk::IOUtil::Load(intensityFileName)[0].GetPointer()); + image = mitk::IOUtil::Load(intensityFileName); tofOpenCVImageGrabber->SetImageType(2); cvImage = tofOpenCVImageGrabber->GetImage(); MITK_TEST_CONDITION_REQUIRED(CompareImages(image,cvImage),"Test intensity image"); MITK_TEST_OUTPUT(<<"Call StopCapturing()"); tofOpenCVImageGrabber->StopCapturing(); } catch(std::exception &e) { MITK_INFO << "Exception is: " << e.what(); } MITK_TEST_END(); } diff --git a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp index 89e8e5eeaf..cb8e930382 100644 --- a/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp +++ b/Modules/ToFHardware/mitkToFCameraMITKPlayerController.cpp @@ -1,337 +1,337 @@ /*=================================================================== 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 // mitk includes #include "mitkIOUtil.h" #include #include "mitkImageReadAccessor.h" namespace mitk { ToFCameraMITKPlayerController::ToFCameraMITKPlayerController() : m_PixelNumber(0), m_RGBPixelNumber(0), m_NumberOfBytes(0), m_NumberOfRGBBytes(0), m_CaptureWidth(0), m_CaptureHeight(0), m_RGBCaptureWidth(0), m_RGBCaptureHeight(0), m_ConnectionCheck(false), m_InputFileName(""), m_ToFImageType(ToFImageType3D), m_DistanceImage(nullptr), m_AmplitudeImage(nullptr), m_IntensityImage(nullptr), m_RGBImage(nullptr), m_DistanceInfile(nullptr), m_AmplitudeInfile(nullptr), m_IntensityInfile(nullptr), m_RGBInfile(nullptr), m_IntensityArray(nullptr), m_DistanceArray(nullptr), m_AmplitudeArray(nullptr), m_RGBArray(nullptr), m_DistanceImageFileName(""), m_AmplitudeImageFileName(""), m_IntensityImageFileName(""), m_RGBImageFileName(""), m_PixelStartInFile(0), m_CurrentFrame(-1), m_NumOfFrames(0) { m_ImageStatus = std::vector(4,true); } ToFCameraMITKPlayerController::~ToFCameraMITKPlayerController() { this->CleanUp(); } void ToFCameraMITKPlayerController::CleanUp() { if(m_DistanceImage.IsNotNull()) { m_DistanceImage->ReleaseData(); m_DistanceImage = nullptr; } if(m_AmplitudeImage.IsNotNull()) { m_AmplitudeImage->ReleaseData(); m_AmplitudeImage = nullptr; } if(m_IntensityImage.IsNotNull()) { m_IntensityImage->ReleaseData(); m_IntensityImage = nullptr; } if(m_RGBImage.IsNotNull()) { m_RGBImage->ReleaseData(); m_RGBImage = nullptr; } delete[] this->m_DistanceArray; this->m_DistanceArray = nullptr; delete[] this->m_AmplitudeArray; this->m_AmplitudeArray = nullptr; delete[] this->m_IntensityArray; this->m_IntensityArray = nullptr; delete[] this->m_RGBArray; this->m_RGBArray = nullptr; this->m_DistanceImageFileName = ""; this->m_AmplitudeImageFileName = ""; this->m_IntensityImageFileName = ""; this->m_RGBImageFileName = ""; } bool ToFCameraMITKPlayerController::OpenCameraConnection() { if(!this->m_ConnectionCheck) { // reset the image status before connection m_ImageStatus = std::vector(4,true); try { if (this->m_DistanceImageFileName.empty() && this->m_AmplitudeImageFileName.empty() && this->m_IntensityImageFileName.empty() && this->m_RGBImageFileName.empty()) { throw std::logic_error("No image data file names set"); } if (!this->m_DistanceImageFileName.empty()) { - m_DistanceImage = dynamic_cast(mitk::IOUtil::Load(this->m_DistanceImageFileName)[0].GetPointer()); + m_DistanceImage = mitk::IOUtil::Load(this->m_DistanceImageFileName); } else { MITK_ERROR << "ToF distance image data file empty"; } if (!this->m_AmplitudeImageFileName.empty()) { - m_AmplitudeImage = dynamic_cast(mitk::IOUtil::Load(this->m_AmplitudeImageFileName)[0].GetPointer()); + m_AmplitudeImage = mitk::IOUtil::Load(this->m_AmplitudeImageFileName); } else { MITK_WARN << "ToF amplitude image data file empty"; } if (!this->m_IntensityImageFileName.empty()) { - m_IntensityImage = dynamic_cast(mitk::IOUtil::Load(this->m_IntensityImageFileName)[0].GetPointer()); + m_IntensityImage = mitk::IOUtil::Load(this->m_IntensityImageFileName); } else { MITK_WARN << "ToF intensity image data file empty"; } if (!this->m_RGBImageFileName.empty()) { - m_RGBImage = dynamic_cast(mitk::IOUtil::Load(this->m_RGBImageFileName)[0].GetPointer()); + m_RGBImage = mitk::IOUtil::Load(this->m_RGBImageFileName); } else { MITK_WARN << "ToF RGB image data file empty"; } // check if the opened files contained data if(m_DistanceImage.IsNull()) { m_ImageStatus.at(0) = false; } if(m_AmplitudeImage.IsNull()) { m_ImageStatus.at(1) = false; } if(m_IntensityImage.IsNull()) { m_ImageStatus.at(2) = false; } if(m_RGBImage.IsNull()) { m_ImageStatus.at(3) = false; } // Check for dimension type mitk::Image::Pointer infoImage = nullptr; if(m_ImageStatus.at(0)) { infoImage = m_DistanceImage; } else if (m_ImageStatus.at(1)) { infoImage = m_AmplitudeImage; } else if(m_ImageStatus.at(2)) { infoImage = m_IntensityImage; } else if(m_ImageStatus.at(3)) { infoImage = m_RGBImage; } if (infoImage->GetDimension() == 2) this->m_ToFImageType = ToFImageType2DPlusT; else if (infoImage->GetDimension() == 3) this->m_ToFImageType = ToFImageType3D; else if (infoImage->GetDimension() == 4) this->m_ToFImageType = ToFImageType2DPlusT; else throw std::logic_error("Error opening ToF data file: Invalid dimension."); this->m_CaptureWidth = infoImage->GetDimension(0); this->m_CaptureHeight = infoImage->GetDimension(1); this->m_PixelNumber = this->m_CaptureWidth*this->m_CaptureHeight; this->m_NumberOfBytes = this->m_PixelNumber * sizeof(float); if(m_RGBImage) { m_RGBCaptureWidth = m_RGBImage->GetDimension(0); m_RGBCaptureHeight = m_RGBImage->GetDimension(1); m_RGBPixelNumber = m_RGBCaptureWidth * m_RGBCaptureHeight; m_NumberOfRGBBytes = m_RGBPixelNumber * 3; } if (this->m_ToFImageType == ToFImageType2DPlusT) { this->m_NumOfFrames = infoImage->GetDimension(3); } else { this->m_NumOfFrames = infoImage->GetDimension(2); } // allocate buffer this->m_DistanceArray = new float[this->m_PixelNumber]; for(int i=0; im_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;} this->m_AmplitudeArray = new float[this->m_PixelNumber]; for(int i=0; im_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;} this->m_IntensityArray = new float[this->m_PixelNumber]; for(int i=0; im_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;} this->m_RGBArray = new unsigned char[m_NumberOfRGBBytes]; for(int i=0; im_RGBArray[i]=0.0;} MITK_INFO << "NumOfFrames: " << this->m_NumOfFrames; this->m_ConnectionCheck = true; return this->m_ConnectionCheck; } catch(std::exception& e) { MITK_ERROR << "Error opening ToF data file " << this->m_InputFileName << " " << e.what(); throw std::logic_error("Error opening ToF data file"); return false; } } else return this->m_ConnectionCheck; } bool ToFCameraMITKPlayerController::CloseCameraConnection() { if (this->m_ConnectionCheck) { this->CleanUp(); this->m_ConnectionCheck = false; return true; } return false; } void ToFCameraMITKPlayerController::UpdateCamera() { this->m_CurrentFrame++; if(this->m_CurrentFrame >= this->m_NumOfFrames) { this->m_CurrentFrame = 0; } if(this->m_ImageStatus.at(0)) { this->AccessData(this->m_CurrentFrame, this->m_DistanceImage, this->m_DistanceArray); } if(this->m_ImageStatus.at(1)) { this->AccessData(this->m_CurrentFrame, this->m_AmplitudeImage, this->m_AmplitudeArray); } if(this->m_ImageStatus.at(2)) { this->AccessData(this->m_CurrentFrame, this->m_IntensityImage, this->m_IntensityArray); } if(this->m_ImageStatus.at(3)) { if(!this->m_ToFImageType) { ImageReadAccessor rgbAcc(m_RGBImage, m_RGBImage->GetSliceData(m_CurrentFrame)); memcpy(m_RGBArray, rgbAcc.GetData(), m_NumberOfRGBBytes ); } else if(this->m_ToFImageType) { ImageReadAccessor rgbAcc(m_RGBImage, m_RGBImage->GetVolumeData(m_CurrentFrame)); memcpy(m_RGBArray, rgbAcc.GetData(), m_NumberOfRGBBytes); } } itksys::SystemTools::Delay(50); } void ToFCameraMITKPlayerController::AccessData(int frame, Image::Pointer image, float* &data) { if(!this->m_ToFImageType) { ImageReadAccessor imgAcc(image, image->GetSliceData(frame)); memcpy(data, imgAcc.GetData(), this->m_NumberOfBytes ); } else if(this->m_ToFImageType) { ImageReadAccessor imgAcc(image, image->GetVolumeData(frame)); memcpy(data, imgAcc.GetData(), this->m_NumberOfBytes); } } void ToFCameraMITKPlayerController::GetAmplitudes(float* amplitudeArray) { memcpy(amplitudeArray, this->m_AmplitudeArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetIntensities(float* intensityArray) { memcpy(intensityArray, this->m_IntensityArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetDistances(float* distanceArray) { memcpy(distanceArray, this->m_DistanceArray, this->m_NumberOfBytes); } void ToFCameraMITKPlayerController::GetRgb(unsigned char* rgbArray) { memcpy(rgbArray, this->m_RGBArray, m_NumberOfRGBBytes); } void ToFCameraMITKPlayerController::SetInputFileName(std::string inputFileName) { this->m_InputFileName = inputFileName; } } diff --git a/Modules/ToFProcessing/Testing/mitkKinectReconstructionTest.cpp b/Modules/ToFProcessing/Testing/mitkKinectReconstructionTest.cpp index 23d02507a7..29a5da1d29 100644 --- a/Modules/ToFProcessing/Testing/mitkKinectReconstructionTest.cpp +++ b/Modules/ToFProcessing/Testing/mitkKinectReconstructionTest.cpp @@ -1,98 +1,98 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include /** * @brief mitkKinectReconstructionTest Testing method for the Kinect reconstruction mode. Specially meant for Kinect. * This tests loads a special data set from MITK-Data and compares it to a reference surface. * This test has no dependency to the mitkKinectModule, although it is thematically connected to it. */ int mitkKinectReconstructionTest(int argc , char* argv[]) { MITK_TEST_BEGIN("mitkKinectReconstructionTest"); MITK_TEST_CONDITION_REQUIRED(argc > 2, "Testing if enough arguments are set."); std::string calibrationFilePath(argv[1]); std::string kinectImagePath(argv[2]); mitk::ToFDistanceImageToSurfaceFilter::Pointer distToSurf = mitk::ToFDistanceImageToSurfaceFilter::New(); mitk::CameraIntrinsics::Pointer intrinsics = mitk::CameraIntrinsics::New(); //load our personal kinect calibration intrinsics->FromXMLFile(calibrationFilePath); MITK_TEST_CONDITION_REQUIRED(intrinsics.IsNotNull(), "Testing if a calibration file could be loaded."); distToSurf->SetCameraIntrinsics(intrinsics); distToSurf->SetReconstructionMode(mitk::ToFDistanceImageToSurfaceFilter::Kinect); //load a data set - mitk::Image::Pointer kinectImage = dynamic_cast(mitk::IOUtil::Load(kinectImagePath)[0].GetPointer()); + mitk::Image::Pointer kinectImage = mitk::IOUtil::Load(kinectImagePath); MITK_TEST_CONDITION_REQUIRED(kinectImage.IsNotNull(), "Testing if a kinect image could be loaded."); distToSurf->SetInput(kinectImage); distToSurf->Update(); mitk::Surface::Pointer resultOfFilter = distToSurf->GetOutput(); MITK_TEST_CONDITION_REQUIRED(resultOfFilter.IsNotNull(), "Testing if any output was generated."); mitk::PointSet::Pointer resultPointSet = mitk::ToFTestingCommon::VtkPolyDataToMitkPointSet(resultOfFilter->GetVtkPolyData()); // generate ground truth data mitk::PointSet::Pointer groundTruthPointSet = mitk::PointSet::New(); mitk::ToFProcessingCommon::ToFPoint2D focalLength; focalLength[0] = intrinsics->GetFocalLengthX(); focalLength[1] = intrinsics->GetFocalLengthY(); mitk::ToFProcessingCommon::ToFPoint2D principalPoint; principalPoint[0] = intrinsics->GetPrincipalPointX(); principalPoint[1] = intrinsics->GetPrincipalPointY(); int xDimension = (int)kinectImage->GetDimension(0); int yDimension = (int)kinectImage->GetDimension(1); int pointCount = 0; mitk::ImagePixelReadAccessor imageAcces(kinectImage, kinectImage->GetSliceData(0)); for (int j=0; j pixel; pixel[0] = i; pixel[1] = j; mitk::ToFProcessingCommon::ToFScalarType distance = (double)imageAcces.GetPixelByIndex(pixel); mitk::Point3D currentPoint; currentPoint = mitk::ToFProcessingCommon::KinectIndexToCartesianCoordinates(i,j,distance,focalLength[0],focalLength[1],principalPoint[0],principalPoint[1]); if (distance>mitk::eps) { groundTruthPointSet->InsertPoint( pointCount, currentPoint ); pointCount++; } } } MITK_TEST_CONDITION_REQUIRED( mitk::ToFTestingCommon::PointSetsEqual(resultPointSet,groundTruthPointSet), "Testing if point sets are equal (with a small epsilon)."); MITK_TEST_END(); } diff --git a/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp b/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp index fb22430ad7..8c124ed5a7 100644 --- a/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp +++ b/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp @@ -1,72 +1,72 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkITKImageImport.h" #include "mitkImage.h" #include #include "itkSignedDanielssonDistanceMapImageFilter.h" using namespace std; typedef itk::Image BinaryType; typedef itk::Image ResultType; int main(int argc, char *argv[]) { mitkCommandLineParser parser; parser.setTitle("Basic Distance Maps"); parser.setCategory("Features"); parser.setDescription("Creates Eucledian Distance Maps of a given ROI segmentation"); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "(binary) seed file"); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "distance map file name"); map parsedArgs = parser.parseArguments(argc, argv); // Show a help message if (parsedArgs.size() == 0 || parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string resultFile = us::any_cast(parsedArgs["output"]); std::string seedFile = us::any_cast(parsedArgs["input"]); - mitk::Image::Pointer seedImage = dynamic_cast(mitk::IOUtil::Load(seedFile)[0].GetPointer()); + mitk::Image::Pointer seedImage = mitk::IOUtil::Load(seedFile); BinaryType::Pointer itkSeed = BinaryType::New(); mitk::CastToItkImage(seedImage, itkSeed); itk::SignedDanielssonDistanceMapImageFilter::Pointer danielssonDistance = itk::SignedDanielssonDistanceMapImageFilter::New(); danielssonDistance->SetInput(itkSeed); danielssonDistance->SetUseImageSpacing(true); danielssonDistance->Update(); mitk::Image::Pointer result = mitk::Image::New(); mitk::GrabItkImageMemory(danielssonDistance->GetOutput(), result); mitk::IOUtil::Save(result, resultFile); return EXIT_SUCCESS; } diff --git a/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp b/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp index 3d7ce01bc5..70bd3fa7d6 100644 --- a/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp +++ b/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp @@ -1,202 +1,202 @@ /*=================================================================== 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 "mitkCommandLineParser.h" #include "mitkITKImageImport.h" #include "mitkImage.h" #include #include #include #include // ITK #include "itkBinaryErodeImageFilter.h" #include "itkFlatStructuringElement.h" using namespace std; typedef itk::Image BinaryType; typedef itk::Image ResultType; typedef itk::Image, 3> ItkTensorImage; int main(int argc, char *argv[]) { // Setup CLI Module parsable interface mitkCommandLineParser parser; parser.setTitle("Connectedness Maps"); parser.setCategory("Features"); parser.setDescription("Computes connectedness maps"); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "input file"); parser.addArgument("seed", "s", mitkCommandLineParser::InputImage, "seed file"); parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "mask file"); parser.addArgument("mode", "t", mitkCommandLineParser::String, "Mode Feature | Vector | FeatureVector"); parser.addArgument("vector", "v", mitkCommandLineParser::InputImage, "Tensor Image (.dti)"); parser.addArgument( "confidence", "c", mitkCommandLineParser::InputImage, "confidence map (only when Tensor Images are used)"); parser.addArgument("valueImage", "x", mitkCommandLineParser::InputImage, "image of values that are propagated"); parser.addArgument("erodeSeed", "a", mitkCommandLineParser::Bool, "apply erosion of seed region"); parser.addArgument("rankFilter", "r", mitkCommandLineParser::Bool, "median filter for propagation"); parser.addArgument("propMap", "p", mitkCommandLineParser::OutputFile, "[out] propagated map"); parser.addArgument("distanceMap", "d", mitkCommandLineParser::OutputFile, "[out] connectedness map"); parser.addArgument("euclidDistanceMap", "e", mitkCommandLineParser::OutputFile, "[out] euclid distance map"); // Parse input parameters map parsedArgs = parser.parseArguments(argc, argv); // Show a help message if (parsedArgs.size() == 0 || parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } bool useRank = false; bool applyErosion = false; bool useValueImage = false; if (parsedArgs.count("rankFilter") || parsedArgs.count("r")) useRank = true; if (parsedArgs.count("valueImage") || parsedArgs.count("x")) useValueImage = true; if (parsedArgs.count("erodeSeed") || parsedArgs.count("a")) applyErosion = true; std::string inputFile = us::any_cast(parsedArgs["input"]); std::string propMap = us::any_cast(parsedArgs["propMap"]); std::string conMap = us::any_cast(parsedArgs["distanceMap"]); std::string tensImageFile = us::any_cast(parsedArgs["vector"]); std::string maskFile = us::any_cast(parsedArgs["mask"]); std::string mode = us::any_cast(parsedArgs["mode"]); std::string seedFile = us::any_cast(parsedArgs["seed"]); std::string confFile = us::any_cast(parsedArgs["confidence"]); std::string euclidFile = us::any_cast(parsedArgs["euclidDistanceMap"]); std::string valueImageFile = ""; if (useValueImage) valueImageFile = us::any_cast(parsedArgs["valueImage"]); // Read-in image data mitk::Image::Pointer tmpImage; - mitk::Image::Pointer inputImage = dynamic_cast(mitk::IOUtil::Load(inputFile)[0].GetPointer()); - mitk::Image::Pointer maskImage = dynamic_cast(mitk::IOUtil::Load(maskFile)[0].GetPointer()); - mitk::Image::Pointer seedImage = dynamic_cast(mitk::IOUtil::Load(seedFile)[0].GetPointer()); + mitk::Image::Pointer inputImage = mitk::IOUtil::Load(inputFile); + mitk::Image::Pointer maskImage = mitk::IOUtil::Load(maskFile); + mitk::Image::Pointer seedImage = mitk::IOUtil::Load(seedFile); mitk::Image::Pointer valueImage; if (useValueImage) - valueImage = dynamic_cast(mitk::IOUtil::Load(valueImageFile)[0].GetPointer()); + valueImage = mitk::IOUtil::Load(valueImageFile); mitk::Image::Pointer confImage; if (mode == "Vector" || mode == "FeatureVector") { MITK_INFO << "Load Tensor/Confidence"; - tmpImage = dynamic_cast(mitk::IOUtil::Load(tensImageFile)[0].GetPointer()); - confImage = dynamic_cast(mitk::IOUtil::Load(confFile)[0].GetPointer()); + tmpImage = mitk::IOUtil::Load(tensImageFile); + confImage = mitk::IOUtil::Load(confFile); } mitk::TensorImage *diffusionImage = static_cast(tmpImage.GetPointer()); // Convert all input data to ITK BinaryType::Pointer itkSeed = BinaryType::New(); BinaryType::Pointer itkMask = BinaryType::New(); ResultType::Pointer itkImage = ResultType::New(); ItkTensorImage::Pointer itkTensor = ItkTensorImage::New(); ResultType::Pointer itkWeight = ResultType::New(); ResultType::Pointer itkValueImage = ResultType::New(); mitk::CastToItkImage(inputImage, itkImage); mitk::CastToItkImage(maskImage, itkMask); mitk::CastToItkImage(seedImage, itkSeed); if (useValueImage) mitk::CastToItkImage(valueImage, itkValueImage); if (applyErosion) { typedef itk::FlatStructuringElement<3> StructuringElementType; StructuringElementType::RadiusType elementRadius; elementRadius.Fill(2); elementRadius[2] = 0; StructuringElementType structuringElement = StructuringElementType::Box(elementRadius); typedef itk::BinaryErodeImageFilter BinaryErodeImageFilterType; BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New(); erodeFilter->SetInput(itkSeed); erodeFilter->SetKernel(structuringElement); erodeFilter->SetForegroundValue(1); erodeFilter->Update(); itkSeed = erodeFilter->GetOutput(); } if (mode == "Vector" || mode == "FeatureVector") { mitk::CastToItkImage(diffusionImage, itkTensor); mitk::CastToItkImage(confImage, itkWeight); } // Setup filter itk::ConnectednessFilter::Pointer filter = itk::ConnectednessFilter::New(); filter->SetInputImage(itkImage); filter->SetInputSeed(itkSeed); filter->SetInputMask(itkMask); if (mode == "Vector") { filter->SetInputVectorField(itkTensor); filter->SetInputVectorFieldConfidenceMap(itkWeight); filter->SetMode(itk::ConnectednessFilter::VectorAgreement); } else if (mode == "FeatureVector") { filter->SetInputVectorField(itkTensor); filter->SetInputVectorFieldConfidenceMap(itkWeight); filter->SetMode(itk::ConnectednessFilter::FeatureVectorAgreement); } else filter->SetMode(itk::ConnectednessFilter::FeatureSimilarity); if (useValueImage) filter->SetPropagationImage(itkValueImage); filter->SetApplyRankFilter(useRank); filter->Update(); // Grab output and write results mitk::Image::Pointer result = mitk::Image::New(); mitk::GrabItkImageMemory(filter->GetOutput(), result); mitk::IOUtil::Save(result, propMap); mitk::Image::Pointer distance = mitk::Image::New(); mitk::GrabItkImageMemory(filter->GetDistanceImage().GetPointer(), distance); mitk::IOUtil::Save(distance, conMap); mitk::Image::Pointer euclidDistance = mitk::Image::New(); mitk::GrabItkImageMemory(filter->GetEuclideanDistanceImage().GetPointer(), euclidDistance); mitk::IOUtil::Save(euclidDistance, euclidFile); return EXIT_SUCCESS; } diff --git a/Modules/TumorInvasionAnalysis/MiniApps/HistogramAdaption.cpp b/Modules/TumorInvasionAnalysis/MiniApps/HistogramAdaption.cpp index 5d5b2ec3af..18ce5faada 100644 --- a/Modules/TumorInvasionAnalysis/MiniApps/HistogramAdaption.cpp +++ b/Modules/TumorInvasionAnalysis/MiniApps/HistogramAdaption.cpp @@ -1,104 +1,104 @@ /*=================================================================== 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 "itkImageRegionIterator.h" #include "mitkIOUtil.h" #include "mitkImageCast.h" #include #include using namespace std; typedef itk::Image SeedImage; typedef itk::Image FeatureImage; typedef itk::ImageRegionIterator SeedIteratorType; typedef itk::ImageRegionIterator FeatureIteratorType; int main(int argc, char *argv[]) { mitkCommandLineParser parser; parser.setTitle("Contrast Adaption"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Stretches or pushes image intensities above a given threshold"); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "input image"); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "output image"); parser.addArgument("cutOff", "c", mitkCommandLineParser::Float, "value at which different slope is to be applied"); parser.addArgument( "slope", "s", mitkCommandLineParser::Float, "slope to be applied (total delta to max value starting from cutOff)"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) return EXIT_FAILURE; // Show a help message if (parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string outFile = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer inputFile = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["input"]))[0].GetPointer()); + mitk::Image::Pointer inputFile = mitk::IOUtil::Load(us::any_cast(parsedArgs["input"])); float cutOff = us::any_cast(parsedArgs["cutOff"]); float slope = us::any_cast(parsedArgs["slope"]); FeatureImage::Pointer itkInputImage = FeatureImage::New(); mitk::CastToItkImage(inputFile, itkInputImage); double max = -99999; itk::ImageRegionIterator inputIt(itkInputImage, itkInputImage->GetLargestPossibleRegion()); while (!inputIt.IsAtEnd()) { if (inputIt.Get() > max) max = inputIt.Get(); ++inputIt; } inputIt.GoToBegin(); // Mapping while (!inputIt.IsAtEnd()) { if (inputIt.Get() > cutOff) { inputIt.Set(cutOff + slope * (inputIt.Get() - cutOff) / (max - cutOff)); } ++inputIt; } mitk::Image::Pointer mitkResult = mitk::Image::New(); // !! CastToItk behaves very differently depending on the original data type // if the target type is the same as the original, only a pointer to the data is set // and an additional GrabItkImageMemory will cause a segfault when the image is destroyed // GrabItkImageMemory - is not necessary in this case since we worked on the original data // See Bug 17538. if (inputFile->GetPixelType().GetComponentTypeAsString() != "double") mitkResult = mitk::GrabItkImageMemory(itkInputImage); else mitkResult = inputFile; mitk::IOUtil::Save(mitkResult, outFile); return EXIT_SUCCESS; } diff --git a/Modules/TumorInvasionAnalysis/MiniApps/MriNormalization.cpp b/Modules/TumorInvasionAnalysis/MiniApps/MriNormalization.cpp index 9164f3bd9f..4c4fb51438 100644 --- a/Modules/TumorInvasionAnalysis/MiniApps/MriNormalization.cpp +++ b/Modules/TumorInvasionAnalysis/MiniApps/MriNormalization.cpp @@ -1,122 +1,122 @@ /*=================================================================== 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 "itkImageRegionIterator.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "mitkImageCast.h" #include using namespace std; typedef itk::Image SeedImage; typedef itk::Image FeatureImage; typedef itk::ImageRegionIterator SeedIteratorType; typedef itk::ImageRegionIterator FeatureIteratorType; int main(int argc, char *argv[]) { mitkCommandLineParser parser; parser.setTitle("Mri Normalization"); parser.setCategory("Preprocessing Tools"); parser.setDescription( "Normalizes an MRI volume between medians of two given masks (e.g. ventricles and brain matter)"); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "input image"); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "output image"); parser.addArgument( "maxMask", "m", mitkCommandLineParser::InputImage, "mask of which median is set as maximal value (1)"); parser.addArgument( "minMask", "l", mitkCommandLineParser::InputImage, "mask of which median is set as minimal value (0)"); parser.addArgument( "excludeMask", "e", mitkCommandLineParser::InputImage, "region which is exluded from the other two"); map parsedArgs = parser.parseArguments(argc, argv); // Show a help message if (parsedArgs.size() == 0 || parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string outFile = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer inputFile = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["input"]))[0].GetPointer()); - mitk::Image::Pointer maxMask = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["maxMask"]))[0].GetPointer()); - mitk::Image::Pointer minMask = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["minMask"]))[0].GetPointer()); - mitk::Image::Pointer excludeMask = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["excludeMask"]))[0].GetPointer()); + mitk::Image::Pointer inputFile = mitk::IOUtil::Load(us::any_cast(parsedArgs["input"])); + mitk::Image::Pointer maxMask = mitk::IOUtil::Load(us::any_cast(parsedArgs["maxMask"])); + mitk::Image::Pointer minMask = mitk::IOUtil::Load(us::any_cast(parsedArgs["minMask"])); + mitk::Image::Pointer excludeMask = mitk::IOUtil::Load(us::any_cast(parsedArgs["excludeMask"])); SeedImage::Pointer itkMaxImage = SeedImage::New(); SeedImage::Pointer itkMinImage = SeedImage::New(); SeedImage::Pointer itkExcludeImage = SeedImage::New(); FeatureImage::Pointer itkInputImage = FeatureImage::New(); mitk::CastToItkImage(inputFile, itkInputImage); mitk::CastToItkImage(maxMask, itkMaxImage); mitk::CastToItkImage(minMask, itkMinImage); mitk::CastToItkImage(excludeMask, itkExcludeImage); std::vector medianMin; std::vector medianMax; itk::ImageRegionIterator inputIt(itkInputImage, itkInputImage->GetLargestPossibleRegion()); itk::ImageRegionIterator excludeIt(itkExcludeImage, itkExcludeImage->GetLargestPossibleRegion()); itk::ImageRegionIterator minIt(itkMinImage, itkMinImage->GetLargestPossibleRegion()); itk::ImageRegionIterator maxIt(itkMaxImage, itkMaxImage->GetLargestPossibleRegion()); while (!inputIt.IsAtEnd()) { if (excludeIt.Get() == 0) { if (minIt.Get() != 0) medianMin.push_back(inputIt.Get()); if (maxIt.Get() != 0) medianMax.push_back(inputIt.Get()); } ++inputIt; ++excludeIt; ++minIt; ++maxIt; } std::sort(medianMax.begin(), medianMax.end()); std::sort(medianMin.begin(), medianMin.end()); mitk::ScalarType minVal = medianMin.at(medianMin.size() / 2); mitk::ScalarType maxVal = medianMax.at(medianMax.size() / 2); inputIt.GoToBegin(); // Create mapping while (!inputIt.IsAtEnd()) { inputIt.Set(1.0 * (inputIt.Get() - minVal) / (maxVal - minVal)); ++inputIt; } mitk::Image::Pointer mitkResult = mitk::Image::New(); mitkResult = mitk::GrabItkImageMemory(itkInputImage); mitk::IOUtil::Save(mitkResult, outFile); return EXIT_SUCCESS; } diff --git a/Modules/TumorInvasionAnalysis/MiniApps/MriOtsuNormalization.cpp b/Modules/TumorInvasionAnalysis/MiniApps/MriOtsuNormalization.cpp index 359c451571..284cd5df10 100644 --- a/Modules/TumorInvasionAnalysis/MiniApps/MriOtsuNormalization.cpp +++ b/Modules/TumorInvasionAnalysis/MiniApps/MriOtsuNormalization.cpp @@ -1,124 +1,124 @@ /*=================================================================== 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 "itkImageRegionIterator.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "mitkImageCast.h" #include // ITK #include using namespace std; typedef itk::Image SeedImage; typedef itk::Image FeatureImage; typedef itk::ImageRegionIterator SeedIteratorType; typedef itk::ImageRegionIterator FeatureIteratorType; int main(int argc, char *argv[]) { mitkCommandLineParser parser; parser.setTitle("Mri Normalization"); parser.setCategory("Preprocessing Tools"); parser.setDescription("Normalizes an MRI volume based on regions determined by Otsu."); parser.setContributor("MBI"); parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "input image", "input image"); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "output image", "output image"); parser.addArgument("bins", "b", mitkCommandLineParser::Int, "number of regions (bins)", "number of regions (bins)"); parser.addArgument( "minBin", "l", mitkCommandLineParser::Int, "bin of which median is set to 0", "bin of which median is set to 0"); parser.addArgument( "maxBin", "h", mitkCommandLineParser::Int, "bin of which median is set to 1", "bin of which median is set to 1"); map parsedArgs = parser.parseArguments(argc, argv); // Show a help message if (parsedArgs.size() == 0 || parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string outFile = us::any_cast(parsedArgs["output"]); - mitk::Image::Pointer inputFile = dynamic_cast(mitk::IOUtil::Load(us::any_cast(parsedArgs["input"]))[0].GetPointer()); + mitk::Image::Pointer inputFile = mitk::IOUtil::Load(us::any_cast(parsedArgs["input"])); int numberOfThresholds = us::any_cast(parsedArgs["bins"]); int minBin = us::any_cast(parsedArgs["minBin"]); int maxBin = us::any_cast(parsedArgs["maxBin"]); FeatureImage::Pointer itkInputImage = FeatureImage::New(); mitk::CastToItkImage(inputFile, itkInputImage); typedef itk::OtsuMultipleThresholdsImageFilter FilterType; FilterType::Pointer otsuFilter = FilterType::New(); otsuFilter->SetInput(itkInputImage); otsuFilter->SetNumberOfThresholds(numberOfThresholds - 1); otsuFilter->Update(); FeatureImage::Pointer itkLabelImage = otsuFilter->GetOutput(); std::vector medianMin; std::vector medianMax; itk::ImageRegionIterator inputIt(itkInputImage, itkInputImage->GetLargestPossibleRegion()); itk::ImageRegionIterator labelIt(itkLabelImage, itkLabelImage->GetLargestPossibleRegion()); while (!inputIt.IsAtEnd()) { if (labelIt.Get() == minBin) { medianMin.push_back(inputIt.Get()); } else if (labelIt.Get() == maxBin) { medianMax.push_back(inputIt.Get()); } ++inputIt; ++labelIt; } std::sort(medianMax.begin(), medianMax.end()); std::sort(medianMin.begin(), medianMin.end()); mitk::ScalarType minVal = medianMin.at(medianMin.size() / 2); mitk::ScalarType maxVal = medianMax.at(medianMax.size() / 2); inputIt.GoToBegin(); // labelIt.GoToBegin(); // Create mapping while (!inputIt.IsAtEnd()) { inputIt.Set(1.0 * (inputIt.Get() - minVal) / (maxVal - minVal)); // inputIt.Set(labelIt.Get()); ++inputIt; //++labelIt; } mitk::Image::Pointer mitkResult = mitk::Image::New(); mitkResult = mitk::GrabItkImageMemory(itkInputImage); mitk::IOUtil::Save(mitkResult, outFile); return EXIT_SUCCESS; } diff --git a/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp b/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp index c0d137d3c8..148979fefc 100644 --- a/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp +++ b/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp @@ -1,554 +1,554 @@ /*=================================================================== 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. ===================================================================*/ // MITK #include #include #include #include #include #include #include #include // ITK #include "itkImageDuplicator.h" #include "itkPermuteAxesImageFilter.h" #include "itkTileImageFilter.h" #include #include #include #include #include #include #include // VTK #include #include #include #include #include // MITK #include #include "itkRescaleIntensityImageFilter.h" #include using namespace std; typedef unsigned short PixelType; typedef double InputPixelType; typedef itk::Image, 2> RGB2DImage; typedef itk::RGBPixel RGBPixelType; typedef std::vector FileList; typedef std::vector ImageList; /// Create list of all files in provided folder ending with same postfix static FileList CreateFileList(std::string folder, std::string postfix) { itk::Directory::Pointer dir = itk::Directory::New(); FileList fileList; if (dir->Load(folder.c_str())) { int n = dir->GetNumberOfFiles(); for (int r = 0; r < n; r++) { std::string filename = dir->GetFile(r); if (filename == "." || filename == "..") continue; filename = folder + filename; if (!itksys::SystemTools::FileExists(filename.c_str())) continue; if (postfix.compare(filename.substr(filename.length() - postfix.length())) == 0) fileList.push_back(filename); } } std::sort(fileList.begin(), fileList.end()); return fileList; } class mitkProgressionVisualization { public: mitkProgressionVisualization() {} /** * @brief ConvertToRGBImage converts a gray image to RGB by filling all three channels with the gray intensity * @param grayImage * @return */ mitk::Image::Pointer ConvertToRGBImage(mitk::Image::Pointer grayImage) { mitk::Image::Pointer rgbImage = mitk::Image::New(); unsigned int *dim = grayImage->GetDimensions(); rgbImage->Initialize(mitk::MakePixelType(), 3, dim); rgbImage->SetGeometry(grayImage->GetGeometry()); itk::Image::Pointer itkGrayImage = itk::Image::New(); mitk::CastToItkImage(grayImage, itkGrayImage); mitk::ImagePixelWriteAccessor writeAcc(rgbImage); typedef itk::RescaleIntensityImageFilter, itk::Image> RescaleFilterType; RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New(); rescaleFilter->SetInput(itkGrayImage); rescaleFilter->SetOutputMinimum(0); rescaleFilter->SetOutputMaximum(255 * 255); rescaleFilter->Update(); itk::Index<3> idx; RGBPixelType value; // Fill rgb image with gray values for (idx[2] = 0; (unsigned int)idx[2] < dim[2]; idx[2]++) { for (idx[1] = 0; (unsigned int)idx[1] < dim[1]; idx[1]++) { for (idx[0] = 0; (unsigned int)idx[0] < dim[0]; idx[0]++) { value.Fill(rescaleFilter->GetOutput()->GetPixel(idx)); writeAcc.SetPixelByIndex(idx, value); } } } return rgbImage; } RGB2DImage::Pointer TextAsImage(std::string text) { vtkSmartPointer textImage = vtkSmartPointer::New(); vtkSmartPointer freetype = vtkSmartPointer::New(); vtkSmartPointer prop = vtkSmartPointer::New(); float color[3] = {1, 1, 1}; float opacity = 1.0; prop->SetColor(color[0], color[1], color[2]); prop->SetFontSize(40); prop->SetOpacity(opacity); textImage->AllocateScalars(VTK_UNSIGNED_SHORT, 3); freetype->RenderString(prop, vtkUnicodeString::from_utf8(text.c_str()), 72, textImage); textImage->Modified(); int *extent = textImage->GetExtent(); RGB2DImage::Pointer itkImage = RGB2DImage::New(); RGB2DImage::IndexType start; start.Fill(0); RGB2DImage::SizeType size; size[0] = extent[1]; size[1] = extent[3]; size[2] = 0; RGB2DImage::RegionType region(start, size); itkImage->SetRegions(region); itkImage->Allocate(); RGB2DImage::IndexType idx; for (unsigned int y = 0; y < size[1]; y++) { for (unsigned int x = 0; x < size[0]; x++) { PixelType *pixel = static_cast(textImage->GetScalarPointer(x, y, 0)); RGBPixelType values; values.Fill(0); values[0] = pixel[1]; values[1] = pixel[1]; values[2] = pixel[1]; idx.Fill(0); idx[0] = x; idx[1] = y; itkImage->SetPixel(idx, values); } } typedef itk::PermuteAxesImageFilter PermuteAxesImageFilterType; itk::FixedArray order; order[0] = 1; order[1] = 0; PermuteAxesImageFilterType::Pointer permuteAxesFilter = PermuteAxesImageFilterType::New(); permuteAxesFilter->SetInput(itkImage); permuteAxesFilter->SetOrder(order); permuteAxesFilter->Update(); RGB2DImage::Pointer itkResultImage = RGB2DImage::New(); itkResultImage->SetRegions(region); itkResultImage->Allocate(); itkResultImage->Graft(permuteAxesFilter->GetOutput()); return itkResultImage; } /** * @brief AddColouredOverlay - Overlays the rgbImage with an coloured overlay * * For all positions in overlayImage not zero, its value is multiplied the the colour value and added * to the rgbImage. * * @param rgbImage - input rgbImage to which the coloured overlay is added * @param overlayImage * @param color */ void AddColouredOverlay(mitk::Image::Pointer rgbImage, mitk::Image::Pointer overlayImage, mitk::Color color) { unsigned int *dim = rgbImage->GetDimensions(); itk::Image::Pointer itkOverlayImage = itk::Image::New(); mitk::CastToItkImage(overlayImage.GetPointer(), itkOverlayImage); mitk::ImagePixelWriteAccessor writeAcc(rgbImage); itk::Index<3> idx; itk::RGBPixel value; unsigned short overlayVal = 0; // Fill rgb image with gray values for (idx[2] = 0; (unsigned int)idx[2] < dim[2]; idx[2]++) { for (idx[1] = 0; (unsigned int)idx[1] < dim[1]; idx[1]++) { for (idx[0] = 0; (unsigned int)idx[0] < dim[0]; idx[0]++) { overlayVal = 255 * itkOverlayImage->GetPixel(idx); value = writeAcc.GetPixelByIndex(idx); value[0] = std::min((int)(value[0] + overlayVal * color[0]), 254 * 255); value[1] = std::min((int)(value[1] + overlayVal * color[1]), 254 * 255); value[2] = std::min((int)(value[2] + overlayVal * color[2]), 254 * 255); writeAcc.SetPixelByIndex(idx, value); } } } } itk::Image, 2>::Pointer ExtractSlice( itk::Image, 3>::Pointer itkImage, unsigned int sliceNo) { typedef itk::Image InputImageType; typedef itk::Image OutputImageType; int dim[3]; dim[0] = itkImage->GetLargestPossibleRegion().GetSize()[0]; dim[1] = itkImage->GetLargestPossibleRegion().GetSize()[1]; dim[2] = itkImage->GetLargestPossibleRegion().GetSize()[2]; itk::Index<3> desiredStart; itk::Size<3> desiredSize; // case AXIAL: // 3rd dimension fixed desiredStart.Fill(0); desiredStart[2] = sliceNo; desiredSize.Fill(0); desiredSize[0] = dim[0]; desiredSize[1] = dim[1]; desiredSize[2] = 0; itk::ImageRegion<3> desiredRegion(desiredStart, desiredSize); // Extract slice itk::ExtractImageFilter::Pointer extractSlice = itk::ExtractImageFilter::New(); extractSlice->SetInput(itkImage); extractSlice->SetExtractionRegion(desiredRegion); extractSlice->SetDirectionCollapseToIdentity(); extractSlice->Update(); return extractSlice->GetOutput(); } }; static std::string GetName(std::string fileName, std::string suffix = "_T2.nrrd") { fileName = itksys::SystemTools::GetFilenameName(fileName); return fileName.substr(0, fileName.length() - suffix.length() - 11); // 10 = date length } static std::string GetDate(std::string fileName, std::string suffix = "_T2.nrrd") { fileName = itksys::SystemTools::GetFilenameName(fileName); fileName = fileName.substr(fileName.length() - suffix.length() - 10, 10); // 10 = date length return fileName; } static ImageList LoadPreprocessedFiles(FileList files) { ImageList images; for (unsigned int i = 0; i < files.size(); ++i) { - images.push_back(dynamic_cast(mitk::IOUtil::Load(files.at(i))[0].GetPointer())); + images.push_back(mitk::IOUtil::Load(files.at(i))); } return images; } int main(int argc, char *argv[]) { // Parse Command-Line Arguments mitkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); parser.setTitle("Tumor Progression Mapping"); parser.setCategory("Preprocessing Tools"); parser.setContributor("MBI"); parser.setDescription("Convert a set of co-registered and resampled follow-up images into a 2D png overview (and " "optionally in a 4D NRRD Volume).\nNaming convecntion of files is " "IDENTIFIER_YYYY-MM-DD_MODALITY.nrrd"); parser.setArgumentPrefix("--", "-"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input folder containing all follow ups"); parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output file (PNG)"); parser.addArgument("blanked", "b", mitkCommandLineParser::Bool, "Only Display Morphology"); parser.addArgument("morphology", "m", mitkCommandLineParser::String, "Morphology postfix.", "_T2.nrrd"); parser.addArgument( "segmentation", "s", mitkCommandLineParser::String, "Segmentation postfix. Default: _GTV.nrrd", "_GTV.nrrd"); parser.addArgument("4dVolume", "v", mitkCommandLineParser::OutputFile, "Filepath to merged 4d NRRD Volume."); parser.addArgument( "skip", "k", mitkCommandLineParser::Int, "Number of slices to be skipped from top and from button (Default 0)"); parser.addArgument( "interval", "n", mitkCommandLineParser::Int, "1 - for all slices, 2 - every second, 3 - every third ..."); parser.addArgument("opacity", "c", mitkCommandLineParser::Float, "Opacity of overlay [0,1] invisible -> visible"); map parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size() == 0) return EXIT_SUCCESS; // Show a help message if (parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string outputFile; std::string inputFolder; if (parsedArgs.count("input") || parsedArgs.count("i")) { inputFolder = us::any_cast(parsedArgs["input"]) + "/"; } if (parsedArgs.count("output") || parsedArgs.count("o")) { outputFile = us::any_cast(parsedArgs["output"]); } int skip = 0; int interval = 1; float opacity = .3; if (parsedArgs.count("skip") || parsedArgs.count("k")) { skip = us::any_cast(parsedArgs["skip"]); } if (parsedArgs.count("interval") || parsedArgs.count("n")) { interval = us::any_cast(parsedArgs["interval"]); } if (parsedArgs.count("opacity") || parsedArgs.count("c")) { opacity = us::any_cast(parsedArgs["opacity"]); } FileList morphFiles; FileList segFiles; std::string refPattern; std::string segPattern; if (parsedArgs.count("morphology") || parsedArgs.count("m")) { refPattern = us::any_cast(parsedArgs["morphology"]); } else return EXIT_FAILURE; if (parsedArgs.count("segmentation") || parsedArgs.count("s")) { segPattern = us::any_cast(parsedArgs["segmentation"]); } bool blank = false; if (parsedArgs.count("blanked") || parsedArgs.count("b")) { blank = true; } /// END Parsing CL Options typedef itk::Image OutputImageType; typedef itk::Image InputImageType; mitkProgressionVisualization progressVis; morphFiles = CreateFileList(inputFolder, refPattern); segFiles = CreateFileList(inputFolder, segPattern); ImageList morphImages = LoadPreprocessedFiles(morphFiles); ImageList segImages; if (segFiles.size() > 0 && blank == false) segImages = LoadPreprocessedFiles(segFiles); mitk::Image::Pointer rgbImage; // define color for overlay image mitk::Color color; color.Fill(0); color[0] = 200 * opacity; color[1] = 0; // Set up itk time image filter to contain 0..N-1 images itk::TileImageFilter::Pointer tileFilter = itk::TileImageFilter::New(); itk::FixedArray layout; unsigned int noOfTimeSteps = morphImages.size(); layout[0] = noOfTimeSteps; layout[1] = 0; // automatic number of neccessary rows tileFilter->SetLayout(layout); // Get Reference image (all images are expected to have exact same dimensions!) std::string fileName = morphFiles.at(0); mitk::Image *referenceImg = morphImages.at(0); mitk::Image::Pointer merged4D; std::string volumeFile; if (parsedArgs.count("4dVolume") || parsedArgs.count("v")) { volumeFile = us::any_cast(parsedArgs["4dVolume"]); if (volumeFile != "") { unsigned int *dims = new unsigned int[4]; dims[0] = referenceImg->GetDimensions()[0]; dims[1] = referenceImg->GetDimensions()[1]; dims[2] = referenceImg->GetDimensions()[2]; dims[3] = morphImages.size(); merged4D = mitk::Image::New(); merged4D->Initialize(referenceImg->GetPixelType(), 4, dims); merged4D->GetTimeGeometry()->Expand(noOfTimeSteps); } } unsigned int *dim = referenceImg->GetDimensions(); unsigned int sliceMaxAxial = dim[2]; // Now iterate over all data sets, extract overlay and add it to reference image mitk::Image *morphImage; mitk::Image *segmentationImage = nullptr; for (unsigned int i = 0; i < noOfTimeSteps; i++) { MITK_INFO << "File : " << i << " of /" << noOfTimeSteps; int currentSliceNo = 0; // Retrieve images of current time step fileName = morphFiles.at(i); morphImage = morphImages.at(i); // Create 4D Volume image if (volumeFile != "") { mitk::ImagePixelReadAccessor readAc(morphImage); merged4D->GetGeometry(i)->SetSpacing(referenceImg->GetGeometry()->GetSpacing()); merged4D->GetGeometry(i)->SetOrigin(referenceImg->GetGeometry()->GetOrigin()); merged4D->GetGeometry(i)->SetIndexToWorldTransform(referenceImg->GetGeometry()->GetIndexToWorldTransform()); merged4D->SetVolume(readAc.GetData(), i); } MITK_INFO << "-- Convert to RGB"; rgbImage = progressVis.ConvertToRGBImage(morphImage); // Add current seg in red color.Fill(0); color[0] = 200 * opacity; if (!blank) { segmentationImage = segImages.at(i); if (segmentationImage != nullptr) { MITK_INFO << "-- Add Overlay"; progressVis.AddColouredOverlay(rgbImage, segmentationImage, color); } } // Add Segmentation of next time step in red if (i == 0) { MITK_INFO << "Skipping retro view in first time step"; } else { color.Fill(0); // Add previous in green color[1] = 200 * opacity; if (!blank) { mitk::Image *nextSeg = segImages.at(i - 1); MITK_INFO << "-- Add Overlay of next Step"; progressVis.AddColouredOverlay(rgbImage, nextSeg, color); } } // Now save all slices from overlay in output folder MITK_INFO << "-- Extract Slices"; for (int slice = sliceMaxAxial - skip - 1; slice > skip; slice -= interval) // sliceMaxAxial/40.0f)) { InputImageType::Pointer itkImage = InputImageType::New(); InputImageType::Pointer itkImage2; mitk::CastToItkImage(rgbImage, itkImage); typedef itk::ImageDuplicator DuplicatorType; DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage(itkImage); duplicator->Update(); itkImage2 = duplicator->GetOutput(); itk::Image::Pointer extractedSlice = itk::Image::New(); extractedSlice->Graft(progressVis.ExtractSlice(itkImage2, slice)); tileFilter->SetInput(((currentSliceNo + 1) * (noOfTimeSteps) + i), extractedSlice); tileFilter->SetInput(i, progressVis.TextAsImage(GetDate(fileName))); currentSliceNo++; } } MITK_INFO << "Tile Filter Update"; tileFilter->Update(); // Write the output image typedef itk::ImageFileWriter WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetInput(tileFilter->GetOutput()); std::string patientName; patientName = GetName(fileName); if (blank) writer->SetFileName(outputFile); else writer->SetFileName(outputFile); writer->Update(); if (volumeFile != "") mitk::IOUtil::Save(merged4D, volumeFile); return EXIT_SUCCESS; } diff --git a/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp b/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp index ee6291fcfd..b9cc4e29b3 100644 --- a/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp +++ b/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp @@ -1,406 +1,406 @@ /*=================================================================== 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. ===================================================================*/ #ifdef _MSC_VER # pragma warning (disable : 4996) #endif #include "mitkDiffusionCollectionReader.h" #include #include #include #include #include //XML StateMachine Tags // Objects const std::string COLLECTION = "col"; const std::string SUBCOLLECTION = "subcol"; const std::string DATA = "data"; const std::string ITEM = "item"; // Properties const std::string NAME = "name"; const std::string ID = "id"; const std::string FILEPATH = "description"; const std::string LINK = "link"; static std::string GetName(std::string fileName,std::string suffix) { fileName = QFileInfo(QString::fromStdString(fileName)).fileName().toStdString(); return fileName.substr(0,fileName.length() -suffix.length()-9); // 8 = date length } static std::string GetDate(std::string fileName,std::string suffix) { fileName = QFileInfo(QString::fromStdString(fileName)).fileName().toStdString(); fileName = fileName.substr(fileName.length() - suffix.length()-8,8); // 8 = date length fileName.insert(6,"-"); fileName.insert(4,"-"); return fileName; } mitk::DiffusionCollectionReader::DiffusionCollectionReader() : m_Collection(nullptr), m_SubCollection(nullptr), m_DataItemCollection(nullptr), m_ColIgnore(false), m_ItemIgnore(false) { } mitk::DiffusionCollectionReader::~DiffusionCollectionReader() { this->Clear(); } /** * @brief Loads the xml file filename and generates the necessary instances. **/ mitk::DataCollection::Pointer mitk::DiffusionCollectionReader::LoadCollection(const std::string& xmlFileName) { QDir fileName = QFileInfo(xmlFileName.c_str()).absoluteDir(); m_BaseDir = fileName.path().toStdString() + QDir::separator().toLatin1(); this->SetFileName(xmlFileName.c_str()); this->Parse(); if (m_Collection.IsNotNull()) m_Collection->SetXMLFile(xmlFileName); return m_Collection; } void mitk::DiffusionCollectionReader::AddDataElementIds(std::vector dataElemetIds) { m_SelectedDataItemIds.insert( m_SelectedDataItemIds.end(), dataElemetIds.begin(), dataElemetIds.end() ); } void mitk::DiffusionCollectionReader::AddSubColIds(std::vector subColIds) { m_SelectedSubColIds.insert( m_SelectedSubColIds.end(), subColIds.begin(), subColIds.end() ); } void mitk::DiffusionCollectionReader::SetDataItemNames(std::vector itemNames) { m_SelectedDataItemNames = itemNames; } void mitk::DiffusionCollectionReader::ClearDataElementIds() { m_SelectedDataItemIds.clear(); } void mitk::DiffusionCollectionReader::ClearSubColIds() { m_SelectedSubColIds.clear(); } void mitk::DiffusionCollectionReader::Clear() { m_DataItemCollection = nullptr; m_SubCollection = nullptr; m_Collection = nullptr; } mitk::DataCollection::Pointer mitk::DiffusionCollectionReader::FolderToCollection(std::string folder, std::vector suffixes,std::vector seriesNames, bool allowGaps) { // Parse folder and look up all data, // after sanitation only fully available groups are included (that is all suffixes are found) FileListType fileList = SanitizeFileList(GenerateFileLists(folder, suffixes, allowGaps)); if (fileList.size() <= 0) return nullptr; DataCollection::Pointer collection = DataCollection::New(); collection->SetName(GetName(fileList.at(0).at(0),suffixes.at(0))); for (unsigned int k=0; k < fileList.at(0).size(); ++k) // all groups have the same amount of items, so looking at 0 is ok. { DataCollection::Pointer subCollection = DataCollection::New(); for (unsigned int i=0; i< suffixes.size(); ++i) { std::string fileName = fileList.at(i).at(k); if (fileName.find(".fib") >= fileName.length()) { - Image::Pointer image = dynamic_cast(IOUtil::Load(fileList.at(i).at(k))[0].GetPointer()); + auto image = IOUtil::Load(fileList.at(i).at(k)); subCollection->AddData(image.GetPointer(),seriesNames.at(i), fileList.at(i).at(k)); } else { subCollection->AddData(mitk::IOUtil::Load(fileName).at(0).GetPointer(),seriesNames.at(i), fileList.at(i).at(k)); } } std::string sDate = GetDate(fileList.at(0).at(k),suffixes.at(0)); collection->AddData(subCollection.GetPointer(),sDate,"--"); } return collection; } void mitk::DiffusionCollectionReader::StartElement(const char* elementName, const char **atts) { std::string name(elementName); if (name == COLLECTION) { m_Collection = DataCollection::New(); std::string colName = ReadXMLStringAttribut(NAME, atts); m_Collection->SetName(colName); } else if (name == SUBCOLLECTION) { m_ColIgnore = false; m_ItemIgnore = false; std::string subColName = ReadXMLStringAttribut(NAME, atts); std::string subColId = ReadXMLStringAttribut(ID, atts); if (m_SelectedSubColIds.size() > 0 && std::find(m_SelectedSubColIds.begin(), m_SelectedSubColIds.end(), subColId) == m_SelectedSubColIds.end() ) { // a) a selection list is provided AND b) the item is not in the list m_ColIgnore = true; return; } // Create subcollection m_SubCollection = DataCollection::New(); m_SubCollection->Init(subColName); } else if (name == DATA) { if (m_ColIgnore) return; std::string dataId = ReadXMLStringAttribut(ID, atts); if (m_SelectedDataItemIds.size() > 0 && std::find(m_SelectedDataItemIds.begin(), m_SelectedDataItemIds.end(), dataId) == m_SelectedDataItemIds.end() ) { // a) a selection list is provided AND b) the item is not in the list m_ItemIgnore = true; return; } m_ItemIgnore = false; std::string dataName = ReadXMLStringAttribut(NAME, atts); m_DataItemCollection = DataCollection::New(); m_DataItemCollection->Init(dataName); } else if (name == ITEM) { if (m_ColIgnore || m_ItemIgnore) return; std::string relativeItemLink = ReadXMLStringAttribut(LINK, atts); std::string itemLink = m_BaseDir + relativeItemLink; std::string itemName = ReadXMLStringAttribut(NAME, atts); // if item names are provided and name is not in list, do not load it if (m_SelectedDataItemNames.size() != 0 && std::find(m_SelectedDataItemNames.begin(), m_SelectedDataItemNames.end(), itemName) == m_SelectedDataItemNames.end() ) return; // Populate Sub-Collection if (itemLink.find(".fib") >= itemLink.length()) { - Image::Pointer image = dynamic_cast(IOUtil::Load(itemLink)[0].GetPointer()); + auto image = IOUtil::Load(itemLink); if (image.IsNotNull()) m_DataItemCollection->AddData(image.GetPointer(),itemName,relativeItemLink); else MITK_ERROR << "File could not be loaded: " << itemLink << ". Wihtin Sub-Collection " << m_SubCollection->GetName() << ", within " << m_DataItemCollection->GetName() ; } else m_DataItemCollection->AddData(mitk::IOUtil::Load(itemLink).at(0).GetPointer(),itemName, relativeItemLink); } else MITK_WARN<< "Malformed description ? -- unknown tag: " << name; } void mitk::DiffusionCollectionReader::EndElement(const char* elementName) { std::string name(elementName); if (name == SUBCOLLECTION) { if (m_SubCollection.IsNull()) return; if (m_ColIgnore || m_SubCollection->Size() == 0) return; m_Collection->AddData(m_SubCollection.GetPointer(),m_SubCollection->GetName()); m_SubCollection = DataCollection::New(); } if (name == DATA) { if (m_DataItemCollection.IsNull()) return; if (m_DataItemCollection->Size() == 0) return; m_SubCollection->AddData(m_DataItemCollection.GetPointer(),m_DataItemCollection->GetName()); m_DataItemCollection = DataCollection::New(); } } std::string mitk::DiffusionCollectionReader::ReadXMLStringAttribut(std::string name, const char** atts) { if (atts) { const char** attsIter = atts; while (*attsIter) { if (name == *attsIter) { attsIter++; return *attsIter; } attsIter++; attsIter++; } } return std::string(); } bool mitk::DiffusionCollectionReader::ReadXMLBooleanAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); std::transform(s.begin(), s.end(), s.begin(), ::toupper); if (s == "TRUE") return true; else return false; } int mitk::DiffusionCollectionReader::ReadXMLIntegerAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); return atoi(s.c_str()); } mitk::DiffusionCollectionReader::FileListType mitk::DiffusionCollectionReader::GenerateFileLists(std::string folder, std::vector suffixes, bool allowGaps) { FileListType fileList; QString qFolder = QString::fromStdString(folder); if (!QFileInfo(qFolder).isDir()) { MITK_ERROR << "Folder does not exist."; return fileList; } // Add vector for each suffix for (unsigned int i=0; i< suffixes.size(); ++i) { std::vector list; fileList.push_back(list); } // if gaps are allowed, file names are build up from reference file (first suffix) // else all lists a file, file by file with regular sorting of the files, // if one suffix has more/less images than the others loading is aborted if (allowGaps) { QDir parseDir; parseDir.setFilter(QDir::Files); parseDir.setPath(qFolder); QStringList filterMorph; filterMorph << "*" + QString::fromStdString( suffixes.at(0) ); parseDir.setNameFilters( filterMorph ); QFileInfoList qFileList = parseDir.entryInfoList(); // now populate lists with files names, non-existing files will be marked with an empty string for (int i = 0; i < qFileList.size(); ++i) { std::string baseFileName = qFileList.at(i).absoluteFilePath().toStdString(); fileList.at(0).push_back( baseFileName ); //check for different suffixes for (unsigned int suffNo=1; suffNo < suffixes.size(); ++suffNo) { std::string derivedFileName = baseFileName.substr(0,baseFileName.length() -suffixes.at(0).length()) + suffixes.at(suffNo); // checking if file exists if (QFileInfo(QString::fromStdString(derivedFileName)).isFile()) fileList.at(suffNo).push_back(derivedFileName); else fileList.at(suffNo).push_back(""); } } } else { int numberOfFiles=-1; for (unsigned int i=0; i< suffixes.size(); ++i) { QDir parseDir; parseDir.setFilter(QDir::Files); parseDir.setPath(qFolder); QStringList filterMorph; filterMorph << "*" + QString::fromStdString( suffixes.at(i) ); parseDir.setNameFilters( filterMorph ); QFileInfoList qFileList = parseDir.entryInfoList(); if (numberOfFiles == -1) numberOfFiles = qFileList.size(); if (numberOfFiles != qFileList.size() ) { MITK_ERROR << "Series contain different number of images. Loading aborting."; fileList.clear(); break; } for (int fileNo=0; fileNo indexRemoval; // Parse through all items and check for empty strings, if one occurs mark this index // for removal. int modalities = list.size(); int timeSteps = list.at(0).size(); MITK_INFO << "Modalities " << modalities; MITK_INFO << "TimeSteps " << timeSteps; if (timeSteps == 0) MITK_ERROR << "No files found. Fatal."; for (int listIndex = 0 ; listIndex < timeSteps; listIndex++) { for (int modalityIndex = 0 ; modalityIndex < modalities; modalityIndex++) { if (list.at(modalityIndex).at(listIndex) == "") { MITK_INFO << "Marked Index " << listIndex << " for removal."; indexRemoval.push_back(listIndex); break; } } } for (int listIndex = indexRemoval.size()-1 ; listIndex >= 0; --listIndex) { for (int i = 0 ; i < modalities; i++) { list.at(i).erase(list.at(i).begin()+indexRemoval.at(listIndex)) ; } } MITK_INFO << "Time Steps after sanitizing: " << list.at(0).size(); return list; } diff --git a/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp b/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp index b0a498b96d..369394315e 100644 --- a/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp +++ b/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp @@ -1,109 +1,109 @@ /*=================================================================== 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. ===================================================================*/ #ifdef _MSC_VER # pragma warning(disable : 4996) #endif #include "mitkTestFixture.h" #include "mitkTestingMacros.h" #include "mitkCompareImageDataFilter.h" #include "mitkIOUtil.h" #include "mitkDataCollection.h" #include "mitkTumorInvasionClassification.h" #include "mitkDiffusionCollectionReader.h" #include "mitkDiffusionCollectionWriter.h" #include /** * @brief mitkClassificationTestSuite * * Tests mitkDecisionForest, mitkClassifyProgression, mitkDataCollection, mitkDiffusionCollectionReader * \warn Reference is compared to results computed based on random forests, which might be a source of random test fails * such sporadic fails do represent total fails, as the result is no longer consitently under the provided margin. * */ class mitkClassificationTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkClassificationTestSuite); MITK_TEST(TestClassification); CPPUNIT_TEST_SUITE_END(); public: /** * @brief Setup - Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override {} void tearDown() override {} void TestClassification() { size_t forestSize = 10; size_t treeDepth = 2; std::string train = GetTestDataFilePath("DiffusionImaging/ProgressionAnalysis/Classification/Train.xml"); std::string eval = GetTestDataFilePath("DiffusionImaging/ProgressionAnalysis/Classification/Test.xml"); std::vector modalities; modalities.push_back("MOD0"); modalities.push_back("MOD1"); mitk::DiffusionCollectionReader colReader; mitk::DataCollection::Pointer collection = colReader.LoadCollection(train); colReader.Clear(); // read evaluation collection mitk::DataCollection::Pointer evaluation = colReader.LoadCollection(eval); mitk::TumorInvasionClassification progression; progression.SetClassRatio(1); progression.SetTrainMargin(4, 0); progression.SetMaskID("MASK"); progression.SelectTrainingSamples(collection); progression.LearnProgressionFeatures(collection, modalities, forestSize, treeDepth); progression.PredictInvasion(evaluation, modalities); - mitk::Image::Pointer refImage = dynamic_cast(mitk::IOUtil::Load( - GetTestDataFilePath("DiffusionImaging/ProgressionAnalysis/Classification/TESTING_RESULT.nrrd"))[0].GetPointer()); + auto refImage = mitk::IOUtil::Load( + GetTestDataFilePath("DiffusionImaging/ProgressionAnalysis/Classification/TESTING_RESULT.nrrd")); mitk::DataCollection *patCol = dynamic_cast(evaluation->GetData(0).GetPointer()); mitk::DataCollection *subCol = dynamic_cast(patCol->GetData(0).GetPointer()); mitk::Image::Pointer resultImage = subCol->GetMitkImage("RESULT"); // Test result against fixed reference. // Require more than 90% to be correct. // 10% margin due to // 1) unsure classification in transitional regions and // 2) stochastic training procedure // Total number of voxels 2400 -> 10% err -> 240 voxels margin mitk::CompareImageDataFilter::Pointer compareFilter = mitk::CompareImageDataFilter::New(); compareFilter->SetInput(0, refImage.GetPointer()); compareFilter->SetInput(1, resultImage); compareFilter->SetTolerance(.1); compareFilter->Update(); MITK_TEST_CONDITION_REQUIRED(compareFilter->GetResult(240), "Compare prediction results to reference image.") } }; MITK_TEST_SUITE_REGISTRATION(mitkClassification) diff --git a/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp b/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp index 9a92f8d511..eceb9306dc 100644 --- a/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp +++ b/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp @@ -1,212 +1,212 @@ /*=================================================================== 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 "mitkUSImageLoggingFilter.h" #include #include #include #include #include #include #include #include "mitkImageGenerator.h" #include "itksys/SystemTools.hxx" #include "Poco/File.h" class mitkUSImageLoggingFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkUSImageLoggingFilterTestSuite); MITK_TEST(TestInstantiation); MITK_TEST(TestSetFileExtension); MITK_TEST(TestSetWrongFileExtension); MITK_TEST(TestSavingValidTestImage); MITK_TEST(TestSavingAfterMupltipleUpdateCalls); MITK_TEST(TestFilterWithEmptyImages); MITK_TEST(TestFilterWithInvalidPath); //MITK_TEST(TestJpgFileExtension); //bug 19614 CPPUNIT_TEST_SUITE_END(); private: mitk::USImageLoggingFilter::Pointer m_TestFilter; std::string m_TemporaryTestDirectory; mitk::Image::Pointer m_RandomRestImage1; mitk::Image::Pointer m_RandomRestImage2; mitk::Image::Pointer m_RandomSingleSliceImage; mitk::Image::Pointer m_RealTestImage; public: void setUp() override { m_TestFilter = mitk::USImageLoggingFilter::New(); m_TemporaryTestDirectory = mitk::IOUtil::GetTempPath(); m_RandomRestImage1 = mitk::ImageGenerator::GenerateRandomImage(100, 100, 100, 1, 0.2, 0.3, 0.4); m_RandomRestImage2 = mitk::ImageGenerator::GenerateRandomImage(100, 100, 100, 1, 0.2, 0.3, 0.4); m_RandomSingleSliceImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 0.2, 0.3, 0.4); - m_RealTestImage = dynamic_cast(mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd"))[0].GetPointer()); + m_RealTestImage = mitk::IOUtil::Load(GetTestDataFilePath("Pic3D.nrrd")); } void tearDown() override { m_TestFilter = nullptr; m_RandomRestImage1 = nullptr; m_RandomRestImage2 = nullptr; m_RealTestImage = nullptr; m_RandomSingleSliceImage = nullptr; } void TestInstantiation() { CPPUNIT_ASSERT_MESSAGE("Testing instantiation",m_TestFilter.IsNotNull()); } void TestSavingValidTestImage() { //######################## Test with valid test images ################################ m_TestFilter->SetInput(m_RandomRestImage1); m_TestFilter->SetInput("secondImage",m_RandomRestImage2); m_TestFilter->Update(); MITK_TEST_OUTPUT(<<"Tested method Update() with valid data."); std::vector filenames; std::string csvFileName; m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName); MITK_TEST_OUTPUT(<<"Tested method SaveImages(...)."); CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 1); CPPUNIT_ASSERT_MESSAGE("Testing if image file exists",Poco::File(filenames.at(0).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists()); //clean up std::remove(filenames.at(0).c_str()); std::remove(csvFileName.c_str()); } void TestSavingAfterMupltipleUpdateCalls() { //######################## Test multiple calls of update ################################ m_TestFilter->SetInput(m_RandomRestImage1); m_TestFilter->SetInput("secondImage",m_RandomRestImage2); for(int i=0; i<5; i++) { m_TestFilter->Update(); std::stringstream testmessage; testmessage << "testmessage" << i; m_TestFilter->AddMessageToCurrentImage(testmessage.str()); itksys::SystemTools::Delay(50); } MITK_TEST_OUTPUT(<<"Call Update() 5 times."); std::vector filenames; std::string csvFileName; m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName); MITK_TEST_OUTPUT(<<"Tested method SaveImages(...)."); CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 5); CPPUNIT_ASSERT_MESSAGE("Testing if file 1 exists",Poco::File(filenames.at(0).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 2 exists",Poco::File(filenames.at(1).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 3 exists",Poco::File(filenames.at(2).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 4 exists",Poco::File(filenames.at(3).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if file 5 exists",Poco::File(filenames.at(4).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists()); //clean up for(size_t i=0; iSetInput(testImage); CPPUNIT_ASSERT_MESSAGE("Testing SetInput(...) for first input.",m_TestFilter->GetNumberOfInputs()==1); m_TestFilter->SetInput("secondImage",testImage2); CPPUNIT_ASSERT_MESSAGE("Testing SetInput(...) for second input.",m_TestFilter->GetNumberOfInputs()==2); //images are empty, but update method should not crash CPPUNIT_ASSERT_NO_THROW_MESSAGE("Tested method Update() with invalid data.",m_TestFilter->Update()); } void TestFilterWithInvalidPath() { #ifdef WIN32 std::string filename = "XV:/342INVALID<>"; //invalid filename for windows #else std::string filename = "/dsfdsf:$�$342INVALID"; //invalid filename for linux #endif m_TestFilter->SetInput(m_RealTestImage); m_TestFilter->Update(); CPPUNIT_ASSERT_THROW_MESSAGE("Testing if correct exception if thrown if an invalid path is given.", m_TestFilter->SaveImages(filename), mitk::Exception); } void TestJpgFileExtension() { CPPUNIT_ASSERT_MESSAGE("Testing setting of jpg extension.",m_TestFilter->SetImageFilesExtension(".jpg")); m_TestFilter->SetInput(m_RandomSingleSliceImage); m_TestFilter->Update(); std::vector filenames; std::string csvFileName; m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName); CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 1); CPPUNIT_ASSERT_MESSAGE("Testing if jpg image file exists",Poco::File(filenames.at(0).c_str()).exists()); CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists()); //clean up std::remove(filenames.at(0).c_str()); std::remove(csvFileName.c_str()); } void TestSetFileExtension() { CPPUNIT_ASSERT_MESSAGE("Testing if PIC extension can be set.",m_TestFilter->SetImageFilesExtension("PIC")); CPPUNIT_ASSERT_MESSAGE("Testing if bmp extension can be set.",m_TestFilter->SetImageFilesExtension("bmp")); CPPUNIT_ASSERT_MESSAGE("Testing if gdc extension can be set.",m_TestFilter->SetImageFilesExtension("gdcm")); CPPUNIT_ASSERT_MESSAGE("Testing if dcm extension can be set.",m_TestFilter->SetImageFilesExtension("dcm")); CPPUNIT_ASSERT_MESSAGE("Testing if dc3 extension can be set.",m_TestFilter->SetImageFilesExtension("dc3")); CPPUNIT_ASSERT_MESSAGE("Testing if ima extension can be set.",m_TestFilter->SetImageFilesExtension(".ima")); CPPUNIT_ASSERT_MESSAGE("Testing if img extension can be set.",m_TestFilter->SetImageFilesExtension("img")); CPPUNIT_ASSERT_MESSAGE("Testing if gip extension can be set.",m_TestFilter->SetImageFilesExtension("gipl")); CPPUNIT_ASSERT_MESSAGE("Testing if gipl.gz extension can be set.",m_TestFilter->SetImageFilesExtension(".gipl.gz")); CPPUNIT_ASSERT_MESSAGE("Testing if jpg extension can be set.",m_TestFilter->SetImageFilesExtension("jpg")); CPPUNIT_ASSERT_MESSAGE("Testing if jpe extension can be set.",m_TestFilter->SetImageFilesExtension("jpeg")); CPPUNIT_ASSERT_MESSAGE("Testing if pic extension can be set.",m_TestFilter->SetImageFilesExtension("pic")); } void TestSetWrongFileExtension() { CPPUNIT_ASSERT_MESSAGE("Testing if wrong obj extension is recognized",!m_TestFilter->SetImageFilesExtension("obj ")); CPPUNIT_ASSERT_MESSAGE("Testing if wrong stl extension is recognized",!m_TestFilter->SetImageFilesExtension("stl ")); CPPUNIT_ASSERT_MESSAGE("Testing if wrong pvtp extension is recognized",!m_TestFilter->SetImageFilesExtension("pvtp")); CPPUNIT_ASSERT_MESSAGE("Testing if wrong vtp extension is recognized",!m_TestFilter->SetImageFilesExtension("vtp ")); CPPUNIT_ASSERT_MESSAGE("Testing if wrong vtk extension is recognized",!m_TestFilter->SetImageFilesExtension("vtk ")); } }; MITK_TEST_SUITE_REGISTRATION(mitkUSImageLoggingFilter) diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp index 549ce8ef16..789a181a45 100644 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp +++ b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp @@ -1,931 +1,931 @@ /*=================================================================== 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. ===================================================================*/ // std dependencies #include #include #include // mitk dependencies #include "mitkUSDiPhASDevice.h" #include "mitkUSDiPhASImageSource.h" #include #include "mitkUSDiPhASBModeImageFilter.h" #include "ITKUltrasound/itkBModeImageFilter.h" #include "mitkImageCast.h" #include "mitkITKImageImport.h" // itk dependencies #include "itkImage.h" #include "itkResampleImageFilter.h" #include "itkCastImageFilter.h" #include "itkCropImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkIntensityWindowingImageFilter.h" #include #include "itkMultiplyImageFilter.h" mitk::USDiPhASImageSource::USDiPhASImageSource(mitk::USDiPhASDevice* device) : m_Device(device), m_StartTime(((float)std::clock()) / CLOCKS_PER_SEC), m_UseGUIOutPut(false), m_DataType(DataType::Image_uChar), m_GUIOutput(nullptr), m_UseBModeFilter(false), m_CurrentlyRecording(false), m_DataTypeModified(true), m_DataTypeNext(DataType::Image_uChar), m_CurrentImageTimestamp(0), m_PyroConnected(false), m_ImageTimestampBuffer(), m_VerticalSpacing(0), m_UseBModeFilterModified(false), m_UseBModeFilterNext(false), m_ScatteringCoefficientModified(false), m_CompensateForScatteringModified(false), m_VerticalSpacingModified(false), m_ScatteringCoefficient(15), m_CompensateForScattering(false), m_CompensateEnergy(false), m_CompensateEnergyNext(false), m_CompensateEnergyModified(false) { m_BufferSize = 100; m_ImageTimestampBuffer.insert(m_ImageTimestampBuffer.begin(), m_BufferSize, 0); m_LastWrittenImage = m_BufferSize - 1; m_ImageBuffer.insert(m_ImageBuffer.begin(), m_BufferSize, nullptr); us::ModuleResource resourceFile; std::string name; m_FluenceCompOriginal.insert(m_FluenceCompOriginal.begin(), 5, Image::New()); for (int i = 5; i <= 25; ++i) { name = "c:\\HomogeneousScatteringAssumptions\\Scattering" + std::to_string(i) + ".nrrd"; - m_FluenceCompOriginal.push_back(mitk::IOUtil::LoadImage(name)); + m_FluenceCompOriginal.push_back(mitk::IOUtil::Load(name)); } m_FluenceCompResized.insert(m_FluenceCompResized.begin(), 26, Image::New()); m_FluenceCompResizedItk.insert(m_FluenceCompResizedItk.begin(), 26, itk::Image::New()); } mitk::USDiPhASImageSource::~USDiPhASImageSource() { // close the pyro MITK_INFO("Pyro Debug") << "StopDataAcquisition: " << m_Pyro->StopDataAcquisition(); MITK_INFO("Pyro Debug") << "CloseConnection: " << m_Pyro->CloseConnection(); m_PyroConnected = false; m_Pyro = nullptr; } void mitk::USDiPhASImageSource::GetNextRawImage(std::vector& imageVector) { // modify all settings that have been changed here, so we don't get multithreading issues if (m_DataTypeModified) { SetDataType(m_DataTypeNext); m_DataTypeModified = false; UpdateImageGeometry(); } if (m_UseBModeFilterModified) { SetUseBModeFilter(m_UseBModeFilterNext); m_UseBModeFilterModified = false; } if (m_VerticalSpacingModified) { m_VerticalSpacing = m_VerticalSpacingNext; m_VerticalSpacingModified = false; } if (m_ScatteringCoefficientModified) { m_ScatteringCoefficient = m_ScatteringCoefficientNext; m_ScatteringCoefficientModified = false; } if (m_CompensateForScatteringModified) { m_CompensateForScattering = m_CompensateForScatteringNext; m_CompensateForScatteringModified = false; } if (m_CompensateEnergyModified) { m_CompensateEnergy = m_CompensateEnergyNext; m_CompensateEnergyModified = false; } if (imageVector.size() != 2) { imageVector.resize(2); } // make sure image is nullptr mitk::Image::Pointer image = nullptr; float ImageEnergyValue = 0; for (int i = 100; i > 90 && ImageEnergyValue <= 0; --i) { if (m_ImageTimestampBuffer[(m_LastWrittenImage + i) % 100] != 0) { ImageEnergyValue = m_Pyro->GetClosestEnergyInmJ(m_ImageTimestampBuffer[(m_LastWrittenImage + i) % 100]); if (ImageEnergyValue > 0) { image = &(*m_ImageBuffer[(m_LastWrittenImage + i) % 100]); } } } // if we did not get any usable Energy value, compensate using this default value if (image == nullptr) { image = &(*m_ImageBuffer[m_LastWrittenImage]); ImageEnergyValue = 40; if (image == nullptr) return; } // do image processing before displaying it if (image.IsNotNull()) { itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(image, itkImage); image = mitk::GrabItkImageMemory(itkImage); //thereby using float images image = CutOffTop(image, 165); // now apply filters to the image, if the options have been selected. if ((m_CompensateForScattering || m_UseBModeFilter) && m_DataType == DataType::Beamformed_Short) { if (m_Device->GetScanMode().beamformingAlgorithm == Beamforming::PlaneWaveCompound) // this is for ultrasound only mode { if (m_UseBModeFilter) { image = ApplyBmodeFilter(image, true); if (m_VerticalSpacing) image = ResampleOutputVertical(image, m_VerticalSpacing); } } else { Image::Pointer imagePA = Image::New(); unsigned int dim[] = { image->GetDimension(0),image->GetDimension(1),1}; imagePA->Initialize(image->GetPixelType(), 3, dim); imagePA->SetGeometry(image->GetGeometry()); Image::Pointer imageUS = Image::New(); imageUS->Initialize(image->GetPixelType(), 3, dim); imageUS->SetGeometry(image->GetGeometry()); ImageReadAccessor inputReadAccessorCopyPA(image, image->GetSliceData(0)); imagePA->SetSlice(inputReadAccessorCopyPA.GetData(), 0); ImageReadAccessor inputReadAccessorCopyUS(image, image->GetSliceData(1)); imageUS->SetSlice(inputReadAccessorCopyUS.GetData(), 0); // first, seperate the PA image from the USImages // then, we compensate the PAImage using our ImageEnergyValue if(m_CompensateEnergy) imagePA = MultiplyImage(imagePA, 1/ImageEnergyValue); // TODO: add the correct prefactor here!!!! // now we apply the BModeFilter if (m_UseBModeFilter) { imageUS = ApplyBmodeFilter(imageUS, true); // the US Images get a logarithmic filter imagePA = ApplyBmodeFilter(imagePA, false); } ImageReadAccessor inputReadAccessorPA(imagePA, imagePA->GetSliceData(0)); image->SetSlice(inputReadAccessorPA.GetData(), 0); ImageReadAccessor inputReadAccessorUS(imageUS, imageUS->GetSliceData(0)); image->SetSlice(inputReadAccessorUS.GetData(), 1); if (m_VerticalSpacing) { image = ResampleOutputVertical(image, m_VerticalSpacing); } // and finally the scattering corrections if (m_CompensateForScattering) { auto curResizeImage = m_FluenceCompResized.at(m_ScatteringCoefficient); // just for convenience // update the fluence reference images! bool doResampling = image->GetDimension(0) != curResizeImage->GetDimension(0) || image->GetDimension(1) != curResizeImage->GetDimension(1) || image->GetGeometry()->GetSpacing()[0] != curResizeImage->GetGeometry()->GetSpacing()[0] || image->GetGeometry()->GetSpacing()[1] != curResizeImage->GetGeometry()->GetSpacing()[1]; if (doResampling) { curResizeImage = ApplyResampling(m_FluenceCompOriginal.at(m_ScatteringCoefficient), image->GetGeometry()->GetSpacing(), image->GetDimensions()); double* rawOutputData = new double[image->GetDimension(0)*image->GetDimension(1)]; double* rawScatteringData = (double*)curResizeImage->GetData(); int sizeRawScatteringData = curResizeImage->GetDimension(0) * curResizeImage->GetDimension(1); int imageSize = image->GetDimension(0)*image->GetDimension(1); //everything above 1.5mm is still inside the transducer; therefore the fluence compensation image has to be positioned a little lower float upperCutoffmm = 1.5; int lowerBound = std::round(upperCutoffmm / image->GetGeometry()->GetSpacing()[1])*image->GetDimension(0); int upperBound = lowerBound + sizeRawScatteringData; for (int i = 0; i < lowerBound && i < imageSize; ++i) { rawOutputData[i] = 0; // everything than cannot be compensated shall be treated as garbage, here the upper 0.15mm } for (int i = lowerBound; i < upperBound && i < imageSize; ++i) { rawOutputData[i] = 1 / rawScatteringData[i-lowerBound]; } for (int i = upperBound; i < imageSize; ++i) { rawOutputData[i] = 0; // everything than cannot be compensated shall be treated as garbage } unsigned int dim[] = { image->GetDimension(0), image->GetDimension(1), 1 }; curResizeImage->Initialize(mitk::MakeScalarPixelType(), 3, dim); curResizeImage->SetGeometry(image->GetGeometry()); curResizeImage->SetSlice(rawOutputData,0); delete[] rawOutputData; mitk::CastToItkImage(curResizeImage, m_FluenceCompResizedItk.at(m_ScatteringCoefficient)); m_FluenceCompResized.at(m_ScatteringCoefficient) = mitk::GrabItkImageMemory(m_FluenceCompResizedItk.at(m_ScatteringCoefficient)); MITK_INFO << "Resized a fluence image."; } // actually apply the scattering compensation imagePA = ApplyScatteringCompensation(imagePA, m_ScatteringCoefficient); ImageReadAccessor inputReadAccessorPA(imagePA, imagePA->GetSliceData(0)); image->SetSlice(inputReadAccessorPA.GetData(), 0); } } } //TODO: completely rewrite this mess imageVector[0] = Image::New(); unsigned int dim[] = { image->GetDimension(0),image->GetDimension(1),1 }; imageVector[0]->Initialize(image->GetPixelType(), 3, dim); imageVector[0]->SetGeometry(image->GetGeometry()); imageVector[1] = Image::New(); imageVector[1]->Initialize(image->GetPixelType(), 3, dim); imageVector[1]->SetGeometry(image->GetGeometry()); ImageReadAccessor inputReadAccessorCopyPA(image, image->GetSliceData(0)); imageVector[0]->SetSlice(inputReadAccessorCopyPA.GetData(), 0); ImageReadAccessor inputReadAccessorCopyUS(image, image->GetSliceData(1)); imageVector[1]->SetSlice(inputReadAccessorCopyUS.GetData(), 0); } } mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyBmodeFilter(mitk::Image::Pointer image, bool useLogFilter) { // we use this seperate ApplyBmodeFilter Method for processing of two-dimensional images // the image needs to be of floating point type for the envelope filter to work; the casting is done automatically by the CastToItkImage typedef itk::BModeImageFilter < itkFloatImageType, itkFloatImageType > BModeFilterType; BModeFilterType::Pointer bModeFilter = BModeFilterType::New(); // LogFilter typedef itk::PhotoacousticBModeImageFilter < itkFloatImageType, itkFloatImageType > PhotoacousticBModeImageFilter; PhotoacousticBModeImageFilter::Pointer photoacousticBModeFilter = PhotoacousticBModeImageFilter::New(); // No LogFilter itkFloatImageType::Pointer itkImage; itkFloatImageType::Pointer bmode; mitk::CastToItkImage(image, itkImage); if (useLogFilter) { bModeFilter->SetInput(itkImage); bModeFilter->SetDirection(1); bmode = bModeFilter->GetOutput(); } else { photoacousticBModeFilter->SetInput(itkImage); photoacousticBModeFilter->SetDirection(1); bmode = photoacousticBModeFilter->GetOutput(); } return mitk::GrabItkImageMemory(bmode); } mitk::Image::Pointer mitk::USDiPhASImageSource::CutOffTop(mitk::Image::Pointer image, int cutOffSize) { typedef itk::CropImageFilter < itkFloatImageType, itkFloatImageType > CutImageFilter; itkFloatImageType::SizeType cropSize; itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(image, itkImage); cropSize[0] = 0; if(itkImage->GetLargestPossibleRegion().GetSize()[1] == 2048) cropSize[1] = cutOffSize; else cropSize[1] = 0; cropSize[2] = 0; CutImageFilter::Pointer cutOffFilter = CutImageFilter::New(); cutOffFilter->SetInput(itkImage); cutOffFilter->SetLowerBoundaryCropSize(cropSize); cutOffFilter->UpdateLargestPossibleRegion(); return mitk::GrabItkImageMemory(cutOffFilter->GetOutput()); } mitk::Image::Pointer mitk::USDiPhASImageSource::ResampleOutputVertical(mitk::Image::Pointer image, float verticalSpacing) { typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(image, itkImage); itkFloatImageType::SpacingType outputSpacing; itkFloatImageType::SizeType inputSize = itkImage->GetLargestPossibleRegion().GetSize(); itkFloatImageType::SizeType outputSize = inputSize; outputSpacing[0] = itkImage->GetSpacing()[0] * (static_cast(inputSize[0]) / static_cast(outputSize[0])); outputSpacing[1] = verticalSpacing; outputSpacing[2] = itkImage->GetSpacing()[2]; outputSize[1] = inputSize[1] * itkImage->GetSpacing()[1] / outputSpacing[1]; typedef itk::IdentityTransform TransformType; resampleImageFilter->SetInput(itkImage); resampleImageFilter->SetSize(outputSize); resampleImageFilter->SetOutputSpacing(outputSpacing); resampleImageFilter->SetTransform(TransformType::New()); resampleImageFilter->UpdateLargestPossibleRegion(); return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); } mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyScatteringCompensation(mitk::Image::Pointer inputImage, int scattering) { typedef itk::MultiplyImageFilter MultiplyImageFilterType; itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(inputImage, itkImage); MultiplyImageFilterType::Pointer multiplyFilter = MultiplyImageFilterType::New(); multiplyFilter->SetInput1(itkImage); multiplyFilter->SetInput2(m_FluenceCompResizedItk.at(m_ScatteringCoefficient)); return mitk::GrabItkImageMemory(multiplyFilter->GetOutput()); } mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyResampling(mitk::Image::Pointer inputImage, mitk::Vector3D outputSpacing, unsigned int outputSize[3]) { typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(inputImage, itkImage); itkFloatImageType::SpacingType outputSpacingItk; itkFloatImageType::SizeType inputSizeItk = itkImage->GetLargestPossibleRegion().GetSize(); itkFloatImageType::SizeType outputSizeItk = inputSizeItk; itkFloatImageType::SpacingType inputSpacing = itkImage->GetSpacing(); outputSizeItk[0] = outputSize[0]; outputSizeItk[1] = 10*(inputSpacing[1] * inputSizeItk[1]) / (outputSpacing[1]); outputSizeItk[2] = 1; outputSpacingItk[0] = 0.996 * inputSpacing[0] * (static_cast(inputSizeItk[0]) / static_cast(outputSizeItk[0])); // TODO: find out why the spacing is not correct, so we need that factor; ?!?! outputSpacingItk[1] = inputSpacing[1] * (static_cast(inputSizeItk[1]) / static_cast(outputSizeItk[1])); outputSpacingItk[2] = outputSpacing[2]; typedef itk::IdentityTransform TransformType; resampleImageFilter->SetInput(itkImage); resampleImageFilter->SetSize(outputSizeItk); resampleImageFilter->SetOutputSpacing(outputSpacingItk); resampleImageFilter->SetTransform(TransformType::New()); resampleImageFilter->UpdateLargestPossibleRegion(); return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); } mitk::Image::Pointer mitk::USDiPhASImageSource::MultiplyImage(mitk::Image::Pointer inputImage, double value) { typedef itk::MultiplyImageFilter MultiplyImageFilterType; itkFloatImageType::Pointer itkImage; mitk::CastToItkImage(inputImage, itkImage); MultiplyImageFilterType::Pointer multiplyFilter = MultiplyImageFilterType::New(); multiplyFilter->SetInput1(itkImage); multiplyFilter->SetConstant(value); return mitk::GrabItkImageMemory(multiplyFilter->GetOutput()); } void mitk::USDiPhASImageSource::ImageDataCallback( short* rfDataChannelData, int& channelDataChannelsPerDataset, int& channelDataSamplesPerChannel, int& channelDataTotalDatasets, short* rfDataArrayBeamformed, int& beamformedLines, int& beamformedSamples, int& beamformedTotalDatasets, unsigned char* imageData, int& imageWidth, int& imageHeight, int& imageBytesPerPixel, int& imageSetsTotal, double& timeStamp) { if (m_DataTypeModified) return; if (!m_PyroConnected) { m_Pyro = mitk::OphirPyro::New(); MITK_INFO << "[Pyro Debug] OpenConnection: " << m_Pyro->OpenConnection(); MITK_INFO << "[Pyro Debug] StartDataAcquisition: " << m_Pyro->StartDataAcquisition(); m_PyroConnected = true; } bool writeImage = ((m_DataType == DataType::Image_uChar) && (imageData != nullptr)) || ((m_DataType == DataType::Beamformed_Short) && (rfDataArrayBeamformed != nullptr)); if (writeImage) { //get the timestamp we might save later on m_CurrentImageTimestamp = std::chrono::high_resolution_clock::now().time_since_epoch().count(); // create a new image and initialize it mitk::Image::Pointer image = mitk::Image::New(); switch (m_DataType) { case DataType::Image_uChar: { m_ImageDimensions[0] = imageWidth; m_ImageDimensions[1] = imageHeight; m_ImageDimensions[2] = imageSetsTotal; image->Initialize(mitk::MakeScalarPixelType(), 3, m_ImageDimensions); break; } case DataType::Beamformed_Short: { m_ImageDimensions[0] = beamformedLines; m_ImageDimensions[1] = beamformedSamples; m_ImageDimensions[2] = beamformedTotalDatasets; image->Initialize(mitk::MakeScalarPixelType(), 3, m_ImageDimensions); break; } } image->GetGeometry()->SetSpacing(m_ImageSpacing); image->GetGeometry()->Modified(); // write the given buffer into the image switch (m_DataType) { case DataType::Image_uChar: { for (unsigned char i = 0; i < imageSetsTotal; i++) { image->SetSlice(&imageData[i*imageHeight*imageWidth], i); } break; } case DataType::Beamformed_Short: { short* flipme = new short[beamformedLines*beamformedSamples*beamformedTotalDatasets]; int pixelsPerImage = beamformedLines*beamformedSamples; for (unsigned char currentSet = 0; currentSet < beamformedTotalDatasets; currentSet++) { for (unsigned short sample = 0; sample < beamformedSamples; sample++) { for (unsigned short line = 0; line < beamformedLines; line++) { flipme[sample*beamformedLines + line + pixelsPerImage*currentSet] = rfDataArrayBeamformed[line*beamformedSamples + sample + pixelsPerImage*currentSet]; } } // the beamformed pa image is flipped by 90 degrees; we need to flip it manually } for (unsigned char i = 0; i < beamformedTotalDatasets; i++) { image->SetSlice(&flipme[i*beamformedLines*beamformedSamples], i); // set every image to a different slice } delete[] flipme; break; } } if (m_SavingSettings.saveRaw && m_CurrentlyRecording && rfDataChannelData != nullptr) { unsigned int dim[3]; dim[0] = channelDataChannelsPerDataset; dim[1] = channelDataSamplesPerChannel; dim[2] = 1; short offset = m_Device->GetScanMode().accumulation * 2048; short* noOffset = new short[channelDataChannelsPerDataset*channelDataSamplesPerChannel*channelDataTotalDatasets]; for (unsigned char set = 0; set < 1; ++set)// channelDataTotalDatasets; ++set) // we ignore the raw US images for now { for (unsigned short sam = 0; sam < channelDataSamplesPerChannel; ++sam) { for (unsigned short chan = 0; chan < channelDataChannelsPerDataset; ++chan) { noOffset[set*channelDataSamplesPerChannel*channelDataChannelsPerDataset + sam * channelDataChannelsPerDataset + chan] = rfDataChannelData[set*channelDataSamplesPerChannel*channelDataChannelsPerDataset + sam * channelDataChannelsPerDataset + chan] - offset; // this offset in the raw Images is given by the API... } } } // save the raw images when recording for (unsigned char i = 0; i < 1; ++i)// channelDataTotalDatasets; ++i) // we ignore the raw US images for now { mitk::Image::Pointer rawImage = mitk::Image::New(); rawImage->Initialize(mitk::MakeScalarPixelType(), 3, dim); rawImage->SetSlice(&noOffset[i*channelDataChannelsPerDataset*channelDataSamplesPerChannel]); float& recordTime = m_Device->GetScanMode().receivePhaseLengthSeconds; int& speedOfSound = m_Device->GetScanMode().averageSpeedOfSound; mitk::Vector3D rawSpacing; rawSpacing[0] = m_Device->GetScanMode().transducerPitchMeter * 1000; // save in mm rawSpacing[1] = recordTime / channelDataSamplesPerChannel * 1000000; // save in us rawSpacing[2] = 1; rawImage->GetGeometry()->SetSpacing(rawSpacing); rawImage->GetGeometry()->Modified(); m_RawRecordedImages.push_back(rawImage); } delete[] noOffset; } itk::Index<3> pixel = { { (itk::Index<3>::IndexValueType)(image->GetDimension(0) / 2), (itk::Index<3>::IndexValueType)(22.0/532.0*m_Device->GetScanMode().reconstructionSamplesPerLine), 0 } }; //22/532*2048 = 84 if (!m_Pyro->IsSyncDelaySet() &&(image->GetPixelValueByIndex(pixel) < -30)) // #MagicNumber { MITK_INFO << "Setting SyncDelay now"; m_Pyro->SetSyncDelay(m_CurrentImageTimestamp); } m_ImageTimestampBuffer[(m_LastWrittenImage + 1) % m_BufferSize] = m_CurrentImageTimestamp; m_ImageBuffer[(m_LastWrittenImage + 1) % m_BufferSize] = image; m_LastWrittenImage = (m_LastWrittenImage + 1) % m_BufferSize; // if the user decides to start recording, we feed the vector the generated images if (m_CurrentlyRecording) { for (unsigned char index = 0; index < image->GetDimension(2); ++index) { if (image->IsSliceSet(index)) { m_RecordedImages.push_back(Image::New()); unsigned int dim[] = { image ->GetDimension(0), image->GetDimension(1), 1}; m_RecordedImages.back()->Initialize(image->GetPixelType(), 3, dim); m_RecordedImages.back()->SetGeometry(image->GetGeometry()); mitk::ImageReadAccessor inputReadAccessor(image, image->GetSliceData(index)); m_RecordedImages.back()->SetSlice(inputReadAccessor.GetData(),0); } } m_ImageTimestampRecord.push_back(m_CurrentImageTimestamp); // save timestamps for each laser image! } } } void mitk::USDiPhASImageSource::UpdateImageGeometry() { MITK_INFO << "Retreaving Image Geometry Information for Spacing..."; float& recordTime = m_Device->GetScanMode().receivePhaseLengthSeconds; int& speedOfSound = m_Device->GetScanMode().averageSpeedOfSound; float& pitch = m_Device->GetScanMode().reconstructedLinePitchMmOrAngleDegree; int& reconstructionLines = m_Device->GetScanMode().reconstructionLines; switch (m_DataType) { case DataType::Image_uChar : { int& imageWidth = m_Device->GetScanMode().imageWidth; int& imageHeight = m_Device->GetScanMode().imageHeight; m_ImageSpacing[0] = pitch * reconstructionLines / imageWidth; m_ImageSpacing[1] = recordTime * speedOfSound / 2 * 1000 / imageHeight; break; } case DataType::Beamformed_Short : { int& imageWidth = reconstructionLines; int& imageHeight = m_Device->GetScanMode().reconstructionSamplesPerLine; m_ImageSpacing[0] = pitch; m_ImageSpacing[1] = recordTime * speedOfSound / 2 * 1000 / imageHeight; break; } } m_ImageSpacing[2] = 1; MITK_INFO << "Retreaving Image Geometry Information for Spacing " << m_ImageSpacing[0] << " ... " << m_ImageSpacing[1] << " ... " << m_ImageSpacing[2] << " ...[DONE]"; } void mitk::USDiPhASImageSource::ModifyDataType(DataType dataT) { m_DataTypeModified = true; m_DataTypeNext = dataT; } void mitk::USDiPhASImageSource::ModifyUseBModeFilter(bool isSet) { m_UseBModeFilterModified = true; m_UseBModeFilterNext = isSet; } void mitk::USDiPhASImageSource::ModifyScatteringCoefficient(int coeff) { m_ScatteringCoefficientNext = coeff; m_ScatteringCoefficientModified = true; } void mitk::USDiPhASImageSource::ModifyCompensateForScattering(bool useIt) { m_CompensateForScatteringNext = useIt; m_CompensateForScatteringModified = true; } void mitk::USDiPhASImageSource::ModifyEnergyCompensation(bool compensate) { m_CompensateEnergyNext = compensate; m_CompensateEnergyModified = true; } void mitk::USDiPhASImageSource::SetDataType(DataType dataT) { if (dataT != m_DataType) { m_DataType = dataT; MITK_INFO << "Setting new DataType..." << dataT; switch (m_DataType) { case DataType::Image_uChar : MITK_INFO << "height: " << m_Device->GetScanMode().imageHeight << " width: " << m_Device->GetScanMode().imageWidth; break; case DataType::Beamformed_Short : MITK_INFO << "samples: " << m_Device->GetScanMode().reconstructionSamplesPerLine << " lines: " << m_Device->GetScanMode().reconstructionLines; break; } } } void mitk::USDiPhASImageSource::SetGUIOutput(std::function out) { USDiPhASImageSource::m_GUIOutput = out; m_StartTime = ((float)std::clock()) / CLOCKS_PER_SEC; //wait till the callback is available again m_UseGUIOutPut = false; } void mitk::USDiPhASImageSource::SetUseBModeFilter(bool isSet) { m_UseBModeFilter = isSet; } void mitk::USDiPhASImageSource::SetVerticalSpacing(float mm) { m_VerticalSpacingNext = mm; m_VerticalSpacingModified = true; } void mitk::USDiPhASImageSource::SetSavingSettings(SavingSettings settings) { m_SavingSettings = settings; } // this is just a little function to set the filenames below right inline void replaceAll(std::string& str, const std::string& from, const std::string& to) { if (from.empty()) return; size_t start_pos = 0; while ((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' } } void mitk::USDiPhASImageSource::SetRecordingStatus(bool record) { // start the recording process if (record) { m_RecordedImages.clear(); m_RawRecordedImages.clear(); // we make sure there are no leftovers m_ImageTimestampRecord.clear(); // also for the timestamps m_PixelValues.clear(); // aaaand for the pixel values if (m_SavingSettings.saveRaw) { m_Device->GetScanMode().transferChannelData = true; m_Device->UpdateScanmode(); // set the raw Data to be transfered } // tell the callback to start recording images m_CurrentlyRecording = true; } // save images, end recording, and clean up else { m_CurrentlyRecording = false; m_Device->GetScanMode().transferChannelData = false; // make sure raw Channel Data is not transferred anymore! m_Device->UpdateScanmode(); // get the time and date, put them into a nice string and create a folder for the images time_t time = std::time(nullptr); time_t* timeptr = &time; std::string currentDate = std::ctime(timeptr); replaceAll(currentDate, ":", "-"); currentDate.pop_back(); //std::string MakeFolder = "mkdir \"c:/DiPhASImageData/" + currentDate + "\""; //system(MakeFolder.c_str()); // initialize file paths and the images Image::Pointer PAImage = Image::New(); Image::Pointer USImage = Image::New(); std::string pathPA = "c:\\ImageData\\" + currentDate + "-" + "PAbeamformed" + ".nrrd"; std::string pathUS = "c:\\ImageData\\" + currentDate + "-" + "USImages" + ".nrrd"; std::string pathTS = "c:\\ImageData\\" + currentDate + "-" + "ts" + ".csv"; std::string pathS = "c:\\ImageData\\" + currentDate + "-" + "Settings" + ".txt"; // idon't forget the raw Images (if chosen to be saved) Image::Pointer PAImageRaw = Image::New(); Image::Pointer USImageRaw = Image::New(); std::string pathPARaw = "c:\\ImageData\\" + currentDate + "-" + "PAraw" + ".nrrd"; std::string pathUSRaw = "c:\\ImageData\\" + currentDate + "-" + "USImagesRaw" + ".nrrd"; if (m_Device->GetScanMode().beamformingAlgorithm == (int)Beamforming::Interleaved_OA_US) // save a PAImage if we used interleaved mode { // first, save the data, so the pyro does not aquire more unneccessary timestamps m_Pyro->SaveData(); // now order the images and save them // the beamformed ones... if (m_SavingSettings.saveBeamformed) { OrderImagesInterleaved(PAImage, USImage, m_RecordedImages, false); mitk::IOUtil::Save(USImage, pathUS); mitk::IOUtil::Save(PAImage, pathPA); } // ...and the raw images if (m_SavingSettings.saveRaw) { OrderImagesInterleaved(PAImageRaw, USImageRaw, m_RawRecordedImages, true); // mitk::IOUtil::Save(USImageRaw, pathUSRaw); mitk::IOUtil::Save(PAImageRaw, pathPARaw); } // read the pixelvalues of the enveloped images at this position itk::Index<3> pixel = { { (itk::Index<3>::IndexValueType)(m_RecordedImages.at(0)->GetDimension(0) / 2), (itk::Index<3>::IndexValueType)(22.0 / 532.0*m_Device->GetScanMode().reconstructionSamplesPerLine), 0 } }; //22/532*2048 = 84 GetPixelValues(pixel, m_PixelValues); // write the Pixelvalues to m_PixelValues // save the timestamps! ofstream timestampFile; timestampFile.open(pathTS); timestampFile << ",timestamp,pixelvalue"; // write the header for (int index = 0; index < m_ImageTimestampRecord.size(); ++index) { timestampFile << "\n" << index << "," << m_ImageTimestampRecord.at(index) << "," << m_PixelValues.at(index); } timestampFile.close(); //save the settings! ofstream settingsFile; settingsFile.open(pathS); auto& sM = m_Device->GetScanMode(); settingsFile << "[General Parameters]\n"; settingsFile << "Scan Depth [mm] = " << sM.receivePhaseLengthSeconds * sM.averageSpeedOfSound / 2 * 1000 << "\n"; settingsFile << "Speed of Sound [m/s] = " << sM.averageSpeedOfSound << "\n"; settingsFile << "Excitation Frequency [MHz] = " << sM.transducerFrequencyHz/1000000 << "\n"; settingsFile << "Voltage [V] = " << sM.voltageV << "\n"; settingsFile << "TGC min = " << (int)sM.tgcdB[0] << " max = " << (int)sM.tgcdB[7] << "\n"; settingsFile << "[Beamforming Parameters]\n"; settingsFile << "Reconstructed Lines = " << sM.reconstructionLines << "\n"; settingsFile << "Samples per Line = " << sM.reconstructionSamplesPerLine << "\n"; settingsFile.close(); } else if (m_Device->GetScanMode().beamformingAlgorithm == (int)Beamforming::PlaneWaveCompound) // save no PAImage if we used US only mode { OrderImagesUltrasound(USImage, m_RecordedImages); mitk::IOUtil::Save(USImage, pathUS); } m_PixelValues.clear(); m_RawRecordedImages.clear(); // clean up the pixel values m_RecordedImages.clear(); // clean up the images m_ImageTimestampRecord.clear(); // clean up the timestamps } } void mitk::USDiPhASImageSource::GetPixelValues(itk::Index<3> pixel, std::vector& values) { unsigned int events = 2; for (int index = 0; index < m_RecordedImages.size(); index += events) // omit sound images { Image::Pointer image = m_RecordedImages.at(index); image = ApplyBmodeFilter(image); values.push_back(image.GetPointer()->GetPixelValueByIndex(pixel)); } } void mitk::USDiPhASImageSource::OrderImagesInterleaved(Image::Pointer PAImage, Image::Pointer USImage, std::vector recordedList, bool raw) { unsigned int width = 32; unsigned int height = 32; unsigned int events = m_Device->GetScanMode().transmitEventsCount + 1; // the PA event is not included in the transmitEvents, so we add 1 here if (!raw) events = 2; // the beamformed image array contains only the resulting image of multiple events if (raw) { width = recordedList.at(0)->GetDimension(0); height = recordedList.at(0)->GetDimension(1); } else if (m_DataType == DataType::Beamformed_Short) { width = m_Device->GetScanMode().reconstructionLines; height = m_Device->GetScanMode().reconstructionSamplesPerLine; } else if (m_DataType == DataType::Image_uChar) { width = m_Device->GetScanMode().imageWidth; height = m_Device->GetScanMode().imageHeight; } unsigned int dimLaser[] = { (unsigned int)width, (unsigned int)height, (unsigned int)(recordedList.size() / events)}; unsigned int dimSound[] = { (unsigned int)width, (unsigned int)height, (unsigned int)(recordedList.size() / events * (events-1))}; PAImage->Initialize(recordedList.back()->GetPixelType(), 3, dimLaser); PAImage->SetGeometry(recordedList.back()->GetGeometry()); USImage->Initialize(recordedList.back()->GetPixelType(), 3, dimSound); USImage->SetGeometry(recordedList.back()->GetGeometry()); for (int index = 0; index < recordedList.size(); ++index) { mitk::ImageReadAccessor inputReadAccessor(recordedList.at(index)); if (index % events == 0) { PAImage->SetSlice(inputReadAccessor.GetData(), index / events); } else { if(!raw) USImage->SetSlice(inputReadAccessor.GetData(), ((index - (index % events)) / events) + (index % events)-1); } } } void mitk::USDiPhASImageSource::OrderImagesUltrasound(Image::Pointer USImage, std::vector recordedList) { unsigned int width = 32; unsigned int height = 32; unsigned int events = m_Device->GetScanMode().transmitEventsCount; if (m_DataType == DataType::Beamformed_Short) { width = (unsigned int)m_Device->GetScanMode().reconstructionLines; height = (unsigned int)m_Device->GetScanMode().reconstructionSamplesPerLine; } else if (m_DataType == DataType::Image_uChar) { width = (unsigned int)m_Device->GetScanMode().imageWidth; height = (unsigned int)m_Device->GetScanMode().imageHeight; } unsigned int dimSound[] = { (unsigned int)width, (unsigned int)height, (unsigned int)recordedList.size()}; USImage->Initialize(recordedList.back()->GetPixelType(), 3, dimSound); USImage->SetGeometry(recordedList.back()->GetGeometry()); for (int index = 0; index < recordedList.size(); ++index) { mitk::ImageReadAccessor inputReadAccessor(recordedList.at(index)); USImage->SetSlice(inputReadAccessor.GetData(), index); } } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp index 84c5f9668f..2960377da6 100644 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp +++ b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp @@ -1,1161 +1,1161 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include // Qmitk #include "PAImageProcessing.h" // Qt #include #include #include #include //mitk image #include #include "mitkPhotoacousticImage.h" #include "mitkPhotoacousticBeamformingFilter.h" //other #include #include #include const std::string PAImageProcessing::VIEW_ID = "org.mitk.views.paimageprocessing"; PAImageProcessing::PAImageProcessing() : m_ResampleSpacing(0), m_UseLogfilter(false), m_FilterBank(mitk::PhotoacousticImage::New()) { qRegisterMetaType(); qRegisterMetaType(); } void PAImageProcessing::SetFocus() { m_Controls.buttonApplyBModeFilter->setFocus(); } void PAImageProcessing::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); connect(m_Controls.buttonApplyBModeFilter, SIGNAL(clicked()), this, SLOT(StartBmodeThread())); connect(m_Controls.DoResampling, SIGNAL(clicked()), this, SLOT(UseResampling())); connect(m_Controls.Logfilter, SIGNAL(clicked()), this, SLOT(UseLogfilter())); connect(m_Controls.ResamplingValue, SIGNAL(valueChanged(double)), this, SLOT(SetResampling())); connect(m_Controls.buttonApplyBeamforming, SIGNAL(clicked()), this, SLOT(StartBeamformingThread())); connect(m_Controls.buttonApplyCropFilter, SIGNAL(clicked()), this, SLOT(StartCropThread())); connect(m_Controls.buttonApplyBandpass, SIGNAL(clicked()), this, SLOT(StartBandpassThread())); connect(m_Controls.UseImageSpacing, SIGNAL(clicked()), this, SLOT(UseImageSpacing())); connect(m_Controls.ScanDepth, SIGNAL(valueChanged(double)), this, SLOT(UpdateImageInfo())); connect(m_Controls.SpeedOfSound, SIGNAL(valueChanged(double)), this, SLOT(UpdateImageInfo())); connect(m_Controls.SpeedOfSound, SIGNAL(valueChanged(double)), this, SLOT(ChangedSOSBeamforming())); connect(m_Controls.BPSpeedOfSound, SIGNAL(valueChanged(double)), this, SLOT(ChangedSOSBandpass())); connect(m_Controls.Samples, SIGNAL(valueChanged(int)), this, SLOT(UpdateImageInfo())); connect(m_Controls.UseImageSpacing, SIGNAL(clicked()), this, SLOT(UpdateImageInfo())); connect(m_Controls.boundLow, SIGNAL(valueChanged(int)), this, SLOT(LowerSliceBoundChanged())); connect(m_Controls.boundHigh, SIGNAL(valueChanged(int)), this, SLOT(UpperSliceBoundChanged())); connect(m_Controls.Partial, SIGNAL(clicked()), this, SLOT(SliceBoundsEnabled())); connect(m_Controls.BatchProcessing, SIGNAL(clicked()), this, SLOT(BatchProcessing())); connect(m_Controls.StepBeamforming, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); connect(m_Controls.StepCropping, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); connect(m_Controls.StepBandpass, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); connect(m_Controls.StepBMode, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); UpdateSaveBoxes(); m_Controls.DoResampling->setChecked(false); m_Controls.ResamplingValue->setEnabled(false); m_Controls.progressBar->setMinimum(0); m_Controls.progressBar->setMaximum(100); m_Controls.progressBar->setVisible(false); m_Controls.UseImageSpacing->setToolTip("Image spacing of y-Axis must be in us, x-Axis in mm."); m_Controls.UseImageSpacing->setToolTipDuration(5000); m_Controls.ProgressInfo->setVisible(false); m_Controls.UseBP->hide(); m_Controls.UseGPUBmode->hide(); #ifndef PHOTOACOUSTICS_USE_GPU m_Controls.UseGPUBf->setEnabled(false); m_Controls.UseGPUBf->setChecked(false); m_Controls.UseGPUBmode->setEnabled(false); m_Controls.UseGPUBmode->setChecked(false); #endif UseImageSpacing(); } void PAImageProcessing::ChangedSOSBandpass() { m_Controls.SpeedOfSound->setValue(m_Controls.BPSpeedOfSound->value()); } void PAImageProcessing::ChangedSOSBeamforming() { m_Controls.BPSpeedOfSound->setValue(m_Controls.SpeedOfSound->value()); } std::vector splitpath( const std::string& str , const std::set delimiters) { std::vector result; char const* pch = str.c_str(); char const* start = pch; for (; *pch; ++pch) { if (delimiters.find(*pch) != delimiters.end()) { if (start != pch) { std::string str(start, pch); result.push_back(str); } else { result.push_back(""); } start = pch + 1; } } result.push_back(start); return result; } void PAImageProcessing::UpdateSaveBoxes() { if (m_Controls.StepBeamforming->isChecked()) m_Controls.SaveBeamforming->setEnabled(true); else m_Controls.SaveBeamforming->setEnabled(false); if (m_Controls.StepCropping->isChecked()) m_Controls.SaveCropping->setEnabled(true); else m_Controls.SaveCropping->setEnabled(false); if (m_Controls.StepBandpass->isChecked()) m_Controls.SaveBandpass->setEnabled(true); else m_Controls.SaveBandpass->setEnabled(false); if (m_Controls.StepBMode->isChecked()) m_Controls.SaveBMode->setEnabled(true); else m_Controls.SaveBMode->setEnabled(false); } void PAImageProcessing::BatchProcessing() { QFileDialog LoadDialog(nullptr, "Select Files to be processed"); LoadDialog.setFileMode(QFileDialog::FileMode::ExistingFiles); LoadDialog.setNameFilter(tr("Images (*.nrrd)")); LoadDialog.setViewMode(QFileDialog::Detail); QStringList fileNames; if (LoadDialog.exec()) fileNames = LoadDialog.selectedFiles(); QString saveDir = QFileDialog::getExistingDirectory(nullptr, tr("Select Directory To Save To"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); DisableControls(); std::set delims{'/'}; bool doSteps[] = { m_Controls.StepBeamforming->isChecked(), m_Controls.StepCropping->isChecked() , m_Controls.StepBandpass->isChecked(), m_Controls.StepBMode->isChecked() }; bool saveSteps[] = { m_Controls.SaveBeamforming->isChecked(), m_Controls.SaveCropping->isChecked() , m_Controls.SaveBandpass->isChecked(), m_Controls.SaveBMode->isChecked() }; for (int fileNumber = 0; fileNumber < fileNames.size(); ++fileNumber) { m_Controls.progressBar->setValue(0); m_Controls.progressBar->setVisible(true); m_Controls.ProgressInfo->setVisible(true); m_Controls.ProgressInfo->setText("loading file"); QString filename = fileNames.at(fileNumber); auto split = splitpath(filename.toStdString(), delims); std::string imageName = split.at(split.size()-1); // remove ".nrrd" imageName = imageName.substr(0, imageName.size()-5); - mitk::Image::Pointer image = mitk::IOUtil::LoadImage(filename.toStdString().c_str()); + mitk::Image::Pointer image = mitk::IOUtil::Load(filename.toStdString().c_str()); UpdateBFSettings(image); // Beamforming if (doSteps[0]) { std::function progressHandle = [this](int progress, std::string progressInfo) { this->UpdateProgress(progress, progressInfo); }; m_Controls.progressBar->setValue(100); std::string errorMessage = ""; image = m_FilterBank->ApplyBeamforming(image, BFconfig, errorMessage, progressHandle); if (saveSteps[0]) { std::string saveFileName = saveDir.toStdString() + "/" + imageName + " beamformed" + ".nrrd"; mitk::IOUtil::Save(image, saveFileName); } } // Cropping if (doSteps[1]) { m_Controls.ProgressInfo->setText("cropping image"); image = m_FilterBank->ApplyCropping(image, m_Controls.CutoffAbove->value(), m_Controls.CutoffBelow->value(), 0, 0, 0, image->GetDimension(2) - 1); if (saveSteps[1]) { std::string saveFileName = saveDir.toStdString() + "/" + imageName + " cropped" + ".nrrd"; mitk::IOUtil::Save(image, saveFileName); } } // Bandpass if (doSteps[2]) { m_Controls.ProgressInfo->setText("applying bandpass"); float recordTime = image->GetDimension(1)*image->GetGeometry()->GetSpacing()[1] / 1000 / m_Controls.BPSpeedOfSound->value(); // add a safeguard so the program does not chrash when applying a Bandpass that reaches out of the bounds of the image float maxFrequency = 1 / (recordTime / image->GetDimension(1)) * image->GetDimension(1) / 2 / 2 / 1000; float BPHighPass = 1000000 * m_Controls.BPhigh->value(); // [Hz] float BPLowPass = maxFrequency - 1000000 * m_Controls.BPlow->value(); // [Hz] if (BPLowPass > maxFrequency && m_Controls.UseBP->isChecked()) { QMessageBox Msgbox; Msgbox.setText("LowPass too low, disabled it."); Msgbox.exec(); BPLowPass = 0; } if (BPLowPass < 0 && m_Controls.UseBP->isChecked()) { QMessageBox Msgbox; Msgbox.setText("LowPass too high, disabled it."); Msgbox.exec(); BPLowPass = 0; } if (BPHighPass > maxFrequency && m_Controls.UseBP->isChecked()) { QMessageBox Msgbox; Msgbox.setText("HighPass too high, disabled it."); Msgbox.exec(); BPHighPass = 0; } if (BPHighPass > maxFrequency - BFconfig.BPLowPass) { QMessageBox Msgbox; Msgbox.setText("HighPass higher than LowPass, disabled both."); Msgbox.exec(); BPHighPass = 0; BPLowPass = 0; } image = m_FilterBank->BandpassFilter(image, recordTime, BPHighPass, BPLowPass, m_Controls.BPFalloff->value()); if (saveSteps[2]) { std::string saveFileName = saveDir.toStdString() + "/" + imageName + " bandpassed" + ".nrrd"; mitk::IOUtil::Save(image, saveFileName); } } // Bmode if (doSteps[3]) { m_Controls.ProgressInfo->setText("applying bmode filter"); bool useGPU = m_Controls.UseGPUBmode->isChecked(); if (m_Controls.BModeMethod->currentText() == "Absolute Filter") image = m_FilterBank->ApplyBmodeFilter(image, mitk::PhotoacousticImage::BModeMethod::Abs, useGPU, m_UseLogfilter, m_ResampleSpacing); else if (m_Controls.BModeMethod->currentText() == "Envelope Detection") image = m_FilterBank->ApplyBmodeFilter(image, mitk::PhotoacousticImage::BModeMethod::EnvelopeDetection, useGPU, m_UseLogfilter, m_ResampleSpacing); if (saveSteps[3]) { std::string saveFileName = saveDir.toStdString() + "/" + imageName + " bmode" + ".nrrd"; mitk::IOUtil::Save(image, saveFileName); } } m_Controls.progressBar->setVisible(false); } EnableControls(); } void PAImageProcessing::StartBeamformingThread() { QList nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; mitk::DataStorage::Pointer storage = this->GetDataStorage(); mitk::DataNode::Pointer node = nodes.front(); if (!node) { // Nothing selected. Inform the user and return QMessageBox::information(NULL, "Template", "Please load and select an image before starting image processing."); return; } mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast(data); if (image) { UpdateBFSettings(image); std::stringstream message; std::string name; message << "Performing beamforming for image "; if (node->GetName(name)) { // a property called "name" was found for this DataNode message << "'" << name << "'"; m_OldNodeName = name; } else m_OldNodeName = " "; message << "."; MITK_INFO << message.str(); m_Controls.progressBar->setValue(0); m_Controls.progressBar->setVisible(true); m_Controls.ProgressInfo->setVisible(true); m_Controls.ProgressInfo->setText("started"); m_Controls.buttonApplyBeamforming->setText("working..."); DisableControls(); BeamformingThread *thread = new BeamformingThread(); connect(thread, &BeamformingThread::result, this, &PAImageProcessing::HandleBeamformingResults); connect(thread, &BeamformingThread::updateProgress, this, &PAImageProcessing::UpdateProgress); connect(thread, &BeamformingThread::message, this, &PAImageProcessing::PAMessageBox); connect(thread, &BeamformingThread::finished, thread, &QObject::deleteLater); thread->setConfig(BFconfig); thread->setInputImage(image); thread->setFilterBank(m_FilterBank); MITK_INFO << "Started new thread for Beamforming"; thread->start(); } } } void PAImageProcessing::HandleBeamformingResults(mitk::Image::Pointer image) { auto newNode = mitk::DataNode::New(); newNode->SetData(image); // name the new Data node std::stringstream newNodeName; newNodeName << m_OldNodeName << " "; if (BFconfig.Algorithm == mitk::BeamformingSettings::BeamformingAlgorithm::DAS) newNodeName << "DAS bf, "; else if (BFconfig.Algorithm == mitk::BeamformingSettings::BeamformingAlgorithm::DMAS) newNodeName << "DMAS bf, "; if (BFconfig.DelayCalculationMethod == mitk::BeamformingSettings::DelayCalc::QuadApprox) newNodeName << "q. delay"; if (BFconfig.DelayCalculationMethod == mitk::BeamformingSettings::DelayCalc::Spherical) newNodeName << "s. delay"; newNode->SetName(newNodeName.str()); // update level window for the current dynamic range mitk::LevelWindow levelWindow; newNode->GetLevelWindow(levelWindow); levelWindow.SetAuto(image, true, true); newNode->SetLevelWindow(levelWindow); // add new node to data storage this->GetDataStorage()->Add(newNode); // disable progress bar m_Controls.progressBar->setVisible(false); m_Controls.ProgressInfo->setVisible(false); m_Controls.buttonApplyBeamforming->setText("Apply Beamforming"); EnableControls(); // update rendering mitk::RenderingManager::GetInstance()->InitializeViews(image->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void PAImageProcessing::StartBmodeThread() { QList nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; mitk::DataStorage::Pointer storage = this->GetDataStorage(); mitk::DataNode::Pointer node = nodes.front(); if (!node) { // Nothing selected. Inform the user and return QMessageBox::information(NULL, "Template", "Please load and select an image before starting image processing."); return; } mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast(data); if (image) { UpdateBFSettings(image); std::stringstream message; std::string name; message << "Performing image processing for image "; if (node->GetName(name)) { // a property called "name" was found for this DataNode message << "'" << name << "'"; m_OldNodeName = name; } else m_OldNodeName = " "; message << "."; MITK_INFO << message.str(); m_Controls.buttonApplyBModeFilter->setText("working..."); DisableControls(); BmodeThread *thread = new BmodeThread(); connect(thread, &BmodeThread::result, this, &PAImageProcessing::HandleBmodeResults); connect(thread, &BmodeThread::finished, thread, &QObject::deleteLater); bool useGPU = m_Controls.UseGPUBmode->isChecked(); if(m_Controls.BModeMethod->currentText() == "Absolute Filter") thread->setConfig(m_UseLogfilter, m_ResampleSpacing, mitk::PhotoacousticImage::BModeMethod::Abs, useGPU); else if(m_Controls.BModeMethod->currentText() == "Envelope Detection") thread->setConfig(m_UseLogfilter, m_ResampleSpacing, mitk::PhotoacousticImage::BModeMethod::EnvelopeDetection, useGPU); thread->setInputImage(image); thread->setFilterBank(m_FilterBank); MITK_INFO << "Started new thread for Image Processing"; thread->start(); } } } void PAImageProcessing::HandleBmodeResults(mitk::Image::Pointer image) { auto newNode = mitk::DataNode::New(); newNode->SetData(image); // name the new Data node std::stringstream newNodeName; newNodeName << m_OldNodeName << " "; newNodeName << "B-Mode"; newNode->SetName(newNodeName.str()); // update level window for the current dynamic range mitk::LevelWindow levelWindow; newNode->GetLevelWindow(levelWindow); auto data = newNode->GetData(); levelWindow.SetAuto(dynamic_cast(data), true, true); newNode->SetLevelWindow(levelWindow); // add new node to data storage this->GetDataStorage()->Add(newNode); // disable progress bar m_Controls.progressBar->setVisible(false); m_Controls.buttonApplyBModeFilter->setText("Apply B-mode Filter"); EnableControls(); // update rendering mitk::RenderingManager::GetInstance()->InitializeViews( dynamic_cast(data)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void PAImageProcessing::StartCropThread() { QList nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; mitk::DataStorage::Pointer storage = this->GetDataStorage(); mitk::DataNode::Pointer node = nodes.front(); if (!node) { // Nothing selected. Inform the user and return QMessageBox::information(NULL, "Template", "Please load and select an image before starting image cropping."); return; } mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast(data); if (image) { UpdateBFSettings(image); std::stringstream message; std::string name; message << "Performing image cropping for image "; if (node->GetName(name)) { // a property called "name" was found for this DataNode message << "'" << name << "'"; m_OldNodeName = name; } else m_OldNodeName = " "; message << "."; MITK_INFO << message.str(); m_Controls.buttonApplyCropFilter->setText("working..."); DisableControls(); CropThread *thread = new CropThread(); connect(thread, &CropThread::result, this, &PAImageProcessing::HandleCropResults); connect(thread, &CropThread::finished, thread, &QObject::deleteLater); thread->setConfig(m_Controls.CutoffAbove->value(), m_Controls.CutoffBelow->value(), 0, image->GetDimension(2) - 1); thread->setInputImage(image); thread->setFilterBank(m_FilterBank); MITK_INFO << "Started new thread for Image Cropping"; thread->start(); } } } void PAImageProcessing::HandleCropResults(mitk::Image::Pointer image) { auto newNode = mitk::DataNode::New(); newNode->SetData(image); // name the new Data node std::stringstream newNodeName; newNodeName << m_OldNodeName << " "; newNodeName << "Cropped"; newNode->SetName(newNodeName.str()); // update level window for the current dynamic range mitk::LevelWindow levelWindow; newNode->GetLevelWindow(levelWindow); auto data = newNode->GetData(); levelWindow.SetAuto(dynamic_cast(data), true, true); newNode->SetLevelWindow(levelWindow); // add new node to data storage this->GetDataStorage()->Add(newNode); m_Controls.buttonApplyCropFilter->setText("Apply Crop Filter"); EnableControls(); // update rendering mitk::RenderingManager::GetInstance()->InitializeViews( dynamic_cast(data)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void PAImageProcessing::StartBandpassThread() { QList nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; mitk::DataStorage::Pointer storage = this->GetDataStorage(); mitk::DataNode::Pointer node = nodes.front(); if (!node) { // Nothing selected. Inform the user and return QMessageBox::information(NULL, "Template", "Please load and select an image before starting image cropping."); return; } mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast(data); if (image) { UpdateBFSettings(image); std::stringstream message; std::string name; message << "Performing Bandpass filter on image "; if (node->GetName(name)) { // a property called "name" was found for this DataNode message << "'" << name << "'"; m_OldNodeName = name; } else m_OldNodeName = " "; message << "."; MITK_INFO << message.str(); m_Controls.buttonApplyBandpass->setText("working..."); DisableControls(); BandpassThread *thread = new BandpassThread(); connect(thread, &BandpassThread::result, this, &PAImageProcessing::HandleBandpassResults); connect(thread, &BandpassThread::finished, thread, &QObject::deleteLater); float recordTime = image->GetDimension(1)*image->GetGeometry()->GetSpacing()[1] / 1000 / m_Controls.BPSpeedOfSound->value(); // add a safeguard so the program does not chrash when applying a Bandpass that reaches out of the bounds of the image float maxFrequency = 1 / (recordTime / image->GetDimension(1)) * image->GetDimension(1) / 2 / 2 / 1000; float BPHighPass = 1000000 * m_Controls.BPhigh->value(); // [Hz] float BPLowPass = maxFrequency - 1000000 * m_Controls.BPlow->value(); // [Hz] if (BPLowPass > maxFrequency && m_Controls.UseBP->isChecked()) { QMessageBox Msgbox; Msgbox.setText("LowPass too low, disabled it."); Msgbox.exec(); BPLowPass = 0; } if (BPLowPass < 0 && m_Controls.UseBP->isChecked()) { QMessageBox Msgbox; Msgbox.setText("LowPass too high, disabled it."); Msgbox.exec(); BPLowPass = 0; } if (BPHighPass > maxFrequency && m_Controls.UseBP->isChecked()) { QMessageBox Msgbox; Msgbox.setText("HighPass too high, disabled it."); Msgbox.exec(); BPHighPass = 0; } if (BPHighPass > maxFrequency - BFconfig.BPLowPass) { QMessageBox Msgbox; Msgbox.setText("HighPass higher than LowPass, disabled both."); Msgbox.exec(); BPHighPass = 0; BPLowPass = 0; } thread->setConfig(BPHighPass, BPLowPass, m_Controls.BPFalloff->value(), recordTime); thread->setInputImage(image); thread->setFilterBank(m_FilterBank); MITK_INFO << "Started new thread for Bandpass filter"; thread->start(); } } } void PAImageProcessing::HandleBandpassResults(mitk::Image::Pointer image) { auto newNode = mitk::DataNode::New(); newNode->SetData(image); // name the new Data node std::stringstream newNodeName; newNodeName << m_OldNodeName << " "; newNodeName << "Bandpassed"; newNode->SetName(newNodeName.str()); // update level window for the current dynamic range mitk::LevelWindow levelWindow; newNode->GetLevelWindow(levelWindow); auto data = newNode->GetData(); levelWindow.SetAuto(dynamic_cast(data), true, true); newNode->SetLevelWindow(levelWindow); // add new node to data storage this->GetDataStorage()->Add(newNode); m_Controls.buttonApplyBandpass->setText("Apply Bandpass"); EnableControls(); // update rendering mitk::RenderingManager::GetInstance()->InitializeViews( dynamic_cast(data)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void PAImageProcessing::SliceBoundsEnabled() { if (!m_Controls.Partial->isChecked()) { m_Controls.boundLow->setEnabled(false); m_Controls.boundHigh->setEnabled(false); return; } else { m_Controls.boundLow->setEnabled(true); m_Controls.boundHigh->setEnabled(true); } } void PAImageProcessing::UpperSliceBoundChanged() { if(m_Controls.boundLow->value() > m_Controls.boundHigh->value()) { m_Controls.boundLow->setValue(m_Controls.boundHigh->value()); } } void PAImageProcessing::LowerSliceBoundChanged() { if (m_Controls.boundLow->value() > m_Controls.boundHigh->value()) { m_Controls.boundHigh->setValue(m_Controls.boundLow->value()); } } void PAImageProcessing::UpdateProgress(int progress, std::string progressInfo) { if (progress < 100) m_Controls.progressBar->setValue(progress); else m_Controls.progressBar->setValue(100); m_Controls.ProgressInfo->setText(progressInfo.c_str()); qApp->processEvents(); } void PAImageProcessing::PAMessageBox(std::string message) { if (0 != message.compare("noMessage")) { QMessageBox msgBox; msgBox.setText(message.c_str()); msgBox.exec(); } } void PAImageProcessing::UpdateImageInfo() { QList nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; mitk::DataNode::Pointer node = nodes.front(); if (!node) { // Nothing selected return; } mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast(data); if (image) { // beamforming configs if (m_Controls.UseImageSpacing->isChecked()) { m_Controls.ElementCount->setValue(image->GetDimension(0)); m_Controls.Pitch->setValue(image->GetGeometry()->GetSpacing()[0]); } m_Controls.boundLow->setMaximum(image->GetDimension(2) - 1); m_Controls.boundHigh->setMaximum(image->GetDimension(2) - 1); UpdateBFSettings(image); m_Controls.CutoffBeforeBF->setValue(0.000001 / BFconfig.TimeSpacing); // 1us standard offset for our transducer std::stringstream frequency; float maxFrequency = (1 / BFconfig.TimeSpacing) * image->GetDimension(1) / 2 / 2 / 1000; frequency << maxFrequency / 1000000; //[MHz] frequency << "MHz"; m_Controls.BPhigh->setMaximum(maxFrequency / 1000000); m_Controls.BPlow->setMaximum(maxFrequency / 1000000); frequency << " is the maximal allowed frequency for the selected image."; m_Controls.BPhigh->setToolTip(frequency.str().c_str()); m_Controls.BPlow->setToolTip(frequency.str().c_str()); m_Controls.BPhigh->setToolTipDuration(5000); m_Controls.BPlow->setToolTipDuration(5000); } } } void PAImageProcessing::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, const QList& nodes ) { // iterate all selected objects, adjust warning visibility foreach( mitk::DataNode::Pointer node, nodes ) { if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_Controls.labelWarning->setVisible( false ); m_Controls.buttonApplyBModeFilter->setEnabled( true ); m_Controls.labelWarning2->setVisible(false); m_Controls.buttonApplyCropFilter->setEnabled(true); m_Controls.labelWarning3->setVisible(false); m_Controls.buttonApplyBandpass->setEnabled(true); m_Controls.labelWarning4->setVisible(false); m_Controls.buttonApplyBeamforming->setEnabled(true); UpdateImageInfo(); return; } } m_Controls.labelWarning->setVisible( true ); m_Controls.buttonApplyBModeFilter->setEnabled( false ); m_Controls.labelWarning2->setVisible(true); m_Controls.buttonApplyCropFilter->setEnabled(false); m_Controls.labelWarning3->setVisible(true); m_Controls.buttonApplyBandpass->setEnabled(false); m_Controls.labelWarning4->setVisible(true); m_Controls.buttonApplyBeamforming->setEnabled(false); } void PAImageProcessing::UseResampling() { if (m_Controls.DoResampling->isChecked()) { m_Controls.ResamplingValue->setEnabled(true); m_ResampleSpacing = m_Controls.ResamplingValue->value(); } else { m_Controls.ResamplingValue->setEnabled(false); m_ResampleSpacing = 0; } } void PAImageProcessing::UseLogfilter() { m_UseLogfilter = m_Controls.Logfilter->isChecked(); } void PAImageProcessing::SetResampling() { m_ResampleSpacing = m_Controls.ResamplingValue->value(); } void PAImageProcessing::UpdateBFSettings(mitk::Image::Pointer image) { if ("DAS" == m_Controls.BFAlgorithm->currentText()) BFconfig.Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DAS; else if ("DMAS" == m_Controls.BFAlgorithm->currentText()) BFconfig.Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DMAS; else if ("sDMAS" == m_Controls.BFAlgorithm->currentText()) BFconfig.Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS; if ("Quad. Approx." == m_Controls.DelayCalculation->currentText()) { BFconfig.DelayCalculationMethod = mitk::BeamformingSettings::DelayCalc::QuadApprox; } else if ("Spherical Wave" == m_Controls.DelayCalculation->currentText()) { BFconfig.DelayCalculationMethod = mitk::BeamformingSettings::DelayCalc::Spherical; } if ("Von Hann" == m_Controls.Apodization->currentText()) { BFconfig.Apod = mitk::BeamformingSettings::Apodization::Hann; } else if ("Hamming" == m_Controls.Apodization->currentText()) { BFconfig.Apod = mitk::BeamformingSettings::Apodization::Hamm; } else if ("Box" == m_Controls.Apodization->currentText()) { BFconfig.Apod = mitk::BeamformingSettings::Apodization::Box; } BFconfig.Pitch = m_Controls.Pitch->value() / 1000; // [m] BFconfig.SpeedOfSound = m_Controls.SpeedOfSound->value(); // [m/s] BFconfig.SamplesPerLine = m_Controls.Samples->value(); BFconfig.ReconstructionLines = m_Controls.Lines->value(); BFconfig.TransducerElements = m_Controls.ElementCount->value(); BFconfig.apodizationArraySize = m_Controls.Lines->value(); BFconfig.Angle = m_Controls.Angle->value(); // [deg] BFconfig.UseBP = m_Controls.UseBP->isChecked(); BFconfig.UseGPU = m_Controls.UseGPUBf->isChecked(); BFconfig.upperCutoff = m_Controls.CutoffBeforeBF->value(); if (m_Controls.UseImageSpacing->isChecked()) { BFconfig.RecordTime = image->GetDimension(1)*image->GetGeometry()->GetSpacing()[1] / 1000000; // [s] BFconfig.TimeSpacing = image->GetGeometry()->GetSpacing()[1] / 1000000; MITK_INFO << "Calculated Scan Depth of " << BFconfig.RecordTime * BFconfig.SpeedOfSound * 100 / 2 << "cm"; } else { BFconfig.RecordTime = 2 * m_Controls.ScanDepth->value() / 1000 / BFconfig.SpeedOfSound; // [s] BFconfig.TimeSpacing = BFconfig.RecordTime / image->GetDimension(1); } if ("US Image" == m_Controls.ImageType->currentText()) { BFconfig.isPhotoacousticImage = false; } else if ("PA Image" == m_Controls.ImageType->currentText()) { BFconfig.isPhotoacousticImage = true; } BFconfig.partial = m_Controls.Partial->isChecked(); BFconfig.CropBounds[0] = m_Controls.boundLow->value(); BFconfig.CropBounds[1] = m_Controls.boundHigh->value(); } void PAImageProcessing::EnableControls() { m_Controls.BatchProcessing->setEnabled(true); m_Controls.StepBeamforming->setEnabled(true); m_Controls.StepBandpass->setEnabled(true); m_Controls.StepCropping->setEnabled(true); m_Controls.StepBMode->setEnabled(true); UpdateSaveBoxes(); m_Controls.DoResampling->setEnabled(true); UseResampling(); m_Controls.Logfilter->setEnabled(true); m_Controls.BModeMethod->setEnabled(true); m_Controls.buttonApplyBModeFilter->setEnabled(true); m_Controls.CutoffAbove->setEnabled(true); m_Controls.CutoffBelow->setEnabled(true); m_Controls.CutoffBeforeBF->setEnabled(true); m_Controls.buttonApplyCropFilter->setEnabled(true); m_Controls.BPSpeedOfSound->setEnabled(true); m_Controls.buttonApplyBandpass->setEnabled(true); m_Controls.Partial->setEnabled(true); m_Controls.boundHigh->setEnabled(true); m_Controls.boundLow->setEnabled(true); m_Controls.BFAlgorithm->setEnabled(true); m_Controls.DelayCalculation->setEnabled(true); m_Controls.ImageType->setEnabled(true); m_Controls.Apodization->setEnabled(true); m_Controls.UseBP->setEnabled(true); #ifdef PHOTOACOUSTICS_USE_GPU m_Controls.UseGPUBf->setEnabled(true); m_Controls.UseGPUBmode->setEnabled(true); #endif m_Controls.BPhigh->setEnabled(true); m_Controls.BPlow->setEnabled(true); m_Controls.BPFalloff->setEnabled(true); m_Controls.UseImageSpacing->setEnabled(true); UseImageSpacing(); m_Controls.Pitch->setEnabled(true); m_Controls.ElementCount->setEnabled(true); m_Controls.SpeedOfSound->setEnabled(true); m_Controls.Samples->setEnabled(true); m_Controls.Lines->setEnabled(true); m_Controls.Angle->setEnabled(true); m_Controls.buttonApplyBeamforming->setEnabled(true); } void PAImageProcessing::DisableControls() { m_Controls.BatchProcessing->setEnabled(false); m_Controls.StepBeamforming->setEnabled(false); m_Controls.StepBandpass->setEnabled(false); m_Controls.StepCropping->setEnabled(false); m_Controls.StepBMode->setEnabled(false); m_Controls.SaveBeamforming->setEnabled(false); m_Controls.SaveBandpass->setEnabled(false); m_Controls.SaveCropping->setEnabled(false); m_Controls.SaveBMode->setEnabled(false); m_Controls.DoResampling->setEnabled(false); m_Controls.ResamplingValue->setEnabled(false); m_Controls.Logfilter->setEnabled(false); m_Controls.BModeMethod->setEnabled(false); m_Controls.buttonApplyBModeFilter->setEnabled(false); m_Controls.CutoffAbove->setEnabled(false); m_Controls.CutoffBelow->setEnabled(false); m_Controls.CutoffBeforeBF->setEnabled(false); m_Controls.buttonApplyCropFilter->setEnabled(false); m_Controls.BPSpeedOfSound->setEnabled(false); m_Controls.buttonApplyBandpass->setEnabled(false); m_Controls.Partial->setEnabled(false); m_Controls.boundHigh->setEnabled(false); m_Controls.boundLow->setEnabled(false); m_Controls.BFAlgorithm->setEnabled(false); m_Controls.DelayCalculation->setEnabled(false); m_Controls.ImageType->setEnabled(false); m_Controls.Apodization->setEnabled(false); m_Controls.UseBP->setEnabled(false); #ifdef PHOTOACOUSTICS_USE_GPU m_Controls.UseGPUBf->setEnabled(false); m_Controls.UseGPUBmode->setEnabled(false); #endif m_Controls.BPhigh->setEnabled(false); m_Controls.BPlow->setEnabled(false); m_Controls.BPFalloff->setEnabled(false); m_Controls.UseImageSpacing->setEnabled(false); m_Controls.ScanDepth->setEnabled(false); m_Controls.Pitch->setEnabled(false); m_Controls.ElementCount->setEnabled(false); m_Controls.SpeedOfSound->setEnabled(false); m_Controls.Samples->setEnabled(false); m_Controls.Lines->setEnabled(false); m_Controls.Angle->setEnabled(false); m_Controls.buttonApplyBeamforming->setEnabled(false); } void PAImageProcessing::UseImageSpacing() { if (m_Controls.UseImageSpacing->isChecked()) { m_Controls.ScanDepth->setDisabled(true); } else { m_Controls.ScanDepth->setEnabled(true); } } #include void BeamformingThread::run() { mitk::Image::Pointer resultImage = mitk::Image::New(); mitk::Image::Pointer resultImageBuffer; std::string errorMessage = ""; std::function progressHandle = [this](int progress, std::string progressInfo) { emit updateProgress(progress, progressInfo); }; resultImageBuffer = m_FilterBank->ApplyBeamforming(m_InputImage, m_BFconfig, errorMessage, progressHandle); mitk::ImageReadAccessor copy(resultImageBuffer); resultImage->Initialize(resultImageBuffer); resultImage->SetSpacing(resultImageBuffer->GetGeometry()->GetSpacing()); resultImage->SetImportVolume(const_cast(copy.GetData()), 0, 0, mitk::Image::CopyMemory); emit result(resultImage); emit message(errorMessage); } void BeamformingThread::setConfig(mitk::BeamformingSettings BFconfig) { m_BFconfig = BFconfig; } void BeamformingThread::setInputImage(mitk::Image::Pointer image) { m_InputImage = image; } void BmodeThread::run() { mitk::Image::Pointer resultImage; resultImage = m_FilterBank->ApplyBmodeFilter(m_InputImage, m_Method, m_UseGPU, m_UseLogfilter, m_ResampleSpacing); emit result(resultImage); } void BmodeThread::setConfig(bool useLogfilter, double resampleSpacing, mitk::PhotoacousticImage::BModeMethod method, bool useGPU) { m_UseLogfilter = useLogfilter; m_ResampleSpacing = resampleSpacing; m_Method = method; m_UseGPU = useGPU; } void BmodeThread::setInputImage(mitk::Image::Pointer image) { m_InputImage = image; } void CropThread::run() { mitk::Image::Pointer resultImage; resultImage = m_FilterBank->ApplyCropping(m_InputImage, m_CutAbove, m_CutBelow, 0, 0, m_CutSliceFirst, m_CutSliceLast); emit result(resultImage); } void CropThread::setConfig(unsigned int CutAbove, unsigned int CutBelow, unsigned int CutSliceFirst, unsigned int CutSliceLast) { m_CutAbove = CutAbove; m_CutBelow = CutBelow; m_CutSliceLast = CutSliceLast; m_CutSliceFirst = CutSliceFirst; } void CropThread::setInputImage(mitk::Image::Pointer image) { m_InputImage = image; } void BandpassThread::run() { mitk::Image::Pointer resultImage; resultImage = m_FilterBank->BandpassFilter(m_InputImage, m_RecordTime, m_BPHighPass, m_BPLowPass, m_TukeyAlpha); emit result(resultImage); } void BandpassThread::setConfig(float BPHighPass, float BPLowPass, float TukeyAlpha, float recordTime) { m_BPHighPass = BPHighPass; m_BPLowPass = BPLowPass; m_TukeyAlpha = TukeyAlpha; m_RecordTime = recordTime; } void BandpassThread::setInputImage(mitk::Image::Pointer image) { m_InputImage = image; }