diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index d153e96dad..4daa70f838 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,86 +1,85 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(MITK_MODULES Core CommandLine AppUtil LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMQI DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel Chart ImageStatistics ContourModel SurfaceInterpolation Segmentation QtWidgets QtWidgetsExt ImageStatisticsUI SegmentationUI MatchPointRegistration MatchPointRegistrationUI Classification OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI PhotoacousticsHardware PhotoacousticsAlgorithms PhotoacousticsLib US USUI DicomUI Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware -# TumorInvasionAnalysis BoundingShape RenderWindowManager RenderWindowManagerUI SemanticRelations SemanticRelationsUI CEST BasicImageProcessing ModelFit ModelFitUI Pharmacokinetics PharmacokineticsUI DICOMPM REST RESTService DICOMweb ) if(MITK_ENABLE_PIC_READER) list(APPEND MITK_MODULES IpPicSupportIO) endif() diff --git a/Modules/TumorInvasionAnalysis/CMakeLists.txt b/Modules/TumorInvasionAnalysis/CMakeLists.txt deleted file mode 100644 index 270882e798..0000000000 --- a/Modules/TumorInvasionAnalysis/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -MITK_CREATE_MODULE( - INCLUDE_DIRS PRIVATE src/Classification src/ImageFilters src/ReaderWriter - DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking MitkDiffusionIO MitkDataCollection MitkSegmentation MitkCLVigraRandomForest #<-- modules on which your module depends - PACKAGE_DEPENDS PUBLIC ITK|ITKDiffusionTensorImage+ITKLevelSets Qt5|Core -) - - -if (MODULE_IS_ENABLED) - add_subdirectory(test) - ADD_SUBDIRECTORY(MiniApps) -endif() diff --git a/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp b/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp deleted file mode 100644 index 6e292ed37d..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/BasicDistanceMaps.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", mitkCommandLineParser::Image, "(binary) seed file", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("output", "o", mitkCommandLineParser::File, "distance map file name", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - - 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 = 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/CMakeLists.txt b/Modules/TumorInvasionAnalysis/MiniApps/CMakeLists.txt deleted file mode 100644 index 8525a62c29..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -option(BUILD_TumorInvasionAnalysisMiniApps "Build commandline tools for tumor invasion analysis" OFF) - -if(BUILD_TumorInvasionAnalysisMiniApps OR MITK_BUILD_ALL_APPS) - - - include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ) - - # list of miniapps - # if an app requires additional dependencies - # they are added after a "^^" and separated by "_" - set( tumorinvasionminiapps - BasicDistanceMaps^^ - MriNormalization^^ - MriOtsuNormalization^^ - #Resampling^^ - TumorResponseEvaluationTool^^ - HistogramAdaption^^ - TumorProgressionMapping^^ - ConnectednessFeatureMaps^^ - TumorInvasionAnalysisTool^^ - ) - - foreach(tumorinvasionminiapps ${tumorinvasionminiapps}) - # extract mini app name and dependencies - string(REPLACE "^^" "\\;" miniapp_info ${tumorinvasionminiapps}) - set(miniapp_info_list ${miniapp_info}) - list(GET miniapp_info_list 0 appname) - list(GET miniapp_info_list 1 raw_dependencies) - string(REPLACE "_" "\\;" dependencies "${raw_dependencies}") - set(dependencies_list ${dependencies}) - - mitkFunctionCreateCommandLineApp( - NAME ${appname} - DEPENDS MitkCore MitkCLCore MitkDataCollection MitkTumorInvasionAnalysis ${dependencies_list} - ) - endforeach() - -endif() diff --git a/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp b/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp deleted file mode 100644 index 9ee23bb745..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/ConnectednessFeatureMaps.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - parser.addArgument("input", "i", mitkCommandLineParser::Image, "input file", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("seed", "s", mitkCommandLineParser::Image, "seed file", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("mask", "m", mitkCommandLineParser::Image, "mask file", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("mode", "t", mitkCommandLineParser::String, "Mode Feature | Vector | FeatureVector"); - parser.addArgument("vector", "v", mitkCommandLineParser::Image, "Tensor Image (.dti)", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "confidence", "c", mitkCommandLineParser::Image, "confidence map (only when Tensor Images are used)", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("valueImage", "x", mitkCommandLineParser::Image, "image of values that are propagated", "", us::Any(), true, false, false, mitkCommandLineParser::Input); - - 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::File, "[out] propagated map", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("distanceMap", "d", mitkCommandLineParser::File, "[out] connectedness map", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("euclidDistanceMap", "e", mitkCommandLineParser::File, "[out] euclid distance map", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - - // 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 = 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 = mitk::IOUtil::Load(valueImageFile); - - mitk::Image::Pointer confImage; - if (mode == "Vector" || mode == "FeatureVector") - { - MITK_INFO << "Load Tensor/Confidence"; - 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 deleted file mode 100644 index cac1581f62..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/HistogramAdaption.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - - // Add command line argument names - parser.addArgument("input", "i", mitkCommandLineParser::Image, "input image", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("output", "o", mitkCommandLineParser::File, "output image", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - 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 = 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 deleted file mode 100644 index 867cf8ee69..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/MriNormalization.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - - // Add command line argument names - parser.addArgument("input", "i", mitkCommandLineParser::Image, "input image", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("output", "o", mitkCommandLineParser::File, "output image", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument( - "maxMask", "m", mitkCommandLineParser::Image, "mask of which median is set as maximal value (1)", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "minMask", "l", mitkCommandLineParser::Image, "mask of which median is set as minimal value (0)", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "excludeMask", "e", mitkCommandLineParser::Image, "region which is exluded from the other two", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - - 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 = 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 deleted file mode 100644 index bee84b9806..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/MriOtsuNormalization.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#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("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - - // Add command line argument names - parser.addArgument("input", "i", mitkCommandLineParser::Image, "input image", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("output", "o", mitkCommandLineParser::File, "output image", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); - 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 = 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/TumorInvasionAnalysisTool.cpp b/Modules/TumorInvasionAnalysis/MiniApps/TumorInvasionAnalysisTool.cpp deleted file mode 100644 index bc40bcc543..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/TumorInvasionAnalysisTool.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// MITK - DataCollection -#include -#include -#include -#include - -#include "mitkDataCollectionImageIterator.h" -#include -#include -// CTK -#include "mitkCommandLineParser.h" -// ITK -#include - -using namespace std; - -int main(int argc, char *argv[]) -{ - // Setup CLI Module parsable interface - mitkCommandLineParser parser; - parser.setTitle("Tumor Invasion Analysis"); - parser.setCategory("Tumor Analysis"); - parser.setDescription("Learns and predicts Invasion behavior"); - parser.setContributor("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - // Add command line argument names - parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Show options"); - parser.addArgument("loadFile", "l", mitkCommandLineParser::File, "DataCollection File", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "colIds", "c", mitkCommandLineParser::String, "Patient Identifiers from DataCollection used for training"); - parser.addArgument( - "testId", "t", mitkCommandLineParser::String, "Patient Identifier from DataCollection used for testing"); - parser.addArgument("features", "b", mitkCommandLineParser::String, "Features"); - parser.addArgument("stats", "s", mitkCommandLineParser::String, "Output file for stats"); - parser.addArgument("ratio", "q", mitkCommandLineParser::Float, "ratio of tumor to healthy"); - parser.addArgument("treeDepth", "d", mitkCommandLineParser::Int, "limits tree depth"); - parser.addArgument("forestSize", "f", mitkCommandLineParser::Int, "number of trees"); - parser.addArgument("samplingMode", "m", mitkCommandLineParser::Int, "mode of sample selection"); - parser.addArgument("configName", "n", mitkCommandLineParser::String, "human readable name for configuration"); - parser.addArgument("output", "o", mitkCommandLineParser::Directory, "output folder for results", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("forest", "t", mitkCommandLineParser::File, "store trained forest to file", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - - map parsedArgs = parser.parseArguments(argc, argv); - // Show a help message - if (parsedArgs.size() == 0) - return EXIT_SUCCESS; - if (parsedArgs.count("help") || parsedArgs.count("h")) - { - std::cout << parser.helpText(); - return EXIT_SUCCESS; - } - - // Default values - float ratio = 1.0; - bool useStatsFile = false; - unsigned int forestSize = 250; - unsigned int treeDepth = 0; - unsigned int samplingMode = 1; - std::string configName = ""; - std::string outputFolder = ""; - std::string forestFile = ""; - - std::vector features; - std::vector trainingIds; - std::vector testingIds; - std::vector loadIds; // features + masks needed for training and evaluation - std::string outputFile; - std::string xmlFile; - std::ofstream experimentFS; - - // Parse input parameters - { - if (parsedArgs.count("colIds") || parsedArgs.count("c")) - { - std::istringstream ss(us::any_cast(parsedArgs["colIds"])); - std::string token; - - while (std::getline(ss, token, ',')) - trainingIds.push_back(token); - } - - if (parsedArgs.count("output") || parsedArgs.count("o")) - { - outputFolder = us::any_cast(parsedArgs["output"]); - } - - if (parsedArgs.count("configName") || parsedArgs.count("n")) - { - configName = us::any_cast(parsedArgs["configName"]); - } - - if (parsedArgs.count("features") || parsedArgs.count("b")) - { - std::istringstream ss(us::any_cast(parsedArgs["features"])); - std::string token; - - while (std::getline(ss, token, ',')) - features.push_back(token); - } - - if (parsedArgs.count("treeDepth") || parsedArgs.count("d")) - { - treeDepth = us::any_cast(parsedArgs["treeDepth"]); - } - - if (parsedArgs.count("ratio") || parsedArgs.count("q")) - { - ratio = us::any_cast(parsedArgs["ratio"]); - } - - if (parsedArgs.count("forestSize") || parsedArgs.count("f")) - { - forestSize = us::any_cast(parsedArgs["forestSize"]); - } - - if (parsedArgs.count("samplingMode") || parsedArgs.count("m")) - { - samplingMode = us::any_cast(parsedArgs["samplingMode"]); - } - - if (parsedArgs.count("stats") || parsedArgs.count("s")) - { - useStatsFile = true; - experimentFS.open(us::any_cast(parsedArgs["stats"]).c_str(), std::ios_base::app); - } - - if (parsedArgs.count("forest") || parsedArgs.count("t")) - { - forestFile = us::any_cast(parsedArgs["stats"]); - } - - if (parsedArgs.count("testId") || parsedArgs.count("t")) - { - std::istringstream ss(us::any_cast(parsedArgs["testId"])); - std::string token; - - while (std::getline(ss, token, ',')) - testingIds.push_back(token); - } - - for (unsigned int i = 0; i < features.size(); i++) - { - loadIds.push_back(features.at(i)); - } - loadIds.push_back("GTV"); - loadIds.push_back("BRAINMASK"); - loadIds.push_back("TARGET"); - - if (parsedArgs.count("stats") || parsedArgs.count("s")) - { - outputFile = us::any_cast(parsedArgs["stats"]); - } - - if (parsedArgs.count("loadFile") || parsedArgs.count("l")) - { - xmlFile = us::any_cast(parsedArgs["loadFile"]); - } - else - { - MITK_ERROR << parser.helpText(); - return EXIT_FAILURE; - } - } - - mitk::DataCollection::Pointer trainCollection; - mitk::DataCollection::Pointer testCollection; - { - mitk::DiffusionCollectionReader colReader; - // Load only relevant images - colReader.SetDataItemNames(loadIds); - colReader.AddSubColIds(testingIds); - testCollection = colReader.LoadCollection(xmlFile); - colReader.ClearDataElementIds(); - colReader.ClearSubColIds(); - colReader.SetDataItemNames(loadIds); - colReader.AddSubColIds(trainingIds); - trainCollection = colReader.LoadCollection(xmlFile); - } - - std::cout << "Setup Training" << std::endl; - mitk::TumorInvasionClassification classifier; - - classifier.SetClassRatio(ratio); - classifier.SetTrainMargin(7, 1); - classifier.SamplesWeightingActivated(true); - classifier.SelectTrainingSamples(trainCollection, samplingMode); - // Learning stage - std::cout << "Start Training" << std::endl; - classifier.LearnProgressionFeatures(trainCollection, features, forestSize, treeDepth); - - if (forestFile != "") - classifier.SaveRandomForest(forestFile); - - std::cout << "Start Predict" << std::endl; - classifier.PredictInvasion(testCollection, features); - - if (false && outputFolder != "") - { - std::cout << "Saving files to " << outputFolder << std::endl; - mitk::DiffusionCollectionWriter::ExportCollectionToFolder(trainCollection, "/tmp/dumple"); - } - classifier.SanitizeResults(testCollection); - - { - mitk::DataCollectionImageIterator gtvIt(testCollection, "GTV"); - mitk::DataCollectionImageIterator result(testCollection, "RESULTOPEN"); - - while (!gtvIt.IsAtEnd()) - { - if (gtvIt.GetVoxel() != 0) - { - result.SetVoxel(2); - } - - result++; - gtvIt++; - } - } - - mitk::CollectionStatistic stat2; - mitk::ProgressionValueToIndexMapper progressionValueToIndexMapper; - mitk::BinaryValueToIndexMapper binaryValueToIndexMapper; - - stat2.SetCollection(testCollection); - stat2.SetClassCount(2); - stat2.SetGoldName("TARGET"); - stat2.SetTestName("RESULTOPEN"); - stat2.SetMaskName("BRAINMASK"); - stat2.SetGroundTruthValueToIndexMapper(&binaryValueToIndexMapper); - stat2.SetTestValueToIndexMapper(&progressionValueToIndexMapper); - - stat2.Update(); - stat2.ComputeRMSD(); - - // FIXME: DICE value available after calling Print method - std::ostringstream out2; - stat2.Print(out2, std::cout, true); - std::cout << std::endl << std::endl << out2.str() << std::endl; - - // Exclude GTV from Statistics by removing it from brain mask, - // insert GTV as tumor region, since it is known before, in the result. - { - mitk::DataCollectionImageIterator gtvIt(testCollection, "GTV"); - mitk::DataCollectionImageIterator brainMaskIter(testCollection, "BRAINMASK"); - mitk::DataCollectionImageIterator result(testCollection, "RESULTOPEN"); - - while (!gtvIt.IsAtEnd()) - { - if (gtvIt.GetVoxel() != 0) - { - brainMaskIter.SetVoxel(0); - result.SetVoxel(2); - } - result++; - gtvIt++; - brainMaskIter++; - } - } - - mitk::CollectionStatistic stat; - stat.SetCollection(testCollection); - stat.SetClassCount(2); - stat.SetGoldName("TARGET"); - stat.SetTestName("RESULTOPEN"); - stat.SetMaskName("BRAINMASK"); - stat.SetGroundTruthValueToIndexMapper(&binaryValueToIndexMapper); - stat.SetTestValueToIndexMapper(&progressionValueToIndexMapper); - - stat.Update(); - stat.ComputeRMSD(); - - // WARN: DICE value computed within Print method, so values are only available - // after - // calling Print() - std::ostringstream out; - stat.Print(out, std::cout, true); - std::cout << std::endl << std::endl << out.str() << std::endl; - - // Statistics for original GTV excluded (Dice,Sensitivity) and for Gold - // Standard vs prediction (RMSE) - mitk::StatisticData statData = stat.GetStatisticData(1).at(0); - mitk::StatisticData statData2 = stat2.GetStatisticData(1).at(0); - - std::cout << "Writing Stats to file" << std::endl; - // one line output - if (useStatsFile) - { - experimentFS << "Tree_Depth " << treeDepth << ','; - experimentFS << "Forest_Size " << forestSize << ','; - experimentFS << "Tumor/healthy_ratio " << ratio << ','; - experimentFS << "Sample_Selection " << samplingMode << ','; - - experimentFS << "Trainined_on: " << ','; - for (unsigned int i = 0; i < trainingIds.size(); i++) - { - experimentFS << trainingIds.at(i) << "/"; - } - experimentFS << ','; - - experimentFS << "Tested_on: " << ','; - for (unsigned int i = 0; i < testingIds.size(); i++) - { - experimentFS << testingIds.at(i) << "/"; - } - experimentFS << ','; - - experimentFS << "Features_used: " << ','; - if (configName == "") - { - for (unsigned int i = 0; i < features.size(); i++) - { - experimentFS << features.at(i) << "/"; - } - } - else - experimentFS << configName; - - experimentFS << ','; - experimentFS << "---- STATS ---" << ','; - experimentFS << " Sensitivity " << statData.m_Sensitivity << ','; - experimentFS << " DICE " << statData.m_DICE << ','; - experimentFS << " RMSE " << statData2.m_RMSD << ','; - experimentFS << std::endl; - } - - if (outputFolder != "") - { - std::cout << "Saving files to " << outputFolder << std::endl; - mitk::DiffusionCollectionWriter::ExportCollectionToFolder(testCollection, outputFolder); - } - - return EXIT_SUCCESS; -} diff --git a/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp b/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp deleted file mode 100644 index 45d832b4a8..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/TumorProgressionMapping.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -// 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(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("German Cancer Research Center (DKFZ)"); - 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::Directory, "Input folder containing all follow ups", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument("output", "o", mitkCommandLineParser::File, "Output file (PNG)", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - 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::File, "Filepath to merged 4d NRRD Volume.", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - 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/MiniApps/TumorResponseEvaluationTool.cpp b/Modules/TumorInvasionAnalysis/MiniApps/TumorResponseEvaluationTool.cpp deleted file mode 100644 index 9ace8b1448..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/TumorResponseEvaluationTool.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// MITK - DataCollection -#include -#include -#include -#include - -#include "mitkDataCollectionImageIterator.h" -#include -#include -// CTK -#include "mitkCommandLineParser.h" -// ITK -#include - -using namespace std; - -int main(int argc, char *argv[]) -{ - // Setup CLI Module parsable interface - mitkCommandLineParser parser; - parser.setTitle("Tumor Invasion Analysis"); - parser.setCategory("Tumor Analysis"); - parser.setDescription("Learns and predicts Invasion behavior"); - parser.setContributor("German Cancer Research Center (DKFZ)"); - - parser.setArgumentPrefix("--", "-"); - // Add command line argument names - parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Show options"); - parser.addArgument("loadFile", "l", mitkCommandLineParser::File, "DataCollection File", "", us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "colIds", "c", mitkCommandLineParser::String, "Patient Identifiers from DataCollection used for training"); - parser.addArgument( - "testId", "t", mitkCommandLineParser::String, "Patient Identifier from DataCollection used for testing"); - parser.addArgument("features", "b", mitkCommandLineParser::String, "Features"); - parser.addArgument("stats", "s", mitkCommandLineParser::String, "Output file for stats"); - parser.addArgument("ratio", "q", mitkCommandLineParser::Float, "ratio of tumor to healthy"); - parser.addArgument("treeDepth", "d", mitkCommandLineParser::Int, "limits tree depth"); - parser.addArgument("forestSize", "f", mitkCommandLineParser::Int, "number of trees"); - parser.addArgument("configName", "n", mitkCommandLineParser::String, "human readable name for configuration"); - parser.addArgument("output", "o", mitkCommandLineParser::Directory, "output folder for results", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument("forest", "t", mitkCommandLineParser::File, "store trained forest to file", "", us::Any(), false, false, false, mitkCommandLineParser::Output); - - map parsedArgs = parser.parseArguments(argc, argv); - // Show a help message - if (parsedArgs.size() == 0) - return EXIT_SUCCESS; - if (parsedArgs.count("help") || parsedArgs.count("h")) - { - std::cout << parser.helpText(); - return EXIT_SUCCESS; - } - - // Default values - float ratio = 1.0; - bool useStatsFile = false; - unsigned int forestSize = 250; - unsigned int treeDepth = 0; - std::string configName = ""; - std::string outputFolder = ""; - std::string forestFile = ""; - - std::vector features; - std::vector trainingIds; - std::vector testingIds; - std::vector loadIds; // features + masks needed for training and evaluation - std::string outputFile; - std::string xmlFile; - std::ofstream experimentFS; - - // Parse input parameters - { - if (parsedArgs.count("colIds") || parsedArgs.count("c")) - { - std::istringstream ss(us::any_cast(parsedArgs["colIds"])); - std::string token; - - while (std::getline(ss, token, ',')) - trainingIds.push_back(token); - } - - if (parsedArgs.count("output") || parsedArgs.count("o")) - { - outputFolder = us::any_cast(parsedArgs["output"]); - } - - if (parsedArgs.count("configName") || parsedArgs.count("n")) - { - configName = us::any_cast(parsedArgs["configName"]); - } - - if (parsedArgs.count("features") || parsedArgs.count("b")) - { - std::istringstream ss(us::any_cast(parsedArgs["features"])); - std::string token; - - while (std::getline(ss, token, ',')) - features.push_back(token); - } - - if (parsedArgs.count("treeDepth") || parsedArgs.count("d")) - { - treeDepth = us::any_cast(parsedArgs["treeDepth"]); - } - - if (parsedArgs.count("ratio") || parsedArgs.count("q")) - { - ratio = us::any_cast(parsedArgs["ratio"]); - } - - if (parsedArgs.count("forestSize") || parsedArgs.count("f")) - { - forestSize = us::any_cast(parsedArgs["forestSize"]); - } - - if (parsedArgs.count("stats") || parsedArgs.count("s")) - { - useStatsFile = true; - experimentFS.open(us::any_cast(parsedArgs["stats"]).c_str(), std::ios_base::app); - } - - if (parsedArgs.count("forest") || parsedArgs.count("t")) - { - forestFile = us::any_cast(parsedArgs["stats"]); - } - - if (parsedArgs.count("testId") || parsedArgs.count("t")) - { - std::istringstream ss(us::any_cast(parsedArgs["testId"])); - std::string token; - - while (std::getline(ss, token, ',')) - testingIds.push_back(token); - } - - for (unsigned int i = 0; i < features.size(); i++) - { - loadIds.push_back(features.at(i)); - } - loadIds.push_back("GTV"); - loadIds.push_back("BRAINMASK"); - loadIds.push_back("TARGET"); - - if (parsedArgs.count("stats") || parsedArgs.count("s")) - { - outputFile = us::any_cast(parsedArgs["stats"]); - } - - if (parsedArgs.count("loadFile") || parsedArgs.count("l")) - { - xmlFile = us::any_cast(parsedArgs["loadFile"]); - } - else - { - MITK_ERROR << parser.helpText(); - return EXIT_FAILURE; - } - } - - mitk::DataCollection::Pointer trainCollection; - mitk::DataCollection::Pointer testCollection; - { - mitk::DiffusionCollectionReader colReader; - // Load only relevant images - colReader.SetDataItemNames(loadIds); - colReader.AddSubColIds(testingIds); - testCollection = colReader.LoadCollection(xmlFile); - colReader.ClearDataElementIds(); - colReader.ClearSubColIds(); - colReader.SetDataItemNames(loadIds); - colReader.AddSubColIds(trainingIds); - trainCollection = colReader.LoadCollection(xmlFile); - } - - std::cout << "Setup Training" << std::endl; - mitk::TumorInvasionClassification classifier; - - classifier.SetClassRatio(ratio); - classifier.SamplesWeightingActivated(true); - classifier.PrepareResponseSamples(trainCollection); - // Learning stage - std::cout << "Start Training" << std::endl; - classifier.LearnProgressionFeatures(trainCollection, features, forestSize, treeDepth); - - if (forestFile != "") - classifier.SaveRandomForest(forestFile); - - std::cout << "Start Predict" << std::endl; - classifier.PredictInvasion(testCollection, features); - - if (outputFolder != "") - { - std::cout << "Saving files to " << outputFolder << std::endl; - mitk::DiffusionCollectionWriter::ExportCollectionToFolder(trainCollection, "/tmp/dumple"); - } - - /* prepare target values to match training values: - * 0 - excluded (e.g. out of brainmask) - * 1 - no involvement (healthy all the time) - * 2 - formerly healthy, now tumor (rezivid) - * 3 - formerly tumor, now necroses (responsive) - */ - - { - mitk::DataCollectionImageIterator gtvIter(testCollection, "GTV"); - mitk::DataCollectionImageIterator targetIt(testCollection, "TARGET"); - - while (!gtvIter.IsAtEnd()) - { - if (targetIt.GetVoxel() == 0 && gtvIter.GetVoxel() == 0) - targetIt.SetVoxel(1); - - if (targetIt.GetVoxel() == 0 && gtvIter.GetVoxel() == 1) - targetIt.SetVoxel(3); - - if (targetIt.GetVoxel() == 1 && gtvIter.GetVoxel() == 0) - targetIt.SetVoxel(2); - - targetIt++; - gtvIter++; - } - } - - mitk::CollectionStatistic stats; - mitk::ProgressionValueToIndexMapper progressionValueToIndexMapper; - mitk::BinaryValueToIndexMapper binaryValueToIndexMapper; - - stats.SetCollection(testCollection); - stats.SetClassCount(4); - stats.SetGoldName("TARGET"); - stats.SetTestName("RESULT"); - stats.SetMaskName("BRAINMASK"); - stats.SetGroundTruthValueToIndexMapper(&binaryValueToIndexMapper); - stats.SetTestValueToIndexMapper(&binaryValueToIndexMapper); - - stats.Update(); - std::ostringstream outStr; - stats.Print(outStr, std::cout, true); - std::cout << std::endl << std::endl << outStr.str() << std::endl; - - if (useStatsFile) - std::cout << "dummy" << std::endl; - - if (outputFolder != "") - { - std::cout << "Saving files to " << outputFolder << std::endl; - mitk::DiffusionCollectionWriter::ExportCollectionToFolder(testCollection, outputFolder); - } - - return EXIT_SUCCESS; -} diff --git a/Modules/TumorInvasionAnalysis/MiniApps/typeExtension.h b/Modules/TumorInvasionAnalysis/MiniApps/typeExtension.h deleted file mode 100644 index eff3e5398d..0000000000 --- a/Modules/TumorInvasionAnalysis/MiniApps/typeExtension.h +++ /dev/null @@ -1,55 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// MITK -#include -#include -#include -#include - -// ITK -#include - -namespace mitk -{ - typedef itk::Image, 3> itkImageRGBUS3; - - template void _CastToItkImage2Access(const itkImageRGBUS3 *, itk::SmartPointer &); - - template - void _CastToItkImage2Access(const itk::Image *itkInputImage, - itk::SmartPointer &itkOutputImage) - { - typedef itk::Image ItkInputImageType; - if (typeid(ItkInputImageType) == typeid(ItkOutputImageType)) - { - itkOutputImage = const_cast(reinterpret_cast(itkInputImage)); - return; - } - typedef itk::CastImageFilter CastImageFilterType; - typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New(); - castImageFilter->SetInput(itkInputImage); - castImageFilter->Update(); - itkOutputImage = castImageFilter->GetOutput(); - } - - template <> - void CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer &itkOutputImage) - { - typedef itkImageRGBUS3 ItkOutputImageType; - AccessFixedTypeByItk_1(mitkImage, - _CastToItkImage2Access, - (itk::RGBPixel), - (ItkOutputImageType::ImageDimension), - itkOutputImage); - } -} diff --git a/Modules/TumorInvasionAnalysis/files.cmake b/Modules/TumorInvasionAnalysis/files.cmake deleted file mode 100644 index a757fcc18b..0000000000 --- a/Modules/TumorInvasionAnalysis/files.cmake +++ /dev/null @@ -1,9 +0,0 @@ -file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") - -SET(CPP_FILES - ReaderWriter/mitkDiffusionCollectionReader.cpp - ReaderWriter/mitkDiffusionCollectionWriter.cpp - Classification/mitkTumorInvasionClassification.cpp - ImageFilters/mitkCollectionDilatation.cpp - ImageFilters/mitkCollectionGrayOpening.cpp -) diff --git a/Modules/TumorInvasionAnalysis/include/itkConnectednessFilter.cxx b/Modules/TumorInvasionAnalysis/include/itkConnectednessFilter.cxx deleted file mode 100644 index cf5d4e4a3e..0000000000 --- a/Modules/TumorInvasionAnalysis/include/itkConnectednessFilter.cxx +++ /dev/null @@ -1,479 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef __ConnectednessFilter_hxx -#define __ConnectednessFilter_hxx - -#ifdef _MSC_VER -# pragma warning(disable : 4996) -#endif - -#include "itkConnectednessFilter.h" -#include "itkImageRegionConstIterator.h" -#include "itkImageRegionIterator.h" -#include "itkObjectFactory.h" -#include -// Vector Fields -#include "itkVectorImage.h" -#include -// -#include "itkConstantBoundaryCondition.h" -#include "itkNeighborhoodIterator.h" - -namespace itk -{ - template - void ConnectednessFilter::SetInputImage(const TFeatureImage *image) - { - this->SetNthInput(0, const_cast(image)); - } - - template - void ConnectednessFilter::SetInputSeed(const TSeedImage *image) - { - this->SetNthInput(1, const_cast(image)); - } - - template - void ConnectednessFilter::SetInputMask(const TSeedImage *image) - { - this->SetNthInput(2, const_cast(image)); - } - - template - void ConnectednessFilter::SetInputVectorFieldConfidenceMap( - const TFeatureImage *conf) - { - // DO NOT set it as nth input, since it is dti derived and therefore does - // not necessarily occupy the same space as the other images - m_ConfidenceImage = const_cast(conf); - } - - template - void ConnectednessFilter::SetPropagationImage(const TFeatureImage *image) - { - this->SetNthInput(3, const_cast(image)); - } - - template - typename TFeatureImage::Pointer ConnectednessFilter::GetDistanceImage() - { - return m_DistanceImage; - } - - template - typename TFeatureImage::Pointer - ConnectednessFilter::GetEuclideanDistanceImage() - { - return m_EuclideanDistance; - } - - template - void ConnectednessFilter::SetInputVectorField(const TTensorImage *vecs) - { - // DO NOT set it as nth input, since it is dti derived and therefore does - // not necessary occupy the same space as the other images - m_TensorImage = const_cast(vecs); - } - - template - void ConnectednessFilter::GenerateData() - { - const char untouchedValue = -10; - const char inListValue = -30; - // Get Inputs - m_InputImage = dynamic_cast(this->ProcessObject::GetInput(0)); - typename TSeedImage::Pointer seed = dynamic_cast(this->ProcessObject::GetInput(1)); - typename TSeedImage::Pointer mask = dynamic_cast(this->ProcessObject::GetInput(2)); - typename TFeatureImage::Pointer propagationImage = dynamic_cast(this->ProcessObject::GetInput(3)); - - if (propagationImage.IsNull()) - propagationImage = m_InputImage; - - // --- - // Allocate Output - typename TFeatureImage::Pointer output = this->GetOutput(); - output->SetRegions(m_InputImage->GetLargestPossibleRegion()); - output->Allocate(); - output->FillBuffer(untouchedValue); - - m_DistanceImage = TFeatureImage::New(); - m_DistanceImage->SetRegions(m_InputImage->GetLargestPossibleRegion()); - m_DistanceImage->Allocate(); - m_DistanceImage->FillBuffer(untouchedValue); - m_DistanceImage->SetOrigin(m_InputImage->GetOrigin()); - m_DistanceImage->SetDirection(m_InputImage->GetDirection()); - m_DistanceImage->SetSpacing(m_InputImage->GetSpacing()); - - m_EuclideanDistance = TFeatureImage::New(); - m_EuclideanDistance->SetRegions(m_InputImage->GetLargestPossibleRegion()); - m_EuclideanDistance->Allocate(); - m_EuclideanDistance->FillBuffer(0.0); - m_EuclideanDistance->SetOrigin(m_InputImage->GetOrigin()); - m_EuclideanDistance->SetDirection(m_InputImage->GetDirection()); - m_EuclideanDistance->SetSpacing(m_InputImage->GetSpacing()); - - // Helper Object - Indicates which voxels are currently in the FIFO, - // this prevents excessive memory and comptutational overhead - typename TFeatureImage::Pointer activeSeeds = TFeatureImage::New(); - activeSeeds->SetRegions(m_InputImage->GetLargestPossibleRegion()); - activeSeeds->Allocate(); - activeSeeds->FillBuffer(untouchedValue); - - // Create Iterators - SeedIteratorType seedIt(seed, seed->GetLargestPossibleRegion()); - FeatureIteratorType outIt(output, output->GetLargestPossibleRegion()); - FeatureIteratorType inputIt(m_InputImage, m_InputImage->GetLargestPossibleRegion()); - - // Set up Neighborhood Iterator to use a 3x3x3 neighborhood - typename itk::NeighborhoodIterator::RadiusType radius; - radius.Fill(1); - radius[2] = 1; - - typename itk::NeighborhoodIterator neighbIt(radius, seed, seed->GetRequestedRegion()); - typename itk::NeighborhoodIterator medianIt( - radius, propagationImage, propagationImage->GetRequestedRegion()); - - // Copy Input Image values from SeedRegion values into Output Image - // Collect border voxel indices to initialize seed list - typedef std::list ContainerType; - ContainerType fifo; - while (!seedIt.IsAtEnd()) - { - if (seedIt.Get() != 0) - { - outIt.Set(inputIt.Get()); - if (activeSeeds->GetPixel(seedIt.GetIndex()) == untouchedValue) - { - neighbIt.SetLocation(seedIt.GetIndex()); - for (unsigned int i = 0; i < neighbIt.Size(); ++i) - { - bool isInside = true; - neighbIt.GetPixel(i, isInside); - if (!isInside) - continue; - if (neighbIt.GetPixel(i) == 0) // border voxel - { - // add index of border voxel into FIFO - fifo.push_back(seedIt.GetIndex()); - activeSeeds->SetPixel(seedIt.GetIndex(), inListValue); - // write propagation value into output image - - if (m_ApplyRankFilter) - { - // Calculate median in 3x3x3 neighborhood and use this value to propagate - medianIt.SetLocation(seedIt.GetIndex()); - std::vector samples; - for (unsigned int j = 0; j < medianIt.Size(); ++j) - { - if (seed->GetPixel(medianIt.GetIndex(j)) != 0) // inside seed region - samples.push_back(medianIt.GetPixel(j)); - } - std::sort(samples.begin(), samples.end()); - - output->SetPixel(seedIt.GetIndex(), samples.at(samples.size() / 2)); - } - else - output->SetPixel(seedIt.GetIndex(), propagationImage->GetPixel(seedIt.GetIndex())); - - m_DistanceImage->SetPixel(seedIt.GetIndex(), 0); - break; - } - } - } - } - - ++inputIt; - ++outIt; - ++seedIt; - } - // - // Now iterate over items in fifo and check all possible paths starting from these indices - // to their neighbors and mark those with lowest cost - while (!fifo.empty()) - { - IndexType index = fifo.front(); - fifo.pop_front(); - // mark voxel as no longer present in fifo - activeSeeds->SetPixel(index, untouchedValue); - - if (mask->GetPixel(index) == 0) - continue; - - neighbIt.SetLocation(index); - - FeaturePixelType currDistance = m_DistanceImage->GetPixel(index); - FeaturePixelType currEuclidDistance = m_EuclideanDistance->GetPixel(index); - FeaturePixelType propagateValue = output->GetPixel(index); - - // compute cost to get to each neighborhood voxel - // if we find a lower way to a neighbor voxel, that voxel gets appended to the fifo - for (unsigned int i = 0; i < neighbIt.Size(); ++i) - { - bool isInside = true; - neighbIt.GetPixel(i, isInside); - if (!isInside || mask->GetPixel(neighbIt.GetIndex(i)) == 0) // || seed->GetPixel(neighbIt.GetIndex(i)) != 0) - continue; - - if (i == neighbIt.Size() / 2) // skip center voxel - continue; - - FeaturePixelType cost = GetDistanceValue(index, neighbIt.GetIndex(i)); - if (cost == -1) - continue; - if (currDistance + cost < m_DistanceImage->GetPixel(neighbIt.GetIndex(i)) || - m_DistanceImage->GetPixel(neighbIt.GetIndex(i)) == untouchedValue) - { - m_DistanceImage->SetPixel(neighbIt.GetIndex(i), currDistance + cost); - - // Compute Euclidean distance between indices - FeaturePixelType eDist = - sqrt(std::pow(index[0] - neighbIt.GetIndex(i)[0], 2) * m_InputImage->GetSpacing()[0] + - std::pow(index[1] - neighbIt.GetIndex(i)[1], 2) * m_InputImage->GetSpacing()[1] + - std::pow(index[2] - neighbIt.GetIndex(i)[2], 2) * m_InputImage->GetSpacing()[2]); - - m_EuclideanDistance->SetPixel(neighbIt.GetIndex(i), currEuclidDistance + eDist); - - output->SetPixel(neighbIt.GetIndex(i), propagateValue); - if (activeSeeds->GetPixel(neighbIt.GetIndex(i)) == untouchedValue) - { - fifo.push_back(neighbIt.GetIndex(i)); - activeSeeds->SetPixel(neighbIt.GetIndex(i), inListValue); - } - } - } - } - } - - template - double ConnectednessFilter::GetDistanceValue(IndexType idxStart, - IndexType idxEnd) - { - FeaturePixelType cost = 0; - - switch (m_Mode) - { - case (FeatureSimilarity): - { - cost = (-1 + exp(std::fabs(m_InputImage->GetPixel(idxStart) - m_InputImage->GetPixel(idxEnd)))); - break; - } - case (VectorAgreement): - { - // Rational - // Evaluate Confidence of Tensors (startIdx and endIdx), the higher the lower the cost - // Evaluate Path direction correspondence with tensor at start and end index - vnl_vector_fixed projection; - vnl_vector_fixed projectionEnd; - projection.fill(0); - projectionEnd.fill(0); - - itk::Point worldPosStart; - itk::Point worldPosEnd; - IndexTensorType tensorIdx; - IndexType featureIdxStart; - IndexTensorType tensorIdxEnd; - IndexType featureIdxEnd; - m_InputImage->TransformIndexToPhysicalPoint(idxStart, worldPosStart); - m_InputImage->TransformIndexToPhysicalPoint(idxEnd, worldPosEnd); - m_TensorImage->TransformPhysicalPointToIndex(worldPosStart, tensorIdx); - m_TensorImage->TransformPhysicalPointToIndex(worldPosEnd, tensorIdxEnd); - - m_ConfidenceImage->TransformPhysicalPointToIndex(worldPosStart, featureIdxStart); - m_ConfidenceImage->TransformPhysicalPointToIndex(worldPosEnd, featureIdxEnd); - - if (!m_TensorImage->GetLargestPossibleRegion().IsInside(tensorIdxEnd) || - !m_TensorImage->GetLargestPossibleRegion().IsInside(tensorIdx)) - return -1; - - if (m_ConfidenceImage->GetPixel(featureIdxStart) < .1) - return -1; - - vnl_vector_fixed direction; - direction[0] = (-worldPosStart[0] + worldPosEnd[0]); - direction[1] = (-worldPosStart[1] + worldPosEnd[1]); - direction[2] = (-worldPosStart[2] + worldPosEnd[2]); - - direction = direction.normalize(); - - TensorPixelType tensorEnd = m_TensorImage->GetPixel(tensorIdxEnd); - TensorPixelType tensorStart = m_TensorImage->GetPixel(tensorIdx); - - typename TensorPixelType::EigenValuesArrayType eigenvalues; - - tensorEnd.ComputeEigenValues(eigenvalues); - double maxEVEnd = std::fabs(eigenvalues[2]); - - tensorStart.ComputeEigenValues(eigenvalues); - double maxEVStart = std::fabs(eigenvalues[2]); - - if (maxEVEnd == 0.0) - maxEVEnd = 1; // no change then .. - // Normalize by largest EV - tensorEnd[0] /= maxEVEnd; - tensorEnd[1] /= maxEVEnd; - tensorEnd[2] /= maxEVEnd; - tensorEnd[3] /= maxEVEnd; - tensorEnd[4] /= maxEVEnd; - tensorEnd[5] /= maxEVEnd; - - if (maxEVStart == 0.0) - maxEVStart = 1; // no change then .. - // Normalize by largest EV - tensorStart[0] /= maxEVStart; - tensorStart[1] /= maxEVStart; - tensorStart[2] /= maxEVStart; - tensorStart[3] /= maxEVStart; - tensorStart[4] /= maxEVStart; - tensorStart[5] /= maxEVStart; - - /* Matrix Style - * | 0 1 2 | - * | X 3 4 | - * | X X 5 | - */ - // Multiply vector with tensor, and then take the magnitude of it. - projection[0] = direction[0] * tensorStart[0] + direction[1] * tensorStart[1] + direction[2] * tensorStart[2]; - projection[1] = direction[0] * tensorStart[1] + direction[1] * tensorStart[3] + direction[2] * tensorStart[4]; - projection[2] = direction[0] * tensorStart[2] + direction[1] * tensorStart[4] + direction[2] * tensorStart[5]; - - projectionEnd[0] = direction[0] * tensorEnd[0] + direction[1] * tensorEnd[1] + direction[2] * tensorEnd[2]; - projectionEnd[1] = direction[0] * tensorEnd[1] + direction[1] * tensorEnd[3] + direction[2] * tensorEnd[4]; - projectionEnd[2] = direction[0] * tensorEnd[2] + direction[1] * tensorEnd[4] + direction[2] * tensorEnd[5]; - - if (direction.magnitude() == 0.0 || projectionEnd.magnitude() == 0.0) - return -1; - - // Confidences higher than 1 are considered to be noise (due to the behavior of FA values derived from tensors - // with negative eigenvalues) - FeaturePixelType confStart = m_ConfidenceImage->GetPixel(featureIdxStart); - if (confStart > 1) - confStart = .1; - FeaturePixelType confEnd = m_ConfidenceImage->GetPixel(featureIdxEnd); - if (confEnd > 1) - confEnd = .1; - - // costs - cost = (1.1 - confStart) * (1.0 / sqrt(projection.magnitude())); - cost *= (1.1 - confEnd) * (1.0 / sqrt(projectionEnd.magnitude())); - - break; - } - case (FeatureVectorAgreement): - { - // Rational - // Evaluate Confidence of Tensors (startIdx and endIdx), the higher the lower the cost - // Evaluate Path direction correspondence with tensor at start and end index - vnl_vector_fixed projection; - vnl_vector_fixed projectionEnd; - projection.fill(0); - projectionEnd.fill(0); - - itk::Point worldPosStart; - itk::Point worldPosEnd; - IndexTensorType tensorIdx; - IndexType featureIdxStart; - IndexTensorType tensorIdxEnd; - IndexType featureIdxEnd; - m_InputImage->TransformIndexToPhysicalPoint(idxStart, worldPosStart); - m_InputImage->TransformIndexToPhysicalPoint(idxEnd, worldPosEnd); - m_TensorImage->TransformPhysicalPointToIndex(worldPosStart, tensorIdx); - m_TensorImage->TransformPhysicalPointToIndex(worldPosEnd, tensorIdxEnd); - - m_ConfidenceImage->TransformPhysicalPointToIndex(worldPosStart, featureIdxStart); - m_ConfidenceImage->TransformPhysicalPointToIndex(worldPosEnd, featureIdxEnd); - - if (!m_TensorImage->GetLargestPossibleRegion().IsInside(tensorIdxEnd) || - !m_TensorImage->GetLargestPossibleRegion().IsInside(tensorIdx)) - return -1; - - if (m_ConfidenceImage->GetPixel(featureIdxStart) < .1) - return -1; - - vnl_vector_fixed direction; - direction[0] = (-worldPosStart[0] + worldPosEnd[0]); - direction[1] = (-worldPosStart[1] + worldPosEnd[1]); - direction[2] = (-worldPosStart[2] + worldPosEnd[2]); - - direction = direction.normalize(); - - TensorPixelType tensorEnd = m_TensorImage->GetPixel(tensorIdxEnd); - TensorPixelType tensorStart = m_TensorImage->GetPixel(tensorIdx); - - typename TensorPixelType::EigenValuesArrayType eigenvalues; - - tensorEnd.ComputeEigenValues(eigenvalues); - double maxEVEnd = std::fabs(eigenvalues[2]); - - tensorStart.ComputeEigenValues(eigenvalues); - double maxEVStart = std::fabs(eigenvalues[2]); - - if (maxEVEnd == 0.0) - maxEVEnd = 1; // no change then .. - // Normalize by largest EV - tensorEnd[0] /= maxEVEnd; - tensorEnd[1] /= maxEVEnd; - tensorEnd[2] /= maxEVEnd; - tensorEnd[3] /= maxEVEnd; - tensorEnd[4] /= maxEVEnd; - tensorEnd[5] /= maxEVEnd; - - if (maxEVStart == 0.0) - maxEVStart = 1; // no change then .. - // Normalize by largest EV - tensorStart[0] /= maxEVStart; - tensorStart[1] /= maxEVStart; - tensorStart[2] /= maxEVStart; - tensorStart[3] /= maxEVStart; - tensorStart[4] /= maxEVStart; - tensorStart[5] /= maxEVStart; - - /* Matrix Style - * | 0 1 2 | - * | X 3 4 | - * | X X 5 | - */ - // Multiply vector with tensor, and then take the magnitude of it. - projection[0] = direction[0] * tensorStart[0] + direction[1] * tensorStart[1] + direction[2] * tensorStart[2]; - projection[1] = direction[0] * tensorStart[1] + direction[1] * tensorStart[3] + direction[2] * tensorStart[4]; - projection[2] = direction[0] * tensorStart[2] + direction[1] * tensorStart[4] + direction[2] * tensorStart[5]; - - projectionEnd[0] = direction[0] * tensorEnd[0] + direction[1] * tensorEnd[1] + direction[2] * tensorEnd[2]; - projectionEnd[1] = direction[0] * tensorEnd[1] + direction[1] * tensorEnd[3] + direction[2] * tensorEnd[4]; - projectionEnd[2] = direction[0] * tensorEnd[2] + direction[1] * tensorEnd[4] + direction[2] * tensorEnd[5]; - - if (direction.magnitude() == 0.0 || projectionEnd.magnitude() == 0.0) - return -1; - - // Confidences higher than 1 are considered to be noise (due to the behavior of FA values derived from tensors - // with negative eigenvalues) - FeaturePixelType confStart = m_ConfidenceImage->GetPixel(featureIdxStart); - if (confStart > 1) - confStart = .1; - FeaturePixelType confEnd = m_ConfidenceImage->GetPixel(featureIdxEnd); - if (confEnd > 1) - confEnd = .1; - - // costs - cost = (1.1 - confStart) * (1.0 / sqrt(projection.magnitude())); - cost *= (1.1 - confEnd) * (1.0 / sqrt(projectionEnd.magnitude())); - cost *= (-1 + exp(std::fabs(m_InputImage->GetPixel(idxStart) - m_InputImage->GetPixel(idxEnd)))); - - break; - } - } - return cost; - } - -} // end itk namespace - -#endif diff --git a/Modules/TumorInvasionAnalysis/include/itkConnectednessFilter.h b/Modules/TumorInvasionAnalysis/include/itkConnectednessFilter.h deleted file mode 100644 index 5858a70459..0000000000 --- a/Modules/TumorInvasionAnalysis/include/itkConnectednessFilter.h +++ /dev/null @@ -1,153 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef __itkConnectednessFilter_h -#define __itkConnectednessFilter_h - -#include "itkImageRegionIterator.h" -#include "itkImageToImageFilter.h" -#include - -namespace itk -{ - /** ConnectednessFilter - Propagate the border voxels of seed region, also calculates distance maps - * - * Propagates the values of the boder-region of the seed mask. This is done by looking for the shortes path - * w.r.t. some distance metric that can be chosen. - * - * Options are - * FeatureSimilarity - shortest path is determined by looking at feature differences only - * VectorAgreement - cost is determined by path agreement with supplied vector field - * FeatureVectorAgreement - cost is a combination of vector agreement and feature similarity - * - */ - - template - class ConnectednessFilter : public ImageToImageFilter - { - public: - /** Standard class typedefs. */ - typedef ConnectednessFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - - typedef typename itk::Image, 3> TTensorImage; - - typedef typename TSeedImage::PixelType SeedPixelType; - typedef typename TFeatureImage::PixelType FeaturePixelType; - typedef typename TTensorImage::PixelType TensorPixelType; - - typedef typename TFeatureImage::IndexType IndexType; - typedef typename TSeedImage::IndexType IndexSeedType; - typedef typename TTensorImage::IndexType IndexTensorType; - - typedef typename itk::ImageRegionIterator SeedIteratorType; - typedef typename itk::ImageRegionIterator FeatureIteratorType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); /** Run-time type information (and related methods). */ - itkTypeMacro(PropagateLocalFeaturesFilter, ImageToImageFilter); - - /** - * @brief The DistanceMode enum Available distance metrics - */ - enum DistanceMode { - FeatureSimilarity, - VectorAgreement, - FeatureVectorAgreement - }; - - void SetInputImage(const TFeatureImage *image); - - /** - * @brief SetInputSeed - seed area from which features are to be propagated - * @param mask - */ - void SetInputSeed(const TSeedImage *mask); - - /** - * @brief SetInputMask - Filter only operates in masked area - * @param mask - */ - void SetInputMask(const TSeedImage *mask); - - /** - * @brief SetInputVectorField - * @param vecs - */ - void SetInputVectorField(const TTensorImage *vecs); - - /** - * @brief SetInputVectorFieldConfidenceMap - Map that assigned a weight/confidence to each vector - * @param conf - */ - void SetInputVectorFieldConfidenceMap(const TFeatureImage *conf); - - /** - * @brief SetPropagationImage - OPTIONAL. Set image which values are propagated, it this is not supplied the - * InputImage is chosen as default. - * @param prop - */ - void SetPropagationImage(const TFeatureImage *prop); - - /** - * @brief GetDistanceImage - Return the distance image using the specified metric - * @return - */ - typename TFeatureImage::Pointer GetDistanceImage(); - - /** - * @brief GetEuclideanDistanceImage - Return distance image that provides distance of shortest path for each voxel - * w.r.t to euclidean space - * @return - */ - - typename TFeatureImage::Pointer GetEuclideanDistanceImage(); - - void SetMode(DistanceMode mode = FeatureSimilarity) { m_Mode = mode; } - /** - * @brief SetApplyRankFilter - if true the values propagated are determined by calculating the median within the - * mask within a 3x3x3 neighborhood - * @param applyFilter - */ - void SetApplyRankFilter(bool applyFilter) { m_ApplyRankFilter = applyFilter; } - protected: - ConnectednessFilter() { m_ApplyRankFilter = false; } - ~ConnectednessFilter() {} - /** Does the real work. */ - virtual void GenerateData(); - - virtual double GetDistanceValue(IndexType idxStart, IndexType idxEnd); - - private: - ConnectednessFilter(const Self &); // purposely not implemented - void operator=(const Self &); // purposely not implemented - - typename TFeatureImage::Pointer m_InputImage; - typename TTensorImage::Pointer m_TensorImage; - typename TFeatureImage::Pointer m_ConfidenceImage; - // Distance image w.r.t. to metric - typename TFeatureImage::Pointer m_DistanceImage; - // Euclidean distance, that keeps track of distance of shortest path - typename TFeatureImage::Pointer m_EuclideanDistance; - - DistanceMode m_Mode; - - bool m_ApplyRankFilter; - }; -} // namespace ITK - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkConnectednessFilter.cxx" -#endif - -#endif // itkConnectednessFilter_h diff --git a/Modules/TumorInvasionAnalysis/include/mitkCollectionDilatation.h b/Modules/TumorInvasionAnalysis/include/mitkCollectionDilatation.h deleted file mode 100644 index d24c9e7049..0000000000 --- a/Modules/TumorInvasionAnalysis/include/mitkCollectionDilatation.h +++ /dev/null @@ -1,65 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkCollectionDilation_H -#define mitkCollectionDilation_H - -// MITK -#include "mitkCommon.h" -#include -#include - -namespace mitk -{ - class MITKTUMORINVASIONANALYSIS_EXPORT CollectionDilation - { - public: - typedef unsigned char BinaryType; - typedef itk::Image BinaryImage; - - CollectionDilation() {} - ~CollectionDilation() {} - /** - * @brief DilateBinaryByName - Dilate all occurances of a modality within a mitk::DataCollection - * @param dataCollection - * @param name - name of modality - * @param xy - dilatation in xy direction - * @param z - dilatation in z direction - * @param suffix - suffix that is appended to newly created image - */ - static void DilateBinaryByName(DataCollection *dataCollection, - std::string name, - unsigned int xy = 5, - unsigned int z = 0, - std::string suffix = "DILATE"); - - /** - * @brief ErodeBinaryByName - Erode all occurances of a modality within a mitk::DataCollection - * @param dataCollection - * @param name - name of modality - * @param xy - erosion in xy direction - * @param z - erosion in z direction - * @param suffix - suffix that is appended to newly created image - */ - static void ErodeBinaryByName(DataCollection *dataCollection, - std::string name, - unsigned int xy = 5, - unsigned int z = 0, - std::string suffix = "ERODE"); - - protected: - private: - // DATA - // FUNCTIONS - }; -} // end namespace -#endif diff --git a/Modules/TumorInvasionAnalysis/include/mitkCollectionGrayOpening.h b/Modules/TumorInvasionAnalysis/include/mitkCollectionGrayOpening.h deleted file mode 100644 index 378381bb1e..0000000000 --- a/Modules/TumorInvasionAnalysis/include/mitkCollectionGrayOpening.h +++ /dev/null @@ -1,47 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkCollectionGrayDilation_H -#define mitkCollectionGrayDilation_H - -// MITK -#include "mitkCommon.h" -#include -#include - -namespace mitk -{ - class MITKTUMORINVASIONANALYSIS_EXPORT CollectionGrayOpening - { - public: - // typedef unsigned char BinaryType; - typedef itk::Image ImageType; - - CollectionGrayOpening() {} - ~CollectionGrayOpening() {} - /** - * @brief PerformGrayOpening - Opening operation on a specific modality type wihtin the DataCollection. Creates a - * new item. - * @param dataCollection - * @param name - * @param suffix - */ - static void PerformGrayOpening(mitk::DataCollection *dataCollection, std::string name, std::string suffix); - - protected: - private: - // DATA - - // FUNCTIONS - }; -} // end namespace -#endif diff --git a/Modules/TumorInvasionAnalysis/include/mitkDiffusionCollectionReader.h b/Modules/TumorInvasionAnalysis/include/mitkDiffusionCollectionReader.h deleted file mode 100644 index c6cea113a2..0000000000 --- a/Modules/TumorInvasionAnalysis/include/mitkDiffusionCollectionReader.h +++ /dev/null @@ -1,143 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_DIFFUSIONCOLLECTION_READER_H -#define MITK_DIFFUSIONCOLLECTION_READER_H - -#include "mitkCommon.h" -#include "mitkDataCollection.h" -#include - -// VTK -#include - -namespace mitk { - class MITKTUMORINVASIONANALYSIS_EXPORT DiffusionCollectionReader : public vtkXMLParser - { - public: - - typedef std::vector > FileListType; - - /** - * @brief Build up a mitk::DataCollection from a XML resource - * - **/ - DataCollection::Pointer LoadCollection(const std::string& xmlFileName); - - void AddDataElementIds(std::vector dataElemetIds); - void AddSubColIds(std::vector subColIds); - - void SetDataItemNames(std::vector itemNames); - - void ClearDataElementIds(); - void ClearSubColIds(); - - void Clear(); - - /** - * @brief Build up a mitk::DataCollection from a folder providing suffixes to group the files - * - **/ - static DataCollection::Pointer FolderToCollection(std::string folder, std::vector suffixes,std::vector seriesNames, bool allowGaps); - - /** - * @brief GenerateFileLists Returns a collection of lists with valid files names in a folder - * - * The first suffix entry in the vector is used for the reference images which are put in the first list, - * then the suffixes are interchanged and checked if the file exists; for each suffix a list is returned with filenames, - * if a file is expected but does not exist an empty string "" is added instead. - * - * @param folder - * @param suffixes - * @param allowGaps - * @return - */ - static FileListType GenerateFileLists(std::string folder, std::vector suffixes, bool allowGaps = false); - - /** - * @brief SanitizeFileList Removes all entries that are lacking at least one modality - * @param list - sanitized list - * @return - */ - - static FileListType SanitizeFileList(FileListType list); - - DiffusionCollectionReader(); - ~DiffusionCollectionReader() override; - protected: - - /** - * @brief Derived from XMLReader - **/ - void StartElement (const char* elementName, const char **atts) override; - /** - * @brief Derived from XMLReader - **/ - void EndElement (const char* elementName) override; - - private: - /** - * @brief Derived from XMLReader - **/ - std::string ReadXMLStringAttribut( std::string name, const char** atts); - /** - * @brief Derived from XMLReader - **/ - bool ReadXMLBooleanAttribut( std::string name, const char** atts ); - /** - * @brief Derived from XMLReader - **/ - int ReadXMLIntegerAttribut( std::string name, const char** atts ); - - /** - * @brief m_DataCollection - * Stores a data collection during build of - */ - DataCollection::Pointer m_Collection; - DataCollection::Pointer m_SubCollection; - DataCollection::Pointer m_DataItemCollection; - - /** - * @brief m_SelectedIds - * - * Stores ids which are to be considered during loading, if this is provided all - * all data sets not matching an ID in this list are skipped. - */ - std::vector m_SelectedSubColIds; - - std::vector m_SelectedDataItemIds; - - /** - * @brief m_SelectedDataItemNames - * Lists names of items to be loaded, rest is ignored - */ - - std::vector m_SelectedDataItemNames; - - /** - * @brief m_Ignore - * - * Determines if current sub-collection is ignored - */ - bool m_ColIgnore; - bool m_ItemIgnore; - - /** - * @brief m_BaseDir - * - * Stores Base directory to allow XML links with relative paths - */ - std::string m_BaseDir; - }; -} // namespace mitk - -#endif /* MITK_COLLECTION_READER_H */ diff --git a/Modules/TumorInvasionAnalysis/include/mitkDiffusionCollectionWriter.h b/Modules/TumorInvasionAnalysis/include/mitkDiffusionCollectionWriter.h deleted file mode 100755 index b00751de53..0000000000 --- a/Modules/TumorInvasionAnalysis/include/mitkDiffusionCollectionWriter.h +++ /dev/null @@ -1,77 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_DIFFUSIONCOLLECTION_WRITER_H -#define MITK_DIFFUSIONCOLLECTION_WRITER_H - -#include "mitkCommon.h" -#include "mitkDataCollection.h" -#include "mitkDiffusionCollectionReader.h" -#include - -namespace mitk { - class MITKTUMORINVASIONANALYSIS_EXPORT DiffusionCollectionWriter - { - public: - - typedef float TensorScalar; - /** - * @brief ExportCollectionToFolder - * - * Creates an XML file and stores all data in the same folder as the xml file (creating sub-folders for sub-collections) - * - * - * Naming Conventions (Neccessary for proper saving of these images): - * DWI - Diffusion Weighted Images - * DTI - Diffusion Tensor Images - * FIB - Fiber Bundles - * - * @param dataCollection - * @param xmlFile - * @param filter - (optional) only items with names contained in this list are written, if list is empty all items are written - * @return - */ - static bool ExportCollectionToFolder(DataCollection* dataCollection, std::string xmlFile , std::vector filter); - - static bool ExportCollectionToFolder(DataCollection* dataCollection, std::string xmlFile); - - /** - * @brief SaveCollection - Stores data collection at original location - * - * Writes the collection back to the files given in the original XML file. - * New data items are stored into the default location, which is relative to the XML file. - * - * If a XML file is provided the files are stored as stated above with the differences that a new XML file is generated and new files are saved - * relative to the newly generated xml. - * - * @param dataCollection - * @param filter - * @param xmlFile - * @return - */ - - static bool SaveCollection(DataCollection* dataCollection, std::vector filter, std::string xmlFile = ""); - - static bool FolderToXml(std::string folder, std::string collectionType, std::string xmlFile, std::vector filter, std::vector seriesNames); - - // GTV last entry in filter list, this item will be made to TARGET - static bool SingleFolderToXml(std::string folder, std::string xmlFile, std::vector filter, std::vector seriesNames, bool longDate = true, int skipUntil = 0, float months = 0); - - protected: - - private: - - static size_t GetIndexForinXMonths(DiffusionCollectionReader::FileListType fileList, float months, size_t curIndex, std::vector filter); - }; -} // namespace mitk - -#endif /* MITK_COLLECTION_WRITER_H */ diff --git a/Modules/TumorInvasionAnalysis/include/mitkTumorInvasionClassification.h b/Modules/TumorInvasionAnalysis/include/mitkTumorInvasionClassification.h deleted file mode 100644 index 5893c0175b..0000000000 --- a/Modules/TumorInvasionAnalysis/include/mitkTumorInvasionClassification.h +++ /dev/null @@ -1,188 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef TumorInvasionAnalysis_H -#define TumorInvasionAnalysis_H - -// MITK -#include "mitkCommon.h" -#include -// DATA -#include -// FORESTS -#include - -namespace mitk -{ - /** - * @brief The TumorInvasionAnalysis class - Classifies Tumor progression using RF and predicts on new cases - * - * Provides a way to learn tumor progression from examples, and predict the growth using random forests. - * - * - * Expected Inputs are DataCollections. The Tumor Segmentations (current extent) are expected to be binary (0 - - * healthy tissue, 1 - tumor tissue), - * likewise the target extent that is to be learnt. - * - */ - class MITKTUMORINVASIONANALYSIS_EXPORT TumorInvasionClassification - { - public: - TumorInvasionClassification(); - ~TumorInvasionClassification() {} - /** - * @brief SelectTrainingSamples - * - * Selects healthy/tumor tissue samples to be included into training. - * \warn This modifies the target data items in the data collection. - * Afterwards the target data is structured as follows: 0 -voxels excluded from training , 1 - healthy sample , 2 - - * "tuning-into-tumor" sample - * - * - * - * @param collection - * @param erodeTrainingMask - Performs erosion on target such that border voxels of tumor region will not be - * included into training - */ - void SelectTrainingSamples(DataCollection *collection, unsigned int mode = 0); - - /** - * @brief PrepareResponseSamples - * - * Selects healthy/tumor tissue samples to be included into training, and weights them to achieve a given ratio. - * \warn This modifies the target data items in the data collection. - * Afterwards the target data is encoded as follows: - * 0 - excluded (e.g. out of brainmask) - * 1 - no involvement (healthy all the time) - * 2 - formerly healthy, now tumor (rezivid) - * 3 - formerly tumor, now necroses (responsive) - */ - void PrepareResponseSamples(DataCollection *collection); - - /** - * @brief LearnProgressionFeatures - * - * - * @param collection - data collection used for training - * @param modalitiesList - modalities (data item names from collection) that are to be used for training - * @param forestSize - number of trees that are trained - * @param treeDepth - maximal depth for a single tree - */ - - void LearnProgressionFeatures(DataCollection *collection, - std::vector modalitiesList, - size_t forestSize = 300, - size_t treeDepth = 10); - - /** - * @brief PredictGrowth - Classify voxels into remaining healthy / turning into tumor - * @param collection - */ - void PredictInvasion(DataCollection *collection, std::vector modalitiesList); - - /** - * @brief SanitizeResults - Performs an Opening Operation on tha data to remove isolated misclassifications - * - * RESULTOPEN - * - * @param collection - */ - void SanitizeResults(DataCollection *collection, std::string resultID = "RESULT"); - - void SetTrainMargin(size_t dil2d, size_t dil3d) - { - m_TargetDil2D = dil2d; - m_TargetDil3D = dil3d; - } - - /** - * @brief SetClassRatio - set ratio of tumor voxels to healthy voxels that is to be used for training - * - * \warn perfect ratio cannot allways be achieved, since by default all tumor voxels are included into training - * (since they ususally are to rare to be skipped) - * - * @param ratio - */ - - void SetClassRatio(ScalarType ratio) { m_ClassRatio = ratio; } - void SetGlobalsStatsFile(std::string fn) { m_GlobalStatsFile = fn; } - /** - * @brief SamplesWeightingActivated If activated a weighted mask for the samples is calculated, weighting samples - * according to their location and ratio - * @param isActive - */ - void SamplesWeightingActivated(bool isActive) { m_WeightSamples = isActive; } - /** - * @brief SetTargetID sets binary mask denoting future tumor area - * @param targetID - */ - void SetTargetID(std::string targetID = "TARGET") { m_TargetID = targetID; } - /** - * @brief SetTumorID sets binary mask denoting current tumor area - * @param tumorID - */ - void SetTumorID(std::string tumorID = "GTV") { m_TumorID = tumorID; } - /** - * @brief SetMaskID sets binary mask denoting area that is evluated/included in training - * @param maskID - */ - void SetMaskID(std::string maskID = "BRAINMASK") { m_MaskID = maskID; } - /** - * @brief SetResultID sets data item name in which prediction results are stored - * @param resultID - */ - void SetResultID(std::string resultID = "RESULT") { m_ResultID = resultID; } - /** - * @brief UseRandomizedTrees - use random splits to build up forest - * @param useRandom - */ - void UseRandomizedTrees(bool useRandom) { m_Randomize = useRandom; } - /** - * @brief DescriptionToLogFile - Append to log file: patient ids and time steps contained in this data collection. - * @param collection - * @param outputFile - */ - void DescriptionToLogFile(DataCollection *collection, std::string outputFile); - - /** - * @brief SaveRandomForest - Saves a trained random forest - * @param filename - */ - void SaveRandomForest(std::string filename); - - /** - * @brief LoadRandomForest - loads a random forest to be used for classification - * @param filename - */ - void LoadRandomForest(std::string); - - protected: - private: - // DATA - mitk::VigraRandomForestClassifier m_Forest; - unsigned int m_TargetDil2D; - unsigned int m_TargetDil3D; - - ScalarType m_ClassRatio; - - std::string m_GlobalStatsFile; - - std::string m_TargetID; - std::string m_TumorID; - std::string m_MaskID; - std::string m_ResultID; - - bool m_Randomize; - bool m_WeightSamples; - }; -} // end namespace -#endif diff --git a/Modules/TumorInvasionAnalysis/src/Classification/mitkTumorInvasionClassification.cpp b/Modules/TumorInvasionAnalysis/src/Classification/mitkTumorInvasionClassification.cpp deleted file mode 100644 index 38e488a6d9..0000000000 --- a/Modules/TumorInvasionAnalysis/src/Classification/mitkTumorInvasionClassification.cpp +++ /dev/null @@ -1,672 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkTumorInvasionClassification.h" - -#include "mitkCLUtil.h" -#include "mitkCollectionDilatation.h" -#include "mitkCollectionGrayOpening.h" -#include "mitkDataCollectionImageIterator.h" -#include "mitkDataCollectionUtilities.h" -#include "mitkIOUtil.h" -#include -// To initialize random number generator -#include - -static void EnsureDataImageInCollection(mitk::DataCollection::Pointer collection, - std::string origin, - std::string target) -{ - typedef itk::Image FeatureImage; - - if (collection->HasElement(origin)) - { - mitk::Image::Pointer originImage = dynamic_cast(collection->GetMitkImage(origin).GetPointer()); - FeatureImage::Pointer itkOriginImage = FeatureImage::New(); - mitk::CastToItkImage(originImage, itkOriginImage); - - if (!collection->HasElement(target) && itkOriginImage.IsNotNull()) - { - FeatureImage::Pointer image = FeatureImage::New(); - image->SetRegions(itkOriginImage->GetLargestPossibleRegion()); - image->SetSpacing(itkOriginImage->GetSpacing()); - image->SetOrigin(itkOriginImage->GetOrigin()); - image->SetDirection(itkOriginImage->GetDirection()); - image->Allocate(); - - collection->AddData(dynamic_cast(image.GetPointer()), target, ""); - } - } - for (std::size_t i = 0; i < collection->Size(); ++i) - { - mitk::DataCollection *newCol = dynamic_cast(collection->GetData(i).GetPointer()); - if (newCol != nullptr) - { - EnsureDataImageInCollection(newCol, origin, target); - } - } -} - -mitk::TumorInvasionClassification::TumorInvasionClassification() - : m_TargetID("TARGET"), - m_TumorID("GTV"), - m_MaskID("BRAINMASK"), - m_ResultID("RESULT"), - m_Randomize(false), - m_WeightSamples(false) -{ -} - -void mitk::TumorInvasionClassification::SelectTrainingSamples(mitk::DataCollection *collection, unsigned int mode) -{ - srand(time(nullptr)); - MITK_INFO << "LearnProgressionFeatures: Selecting training voxels."; - switch (mode) - { - case 0: - { - MITK_INFO << " Selection Mode " << mode << " use all tumor voxels, healthy: 50% vicinity / 50% far away"; - - CollectionDilation::DilateBinaryByName(collection, m_TargetID, 2, 0, "EXCLUDE"); - CollectionDilation::ErodeBinaryByName(collection, m_TargetID, 1, 0, "ERODE"); - CollectionDilation::DilateBinaryByName(collection, m_TargetID, m_TargetDil2D, m_TargetDil3D, "TRAIN"); - DataCollectionImageIterator gtvIter(collection, m_TumorID); - DataCollectionImageIterator brainMaskIter(collection, m_MaskID); - DataCollectionImageIterator targetIter(collection, m_TargetID); - DataCollectionImageIterator targetDil(collection, m_TargetID + "TRAIN"); - - // Count Healthy/ Tumor voxels - // i.o. to decide how many of each are taken - unsigned int totalTumor = 0; - unsigned int totalHealthyClose = 0; - unsigned int totalHealthy = 0; - - while (!brainMaskIter.IsAtEnd()) - { - if (brainMaskIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1 && gtvIter.GetVoxel() == 0) - ++totalTumor; - - if (targetIter.GetVoxel() == 0 && targetDil.GetVoxel() == 1 && gtvIter.GetVoxel() == 0) - ++totalHealthyClose; - - if (targetIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 0 && targetDil.GetVoxel() == 0) - ++totalHealthy; // healthy but not close - } - ++brainMaskIter; - ++targetIter; - ++targetDil; - ++gtvIter; - } - brainMaskIter.ToBegin(); - targetIter.ToBegin(); - targetDil.ToBegin(); - gtvIter.ToBegin(); - // Total of healthy samples that is to be collected - unsigned int targetHealthy = totalTumor * m_ClassRatio; - // Determines which portion of the healthy samples is drawn from the immediate vicinity of the newly grown tumor - ScalarType ratioClose = .5; - - // Compute probabilities thresholds for choosing a close healthy voxel / any healthy voxel - ScalarType thHealthyClose = std::min(1.0, (targetHealthy * ratioClose) / totalHealthyClose); - ScalarType thHealthyAny = std::min(1.0, (targetHealthy * (1.0 - ratioClose)) / totalHealthy); - // Some stats - { - MITK_INFO << "Total # Tumor Voxels " << totalTumor; - MITK_INFO << "Total # Healthy Voxels" << totalHealthy; - MITK_INFO << "Target Ratio " << m_ClassRatio; - MITK_INFO << "Ratio for healthy close: " << thHealthyClose; - MITK_INFO << "Ratio for healthy any other: " << thHealthyAny; - } - - // DEBUG count occurances to compare - unsigned int tumor = 0; - unsigned int healthy = 0; - while (!brainMaskIter.IsAtEnd()) - { - if (brainMaskIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1) - { // choose tumor voxels for training - if (gtvIter.GetVoxel() == 0) // tumor always - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - ++tumor; - } - else - targetIter.SetVoxel(0); - } - else - { // choose healty tissue voxels for training - ScalarType rndVal = (float)rand() / (float)(RAND_MAX); //(0..1) - if (gtvIter.GetVoxel() == 0 && ((targetDil.GetVoxel() == 1 && rndVal <= thHealthyClose))) - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - ++healthy; - } - else if (((targetDil.GetVoxel() == 0 && rndVal <= thHealthyAny))) - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - ++healthy; - } - else - targetIter.SetVoxel(0); - } - } - else - targetIter.SetVoxel(0); - - ++brainMaskIter; - ++targetIter; - ++gtvIter; - ++targetDil; - } - MITK_INFO << "Training with Samples #Tumor " << tumor << " / healthy # " << healthy; - } - break; - case 2: - { - MITK_INFO << " Selection Mode " << mode << " Weighted with ratio"; - - EnsureDataImageInCollection(collection, m_TumorID, "WEIGHTS"); - - CollectionDilation::DilateBinaryByName(collection, m_TargetID, 1, 0, "EXCLUDE"); - CollectionDilation::ErodeBinaryByName(collection, m_TargetID, 1, 0, "ERODE"); - CollectionDilation::DilateBinaryByName(collection, m_TargetID + "EXCLUDE", m_TargetDil2D, m_TargetDil3D, "TRAIN"); - DataCollectionImageIterator gtvIter(collection, m_TumorID); - DataCollectionImageIterator brainMaskIter(collection, m_MaskID); - DataCollectionImageIterator targetIter(collection, m_TargetID); - DataCollectionImageIterator targetDil(collection, m_TargetID + "EXCLUDETRAIN"); - DataCollectionImageIterator excludeTumorIter(collection, m_TargetID + "ERODE"); - DataCollectionImageIterator excludeHealthyIter(collection, m_TargetID + "EXCLUDE"); - - DataCollectionImageIterator weightsIter(collection, "WEIGHTS"); - - // Count Healthy/ Tumor voxels - // i.o. to decide how many of each are taken - double totalTumor = 0; - double totalHealthyClose = 0; - double totalHealthyNonClose = 0; - double totalHealthy = 0; - - while (!brainMaskIter.IsAtEnd()) - { - if (brainMaskIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1 && gtvIter.GetVoxel() == 0 && excludeTumorIter.GetVoxel() == 1) - ++totalTumor; - - if (excludeHealthyIter.GetVoxel() == 0 && targetDil.GetVoxel() == 1 && gtvIter.GetVoxel() == 0) - ++totalHealthyClose; - - if (excludeHealthyIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 0 && targetDil.GetVoxel() == 0) - ++totalHealthyNonClose; // healthy but not close - - if (excludeHealthyIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 0 && targetIter.GetVoxel() == 0) - ++totalHealthy; // healthy - } - ++brainMaskIter; - ++targetIter; - ++targetDil; - ++gtvIter; - ++excludeHealthyIter; - ++excludeTumorIter; - } - brainMaskIter.ToBegin(); - targetIter.ToBegin(); - targetDil.ToBegin(); - gtvIter.ToBegin(); - excludeHealthyIter.ToBegin(); - excludeTumorIter.ToBegin(); - - // Compute probabilities thresholds for choosing a close healthy voxel / any healthy voxel - ScalarType wHealthyClose = 10000.0 / totalHealthyClose; - ScalarType wHealthyAny = 5000.0 / totalHealthyNonClose; - ScalarType wTumor = (m_ClassRatio * (10000.0 + 5000.0)) / totalTumor; - - // DEBUG count occurances to compare - double potentialClose = 0; - double selectedClose = 0; - double tumor = 0; - double healthy = 0; - while (!brainMaskIter.IsAtEnd()) - { - weightsIter.SetVoxel(0); - if (brainMaskIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1) - { // choose tumor voxels for training - if (gtvIter.GetVoxel() == 0 && excludeTumorIter.GetVoxel() == 1) // tumor always - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(wTumor); - ++tumor; - } - else if (gtvIter.GetVoxel() == 0) - { - weightsIter.SetVoxel(0); //.1); - targetIter.SetVoxel(0); // 2); - } - } - else - { // choose healty tissue voxels for training - if (gtvIter.GetVoxel() == 0 && ((excludeHealthyIter.GetVoxel() == 0 && targetDil.GetVoxel() == 1))) - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(wHealthyClose); - healthy += wHealthyClose; - } - else if (((targetDil.GetVoxel() == 0 && excludeHealthyIter.GetVoxel() == 0))) - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(wHealthyAny); - healthy += wHealthyAny; - } - else if ((gtvIter.GetVoxel() == 0 && excludeHealthyIter.GetVoxel() == 1)) - { - targetIter.SetVoxel(0); // brainMaskIter.GetVoxel()+targetIter.GetVoxel()); - weightsIter.SetVoxel(0); //.1); - } - else - { - targetIter.SetVoxel(0); - weightsIter.SetVoxel(0); - } - } - } - else - { - targetIter.SetVoxel(0); - weightsIter.SetVoxel(0); - } - - if (gtvIter.GetVoxel() != 0) - targetIter.SetVoxel(0); - - ++brainMaskIter; - ++targetIter; - ++gtvIter; - ++targetDil; - ++excludeHealthyIter; - ++excludeTumorIter; - ++weightsIter; - } - MITK_INFO << "Training with Samples #Tumor " << tumor << " / healthy # " << healthy; - MITK_INFO << "Potential Close" << potentialClose; - MITK_INFO << "Selected Close" << selectedClose; - } - break; - default: - { - MITK_INFO << " Selection Mode " << mode - << " Exclude voxels in border regions, healthy: 50% vicinity / 50% far away"; - - // weights - ScalarType tumorWeight = 1; - // ScalarType unsureRegion = .25; - ScalarType healthyTissue = 1; - - EnsureDataImageInCollection(collection, m_TumorID, "WEIGHTS"); - - CollectionDilation::DilateBinaryByName(collection, m_TargetID, 1, 0, "EXCLUDE"); - CollectionDilation::ErodeBinaryByName(collection, m_TargetID, 1, 0, "ERODE"); - CollectionDilation::DilateBinaryByName(collection, m_TargetID + "EXCLUDE", m_TargetDil2D, m_TargetDil3D, "TRAIN"); - DataCollectionImageIterator gtvIter(collection, m_TumorID); - DataCollectionImageIterator brainMaskIter(collection, m_MaskID); - DataCollectionImageIterator targetIter(collection, m_TargetID); - DataCollectionImageIterator targetDil(collection, m_TargetID + "EXCLUDETRAIN"); - DataCollectionImageIterator excludeTumorIter(collection, m_TargetID + "ERODE"); - DataCollectionImageIterator excludeHealthyIter(collection, m_TargetID + "EXCLUDE"); - - DataCollectionImageIterator weightsIter(collection, "WEIGHTS"); - - // Count Healthy/ Tumor voxels - // i.o. to decide how many of each are taken - double totalTumor = 0; - double totalHealthyClose = 0; - double totalHealthyNonClose = 0; - double totalHealthy = 0; - - while (!brainMaskIter.IsAtEnd()) - { - if (brainMaskIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1 && gtvIter.GetVoxel() == 0 && excludeTumorIter.GetVoxel() == 1) - ++totalTumor; - - if (excludeHealthyIter.GetVoxel() == 0 && targetDil.GetVoxel() == 1 && gtvIter.GetVoxel() == 0) - ++totalHealthyClose; - - if (excludeHealthyIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 0 && targetDil.GetVoxel() == 0) - ++totalHealthyNonClose; // healthy but not close - - if (excludeHealthyIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 0 && targetIter.GetVoxel() == 0) - ++totalHealthy; // healthy - } - ++brainMaskIter; - ++targetIter; - ++targetDil; - ++gtvIter; - ++excludeHealthyIter; - ++excludeTumorIter; - } - brainMaskIter.ToBegin(); - targetIter.ToBegin(); - targetDil.ToBegin(); - gtvIter.ToBegin(); - excludeHealthyIter.ToBegin(); - excludeTumorIter.ToBegin(); - - // Total of healthy samples that is to be collected - unsigned int targetHealthy = (tumorWeight / healthyTissue) * totalTumor * m_ClassRatio; - // Determines which portion of the healthy samples is drawn from the immediate vicinity of the newly grown tumor - ScalarType ratioClose = .5; - - // Compute probabilities thresholds for choosing a close healthy voxel / any healthy voxel - ScalarType thHealthyClose = std::min(1.0, ((double)targetHealthy * ratioClose) / totalHealthyClose); - ScalarType thHealthyAny = std::min(1.0, ((double)targetHealthy * (1.0 - ratioClose)) / totalHealthyNonClose); - // Some stats - { - MITK_INFO << "Total Tumor " << totalTumor; - MITK_INFO << "Total healthy " << totalHealthyNonClose; - MITK_INFO << "Total healthy close " << totalHealthyClose; - MITK_INFO << "Total healthy non-close " << totalHealthyNonClose; - MITK_INFO << "Target Ratio " << m_ClassRatio; - - MITK_INFO << "Target Healthy " << targetHealthy; - MITK_INFO << "Probabilty close " << thHealthyClose; - MITK_INFO << "Probabilty any other " << thHealthyAny; - } - - // DEBUG count occurances to compare - double potentialClose = 0; - double selectedClose = 0; - double tumor = 0; - double healthy = 0; - while (!brainMaskIter.IsAtEnd()) - { - weightsIter.SetVoxel(0); - if (brainMaskIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1) - { // choose tumor voxels for training - if (gtvIter.GetVoxel() == 0 && excludeTumorIter.GetVoxel() == 1) // tumor always - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(tumorWeight); - ++tumor; - } - else if (gtvIter.GetVoxel() == 0) - { - weightsIter.SetVoxel(0); //.1); - targetIter.SetVoxel(0); // 2); - } - } - else - { // choose healty tissue voxels for training - if (gtvIter.GetVoxel() == 0 && ((excludeHealthyIter.GetVoxel() == 0 && targetDil.GetVoxel() == 1))) - { - if (!m_WeightSamples && ((float)rand() / (float)(RAND_MAX) < thHealthyClose)) - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(1); - ++healthy; - } - else - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(thHealthyClose); - healthy += thHealthyClose; - } - } - else if (((targetDil.GetVoxel() == 0 && excludeHealthyIter.GetVoxel() == 0))) - { - if (!m_WeightSamples && ((float)rand() / (float)(RAND_MAX) < thHealthyAny)) - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(1); - ++healthy; - } - else - { - targetIter.SetVoxel(brainMaskIter.GetVoxel() + targetIter.GetVoxel()); - weightsIter.SetVoxel(thHealthyAny); - healthy += thHealthyAny; - } - } - else if ((gtvIter.GetVoxel() == 0 && excludeHealthyIter.GetVoxel() == 1)) - { - targetIter.SetVoxel(0); // brainMaskIter.GetVoxel()+targetIter.GetVoxel()); - weightsIter.SetVoxel(0); //.1); - } - else - { - targetIter.SetVoxel(0); - weightsIter.SetVoxel(0); - } - - if (gtvIter.GetVoxel() == 0 && ((excludeHealthyIter.GetVoxel() == 0 && targetDil.GetVoxel() == 1))) - { - potentialClose++; - - if ((float)rand() / (float)(RAND_MAX) < thHealthyClose) - selectedClose++; - } - } - } - else - { - targetIter.SetVoxel(0); - weightsIter.SetVoxel(0); - } - - if (gtvIter.GetVoxel() != 0) - targetIter.SetVoxel(0); - - ++brainMaskIter; - ++targetIter; - ++gtvIter; - ++targetDil; - ++excludeHealthyIter; - ++excludeTumorIter; - ++weightsIter; - } - MITK_INFO << "Training with Samples #Tumor " << tumor << " / healthy # " << healthy; - MITK_INFO << "Potential Close" << potentialClose; - MITK_INFO << "Selected Close" << selectedClose; - } - break; - } -} - -void mitk::TumorInvasionClassification::PrepareResponseSamples(mitk::DataCollection *collection) -{ - srand(time(nullptr)); - MITK_INFO << "PrepareResponseSamples: Selecting training voxels."; - - EnsureDataImageInCollection(collection, m_TumorID, "WEIGHTS"); - - CollectionDilation::DilateBinaryByName(collection, m_TargetID, 10, 4, "TRAIN"); - DataCollectionImageIterator gtvIter(collection, m_TumorID); - DataCollectionImageIterator brainMaskIter(collection, m_MaskID); - DataCollectionImageIterator targetIter(collection, m_TargetID); - DataCollectionImageIterator dilIter(collection, m_TargetID + "TRAIN"); - - // Count Non-Involved/Responsive/Rezidiv Voxels - - double nonInvolved = 0; - double responsive = 0; - double rezidiv = 0; - - while (!brainMaskIter.IsAtEnd()) - { - if (brainMaskIter.GetVoxel() != 0 && dilIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 0) - { - targetIter.SetVoxel(1); - ++nonInvolved; - } - - if (targetIter.GetVoxel() == 0 && gtvIter.GetVoxel() == 1) - { - targetIter.SetVoxel(3); - ++responsive; - } - - if (targetIter.GetVoxel() == 1 && gtvIter.GetVoxel() == 0) - { - targetIter.SetVoxel(2); - ++rezidiv; - } - } - else - targetIter.SetVoxel(0); - - ++brainMaskIter; - ++targetIter; - ++gtvIter; - ++dilIter; - } - brainMaskIter.ToBegin(); - targetIter.ToBegin(); - gtvIter.ToBegin(); - dilIter.ToBegin(); - - // weight for groups - - double wNonInvolved = 10000.0 / nonInvolved; - double wResponsive = 10000.0 / responsive; - double wRezidiv = 10000.0 / rezidiv; - - std::cout << "Weights are " << wNonInvolved << "/ " << wResponsive << " / " << wRezidiv << std::endl; - - // Assign weight for each voxel - DataCollectionImageIterator weightsIter(collection, "WEIGHTS"); - - while (!brainMaskIter.IsAtEnd()) - { - if (brainMaskIter.GetVoxel() != 0 && dilIter.GetVoxel() != 0) - { - if (targetIter.GetVoxel() == 1) - weightsIter.SetVoxel(wNonInvolved); - - if (targetIter.GetVoxel() == 2) - weightsIter.SetVoxel(wRezidiv); - - if (targetIter.GetVoxel() == 3) - weightsIter.SetVoxel(wResponsive); - } - - ++dilIter; - ++brainMaskIter; - ++targetIter; - ++weightsIter; - } -} - -void mitk::TumorInvasionClassification::LearnProgressionFeatures(mitk::DataCollection *collection, - std::vector modalitiesList, - size_t forestSize, - size_t treeDepth) -{ - auto trainDataX = mitk::DCUtilities::DC3dDToMatrixXd(collection, modalitiesList, m_TargetID); - auto trainDataY = mitk::DCUtilities::DC3dDToMatrixXi(collection, m_TargetID, m_TargetID); - - if (treeDepth != 0) - m_Forest.SetMaximumTreeDepth(treeDepth); - - m_Forest.SetTreeCount(forestSize); - - if (m_WeightSamples) - { - auto trainDataW = mitk::DCUtilities::DC3dDToMatrixXd(collection, "WEIGHTS", m_TargetID); - m_Forest.SetPointWiseWeight(trainDataW); - m_Forest.UsePointWiseWeight(true); - } - - MITK_INFO << "Start Training:"; - try - { - m_Forest.Train(trainDataX, trainDataY); - } - catch (std::exception &e) - { - MITK_INFO << "Exception while training forest: " << e.what(); - } - std::cout << "Training finished" << std::endl; -} - -void mitk::TumorInvasionClassification::PredictInvasion(mitk::DataCollection *collection, - std::vector modalitiesList) -{ - if (collection != nullptr) - { - MITK_INFO << "Evaluating Forest"; - - auto testDataX = mitk::DCUtilities::DC3dDToMatrixXd(collection, modalitiesList, m_MaskID); - auto testDataNewY = m_Forest.Predict(testDataX); - mitk::DCUtilities::MatrixToDC3d(testDataNewY, collection, m_ResultID, m_MaskID); - - Eigen::MatrixXd Probs = m_Forest.GetPointWiseProbabilities(); - - Eigen::MatrixXd prob0 = Probs.col(0); - Eigen::MatrixXd prob1 = Probs.col(1); - - mitk::DCUtilities::MatrixToDC3d(prob0, collection, "prob0", m_MaskID); - mitk::DCUtilities::MatrixToDC3d(prob1, collection, "prob1", m_MaskID); - if (Probs.cols() >= 3) - { - Eigen::MatrixXd prob2 = Probs.col(2); - mitk::DCUtilities::MatrixToDC3d(prob2, collection, "prob2", m_MaskID); - } - } - else - MITK_ERROR << "TumorInvasionClassification::PredictInvasion - provided collection is nullptr."; -} - -void mitk::TumorInvasionClassification::SanitizeResults(mitk::DataCollection *collection, std::string resultID) -{ - CollectionGrayOpening::PerformGrayOpening(collection, resultID, "OPEN"); -} - -void mitk::TumorInvasionClassification::DescriptionToLogFile(mitk::DataCollection *collection, std::string outputFile) -{ - std::ofstream fileStream; - fileStream.open(outputFile.c_str(), std::ios_base::app); - - fileStream << "Configuration:" << std::endl; - for (size_t patient = 0; patient < collection->Size(); ++patient) - { - DataCollection *dataPatient = dynamic_cast(collection->GetData(patient).GetPointer()); - fileStream << "Name : " << dataPatient->GetName() << " with time steps:" << std::endl; - for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep) - { - fileStream << dataPatient->IndexToName(timeStep) << "-" << std::endl; - DataCollection *dataTS = dynamic_cast(dataPatient->GetData(timeStep).GetPointer()); - for (size_t ts = 0; ts < dataTS->Size(); ++ts) - fileStream << dataTS->IndexToName(ts) << "-" << std::endl; - } - } -} - -void mitk::TumorInvasionClassification::SaveRandomForest(std::string filename) -{ - mitk::IOUtil::Save(&m_Forest, filename); -} - -void mitk::TumorInvasionClassification::LoadRandomForest(std::string /*filename*/) -{ - // TBD - MITK_ERROR << "not yet implemented ..."; -} diff --git a/Modules/TumorInvasionAnalysis/src/ImageFilters/mitkCollectionDilatation.cpp b/Modules/TumorInvasionAnalysis/src/ImageFilters/mitkCollectionDilatation.cpp deleted file mode 100644 index 9b384be934..0000000000 --- a/Modules/TumorInvasionAnalysis/src/ImageFilters/mitkCollectionDilatation.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include "mitkCollectionDilatation.h" - -#include -#include - -#include "itkBinaryBallStructuringElement.h" -#include "itkBinaryDilateImageFilter.h" -#include "itkBinaryErodeImageFilter.h" -#include "itkFlatStructuringElement.h" -#include "itkGrayscaleDilateImageFilter.h" - -void mitk::CollectionDilation::DilateBinaryByName( - mitk::DataCollection *dataCollection, std::string name, unsigned int xy, unsigned int z, std::string suffix) -{ - for (size_t patient = 0; patient < dataCollection->Size(); ++patient) - { - DataCollection *dataPatient = dynamic_cast(dataCollection->GetData(patient).GetPointer()); - if (dataPatient == nullptr) - MITK_ERROR << "DilateBinaryByName - Structure of DataCollection is invalid at patient level. Data inconsistent!"; - - if (dataPatient->Size() == 0) - MITK_ERROR << "Empty Patient Collective. Probably Fatal."; - - for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep) - { - DataCollection *dataTimeStep = dynamic_cast(dataPatient->GetData(timeStep).GetPointer()); - if (dataTimeStep == nullptr) - MITK_ERROR - << "DilateBinaryByName- Structure of DataCollection is invalid at time step level. Data inconsistent!"; - - BinaryImage::Pointer itkTumorSeed = BinaryImage::New(); - Image *tumorSeed = dynamic_cast(dataTimeStep->GetMitkImage(name).GetPointer()); - if (tumorSeed == nullptr) - MITK_ERROR << "Image " << name << " does not exits. Fatal."; - - CastToItkImage(tumorSeed, itkTumorSeed); - - typedef itk::FlatStructuringElement<3> StructuringElementType; - StructuringElementType::RadiusType elementRadius; - elementRadius.Fill(xy); - elementRadius[2] = z; - - StructuringElementType structuringElement = StructuringElementType::Box(elementRadius); - typedef itk::BinaryDilateImageFilter - BinaryDilateImageFilterType; - - BinaryDilateImageFilterType::Pointer dilateFilter0 = BinaryDilateImageFilterType::New(); - dilateFilter0->SetInput(itkTumorSeed); - dilateFilter0->SetKernel(structuringElement); - dilateFilter0->SetForegroundValue(1); - dilateFilter0->Update(); - - Image::Pointer dil = GrabItkImageMemory(dilateFilter0->GetOutput()); - - dil->SetGeometry(tumorSeed->GetGeometry()); - dataTimeStep->AddData(dil.GetPointer(), name + suffix, "Dilated Binary"); - } - } -} - -void mitk::CollectionDilation::ErodeBinaryByName( - mitk::DataCollection *dataCollection, std::string name, unsigned int xy, unsigned int z, std::string suffix) -{ - for (size_t patient = 0; patient < dataCollection->Size(); ++patient) - { - DataCollection *dataPatient = dynamic_cast(dataCollection->GetData(patient).GetPointer()); - if (dataPatient == nullptr) - MITK_ERROR << "DilateBinaryByName - Structure of DataCollection is invalid at patient level. Data inconsistent!"; - - if (dataPatient->Size() == 0) - MITK_ERROR << "Empty Patient Collective. Probably Fatal."; - - for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep) - { - DataCollection *dataTimeStep = dynamic_cast(dataPatient->GetData(timeStep).GetPointer()); - if (dataTimeStep == nullptr) - MITK_ERROR - << "DilateBinaryByName- Structure of DataCollection is invalid at time step level. Data inconsistent!"; - - BinaryImage::Pointer itkTumorSeed = BinaryImage::New(); - Image *tumorSeed = dynamic_cast(dataTimeStep->GetMitkImage(name).GetPointer()); - if (tumorSeed == nullptr) - MITK_ERROR << "Image " << name << " does not exits. Fatal."; - - CastToItkImage(tumorSeed, itkTumorSeed); - - typedef itk::FlatStructuringElement<3> StructuringElementType; - StructuringElementType::RadiusType elementRadius; - elementRadius.Fill(xy); - elementRadius[2] = z; - - StructuringElementType structuringElement = StructuringElementType::Box(elementRadius); - - typedef itk::BinaryErodeImageFilter BinaryErodeImageFilterType; - - BinaryErodeImageFilterType::Pointer dilateFilter0 = BinaryErodeImageFilterType::New(); - dilateFilter0->SetInput(itkTumorSeed); - dilateFilter0->SetKernel(structuringElement); - dilateFilter0->SetForegroundValue(1); - dilateFilter0->Update(); - - Image::Pointer dil = GrabItkImageMemory(dilateFilter0->GetOutput()); - - dil->SetGeometry(tumorSeed->GetGeometry()); - dataTimeStep->AddData(dil.GetPointer(), name + suffix, "Dilated Binary"); - } - } -} diff --git a/Modules/TumorInvasionAnalysis/src/ImageFilters/mitkCollectionGrayOpening.cpp b/Modules/TumorInvasionAnalysis/src/ImageFilters/mitkCollectionGrayOpening.cpp deleted file mode 100644 index 4d2811f5c8..0000000000 --- a/Modules/TumorInvasionAnalysis/src/ImageFilters/mitkCollectionGrayOpening.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkCollectionGrayOpening.h" -#include -#include - -#include "itkBinaryBallStructuringElement.h" -#include "itkBinaryDilateImageFilter.h" -#include "itkFlatStructuringElement.h" -#include "itkGrayscaleMorphologicalOpeningImageFilter.h" - -void mitk::CollectionGrayOpening::PerformGrayOpening(mitk::DataCollection *dataCollection, - std::string name, - std::string suffix) -{ - for (size_t patient = 0; patient < dataCollection->Size(); ++patient) - { - DataCollection *dataPatient = dynamic_cast(dataCollection->GetData(patient).GetPointer()); - if (dataPatient == nullptr) - MITK_ERROR << "PerformGrayOpening - Structure of DataCollection is invalid at patient level. Data inconsistent!"; - - if (dataPatient->Size() == 0) - MITK_ERROR << "Empty Patient Collective. Probably Fatal."; - - for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep) - { - DataCollection *dataTimeStep = dynamic_cast(dataPatient->GetData(timeStep).GetPointer()); - if (dataTimeStep == nullptr) - MITK_ERROR - << "DilateBinaryByName- Structure of DataCollection is invalid at time step level. Data inconsistent!"; - - // BinaryImage::Pointer itkImage = BinaryImage::New(); - ImageType::Pointer itkImage = ImageType::New(); - Image::Pointer tmp = dataTimeStep->GetMitkImage(name).GetPointer(); - if (tmp.IsNull()) - MITK_ERROR << "null"; - CastToItkImage(tmp, itkImage); - if (itkImage.IsNull()) - MITK_ERROR << "Image " << name << " does not exist. Fatal."; - - typedef itk::FlatStructuringElement<3> StructuringElementType; - StructuringElementType::RadiusType elementRadius; - elementRadius.Fill(1); - elementRadius[2] = 0; - StructuringElementType structuringElement = StructuringElementType::Box(elementRadius); - - typedef itk::GrayscaleMorphologicalOpeningImageFilter - DilateImageFilterType; - - DilateImageFilterType::Pointer dilateFilter0 = DilateImageFilterType::New(); - dilateFilter0->SetInput(itkImage); - dilateFilter0->SetKernel(structuringElement); - dilateFilter0->Update(); - - DilateImageFilterType::Pointer dilateFilter1 = DilateImageFilterType::New(); - dilateFilter1->SetInput(dilateFilter0->GetOutput()); - dilateFilter1->SetKernel(structuringElement); - dilateFilter1->Update(); - - Image::Pointer dil = GrabItkImageMemory(dilateFilter1->GetOutput()); - dataTimeStep->AddData(dil.GetPointer(), name + suffix, ""); - } - } -} diff --git a/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp b/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp deleted file mode 100644 index 1ba2eb7170..0000000000 --- a/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionReader.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#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()) - { - 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()) - { - 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/src/ReaderWriter/mitkDiffusionCollectionWriter.cpp b/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionWriter.cpp deleted file mode 100755 index 9a2fbb56b3..0000000000 --- a/Modules/TumorInvasionAnalysis/src/ReaderWriter/mitkDiffusionCollectionWriter.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#ifdef _MSC_VER -# pragma warning (disable : 4996) -#endif - -#include "mitkDiffusionCollectionWriter.h" - -#include -#include -#include - -#include "mitkImageCast.h" -#include "mitkTensorImage.h" -#include "itkNrrdImageIO.h" -#include "itkImageFileWriter.h" -#include "mitkCoreObjectFactory.h" - - -#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 = "filepath"; -const std::string LINK = "link"; - - -static std::string GetName(std::string fileName,std::string suffix, bool longName = false) -{ - fileName = QFileInfo(QString::fromStdString(fileName)).fileName().toStdString(); - if (longName) - return fileName.substr(0,fileName.length() -suffix.length()-11); // 10 = date length - else - return fileName.substr(0,fileName.length() -suffix.length()-9); // 8 = date length -} - -static std::string GetDate(std::string fileName,std::string suffix, bool longName = false) -{ - fileName = QFileInfo(QString::fromStdString(fileName)).fileName().toStdString(); - if (longName) - fileName = fileName.substr(fileName.length() - suffix.length()-10,10); // 8 = date length - else - fileName = fileName.substr(fileName.length() - suffix.length()-8,8); // 8 = date length - if (!longName) - { - fileName.insert(6,"-"); - fileName.insert(4,"-"); - } - return fileName; -} - - - - -bool mitk::DiffusionCollectionWriter::ExportCollectionToFolder(DataCollection *dataCollection, std::string xmlFile, std::vector filter) -{ - // Quick and Dirty: Assumes three level DataCollection - QDir fileName = QFileInfo(xmlFile.c_str()).absoluteDir(); - std::string outputFolder = fileName.path().toStdString() + QDir::separator().toLatin1(); - QDir baseFolder(outputFolder.c_str()); - baseFolder.mkpath(outputFolder.c_str()); - - std::ofstream xmlFileStream; - xmlFileStream.open (xmlFile.c_str()); - xmlFileStream << " \n"; - xmlFileStream << "<" << COLLECTION << " " << NAME << "=\"" << dataCollection->GetName() << "\" >\n"; - unsigned int subColId = 0; - - unsigned int dataId = 0; - - QDir dir(QString::fromStdString(outputFolder)); - for (size_t i = 0 ; i < dataCollection->Size(); ++i) - { - // Write Subcollection tag - xmlFileStream << " <" << SUBCOLLECTION << " " << NAME << "=\"" << dataCollection->IndexToName(i) << "\" " << FILEPATH << "=\"" << dataCollection->GetDataFilePath(i) << "\" id=\"Col" << subColId << "\" >\n"; - // Create Sub-Folder - dir.mkpath(QString::fromStdString(dataCollection->IndexToName(i))); - - // Herein create data folders - DataCollection* subCollections = dynamic_cast (dataCollection->GetData(i).GetPointer()); - if (subCollections == nullptr) - { - MITK_ERROR<< "mitk::DiffusionCollectionWriter::SaveCollectionToFolder: Container is illformed. Aborting"; - return false; - } - - for (size_t d = 0; d < subCollections->Size(); d++ ) - { - // Create Sub Paths - QString subPath = QString::fromStdString(dataCollection->IndexToName(i))+"/"+QString::fromStdString(subCollections->IndexToName(d)); - dir.mkpath(subPath); - xmlFileStream << " <" << DATA << " " << NAME << "=\"" << subCollections->IndexToName(d) << "\" " << FILEPATH << "=\"" << subCollections->GetDataFilePath(d) << "\" id=\"Data" << dataId << "\" >\n"; - - DataCollection* itemCollections = dynamic_cast (subCollections->GetData(d).GetPointer()); - if (itemCollections == nullptr) - { - MITK_ERROR<< "mitk::DiffusionCollectionWriter::SaveCollectionToFolder: Container is illformed. Aborting"; - return false; - } - - for (size_t s = 0; s < itemCollections->Size(); s++) - { - if (filter.size() > 0) - { - bool isSelected = false; - for (size_t f = 0; f < filter.size(); f++) - { - if (filter.at(f) == itemCollections->IndexToName(s) ) - { - isSelected = true; - break; - } - } - if (isSelected == false) - continue; - } - Image* image = dynamic_cast (itemCollections->GetData(s).GetPointer()); - QString fileName = dir.path() + dir.separator() + subPath + dir.separator() + QString::fromStdString(dataCollection->IndexToName(i)) + "_" + QString::fromStdString(subCollections->IndexToName(d)) + "_" + QString::fromStdString(itemCollections->IndexToName(s)); - try - { - if (itemCollections->IndexToName(s) == "DTI" || itemCollections->IndexToName(s) == "DTIFWE") - { - fileName += ".dti"; - IOUtil::Save(image,fileName.toStdString()); - } - else if (itemCollections->IndexToName(s) == "FIB") - { - fileName += ".fib"; - FiberBundle* fib = dynamic_cast (itemCollections->GetData(s).GetPointer()); - IOUtil::Save(fib, fileName.toStdString()); - } - else if (itemCollections->IndexToName(s) == "DWI") - { - fileName += ".dwi"; - IOUtil::Save(image,fileName.toStdString()); - } - else - { - fileName += ".nrrd"; - Image::Pointer image = itemCollections->GetMitkImage(s).GetPointer(); - IOUtil::Save(image,fileName.toStdString()); - } - } - catch( const std::exception& e) - { - MITK_ERROR << "Caught exception: " << e.what(); - } - - std::string relativeFilename = baseFolder.relativeFilePath(fileName).toStdString(); - xmlFileStream << " <" << ITEM << " " << NAME << "=\"" <IndexToName(s) << "\" " << FILEPATH << "=\"" << "\" " << LINK << "=\"" << relativeFilename << "\" />\n"; - } - xmlFileStream << " \n"; - dataId++; - } - - xmlFileStream << " \n"; - subColId++; - } - xmlFileStream << "\n"; - xmlFileStream.flush(); - xmlFileStream.close(); - return true; -} - -bool mitk::DiffusionCollectionWriter::ExportCollectionToFolder(mitk::DataCollection *dataCollection, std::string xmlFile) -{ - std::vector mods; - return ExportCollectionToFolder(dataCollection,xmlFile, mods); -} - -bool mitk::DiffusionCollectionWriter::SaveCollection(mitk::DataCollection *dataCollection, std::vector filter, std::string xmlFile) -{ - QDir origFilename = QFileInfo(dataCollection->GetXMLFile().c_str()).absoluteDir(); - QString originalFolder = origFilename.path() + QDir::separator(); - - if (xmlFile == "") - xmlFile = dataCollection->GetXMLFile(); - - QDir fileName = QFileInfo(xmlFile.c_str()).absoluteDir(); - std::string outputFolder = fileName.path().toStdString() + QDir::separator().toLatin1(); - QDir baseFolder(outputFolder.c_str()); - - std::ofstream xmlFileStream; - xmlFileStream.open (xmlFile.c_str()); - xmlFileStream << " \n"; - xmlFileStream << "<" << COLLECTION << " " << NAME << "=\"" << dataCollection->GetName() << "\" >\n"; - unsigned int subColId = 0; - - unsigned int dataId = 0; - - QDir dir(QString::fromStdString(outputFolder)); - for (size_t i = 0 ; i < dataCollection->Size(); ++i) - { - // Write Subcollection tag - xmlFileStream << " <" << SUBCOLLECTION << " " << NAME << "=\"" << dataCollection->IndexToName(i) << "\" " << FILEPATH << "=\"" << dataCollection->GetDataFilePath(i) << "\" id=\"Col" << subColId << "\" >\n"; - // Create Sub-Folder - dir.mkpath(QString::fromStdString(dataCollection->IndexToName(i))); - - // Herein create data folders - DataCollection* subCollections = dynamic_cast (dataCollection->GetData(i).GetPointer()); - if (subCollections == nullptr) - { - MITK_ERROR<< "mitk::DiffusionCollectionWriter::SaveCollectionToFolder: Container is illformed. Aborting"; - return false; - } - - for (size_t d = 0; d < subCollections->Size(); d++ ) - { - // Create Sub Paths - QString subPath = QString::fromStdString(dataCollection->IndexToName(i))+"/"+QString::fromStdString(subCollections->IndexToName(d)); - dir.mkpath(subPath); - xmlFileStream << " <" << DATA << " " << NAME << "=\"" << subCollections->IndexToName(d) << "\" " << FILEPATH << "=\"" << subCollections->GetDataFilePath(d) << "\" id=\"Data" << dataId << "\" >\n"; - - DataCollection* itemCollections = dynamic_cast (subCollections->GetData(d).GetPointer()); - if (itemCollections == nullptr) - { - MITK_ERROR<< "mitk::DiffusionCollectionWriter::SaveCollectionToFolder: Container is illformed. Aborting"; - return false; - } - - for (size_t s = 0; s < itemCollections->Size(); s++) - { - if (filter.size() > 0) - { - bool isSelected = false; - for (size_t f = 0; f < filter.size(); f++) - { - if (filter.at(f) == itemCollections->IndexToName(s) ) - { - isSelected = true; - break; - } - } - if (isSelected == false) - continue; - } - Image* image = dynamic_cast (itemCollections->GetData(s).GetPointer()); - QString fileName; - bool fullName = false; - if (itemCollections->GetDataFilePath(s) != "") - { - fileName = originalFolder + QString::fromStdString(itemCollections->GetDataFilePath(s)); - fullName = true; - MITK_INFO << "original path: " << itemCollections->GetDataFilePath(s) ; - } - else - fileName = dir.path() + dir.separator() + subPath + dir.separator() + QString::fromStdString(dataCollection->IndexToName(i)) + "_" + QString::fromStdString(subCollections->IndexToName(d)) + "_" + QString::fromStdString(itemCollections->IndexToName(s)); - - try - { - if (itemCollections->IndexToName(s) == "DTI" || itemCollections->IndexToName(s) == "DTIFWE") - { - if (!fullName) - fileName += ".dti"; - IOUtil::Save(image,fileName.toStdString()); - } - else if (itemCollections->IndexToName(s) == "FIB") - { - if (!fullName) - fileName += ".fib"; - FiberBundle* fib = dynamic_cast (itemCollections->GetData(s).GetPointer()); - IOUtil::Save(fib, fileName.toStdString()); - } - else if (itemCollections->IndexToName(s) == "DWI") - { - if (!fullName) - fileName += ".dwi"; - IOUtil::Save(image,fileName.toStdString()); - } - else - { - if (!fullName) - fileName += ".nrrd"; - Image::Pointer image = itemCollections->GetMitkImage(s).GetPointer(); - IOUtil::Save(image,fileName.toStdString()); - } - } - catch( const std::exception& e) - { - MITK_ERROR << "Caught exception: " << e.what(); - } - - std::string relativeFilename =baseFolder.relativeFilePath(fileName).toStdString(); - xmlFileStream << " <" << ITEM << " " << NAME << "=\"" <IndexToName(s) << "\" " << FILEPATH << "=\"" << "\" " << LINK << "=\"" << relativeFilename << "\" />\n"; - } - xmlFileStream << " \n"; - dataId++; - } - - xmlFileStream << " \n"; - subColId++; - } - xmlFileStream << "\n"; - xmlFileStream.flush(); - xmlFileStream.close(); - return true; -} - -bool mitk::DiffusionCollectionWriter::FolderToXml(std::string folder, std::string collectionType, std::string xmlFile, std::vector filter, std::vector seriesNames) -{ - // 1) Parse for folders - - QDir parseDir; - parseDir.setFilter( QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot); - parseDir.setPath(QString::fromStdString(folder)); - - QFileInfoList qFileList = parseDir.entryInfoList(); - - - std::ofstream xmlFileStream; - xmlFileStream.open (xmlFile.c_str()); - xmlFileStream << " \n"; - xmlFileStream << "<" << COLLECTION << " " << NAME << "=\"" << "GEN" << "\" >\n"; - - unsigned int dataId = 0; - - // now populate lists with files names, non-existing files will be marked with an empty string - for (int i = 0; i < qFileList.size(); ++i) - { - // 2) For Each sub folder construct collectionType sub-folder - std::string baseFolder = qFileList.at(i).absoluteFilePath().toStdString() + QDir::separator().toLatin1() + collectionType; - - MITK_INFO << "Processing : " << baseFolder; - if (!QFileInfo(QString::fromStdString(baseFolder)).isDir()) - { - MITK_WARN << "Not a valid folder, skipping."; - continue; - } - - // 3) Parse each sub folder and extend XML file - // Parse folder and look up all data, - // after sanitation only fully available groups are included (that is all suffixes are found) - - DiffusionCollectionReader::FileListType fileList = DiffusionCollectionReader::SanitizeFileList(DiffusionCollectionReader::GenerateFileLists(baseFolder, filter,true)); - if (fileList.size() <= 0 || fileList.at(0).size() <= 0) - continue; - - // Write Subcollection tag - // try to extract date out of filename - std::string name = GetName(fileList.at(0).at(0),filter.at(0)); - xmlFileStream << " <" << SUBCOLLECTION << " " << NAME << "=\"" << name << "\" " << FILEPATH << "=\"\" id=\"Col" << i << "\" >\n"; - - - 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. - { - std::string strDate = GetDate(fileList.at(0).at(k),filter.at(0)); - xmlFileStream << " <" << DATA << " " << NAME << "=\"" << strDate << "\" " << " id=\"Data" << dataId << "\" >\n"; - dataId++; - for (unsigned int i=0; i< filter.size(); ++i) - { - std::string fileName = fileList.at(i).at(k); - xmlFileStream << " <" << ITEM << " " << NAME << "=\"" << seriesNames.at(i) << "\" " << LINK << "=\"" << fileName << "\" />\n"; - } - xmlFileStream << " \n" ; - } - xmlFileStream << " \n"; - } - - xmlFileStream << "\n"; - xmlFileStream.flush(); - xmlFileStream.close(); - - return true; -} - -bool mitk::DiffusionCollectionWriter::SingleFolderToXml(std::string folder, std::string xmlFile, std::vector filter, std::vector seriesNames, bool longDate, int skipUntil, float months) -{ - std::ofstream xmlFileStream; - xmlFileStream.open (xmlFile.c_str()); - xmlFileStream << " \n"; - xmlFileStream << "<" << COLLECTION << " " << NAME << "=\"" << "GEN" << "\" >\n"; - - unsigned int dataId = 0; - - // 1) - // Parse folder and look up all data, - // after sanitation only fully available groups are included (that is all suffixes are found) - - DiffusionCollectionReader::FileListType fileList = DiffusionCollectionReader::SanitizeFileList(DiffusionCollectionReader::GenerateFileLists(folder, filter,true)); - - // Write Subcollection tag - // try to extract date out of filename - std::string name = GetName(fileList.at(0).at(0),filter.at(0),longDate); - xmlFileStream << " <" << SUBCOLLECTION << " " << NAME << "=\"" << name << "\" " << FILEPATH << "=\"\" id=\"Col" << 0 << "\" >\n"; - - - for (unsigned int k=skipUntil; k < fileList.at(0).size(); ++k) // all groups have the same amount of items, so looking at 0 is ok. - { - std::string strDate = GetDate(fileList.at(0).at(k),filter.at(0),true); - xmlFileStream << " <" << DATA << " " << NAME << "=\"" << strDate << "\" " << " id=\"Data" << dataId << "\" >\n"; - dataId++; - for (unsigned int i=0; i< filter.size(); ++i) - { - std::string fileName = fileList.at(i).at(k); - xmlFileStream << " <" << ITEM << " " << NAME << "=\"" << seriesNames.at(i) << "\" " << LINK << "=\"" << fileName << "\" />\n"; - } - - // size_t ind = GetIndexForinXMonths(fileList,months,k,filter); - // xmlFileStream << " <" << ITEM << " " << NAME << "=\"TARGET\" " << LINK << "=\"" << fileList.at(filter.size()-1).at(ind) << "\" />\n"; - - xmlFileStream << " \n" ; - // check if target still exists for next step - if (GetIndexForinXMonths(fileList,months,k+1,filter)== 0) - break; - } - xmlFileStream << " \n"; - - xmlFileStream << "\n"; - xmlFileStream.flush(); - xmlFileStream.close(); - - return true; -} - -size_t mitk::DiffusionCollectionWriter::GetIndexForinXMonths(mitk::DiffusionCollectionReader::FileListType fileList,float months, size_t curIndex,std::vector filter) -{ - std::string strDate0 = GetDate(fileList.at(0).at(curIndex),filter.at(0),true); - - int year0 =std::atoi(strDate0.substr(0,4).c_str()); - int month0 =std::atoi(strDate0.substr(5,2).c_str()); - int day0 = std::atoi(strDate0.substr(8,2).c_str()); - - size_t bestIndex = 0; - int bestFit = 1e5; - - for (size_t i=curIndex+1; i < fileList.at(0).size(); ++i) - { - std::string strDate = GetDate(fileList.at(0).at(i),filter.at(0),true); - int year =std::atoi(strDate.substr(0,4).c_str()); - int month =std::atoi(strDate.substr(5,2).c_str()); - int day = std::atoi(strDate.substr(8,2).c_str()); - - int fit = std::fabs((months * 30 ) - (((year-year0)*360) +((month-month0)*30) + (day-day0))); // days difference from x months - if (fit < bestFit) - { - bestFit = fit; - bestIndex = i; - } - } - return bestIndex; -} diff --git a/Modules/TumorInvasionAnalysis/test/CMakeLists.txt b/Modules/TumorInvasionAnalysis/test/CMakeLists.txt deleted file mode 100644 index 153cd81e2e..0000000000 --- a/Modules/TumorInvasionAnalysis/test/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -MITK_CREATE_MODULE_TESTS() diff --git a/Modules/TumorInvasionAnalysis/test/files.cmake b/Modules/TumorInvasionAnalysis/test/files.cmake deleted file mode 100644 index 138e885252..0000000000 --- a/Modules/TumorInvasionAnalysis/test/files.cmake +++ /dev/null @@ -1,4 +0,0 @@ -set(MODULE_CUSTOM_TESTS - ## Testing the basic classification funtionality - mitkClassificationTest.cpp -) diff --git a/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp b/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp deleted file mode 100644 index 0a85a7e36a..0000000000 --- a/Modules/TumorInvasionAnalysis/test/mitkClassificationTest.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#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); - - 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)