diff --git a/Modules/ShapeComparison/files.cmake b/Modules/ShapeComparison/files.cmake index ae8021f0fc..2a50fff01f 100644 --- a/Modules/ShapeComparison/files.cmake +++ b/Modules/ShapeComparison/files.cmake @@ -1,10 +1,13 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkShapeComparisonManager.cpp DataManagement/mitkLabelOverlapMetricCalculator.cpp + DataManagement/mitkSurfaceDistanceCalculator.cpp + DataManagement/mitkCurvatureMetricCalculator.cpp + DataManagement/mitkPrintResultHelper.cpp ) set(RESOURCE_FILES ) diff --git a/Modules/ShapeComparison/include/MitkShapeComparisonManager.h b/Modules/ShapeComparison/include/MitkShapeComparisonManager.h index 790c748f52..cf4e5728d2 100644 --- a/Modules/ShapeComparison/include/MitkShapeComparisonManager.h +++ b/Modules/ShapeComparison/include/MitkShapeComparisonManager.h @@ -1,60 +1,62 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkShapeComparisonManager_h #define mitkShapeComparisonManager_h #include #include +#include #include #include namespace mitk { class MITKSHAPECOMPARISON_EXPORT ShapeComparisonManager { public: - ShapeComparisonManager(mitk::Image::Pointer firstImg, mitk::Image::Pointer secondImg); + ShapeComparisonManager(); ~ShapeComparisonManager(); - void setFirstImage(mitk::Image::Pointer firstImg); - void setSecondImage(mitk::Image::Pointer secondImg); + std::map calculateLabelOverlapMetrics(mitk::Image::Pointer firstImg, mitk::Image::Pointer secondImg); + std::map calculateLabelOverlapMetricsSlices(mitk::Image::Pointer firstImg, mitk::Image::Pointer secondImg, PlaneGeometry* plane); - void calculateMetrics(); - void calculateMetricsSlices(PlaneGeometry* plane, int slicenumber); - std::map getLabelOverlapResults(); - mitk::Image::Pointer getMFirstSlice(); - mitk::Image::Pointer getMSecondSlice(); + std::map calculateDistanceMetrics(mitk::Surface::Pointer firstSurface, mitk::Surface::Pointer secondSurface); + std::map calculateDistanceMetricsSlices(mitk::Surface::Pointer firstSurface, mitk::Surface::Pointer secondSurface, PlaneGeometry* plane); + mitk::Image::Pointer extractSlice(mitk::Image::Pointer img, PlaneGeometry::Pointer plane); - private: + void setOutputpath(std::string outputpath); + void startOutputGeneration(); - mitk::Image::Pointer m_firstImg; - mitk::Image::Pointer m_secondImg; + private: - mitk::Image::Pointer m_firstImgSlice; - mitk::Image::Pointer m_secondImgSlice; + std::map m_LabelOverlapResults; - mitk::Image::Pointer extractImageSlice(mitk::Image::Pointer img, PlaneGeometry* plane, int sliceNumber); + std::string m_outputpath; + std::ofstream m_OutputFile; + bool m_generateOutput = false; + int sliceCounterOverlap = -70; + int sliceCounterDistance = -70; }; } #endif diff --git a/Modules/ShapeComparison/include/mitkCurvatureMetricCalculator.h b/Modules/ShapeComparison/include/mitkCurvatureMetricCalculator.h new file mode 100644 index 0000000000..e40ea61477 --- /dev/null +++ b/Modules/ShapeComparison/include/mitkCurvatureMetricCalculator.h @@ -0,0 +1,55 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkCurvatureMetricCalculator_h +#define mitkCurvatureMetricCalculator_h + +#include + +#include +#include + + +namespace mitk +{ + class CurvatureMetricCalculator + { + public: + CurvatureMetricCalculator(mitk::Surface::Pointer first, mitk::Surface::Pointer second); + ~CurvatureMetricCalculator(); + void calculateCurvatureMetrics3D(); + void calculateCurvatureMetrics2D(); + + std::map getResults(); + void printResults(); + + protected: + + + + private: + + mitk::Surface::Pointer m_firstImg; + mitk::Surface::Pointer m_secondImg; + + std::map m_Results; + + }; + + +} + +#endif diff --git a/Modules/ShapeComparison/include/mitkPrintResultHelper.h b/Modules/ShapeComparison/include/mitkPrintResultHelper.h new file mode 100644 index 0000000000..17264f2645 --- /dev/null +++ b/Modules/ShapeComparison/include/mitkPrintResultHelper.h @@ -0,0 +1,45 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkPrintResultHelper_h +#define mitkPrintResultHelper_h + +#include + +#include "itkImage.h" +#include +#include + + +namespace mitk +{ + class PrintResultHelper + { + public: + PrintResultHelper(); + ~PrintResultHelper(); + + void printResults(std::string path, std::map results); + + protected: + + private: +//TODO outputstream + + }; +} + +#endif diff --git a/Modules/ShapeComparison/include/mitkSurfaceDistanceCalculator.h b/Modules/ShapeComparison/include/mitkSurfaceDistanceCalculator.h new file mode 100644 index 0000000000..7d89a1a50e --- /dev/null +++ b/Modules/ShapeComparison/include/mitkSurfaceDistanceCalculator.h @@ -0,0 +1,57 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkSurfaceDistanceCalculator_h +#define mitkSurfaceDistanceCalculator_h + +#include + +#include +#include + +#include + + +namespace mitk +{ + class SurfaceDistanceCalculator + { + public: + SurfaceDistanceCalculator(mitk::Surface::Pointer first, mitk::Surface::Pointer second); + ~SurfaceDistanceCalculator(); + std::map calculateSurfaceDistanceMetric3D(); + std::map calculateSurfaceDistanceMetric2D(mitk::PlaneGeometry::Pointer planegeo); + + protected: + + + private: + + mitk::Surface::Pointer m_First; + mitk::Surface::Pointer m_Second; + + double calculateAverageSurfaceDistance(vtkSmartPointer distances); + double calculateAverageSymmetricSurfaceDistance(double asdA, double asdB); + + vtkSmartPointer getPointsOnPlane(vtkSmartPointer pointset, mitk::PlaneGeometry::Pointer planegeo); + + void printResults(std::map results); + }; + + +} + +#endif diff --git a/Modules/ShapeComparison/src/DataManagement/mitkCurvatureMetricCalculator.cpp b/Modules/ShapeComparison/src/DataManagement/mitkCurvatureMetricCalculator.cpp new file mode 100644 index 0000000000..fcbc5313a6 --- /dev/null +++ b/Modules/ShapeComparison/src/DataManagement/mitkCurvatureMetricCalculator.cpp @@ -0,0 +1,29 @@ +#include "mitkCurvatureMetricCalculator.h" + + + +mitk::CurvatureMetricCalculator::CurvatureMetricCalculator(mitk::Surface::Pointer first, mitk::Surface::Pointer second) +{ +} + + +mitk::CurvatureMetricCalculator::~CurvatureMetricCalculator() +{ +} + +void mitk::CurvatureMetricCalculator::calculateCurvatureMetrics3D() +{ +} + +void mitk::CurvatureMetricCalculator::calculateCurvatureMetrics2D() +{ +} + +std::map mitk::CurvatureMetricCalculator::getResults() +{ + return std::map(); +} + +void mitk::CurvatureMetricCalculator::printResults() +{ +} diff --git a/Modules/ShapeComparison/src/DataManagement/mitkLabelOverlapMetricCalculator.cpp b/Modules/ShapeComparison/src/DataManagement/mitkLabelOverlapMetricCalculator.cpp index dc9a465e6f..d6b20c5872 100644 --- a/Modules/ShapeComparison/src/DataManagement/mitkLabelOverlapMetricCalculator.cpp +++ b/Modules/ShapeComparison/src/DataManagement/mitkLabelOverlapMetricCalculator.cpp @@ -1,154 +1,118 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include "vtkVersion.h" #include "vtkImageViewer.h" #include "vtkImageMapper3D.h" #include "vtkRenderWindowInteractor.h" #include "vtkSmartPointer.h" #include "vtkImageActor.h" #include "vtkInteractorStyleImage.h" #include "vtkRenderer.h" #include "itkRGBPixel.h" mitk::LabelOverlapMetricCalculator::LabelOverlapMetricCalculator(mitk::Image::Pointer first, mitk::Image::Pointer second) { this->m_firstImg = first; this->m_secondImg = second; } mitk::LabelOverlapMetricCalculator::~LabelOverlapMetricCalculator() { m_firstImg->Delete(); m_secondImg->Delete(); } void mitk::LabelOverlapMetricCalculator::calculateLabelOverlapMeasures3D() { MITK_INFO << "calculateLabelOverlapMeasures"; // Create ITK image, cast from MITK image typedef itk::Image ImageType; - ImageType::Pointer itkFirstImg = ImageType::New(); - mitk::CastToItkImage(m_firstImg, itkFirstImg);//ImagetoITKImage + mitk::CastToItkImage(m_firstImg, itkFirstImg); ImageType::Pointer itkSecondImg = ImageType::New(); mitk::CastToItkImage(m_secondImg, itkSecondImg); - - - MITK_INFO << "itk casts"; typedef itk::LabelOverlapMeasuresImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetSourceImage(itkFirstImg); filter->SetTargetImage(itkSecondImg); - MITK_INFO << "Update"; filter->Update(); //fill result map m_Results["Dice"] = filter->GetDiceCoefficient(); m_Results["FNR"] = filter->GetFalseNegativeError(); m_Results["FPR"] = filter->GetFalsePositiveError(); m_Results["Jaccard"] = filter->GetJaccardCoefficient(); m_Results["VolumeSimilarity"] = filter->GetVolumeSimilarity(); } void mitk::LabelOverlapMetricCalculator::calculateLabelOverlapMeasures2D() { MITK_INFO << "calculateLabelOverlapMeasures"; // Create ITK image, cast from MITK image typedef itk::Image ImageType; - ImageType::Pointer itkFirstImg = ImageType::New(); mitk::CastToItkImage(m_firstImg, itkFirstImg);//ImagetoITKImage ImageType::Pointer itkSecondImg = ImageType::New(); mitk::CastToItkImage(m_secondImg, itkSecondImg); -// //black img -// vtkSmartPointer actor = -// vtkSmartPointer::New(); -//#if VTK_MAJOR_VERSION <= 5 -// actor->SetInput(connector->GetOutput()); -//#else -// actor->GetMapper()->SetInputData(m_secondImg->GetVtkImageData()); -//#endif -// vtkSmartPointer renderer = -// vtkSmartPointer::New(); -// renderer->AddActor(actor); -// renderer->ResetCamera(); -// -// vtkSmartPointer renderWindow = -// vtkSmartPointer::New(); -// renderWindow->AddRenderer(renderer); -// -// vtkSmartPointer renderWindowInteractor = -// vtkSmartPointer::New(); -// vtkSmartPointer style = -// vtkSmartPointer::New(); -// -// renderWindowInteractor->SetInteractorStyle(style); -// -// renderWindowInteractor->SetRenderWindow(renderWindow); -// renderWindowInteractor->Initialize(); -// -// renderWindowInteractor->Start(); - - MITK_INFO << "itk casts"; typedef itk::LabelOverlapMeasuresImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetSourceImage(itkFirstImg); filter->SetTargetImage(itkSecondImg); - MITK_INFO << "Update"; filter->Update(); //fill result map m_Results["Dice"] = filter->GetDiceCoefficient(); m_Results["FNR"] = filter->GetFalseNegativeError(); m_Results["FPR"] = filter->GetFalsePositiveError(); m_Results["Jaccard"] = filter->GetJaccardCoefficient(); m_Results["VolumeSimilarity"] = filter->GetVolumeSimilarity(); + printResults(); } std::map mitk::LabelOverlapMetricCalculator::getResults() { return m_Results; } void mitk::LabelOverlapMetricCalculator::printResults() { MITK_INFO << "FPR: " << m_Results["FPR"]; MITK_INFO << "FNR: " << m_Results["FNR"]; MITK_INFO << "Dice: " << m_Results["Dice"]; MITK_INFO << "Jaccard: " << m_Results["Jaccard"]; MITK_INFO << "Volume Similarity: " << m_Results["VolumeSimilarity"]; } diff --git a/Modules/ShapeComparison/src/DataManagement/mitkPrintResultHelper.cpp b/Modules/ShapeComparison/src/DataManagement/mitkPrintResultHelper.cpp new file mode 100644 index 0000000000..9562e80403 --- /dev/null +++ b/Modules/ShapeComparison/src/DataManagement/mitkPrintResultHelper.cpp @@ -0,0 +1,19 @@ +#include "mitkPrintResultHelper.h" + + + + +mitk::PrintResultHelper::PrintResultHelper() +{ +} + + +mitk::PrintResultHelper::~PrintResultHelper() +{ +} + +void mitk::PrintResultHelper::printResults(std::string path, std::map results) +{ + + +} diff --git a/Modules/ShapeComparison/src/DataManagement/mitkSurfaceDistanceCalculator.cpp b/Modules/ShapeComparison/src/DataManagement/mitkSurfaceDistanceCalculator.cpp new file mode 100644 index 0000000000..2c82784de3 --- /dev/null +++ b/Modules/ShapeComparison/src/DataManagement/mitkSurfaceDistanceCalculator.cpp @@ -0,0 +1,133 @@ +#include "mitkSurfaceDistanceCalculator.h" + +#include + +#include +#include +#include +#include +#include + + +mitk::SurfaceDistanceCalculator::SurfaceDistanceCalculator(mitk::Surface::Pointer first, mitk::Surface::Pointer second) +{ + this->m_First = first; + this->m_Second = second; +} + + +mitk::SurfaceDistanceCalculator::~SurfaceDistanceCalculator() +{ +} + +std::map mitk::SurfaceDistanceCalculator::calculateSurfaceDistanceMetric3D() +{ + std::map results; + MITK_INFO << "calculating SurfaceDistanceMetrics 3D"; + vtkSmartPointer distancesFirst = m_First->GetVtkPolyData()->GetPointData()->GetScalars("Distances"); + vtkSmartPointer distancesSecond = m_Second->GetVtkPolyData()->GetPointData()->GetScalars("Distances"); + double asdFirst = calculateAverageSurfaceDistance(distancesFirst); + double asdSecond = calculateAverageSurfaceDistance(distancesSecond); + double assd = calculateAverageSymmetricSurfaceDistance(asdFirst, asdSecond); + results.emplace("ASDFirst", asdFirst); + results.emplace("ASDSecond", asdSecond); + results.emplace("ASSD", assd); + printResults(results); + return results; +} + +std::map mitk::SurfaceDistanceCalculator::calculateSurfaceDistanceMetric2D(mitk::PlaneGeometry::Pointer planegeo) +{ + std::map results; + double asdFirst; + double asdSecond; + double assd; + vtkSmartPointer pointsOnFirstPlane = getPointsOnPlane(m_First->GetVtkPolyData(), planegeo); + vtkSmartPointer pointsOnSecondPlane = getPointsOnPlane(m_Second->GetVtkPolyData(), planegeo); + if (pointsOnFirstPlane->GetNumberOfPoints() > 0 && pointsOnSecondPlane->GetNumberOfPoints() > 0) + { + vtkSmartPointer distancesFirst = pointsOnFirstPlane->GetPointData()->GetScalars("Distances"); + vtkSmartPointer distancesSecond = pointsOnSecondPlane->GetPointData()->GetScalars("Distances"); + MITK_INFO << "distancesFirst: " << distancesFirst.Get()->GetSize(); + MITK_INFO << "distancesSecond: " << distancesSecond.Get()->GetSize(); + double asdFirst = calculateAverageSurfaceDistance(distancesFirst); + double asdSecond = calculateAverageSurfaceDistance(distancesSecond); + double assd = calculateAverageSymmetricSurfaceDistance(asdFirst, asdSecond); + results.emplace("ASDFirst", asdFirst); + results.emplace("ASDSecond", asdSecond); + results.emplace("ASSD", assd); + } + results.emplace("ASDFirst", asdFirst); + results.emplace("ASDSecond", asdSecond); + results.emplace("ASSD", assd); + printResults(results); + return results; +} + +void mitk::SurfaceDistanceCalculator::printResults(std::map results) +{ + MITK_INFO << "ASDFirst: " << results["ASDFirst"]; + MITK_INFO << "ASDSecond: " << results["ASDSecond"]; + MITK_INFO << "ASSD: " << results["ASSD"]; +} + +double mitk::SurfaceDistanceCalculator::calculateAverageSurfaceDistance(vtkSmartPointer distances) +{ + double sum = 0.0; + double result = -1; + for (int i = 0; i < distances->GetSize(); ++i) + { + sum += std::abs(distances.GetPointer()->GetTuple(i)[0]); + } + if (distances->GetSize() != 0) { + result = sum / distances->GetSize(); + } + return result; +} + +double mitk::SurfaceDistanceCalculator::calculateAverageSymmetricSurfaceDistance(double asdA, double asdB) +{ + return (asdA +asdB)/2; +} + +vtkSmartPointer mitk::SurfaceDistanceCalculator::getPointsOnPlane(vtkSmartPointer pointset, mitk::PlaneGeometry::Pointer planegeo) +{ + vtkSmartPointer pointsOnPlane = vtkSmartPointer::New(); + vtkSmartPointer points = vtkSmartPointer::New(); + // Create the topology of the point (a vertex) + vtkSmartPointer vertices = + vtkSmartPointer::New(); + vtkIdType pid[1]; + + vtkSmartPointer scalars = vtkSmartPointer::New(); + + double tempPoint[3] = { 0, 0, 0 }; + int pointcounter = 0; + + //search for points with half the distance of the spacing z-direction + double searchingRange = planegeo->GetSpacing()[2] / 2; + int pointSetSize = pointset->GetPoints()->GetNumberOfPoints(); + for (int i = 0; i < pointSetSize; ++i) + { + pointset->GetPoints()->GetPoint(i, tempPoint); + if (planegeo->Distance(tempPoint) < searchingRange) + { + points->InsertNextPoint(tempPoint); + pid[0] = points->InsertNextPoint(tempPoint); + // MITK_INFO << pointset->GetPointData()->GetScalars()->GetComponent(i, 0); + // scalars->FillValue(pointset->GetPointData()->GetScalars()->GetComponent(i, 0)); + scalars->InsertValue(pointcounter, pointset->GetPointData()->GetScalars()->GetComponent(i, 0)); + // scalars->SetValue(i, pointset->GetPointData()->GetScalars()->GetComponent(i, 0)); + ++pointcounter; + } + } + MITK_INFO << "Number of Points near plane: " << pointcounter; + if (pointcounter > 1) + { + pointsOnPlane->SetPoints(points); + MITK_INFO << "Scalars: " << scalars->GetSize(); + scalars->SetName("Distances"); + pointsOnPlane->GetPointData()->SetScalars(scalars); + } + return pointsOnPlane; +} diff --git a/Modules/ShapeComparison/src/mitkShapeComparisonManager.cpp b/Modules/ShapeComparison/src/mitkShapeComparisonManager.cpp index 736dc8f08d..d6fa305630 100644 --- a/Modules/ShapeComparison/src/mitkShapeComparisonManager.cpp +++ b/Modules/ShapeComparison/src/mitkShapeComparisonManager.cpp @@ -1,138 +1,158 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include -#include +#include +#include #include #include #include #include "vtkVersion.h" #include "vtkImageViewer.h" #include "vtkImageMapper3D.h" #include "vtkRenderWindowInteractor.h" #include "vtkSmartPointer.h" #include "vtkImageActor.h" #include "vtkInteractorStyleImage.h" #include "vtkRenderer.h" #include "itkRGBPixel.h" #include #include #include -mitk::ShapeComparisonManager::ShapeComparisonManager(mitk::Image::Pointer firstImg, mitk::Image::Pointer secondImg) +mitk::ShapeComparisonManager::ShapeComparisonManager() { - this->m_firstImg = firstImg; - this->m_secondImg = secondImg; } mitk::ShapeComparisonManager::~ShapeComparisonManager() { - + m_OutputFile.close(); } -void mitk::ShapeComparisonManager::setFirstImage(mitk::Image::Pointer firstImg) +std::map mitk::ShapeComparisonManager::calculateLabelOverlapMetrics(mitk::Image::Pointer firstImg, mitk::Image::Pointer secondImg) { - this->m_firstImg = firstImg; -} - -void mitk::ShapeComparisonManager::setSecondImage(mitk::Image::Pointer secondImg) -{ - this->m_secondImg = secondImg; + mitk::LabelOverlapMetricCalculator *labelOverlapCalc = new mitk::LabelOverlapMetricCalculator(firstImg, secondImg); + labelOverlapCalc->calculateLabelOverlapMeasures3D(); + std::map results = labelOverlapCalc->getResults(); + if (m_generateOutput) + { + m_OutputFile << "/*****************************************************************************/" << std::endl; + m_OutputFile << "Global LabelOverlap Metrics" << std::endl; + m_OutputFile << "FPR: " << results.at("FPR") << std::endl; + m_OutputFile << "FNR: " << results.at("FNR") << std::endl; + m_OutputFile << "Dice: " << results.at("Dice") << std::endl; + m_OutputFile << "Jaccard: " << results.at("Jaccard") << std::endl; + m_OutputFile << "/*****************************************************************************/" << std::endl; + } + return results; } -void mitk::ShapeComparisonManager::calculateMetrics() +std::map mitk::ShapeComparisonManager::calculateLabelOverlapMetricsSlices(mitk::Image::Pointer firstImg, mitk::Image::Pointer secondImg, PlaneGeometry* plane) { - mitk::LabelOverlapMetricCalculator *labelOverlapCalc = new mitk::LabelOverlapMetricCalculator(m_firstImg, m_secondImg); - MITK_INFO << "New LabelOverlapCalculator instantiated."; - labelOverlapCalc->calculateLabelOverlapMeasures3D(); - m_LabelOverlapResults = labelOverlapCalc->getResults(); + auto sourceSlice = extractSlice(firstImg, plane->Clone()); + auto targetSlice = extractSlice(secondImg, plane->Clone()); + auto labelOverlapCalc = new mitk::LabelOverlapMetricCalculator(sourceSlice, targetSlice); + labelOverlapCalc->calculateLabelOverlapMeasures2D(); + std::map results = labelOverlapCalc->getResults(); + if (m_generateOutput) + { + m_OutputFile << "Local LabelOverlap Metrics" << std::endl; + m_OutputFile << "Slice: " << sliceCounterOverlap << std::endl; + m_OutputFile << "FPR: " << results.at("FPR") << std::endl; + m_OutputFile << "FNR: " << results.at("FNR") << std::endl; + m_OutputFile << "Dice: " << results.at("Dice") << std::endl; + m_OutputFile << "Jaccard: " << results.at("Jaccard") << std::endl; + ++sliceCounterOverlap; + } + return results; } -void mitk::ShapeComparisonManager::calculateMetricsSlices(PlaneGeometry* plane, int slicenumber) +std::map mitk::ShapeComparisonManager::calculateDistanceMetrics(mitk::Surface::Pointer firstSurface, mitk::Surface::Pointer secondSurface) { - /*int box = 250; - for (int i = 0; i < box; ++i) - {*/ - mitk::Image::Pointer sourceSlice = extractImageSlice(m_firstImg, plane, slicenumber); - m_firstImgSlice = sourceSlice; - mitk::Image::Pointer targetSlice = extractImageSlice(m_secondImg, plane, slicenumber); - m_secondImgSlice = targetSlice; - /* mitk::ImageStatisticsHolder* sourceStatHolder = sourceSlice->GetStatistics(); - mitk::ImageStatisticsHolder* targetStatHolder = sourceSlice->GetStatistics();*/ - //if (sourceStatHolder->GetScalarValueMax() > 0 && targetStatHolder->GetScalarValueMax() > 0) TODO - //{ - mitk::LabelOverlapMetricCalculator *labelOverlapCalc = new mitk::LabelOverlapMetricCalculator(sourceSlice, targetSlice); - labelOverlapCalc->calculateLabelOverlapMeasures2D(); - labelOverlapCalc->printResults(); - //} - //} + auto surfaceDistanceCalc = new mitk::SurfaceDistanceCalculator(firstSurface, secondSurface); + MITK_INFO << "New SurfaceDistanceCalculator instantiated."; + std::map results = surfaceDistanceCalc->calculateSurfaceDistanceMetric3D(); + if (m_generateOutput) + { + m_OutputFile << "/*****************************************************************************/" << std::endl; + m_OutputFile << "Global SurfaceDistance Metrics" << std::endl; + m_OutputFile << "ASDFirst: " << results.at("ASDFirst") << std::endl; + m_OutputFile << "ASDSecond: " << results.at("ASDSecond") << std::endl; + m_OutputFile << "ASSD: " << results.at("ASSD") << std::endl; + m_OutputFile << "/*****************************************************************************/" << std::endl; + } + return results; } -std::map mitk::ShapeComparisonManager::getLabelOverlapResults() +std::map mitk::ShapeComparisonManager::calculateDistanceMetricsSlices(mitk::Surface::Pointer firstSurface, mitk::Surface::Pointer secondSurface, PlaneGeometry * plane) { - return m_LabelOverlapResults; + //TODO use PolyData and get points on plane first + auto surfaceDistanceCalc = new mitk::SurfaceDistanceCalculator(firstSurface, secondSurface); + std::map results = surfaceDistanceCalc->calculateSurfaceDistanceMetric2D(plane); + if (m_generateOutput) + { + m_OutputFile << "Local SurfaceDistance Metrics" << std::endl; + m_OutputFile << "Slice: " << sliceCounterDistance << std::endl; + m_OutputFile << "ASDFirst: " << results.at("ASDFirst") << std::endl; + m_OutputFile << "ASDSecond: " << results.at("ASDSecond") << std::endl; + m_OutputFile << "ASSD: " << results.at("ASSD") << std::endl; + ++sliceCounterDistance; + } + return results; } -mitk::Image::Pointer mitk::ShapeComparisonManager::getMFirstSlice() +mitk::Image::Pointer mitk::ShapeComparisonManager::extractSlice(mitk::Image::Pointer img, PlaneGeometry::Pointer planeT) { - return m_firstImgSlice; + auto imgSlice = mitk::Image::Pointer(); + mitk::ExtractSliceFilter2::Pointer extractSliceFilter = mitk::ExtractSliceFilter2::New(); + + MITK_INFO << img->GetReferenceCount(); + MITK_INFO << planeT->GetReferenceCount(); + + extractSliceFilter->SetInput(img); + extractSliceFilter->SetOutputGeometry(planeT); + try + { + extractSliceFilter->Update(); + } + catch (const mitk::Exception& exception) + { + MITK_ERROR << exception.GetDescription(); + // return; + } + imgSlice = extractSliceFilter->GetOutput(); + extractSliceFilter->ResetPipeline(); + imgSlice->DisconnectPipeline(); + return imgSlice; } -mitk::Image::Pointer mitk::ShapeComparisonManager::getMSecondSlice() +void mitk::ShapeComparisonManager::setOutputpath(std::string outputpath) { - return m_secondImgSlice; + this->m_outputpath = outputpath; } -mitk::Image::Pointer mitk::ShapeComparisonManager::extractImageSlice(mitk::Image::Pointer img, PlaneGeometry* planeT, int sliceNumber) +void mitk::ShapeComparisonManager::startOutputGeneration() { - - //double spacingX = img->GetGeometry()->GetSpacing()[0]; positive vlaue - //double spacingY = img->GetGeometry()->GetSpacing()[1]; - //double spacingZ = img->GetGeometry()->GetSpacing()[2]; - //std::array spacing = { -0.47499999999999992, 0.47499999999999992, 0.47500228881835938 }; - // std::array spacing = { spacingX, spacingY, spacingZ }; - //double actualsliceNumber = sliceNumber * spacing[2]; - - //plane->InitializeStandardPlane(256.0, 256.0, image->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetSpacing(), mitk::PlaneGeometry::Axial, sliceNumber); - //planeT->InitializeStandardPlane(256.0, 256.0, img->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetSpacing()); - //planeT->SetSpacing(mitk::Vector3D(spacing.data())); - - // planeT->SetOrigin(img->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetOrigin()); - //mitk::Point3D modOrigin; - //modOrigin[0] = planeT->GetOrigin()[0]; - //modOrigin[1] = planeT->GetOrigin()[1]; - //modOrigin[2] = planeT->GetOrigin()[2] + actualsliceNumber; - //planeT->SetOrigin(modOrigin); - mitk::Image::Pointer imgSlice = mitk::Image::New(); - mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(); - extractor->SetInput(img); - extractor->SetWorldGeometry(planeT); - extractor->SetOutputDimensionality(2); - extractor->SetInPlaneResampleExtentByGeometry(true); - extractor->SetResliceTransformByGeometry(img->GetTimeGeometry()->GetGeometryForTimeStep(0)); - extractor->SetInterpolationMode(mitk::ExtractSliceFilter::RESLICE_NEAREST); - extractor->Update(); - imgSlice = extractor->GetOutput(); - - return imgSlice; + m_OutputFile.open(m_outputpath); + this->m_generateOutput = true; } diff --git a/Plugins/org.mitk.gui.qt.shapecomparison/resources/icon.png b/Plugins/org.mitk.gui.qt.shapecomparison/resources/icon.png new file mode 100644 index 0000000000..d7283370f7 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.shapecomparison/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.shapecomparison/resources/icon2.png b/Plugins/org.mitk.gui.qt.shapecomparison/resources/icon2.png new file mode 100644 index 0000000000..2829a099af Binary files /dev/null and b/Plugins/org.mitk.gui.qt.shapecomparison/resources/icon2.png differ diff --git a/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.cpp b/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.cpp index 19b707d4bc..f17a8d6ef0 100644 --- a/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.cpp +++ b/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.cpp @@ -1,421 +1,424 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkShapeComparison.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "org_mitk_gui_qt_shapecomparison_Activator.h" #include #include #include #include #include -#include +#include #include #include #include +#include #include #include #include #include - - - const std::string QmitkShapeComparison::VIEW_ID = "org.mitk.views.shapecomparison"; QmitkShapeComparison::QmitkShapeComparison(QObject *parent) : m_ParentWidget(0) { } QmitkShapeComparison::~QmitkShapeComparison() { } QWidget * QmitkShapeComparison::GetControls() { return nullptr; } void QmitkShapeComparison::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.firstImageNameComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.firstImageNameComboBox->SetPredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType::New(), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); m_Controls.secondImageNameComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.secondImageNameComboBox->SetPredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType::New(), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); m_Controls.selectGeometryImgComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.selectGeometryImgComboBox->SetPredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType::New(), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); connect(m_Controls.comparePushButton, SIGNAL(clicked()), this, SLOT(compare())); connect(m_Controls.firstImageNameComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSelectedFirstImgChanged(const mitk::DataNode *))); connect(m_Controls.secondImageNameComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSelectedSecondImgChanged(const mitk::DataNode *))); m_Controls.comparePushButton->setEnabled(true); mitk::RenderingManager::GetInstance()->SetDataStorage(this->GetDataStorageReference()->GetDataStorage()); mitk::RenderingManager::GetInstance()->InitializeViews(); m_ParentWidget = parent; } void QmitkShapeComparison::SetFocus() { } void QmitkShapeComparison::OnSelectedFirstImgChanged(const mitk::DataNode *node) { if (node != nullptr) { m_firstImg = dynamic_cast(node->GetData()); m_Controls.selectFirstImageLabel->setText("Selected first Image:"); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (m_secondImg != nullptr && m_secondImg.GetPointer() != m_firstImg.GetPointer()) { m_Controls.comparePushButton->setEnabled(true); } } } void QmitkShapeComparison::OnSelectedSecondImgChanged(const mitk::DataNode *node) { if (node != nullptr) { m_secondImg = dynamic_cast(node->GetData()); m_Controls.selectSecondImageLabel->setText("Selected second Image:"); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (m_firstImg != nullptr && m_secondImg.GetPointer() != m_secondImg.GetPointer()) { m_Controls.comparePushButton->setEnabled(true); } } } void QmitkShapeComparison::compare() { MITK_INFO << "compare clicked!"; mitk::Image* img = dynamic_cast(m_Controls.firstImageNameComboBox->GetSelectedNode()->GetData()); - //int sliceNumber = 120; - ////double spacingX = img->GetGeometry()->GetSpacing()[0]; positive vlaue - ////double spacingY = img->GetGeometry()->GetSpacing()[1]; - ////double spacingZ = img->GetGeometry()->GetSpacing()[2]; - //std::array spacing = { -0.47499999999999992, 0.47499999999999992, 0.47500228881835938 }; - //// std::array spacing = { spacingX, spacingY, spacingZ }; - //double actualsliceNumber = sliceNumber * spacing[2]; - //mitk::PlaneGeometry::Pointer planeT = mitk::PlaneGeometry::New(); - ////plane->InitializeStandardPlane(256.0, 256.0, image->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetSpacing(), mitk::PlaneGeometry::Axial, sliceNumber); - //planeT->InitializeStandardPlane(256.0, 256.0, img->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetSpacing()); - //planeT->SetSpacing(mitk::Vector3D(spacing.data())); - //mitk::Image::Pointer imgSlice = mitk::Image::New(); - //planeT->SetOrigin(img->GetTimeGeometry()->GetGeometryForTimeStep(0)->GetOrigin()); - //mitk::Point3D modOrigin; - //modOrigin[0] = planeT->GetOrigin()[0]; - //modOrigin[1] = planeT->GetOrigin()[1]; - //modOrigin[2] = planeT->GetOrigin()[2] + actualsliceNumber; - //planeT->SetOrigin(modOrigin); - //mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(); - //extractor->SetInput(img); - //extractor->SetWorldGeometry(planeT); - //extractor->SetOutputDimensionality(2); - //extractor->SetInPlaneResampleExtentByGeometry(true); - //extractor->SetResliceTransformByGeometry(img->GetTimeGeometry()->GetGeometryForTimeStep(0)); - //extractor->SetInterpolationMode(mitk::ExtractSliceFilter::RESLICE_NEAREST); - //extractor->Update(); - //imgSlice = extractor->GetOutput(); - - //mitk::DataNode::Pointer testNode = mitk::DataNode::New(); - //testNode->SetData(imgSlice); - //testNode->SetVisibility(true); - //testNode->SetName("TestImage"); - - //this->GetDataStorage()->Add(testNode); - //this->GetDataStorageReference()->GetDataStorage()->Modified(); - - // mitk::Image* img = dynamic_cast( m_Controls.firstImageNameComboBox->GetSelectedNode()->GetData()); - ////Code for comparison - mitk::ShapeComparisonManager *shapeComparisonManager = new mitk::ShapeComparisonManager(m_firstImg, m_secondImg); - shapeComparisonManager->calculateMetrics(); - std::map labelOverlapResults = shapeComparisonManager->getLabelOverlapResults(); + mitk::ShapeComparisonManager *shapeComparisonManager = new mitk::ShapeComparisonManager(); + + ////Code for comparison + mitk::Surface::Pointer testA = dynamic_cast(this->GetDataStorage()->GetNamedNode("TibiaMovingL")->GetData()); + mitk::Surface::Pointer testB = dynamic_cast(this->GetDataStorage()->GetNamedNode("TibiaMovingR")->GetData()); + + std::map labelOverlapResults = shapeComparisonManager->calculateLabelOverlapMetrics(m_firstImg, m_secondImg); + + std::map distanceMetricsResults = shapeComparisonManager-> + calculateDistanceMetrics(testA, testB); + shapeComparisonManager->~ShapeComparisonManager(); + //Results to Qstring m_Controls.labelFPR->setText(QString::number(labelOverlapResults["FPR"])); m_Controls.labelFNR->setText(QString::number(labelOverlapResults["FNR"])); m_Controls.labelDice->setText(QString::number(labelOverlapResults["Dice"])); m_Controls.labelJaccard->setText(QString::number(labelOverlapResults["Jaccard"])); m_Controls.labelVolumeSimilarity->setText(QString::number(labelOverlapResults["VolumeSimilarity"])); - //Chart test - std::vector temperatureHD = { 1.8, 3.1}; - std::vector temperatureOslo = { -4.3, -4}; - m_Controls.DistanceTabWidget->AddData1D(temperatureHD, "Heidelberg"); - m_Controls.DistanceTabWidget->AddData1D(temperatureOslo, "Oslo"); - m_Controls.DistanceTabWidget->SetChartType("Heidelberg", QmitkChartWidget::ChartType::line); - m_Controls.DistanceTabWidget->SetChartType("Oslo", QmitkChartWidget::ChartType::line); - m_Controls.DistanceTabWidget->SetXAxisLabel("month"); - m_Controls.DistanceTabWidget->SetYAxisLabel("temperature"); - m_Controls.DistanceTabWidget->Show(); + testloadPosition(); + iteratePlanePositionImages(axial);// TODO solve debug error or run in release mode + MITK_INFO << "Now display results!"; + iteratePlanePositionSurfaces(testA, testB, axial); - //TODO remove - m_Controls.LabelOverlapTabWidget->AddData1D(std::vector{(labelOverlapResults["FPR"])}, "FPR", QmitkChartWidget::ChartType::bar); - m_Controls.LabelOverlapTabWidget->AddData1D(std::vector{(labelOverlapResults["FNR"])}, "FNR", QmitkChartWidget::ChartType::bar); - m_Controls.LabelOverlapTabWidget->AddData1D(std::vector{(labelOverlapResults["Jaccard"])}, "Jaccard", QmitkChartWidget::ChartType::bar); - m_Controls.LabelOverlapTabWidget->AddData1D(std::vector{(labelOverlapResults["Dice"])}, "Dice", QmitkChartWidget::ChartType::bar); - m_Controls.LabelOverlapTabWidget->baseSize(); - m_Controls.LabelOverlapTabWidget->Show(); - //// // careful - //testloadPosition(); + std::map diceMap; + std::map jaccardMap; + std::map FNRMap; + std::map FPRMap; + std::map asd1Map; + std::map asd2Map; + std::map assdMap; + for (int i = -70; i < 70; ++i) + { + std::map sliceMap = m_SliceResults.at(i); + //labelOverlap + diceMap.emplace(i, sliceMap.at("Dice")); + if(sliceMap.at("Jaccard") < 2) + jaccardMap.emplace(i, sliceMap.at("Jaccard")); + if (sliceMap.at("FNR") < 2) + FNRMap.emplace(i, sliceMap.at("FNR")); + if (sliceMap.at("FPR") < 2) + FPRMap.emplace(i, sliceMap.at("FPR")); + //SurfaceDistance + std::map distanceSliceMap = m_DistanceSliceResults.at(i); + if (distanceSliceMap.at("ASDFirst") < 10) + asd1Map.emplace(i, distanceSliceMap.at("ASDFirst")); + if (distanceSliceMap.at("ASDSecond") < 10) + asd2Map.emplace(i, distanceSliceMap.at("ASDSecond")); + if (distanceSliceMap.at("ASSD") < 10) + assdMap.emplace(i, distanceSliceMap.at("ASSD")); + } + m_Controls.LabelOverlapTabWidget->Clear(); - iteratePlanePosition(axial); + m_Controls.LabelOverlapTabWidget->AddData2D(diceMap, "Dice", QmitkChartWidget::ChartType::line); + m_Controls.LabelOverlapTabWidget->AddData2D(jaccardMap, "Jaccard", QmitkChartWidget::ChartType::line); + m_Controls.LabelOverlapTabWidget->AddData2D(FNRMap, "FNR", QmitkChartWidget::ChartType::line); + m_Controls.LabelOverlapTabWidget->AddData2D(FPRMap, "FPR", QmitkChartWidget::ChartType::line); + m_Controls.LabelOverlapTabWidget->SetXAxisLabel("Distance from StandardPlane");//rename + + m_Controls.DistanceTabWidget->AddData2D(asd1Map, "ASD1", QmitkChartWidget::ChartType::line); + m_Controls.DistanceTabWidget->AddData2D(asd2Map, "ASD2", QmitkChartWidget::ChartType::line); + m_Controls.DistanceTabWidget->AddData2D(assdMap, "ASSD", QmitkChartWidget::ChartType::line); + m_Controls.DistanceTabWidget->SetXAxisLabel("Distance from StandardPlane"); + + // //m_Controls.LabelOverlapTabWidget->baseSize(); + m_Controls.LabelOverlapTabWidget->Show(); + m_Controls.LabelOverlapTabWidget->setEnabled(true); + m_Controls.DistanceTabWidget->Show(); + m_Controls.DistanceTabWidget->setEnabled(true); // //iteratePlanePosition(coronal); // // iteratePlanePosition(saggital); } void QmitkShapeComparison::reloadDataNodePlanePosition(const mitk::DataNode::Pointer node, int id) { QmitkRenderWindow* selectedRenderWindow = 0; QmitkRenderWindow* axialWindow = this->GetRenderWindowPart()->GetQmitkRenderWindow("axial"); QmitkRenderWindow* saggitalWindow = this->GetRenderWindowPart()->GetQmitkRenderWindow("sagittal"); QmitkRenderWindow* coronalWindow = this->GetRenderWindowPart()->GetQmitkRenderWindow("coronal"); bool PlanarFigureInitializedWindow = false; //find initialized renderwindow if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, axialWindow->GetRenderer())) { selectedRenderWindow = axialWindow; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, saggitalWindow->GetRenderer())) { selectedRenderWindow = saggitalWindow; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, coronalWindow->GetRenderer())) { selectedRenderWindow = coronalWindow; } if (selectedRenderWindow) { { mitk::PlanePositionManagerService* service = this->getPlanePositionManagerService(); selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); } mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } bool QmitkShapeComparison::loadPlanePositions() { mitk::PlanePositionManagerService* service = this->getPlanePositionManagerService(); int sliceIndex = 0; mitk::PlanarCircle::Pointer positionMarker = mitk::PlanarCircle::New(); mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isPositionNode", mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer markers; - //load all nodes that are children of the working node in data storage mitk::DataNode* imageNode(m_Controls.selectGeometryImgComboBox->GetSelectedNode()); markers = this->GetDataStorage()->GetDerivations(imageNode, isMarker); if (!markers->empty()) { //iterate over all child nodes with NodePredicateProperty for (mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin(); iter != markers->end(); ++iter) { int markerId; std::string nodeName = (*iter)->GetName(); //get position nodes in the data manager and add them with the planepositionmanger service if (nodeName == "Planeposition coronal") { mitk::DataNode::Pointer coronalPosNode = (*iter); coronalPosNode->GetIntProperty("sliceIndex", sliceIndex); positionMarker = dynamic_cast (coronalPosNode->GetData()); mitk::PlaneGeometry::ConstPointer corPlane = positionMarker->GetPlaneGeometry(); markerId = service->AddNewPlanePosition(corPlane, sliceIndex); coronalPosNode->SetIntProperty("Plane Position ID", markerId); } else if (nodeName == "Planeposition axial") { mitk::DataNode::Pointer axialPosNode = (*iter); axialPosNode->GetIntProperty("sliceIndex", sliceIndex); positionMarker = dynamic_cast (axialPosNode->GetData()); mitk::PlaneGeometry::ConstPointer axiPlane = positionMarker->GetPlaneGeometry(); markerId = service->AddNewPlanePosition(axiPlane, sliceIndex); axialPosNode->SetIntProperty("Plane Position ID", markerId); } else if (nodeName == "Planeposition sagittal") { mitk::DataNode::Pointer sagittalPosNode = (*iter); sagittalPosNode->GetIntProperty("sliceIndex", sliceIndex); positionMarker = dynamic_cast (sagittalPosNode->GetData()); mitk::PlaneGeometry::ConstPointer sagPlane = positionMarker->GetPlaneGeometry(); markerId = service->AddNewPlanePosition(sagPlane, sliceIndex); sagittalPosNode->SetIntProperty("Plane Position ID", markerId); } (*iter)->GetIntProperty("Plane Position ID", markerId); this->reloadDataNodePlanePosition((*iter), markerId); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); return true; } return false; } mitk::PlanePositionManagerService* QmitkShapeComparison::getPlanePositionManagerService() { ctkPluginContext* context = mitk::org_mitk_gui_qt_shapecomparison_Activator::GetContext(); ctkServiceReference ppmRef = context->getServiceReference(); mitk::PlanePositionManagerService* service = nullptr; service = context->getService(ppmRef); context->ungetService(ppmRef); return service; } void QmitkShapeComparison::GetAxisPositions(mitk::DataNode::Pointer node) { bool planePosLoaded = loadPlanePositions(); if (planePosLoaded) { for (int i = 1; i <= 3; i++) { std::stringstream multiWidgetStream; multiWidgetStream << "stdmulti.widget"; multiWidgetStream << i; std::string multiWidgetString = multiWidgetStream.str(); // mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); mitk::BaseRenderer *rendereri = m_Renderer->GetByName(multiWidgetString.c_str()); } } } -void QmitkShapeComparison::iteratePlanePosition(Plane plane) +void QmitkShapeComparison::iteratePlanePositionImages(Plane plane) { - int stopper = 1; - for (int i = 0; i < stopper; ++i) + m_SliceResults.clear(); + mitk::ShapeComparisonManager *shapeComparisonManager = new mitk::ShapeComparisonManager(); + int stopper = 70; + std::map currentSliceResults; + + for (int i = -70; i < stopper; ++i) { MITK_INFO << "Current plane number: " << i; - mitk::PlaneGeometry::Pointer planeGeo = translatePlane(120, plane); - //TODO - //mitk::Image::Pointer imgSlice = mitk::Image::New(); - //mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(); - //extractor->SetInput(m_firstImg); - //extractor->SetWorldGeometry(planeGeo); - //extractor->SetOutputDimensionality(2); - //extractor->SetInPlaneResampleExtentByGeometry(true); - //extractor->SetResliceTransformByGeometry(m_firstImg->GetTimeGeometry()->GetGeometryForTimeStep(0)); - //extractor->SetInterpolationMode(mitk::ExtractSliceFilter::RESLICE_NEAREST); - //extractor->Update(); - //imgSlice = extractor->GetOutput(); - - //mitk::DataNode::Pointer testNode = mitk::DataNode::New(); - //testNode->SetData(imgSlice); - //testNode->SetVisibility(true); - //testNode->SetName("TestNode"); - - //this->GetDataStorage()->Add(testNode); - //this->GetDataStorageReference()->GetDataStorage()->Modified(); - - //mitk::ShapeComparisonManager *shapeComparisonManager = new mitk::ShapeComparisonManager(m_firstImg, m_secondImg); - //TODO - - //shapeComparisonManager->calculateMetricsSlices(planeGeo, 120); + mitk::PlaneGeometry::Pointer planeGeo = translatePlane(-i, plane)->Clone(); + planeGeo->ChangeImageGeometryConsideringOriginOffset(true); + planeGeo->SetImageGeometry(true); + currentSliceResults = shapeComparisonManager->calculateLabelOverlapMetricsSlices(m_firstImg, m_secondImg, planeGeo); + m_SliceResults.emplace(i, currentSliceResults); } MITK_INFO << "finished"; + shapeComparisonManager->~ShapeComparisonManager(); +} + +void QmitkShapeComparison::iteratePlanePositionSurfaces(mitk::Surface::Pointer first, mitk::Surface::Pointer second, Plane plane) +{ + m_DistanceSliceResults.clear(); + mitk::ShapeComparisonManager *shapeComparisonManager = new mitk::ShapeComparisonManager(); + int stopper = 70; + std::map currentSliceResults; + + for (int i = -70; i < stopper; ++i) + { + MITK_INFO << "Current plane number: " << i; + mitk::PlaneGeometry::Pointer planeGeo = translatePlane(-i, plane)->Clone(); + planeGeo->ChangeImageGeometryConsideringOriginOffset(true); + planeGeo->SetImageGeometry(true); + + currentSliceResults = shapeComparisonManager->calculateDistanceMetricsSlices(first, second, planeGeo); + m_DistanceSliceResults.emplace(i, currentSliceResults); + } + MITK_INFO << "finished"; + shapeComparisonManager->~ShapeComparisonManager(); + } mitk::PlaneGeometry::Pointer QmitkShapeComparison::translatePlane(int id, Plane plane) { - mitk::DataNode::Pointer dataNode = m_Controls.selectGeometryImgComboBox->GetSelectedNode(); + mitk::DataNode::Pointer geoImg = m_Controls.selectGeometryImgComboBox->GetSelectedNode(); std::stringstream multiWidgetStream; multiWidgetStream << "stdmulti.widget"; switch (plane) { case QmitkShapeComparison::axial: multiWidgetStream << 1; break; case QmitkShapeComparison::coronal: multiWidgetStream << 2; break; case QmitkShapeComparison::saggital: multiWidgetStream << 3; break; default: break; } std::string multiWidgetString = multiWidgetStream.str(); mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); const mitk::PlaneGeometry* planeGeo = dynamic_cast(renderer->GetCurrentWorldPlaneGeometry()); mitk::PlaneGeometry::Pointer newPlaneGeo = mitk::PlaneGeometry::New(); newPlaneGeo = planeGeo->Clone(); mitk::Vector3D normal = newPlaneGeo->GetNormal(); - newPlaneGeo->GetIndexToWorldTransform()->GetInverseTransform()->TransformVector(normal); // normal already in world cords?! + newPlaneGeo->GetIndexToWorldTransform()->GetInverseTransform()->TransformVector(normal); newPlaneGeo->Translate(normal * id); MITK_INFO << "Center der neuen Plane: " << newPlaneGeo->GetCenter(); m_Renderer = renderer; m_Renderer->RequestUpdate(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); return newPlaneGeo; } void QmitkShapeComparison::testloadPosition() { mitk::DataNode::Pointer selectedNode = m_Controls.selectGeometryImgComboBox->GetSelectedNode(); GetAxisPositions(selectedNode); mitk::RenderingManager::GetInstance()->InitializeViews(); } diff --git a/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.h b/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.h index cf56b38587..d19b91e7b8 100644 --- a/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.h +++ b/Plugins/org.mitk.gui.qt.shapecomparison/src/internal/QmitkShapeComparison.h @@ -1,149 +1,153 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef QmitkShapeComparison_h #define QmitkShapeComparison_h #include #ifdef WIN32 #pragma warning( disable : 4250 ) #endif #include "QVTKWidget.h" #include "QmitkRegisterClasses.h" #include #include #include "ui_ShapeComparisonControls.h" #include "usServiceRegistration.h" #include #include #include #include /*! @brief QmitkShapeComparisonView \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \sa QmitkFunctionality \ingroup ${plugin_target}_internal */ class QmitkShapeComparison : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) private: Q_OBJECT public: /*! @brief Constructor. Called by SampleApp (or other apps that use functionalities) */ QmitkShapeComparison(QObject *parent = 0); virtual ~QmitkShapeComparison(); static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent); virtual void SetFocus() override; ///*! //@brief Creates the Qt connections needed //*/ QWidget* GetControls(); /// @brief Called when the user clicks the GUI button protected slots: void compare(); void OnSelectedFirstImgChanged(const mitk::DataNode *); void OnSelectedSecondImgChanged(const mitk::DataNode *); protected: private: const std::string outputpath = "";//TODO const mitk::NodePredicateDataType::Pointer isSurface = mitk::NodePredicateDataType::New("Surface"); const mitk::NodePredicateDataType::Pointer isLabelSetImage = mitk::NodePredicateDataType::New("LabelSetImage"); /*! * The parent QWidget */ QWidget* m_ParentWidget; mitk::BaseRenderer *m_Renderer; Ui::ShapeComparisonControls m_Controls; mitk::ShapeComparisonManager *m_ShapeComparisonManager; mitk::Image::Pointer m_firstImg; mitk::Image::Pointer m_secondImg; + std::map> m_SliceResults; + std::map> m_DistanceSliceResults; + //test void testloadPosition(); /*! * @brief Reloads the plane position of the node in the corresponding rendering window * @param int id Id of the markerID corresponding to the rendering window * @param const DataNode::Pointer node */ void reloadDataNodePlanePosition(const mitk::DataNode::Pointer node, int id); enum Plane { axial, coronal, saggital }; /*! * @brief loads the adjusted plan positions from the data storage. The rendering windows are updated afterwards. * @returns true if plane positions are successfully loaded */ bool loadPlanePositions(); mitk::PlanePositionManagerService* getPlanePositionManagerService(); //TODO void GetAxisPositions(mitk::DataNode::Pointer node); - void iteratePlanePosition(Plane plane); + void iteratePlanePositionImages(Plane plane); //TODO insert image parameters + void iteratePlanePositionSurfaces(mitk::Surface::Pointer first, mitk::Surface::Pointer second, Plane plane); /*! * @brief translates the plane in direction of its normal by the length of the id * @param int id the lenght of the normal * @param Plane plane the plane to translate */ mitk::PlaneGeometry::Pointer translatePlane(int id, Plane plane); mitk::PlaneGeometry::ConstPointer m_axialPlane; }; #endif \ No newline at end of file