diff --git a/Modules/Chart/resource/Chart.js b/Modules/Chart/resource/Chart.js index 437c439153..ed2ade45ba 100644 --- a/Modules/Chart/resource/Chart.js +++ b/Modules/Chart/resource/Chart.js @@ -1,236 +1,236 @@ //Based on C3.js (http://c3js.org). See Website for examples! document.body.style.backgroundColor = 'rgb(240, 240, 240)'; var minHeight = 255; var chart; GenerateChart() var chartData; var xValues=[]; var yValues=[]; var xs = {}; var dataColors = {}; var chartTypes = {}; var lineStyle = {}; //Is executed when js is loaded first. //Extracts relevant information from chartData in variables window.onload = function() { new QWebChannel(qt.webChannelTransport, function(channel) { chartData = channel.objects.chartData; var count = 0; for(var propertyName in channel.objects) { if (propertyName != 'chartData'){ var xDataTemp = channel.objects[propertyName].m_XData var yDataTemp = channel.objects[propertyName].m_YData var dataLabelsTemp; //add label to x array xDataTemp.unshift('x'+count.toString()) dataLabelsTemp = channel.objects[propertyName].m_Label xs[dataLabelsTemp] = 'x'+count.toString() xDataTemp.push(null); //append null value, to make sure the last tick on x-axis is displayed correctly yDataTemp.unshift(dataLabelsTemp) yDataTemp.push(null); //append null value, to make sure the last tick on y-axis is displayed correctly xValues[count] = xDataTemp yValues[count] = yDataTemp dataColors[dataLabelsTemp] = channel.objects[propertyName].m_Color chartTypes[dataLabelsTemp] = channel.objects[propertyName].m_ChartType if (channel.objects[propertyName].m_LineStyleName=="solid"){ lineStyle[dataLabelsTemp]= '' } else { lineStyle[dataLabelsTemp]= [{'style':'dashed'}] } count++; } } setupChart(chartData) }); } //This is necessary to resize the chart, after the size of the parent changed window.onresize = function () { var size = window.innerHeight-(window.innerHeight/100*10); //subtract 5% of height to hide vertical scrool bar if (size < minHeight) { size = minHeight; } chart.resize({ height: size, }); } function ReloadChart(showSubchart) { chartData.m_ShowSubchart = showSubchart; setupChart(chartData); } function setupChart(chartData) { window.onresize(); GenerateChart(chartData) chart.unload(); //unload data before loading new data //for multiple xy line chart, see http://c3js.org/samples/simple_xy_multiple.html var columns = []; for (var i in xValues){ columns.push(xValues[i]) } for (var i in yValues){ columns.push(yValues[i]) } chart.load({ xs: xs, columns: columns }); } //Transformation between different chart types //takes the name of the chart type as a parameter //called by QmitkC3jsWidget function transformView(TransformTo) { chart.transform(TransformTo); }; function changeTheme(color) { link = document.getElementsByTagName("link")[0]; if (color == 'dark') { link.href = "Chart_dark.css"; } else { link.href = "Chart.css"; } }; //Here, the chart magic takes place. C3js is called function GenerateChart(chartData) { if (chartData === undefined) { chartData = {} } //adaption for bar ratio indepenend of amount of data points //otherwise, bars could be covered. var barRatio; try { barRatio = 0.8*Math.exp(-0.015*xValues[0].length); } catch (err){ barRatio=0.42 } var formatCharacter; if (chartData.m_UsePercentageInPieChart==true){ formatCharacter = '%' } else{ - formatCharacter = '.1f' + formatCharacter = '.5f' } chart = c3.generate({ title:{ text: chartData.m_diagramTitle, position: 'top-center' }, data: { xs: {}, //use first "column" as x axis values columns: [], //initialize empty. Data will be loaded in function setupChart(chartData) types: chartTypes, selection: { enabled: false, multiple: false, }, colors: dataColors, regions: lineStyle, }, legend: { position: chartData.m_LegendPosition, show: chartData.m_ShowLegend }, grid: { y: { lines: [{value:0}] //Draws a horizontal line at y=0 } }, bar: { width: { ratio: barRatio } }, pie:{ label: { format: function (value, ratio, id) { if (chartData.m_UsePercentageInPieChart==true){ return d3.format('%') (ratio); } else{ return value; } } } }, zoom: { enabled: true, }, subchart: { show: chartData.m_ShowSubchart //Shows a subchart that shows the region the primary chart is zoomed in to by overlay. }, axis: { x: { tick: { multiline: false, fit: false, //to make more x labels appear on zoom centered: true, format: d3.format(".1f"), }, label: { text: chartData.m_xAxisLabel, position: 'outer-center' } }, y: { tick: { format: d3.format(formatCharacter) }, label: { text: chartData.m_yAxisLabel, position: 'outer-middle' }, scale: { name: chartData.m_YAxisScale } } }, tooltip: { format: { title: function (x) { return chartData.m_xAxisLabel + ': ' + d3.format(".2f")(x)} }, }, //Style data points in linegraph point: { r: chartData.m_DataPointSize, focus: { expand: { r: chartData.m_DataPointSize + 2 } } }, }); } diff --git a/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp b/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp index 27fccd5fd5..e3f56a648e 100644 --- a/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp +++ b/Modules/Core/src/Algorithms/mitkImageToSurfaceFilter.cpp @@ -1,234 +1,239 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkException.h" #include #include #include #include #include #include #include #include #include #include #include #include "mitkProgressBar.h" +// +#include + mitk::ImageToSurfaceFilter::ImageToSurfaceFilter() : m_Smooth(false), - m_Decimate(NoDecimation), - m_Threshold(1.0), - m_TargetReduction(0.95f), - m_SmoothIteration(50), - m_SmoothRelaxation(0.1) + m_Decimate(NoDecimation), + m_Threshold(1.0), + m_TargetReduction(0.95f), + m_SmoothIteration(50), + m_SmoothRelaxation(0.1) { } mitk::ImageToSurfaceFilter::~ImageToSurfaceFilter() { } void mitk::ImageToSurfaceFilter::CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface *surface, const ScalarType threshold) { vtkImageChangeInformation *indexCoordinatesImageFilter = vtkImageChangeInformation::New(); indexCoordinatesImageFilter->SetInputData(vtkimage); indexCoordinatesImageFilter->SetOutputOrigin(0.0, 0.0, 0.0); // MarchingCube -->create Surface vtkSmartPointer skinExtractor = vtkSmartPointer::New(); skinExtractor->ComputeScalarsOff(); skinExtractor->SetInputConnection(indexCoordinatesImageFilter->GetOutputPort()); // RC++ indexCoordinatesImageFilter->Delete(); skinExtractor->SetValue(0, threshold); vtkPolyData *polydata; skinExtractor->Update(); polydata = skinExtractor->GetOutput(); polydata->Register(nullptr); // RC++ if (m_Smooth) { vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New(); - // read poly1 (poly1 can be the original polygon, or the decimated polygon) + //read poly1 (poly1 can be the original polygon, or the decimated polygon) smoother->SetInputConnection(skinExtractor->GetOutputPort()); // RC++ smoother->SetNumberOfIterations(m_SmoothIteration); smoother->SetRelaxationFactor(m_SmoothRelaxation); smoother->SetFeatureAngle(60); smoother->FeatureEdgeSmoothingOff(); smoother->BoundarySmoothingOff(); smoother->SetConvergence(0); smoother->Update(); polydata->Delete(); // RC-- polydata = smoother->GetOutput(); polydata->Register(nullptr); // RC++ smoother->Delete(); } ProgressBar::GetInstance()->Progress(); // decimate = to reduce number of polygons if (m_Decimate == DecimatePro) { vtkDecimatePro *decimate = vtkDecimatePro::New(); decimate->SplittingOff(); decimate->SetErrorIsAbsolute(5); decimate->SetFeatureAngle(30); decimate->PreserveTopologyOn(); decimate->BoundaryVertexDeletionOff(); decimate->SetDegree(10); // std-value is 25! decimate->SetInputData(polydata); // RC++ decimate->SetTargetReduction(m_TargetReduction); decimate->SetMaximumError(0.002); decimate->Update(); polydata->Delete(); // RC-- polydata = decimate->GetOutput(); polydata->Register(nullptr); // RC++ decimate->Delete(); } else if (m_Decimate == QuadricDecimation) { vtkQuadricDecimation *decimate = vtkQuadricDecimation::New(); decimate->SetTargetReduction(m_TargetReduction); decimate->SetInputData(polydata); decimate->Update(); polydata->Delete(); polydata = decimate->GetOutput(); polydata->Register(nullptr); decimate->Delete(); } ProgressBar::GetInstance()->Progress(); if (polydata->GetNumberOfPoints() > 0) { mitk::Vector3D spacing = GetInput()->GetGeometry(time)->GetSpacing(); vtkPoints *points = polydata->GetPoints(); vtkMatrix4x4 *vtkmatrix = vtkMatrix4x4::New(); GetInput()->GetGeometry(time)->GetVtkTransform()->GetMatrix(vtkmatrix); double(*matrix)[4] = vtkmatrix->Element; unsigned int i, j; for (i = 0; i < 3; ++i) for (j = 0; j < 3; ++j) matrix[i][j] /= spacing[j]; unsigned int n = points->GetNumberOfPoints(); double point[3]; for (i = 0; i < n; i++) { points->GetPoint(i, point); mitkVtkLinearTransformPoint(matrix, point, point); points->SetPoint(i, point); } vtkmatrix->Delete(); } ProgressBar::GetInstance()->Progress(); // determine point_data normals for the poly data points. vtkSmartPointer normalsGenerator = vtkSmartPointer::New(); normalsGenerator->SetInputData(polydata); normalsGenerator->FlipNormalsOn(); vtkSmartPointer cleanPolyDataFilter = vtkSmartPointer::New(); cleanPolyDataFilter->SetInputConnection(normalsGenerator->GetOutputPort()); cleanPolyDataFilter->PieceInvariantOff(); cleanPolyDataFilter->ConvertLinesToPointsOff(); cleanPolyDataFilter->ConvertPolysToLinesOff(); cleanPolyDataFilter->ConvertStripsToPolysOff(); cleanPolyDataFilter->PointMergingOn(); cleanPolyDataFilter->Update(); surface->SetVtkPolyData(cleanPolyDataFilter->GetOutput(), time); + + mitk::IOUtil::Save(surface, "C:/Users/hempe/Desktop/Artifacts/crSurf.stl"); polydata->UnRegister(nullptr); } void mitk::ImageToSurfaceFilter::GenerateData() { mitk::Surface *surface = this->GetOutput(); auto *image = (mitk::Image *)GetInput(); if (image == nullptr || !image->IsInitialized()) mitkThrow() << "No input image set, please set an valid input image!"; mitk::Image::RegionType outputRegion = image->GetRequestedRegion(); int tstart = outputRegion.GetIndex(3); int tmax = tstart + outputRegion.GetSize(3); // GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloest if ((tmax - tstart) > 0) { ProgressBar::GetInstance()->AddStepsToDo(4 * (tmax - tstart)); } int t; for (t = tstart; t < tmax; ++t) { vtkImageData *vtkimagedata = image->GetVtkImageData(t); CreateSurface(t, vtkimagedata, surface, m_Threshold); ProgressBar::GetInstance()->Progress(); } } void mitk::ImageToSurfaceFilter::SetSmoothIteration(int smoothIteration) { m_SmoothIteration = smoothIteration; } void mitk::ImageToSurfaceFilter::SetSmoothRelaxation(float smoothRelaxation) { m_SmoothRelaxation = smoothRelaxation; } void mitk::ImageToSurfaceFilter::SetInput(const mitk::Image *image) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput(0, const_cast(image)); } const mitk::Image *mitk::ImageToSurfaceFilter::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return nullptr; } return static_cast(this->ProcessObject::GetInput(0)); } void mitk::ImageToSurfaceFilter::GenerateOutputInformation() { mitk::Image::ConstPointer inputImage = (mitk::Image *)this->GetInput(); // mitk::Image *inputImage = (mitk::Image*)this->GetImage(); mitk::Surface::Pointer output = this->GetOutput(); itkDebugMacro(<< "GenerateOutputInformation()"); if (inputImage.IsNull()) return; // Set Data } diff --git a/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp b/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp index 532a9eeac7..a7a2d4952f 100644 --- a/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkManualSegmentationToSurfaceFilter.cpp @@ -1,169 +1,181 @@ /*=================================================================== 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 "mitkProgressBar.h" +//TODO remove +#include + + mitk::ManualSegmentationToSurfaceFilter::ManualSegmentationToSurfaceFilter() { m_MedianFilter3D = false; m_MedianKernelSizeX = 3; m_MedianKernelSizeY = 3; m_MedianKernelSizeZ = 3; m_UseGaussianImageSmooth = false; m_GaussianStandardDeviation = 1.5; m_Interpolation = false; m_InterpolationX = 1.0f; m_InterpolationY = 1.0f; m_InterpolationZ = 1.0f; }; mitk::ManualSegmentationToSurfaceFilter::~ManualSegmentationToSurfaceFilter(){}; void mitk::ManualSegmentationToSurfaceFilter::GenerateData() { mitk::Surface *surface = this->GetOutput(); auto *image = (mitk::Image *)GetInput(); mitk::Image::RegionType outputRegion = image->GetRequestedRegion(); + mitk::IOUtil::Save(image, "C:/Users/hempe/Desktop/Artifacts/originalImg.nrrd"); + int tstart = outputRegion.GetIndex(3); int tmax = tstart + outputRegion.GetSize(3); // GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgeloest ScalarType thresholdExpanded = this->m_Threshold; if ((tmax - tstart) > 0) { ProgressBar::GetInstance()->AddStepsToDo(7 * (tmax - tstart)); } else { ProgressBar::GetInstance()->AddStepsToDo(7); } for (int t = tstart; t < tmax; ++t) { vtkSmartPointer vtkimage = image->GetVtkImageData(t); // Median -->smooth 3D MITK_INFO << (m_MedianFilter3D ? "Applying median..." : "No median filtering"); if (m_MedianFilter3D) { vtkImageMedian3D *median = vtkImageMedian3D::New(); median->SetInputData(vtkimage); // RC++ (VTK < 5.0) median->SetKernelSize(m_MedianKernelSizeX, m_MedianKernelSizeY, m_MedianKernelSizeZ); // Std: 3x3x3 median->ReleaseDataFlagOn(); median->UpdateInformation(); median->Update(); vtkimage = median->GetOutput(); //->Out median->Delete(); } ProgressBar::GetInstance()->Progress(); - // Interpolate image spacing + + //Interpolate image spacing MITK_INFO << (m_Interpolation ? "Resampling..." : "No resampling"); if (m_Interpolation) { vtkImageResample *imageresample = vtkImageResample::New(); imageresample->SetInputData(vtkimage); // Set Spacing Manual to 1mm in each direction (Original spacing is lost during image processing) imageresample->SetAxisOutputSpacing(0, m_InterpolationX); imageresample->SetAxisOutputSpacing(1, m_InterpolationY); imageresample->SetAxisOutputSpacing(2, m_InterpolationZ); imageresample->UpdateInformation(); imageresample->Update(); vtkimage = imageresample->GetOutput(); //->Output imageresample->Delete(); } ProgressBar::GetInstance()->Progress(); MITK_INFO << (m_UseGaussianImageSmooth ? "Applying gaussian smoothing..." : "No gaussian smoothing"); if (m_UseGaussianImageSmooth) // gauss { vtkImageShiftScale *scalefilter = vtkImageShiftScale::New(); scalefilter->SetScale(100); scalefilter->SetInputData(vtkimage); scalefilter->Update(); vtkImageGaussianSmooth *gaussian = vtkImageGaussianSmooth::New(); gaussian->SetInputConnection(scalefilter->GetOutputPort()); gaussian->SetDimensionality(3); gaussian->SetRadiusFactor(0.49); gaussian->SetStandardDeviation(m_GaussianStandardDeviation); gaussian->ReleaseDataFlagOn(); gaussian->UpdateInformation(); gaussian->Update(); vtkimage = scalefilter->GetOutput(); double range[2]; vtkimage->GetScalarRange(range); + MITK_DEBUG << "Current scalar max is: " << range[1]; if (range[1] != 0) // too little slices, image smoothing eliminates all segmentation pixels { vtkimage = gaussian->GetOutput(); //->Out } else { MITK_INFO << "Smoothing removes all pixels of the segmentation. Use unsmoothed result"; } gaussian->Delete(); scalefilter->Delete(); } ProgressBar::GetInstance()->Progress(); // Create surface for t-Slice CreateSurface(t, vtkimage, surface, thresholdExpanded); ProgressBar::GetInstance()->Progress(); + + mitk::IOUtil::Save(surface, "C:/Users/hempe/Desktop/Artifacts/resultSurf.stl"); } + + MITK_INFO << "Updating Time Geometry to ensure right timely displaying"; // Fixing wrong time geometry TimeGeometry *surfaceTG = surface->GetTimeGeometry(); auto *surfacePTG = dynamic_cast(surfaceTG); TimeGeometry *imageTG = image->GetTimeGeometry(); auto *imagePTG = dynamic_cast(imageTG); // Requires ProportionalTimeGeometries to work. May not be available for all steps. assert(surfacePTG != nullptr); assert(imagePTG != nullptr); if ((surfacePTG != nullptr) && (imagePTG != nullptr)) { TimePointType firstTime = imagePTG->GetFirstTimePoint(); TimePointType duration = imagePTG->GetStepDuration(); surfacePTG->SetFirstTimePoint(firstTime); surfacePTG->SetStepDuration(duration); MITK_INFO << "First Time Point: " << firstTime << " Duration: " << duration; } }; void mitk::ManualSegmentationToSurfaceFilter::SetMedianKernelSize(int x, int y, int z) { m_MedianKernelSizeX = x; m_MedianKernelSizeY = y; m_MedianKernelSizeZ = z; } void mitk::ManualSegmentationToSurfaceFilter::SetInterpolation(vtkDouble x, vtkDouble y, vtkDouble z) { m_InterpolationX = x; m_InterpolationY = y; m_InterpolationZ = z; } diff --git a/Modules/SurfaceRegistration/include/MitkSurfaceRegistrationManager.h b/Modules/SurfaceRegistration/include/MitkSurfaceRegistrationManager.h index 404dfa7ef6..fbf3cd35da 100644 --- a/Modules/SurfaceRegistration/include/MitkSurfaceRegistrationManager.h +++ b/Modules/SurfaceRegistration/include/MitkSurfaceRegistrationManager.h @@ -1,87 +1,91 @@ /*=================================================================== 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 mitkSurfaceRegistrationManager_h #define mitkSurfaceRegistrationManager_h #include "mitkSurface.h" #include #include "mitkDataNode.h" #include #include #include #include #include #include #include #include #include #include namespace mitk { class MITKSURFACEREGISTRATION_EXPORT SurfaceRegistrationManager { public: SurfaceRegistrationManager(mitk::Surface::Pointer moving, mitk::Surface::Pointer target); ~SurfaceRegistrationManager(); mitk::Surface::Pointer performRegistration(); void performComparison(); vtkSmartPointer getTable(); mitk::DataNode::Pointer getColourTransformedDataNode(); void setMirroring(bool mirroring); bool getMirroring(); mitk::Surface::Pointer getRegisteredSurface(); std::map getDistanceResults(); + vtkSmartPointer getTransformation(); + private: void manageICPCalculation(); void manageCalculateDistances(); void createLookUpTable(); void printPoints(mitk::Surface::Pointer surfaceA, mitk::Surface::Pointer surfaceB);//for test purposes --> CPD mitk::Surface::Pointer m_MovingSurface; mitk::Surface::Pointer m_TargetSurface; mitk::Surface::Pointer m_RegisteredSurface; mitk::Surface::Pointer m_MirroredSurface; ShortestDistanceCalculator *m_DistanceCalculator; vtkSmartPointer m_LookupTable; bool m_Mirroring = false; std::map m_DistanceResults; vtkSmartPointer m_CurvatureResults; + vtkSmartPointer m_ICPTransformation; + }; } #endif diff --git a/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h b/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h index 7be18b4831..d9c60255d1 100644 --- a/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h +++ b/Modules/SurfaceRegistration/include/mitkSurfaceRegistrationICP.h @@ -1,77 +1,82 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include +#include #include #include #include #include namespace mitk{ #ifndef mitkSurfaceRegistrationICP_h #define mitkSurfaceRegistrationICP_h class SurfaceRegistrationICP { public: SurfaceRegistrationICP(); ~SurfaceRegistrationICP(); mitk::Surface::Pointer CalculateICP(mitk::Surface::Pointer movingSurface, mitk::Surface::Pointer targetSurface); + vtkSmartPointer getTransformation(); + private: void SafeTransformationMatrix(vtkMatrix4x4 *matrix, std::string path); + + vtkSmartPointer m_Transformation; }; #endif }; namespace mitk { /** \brief Load a VNL matrix from file * * \param filename file and path as std::string * \tparam T element type * \tparam M number of matrix rows * \tparam N number of matrix columns */ template vnl_matrix_fixed ReadVNLMatrixFromFile(std::string filename) { std::ifstream read(filename.c_str()); vnl_matrix_fixed matrix; read >> matrix; read.close(); return matrix; } /** \brief Write a VNL matrix to file * * \param filename file and path as std::string * \tparam T element type * \tparam M number of matrix rows * \tparam N number of matrix columns */ template void WriteVNLMatrixToFile(std::string filename, vnl_matrix_fixed matrix) { std::ofstream write(filename.c_str()); write << matrix; write.close(); } } \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/DataManagement/mitkShapeComparisonUtil.cpp b/Modules/SurfaceRegistration/src/DataManagement/mitkShapeComparisonUtil.cpp index a5a7339780..ebcd8d5fa1 100644 --- a/Modules/SurfaceRegistration/src/DataManagement/mitkShapeComparisonUtil.cpp +++ b/Modules/SurfaceRegistration/src/DataManagement/mitkShapeComparisonUtil.cpp @@ -1,151 +1,120 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkShapeComparisonUtil.h" -#include -#include +//#include +//#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::ShapeComparisonUtil::ShapeComparisonUtil(mitk::Surface::Pointer movedSurface, mitk::Surface::Pointer targetSurface) { m_MovedSurface = movedSurface; m_TargetSurface = targetSurface; - //TODO append timestamp - m_OutputFile.open("X:/ergebnissse/results.txt"); } mitk::ShapeComparisonUtil::~ShapeComparisonUtil() { m_OutputFile.close(); m_MovedSurface->Delete(); m_TargetSurface->Delete(); } void mitk::ShapeComparisonUtil::calculateSliceDifferences(mitk::PlaneGeometry::Pointer planegeo) { m_OutputFile << "/*****************************************************************************/" << std::endl; ++m_counter; m_OutputFile << "Plane Number: " << m_counter << std::endl; - vtkSmartPointer movedPointsOnPlane = getPointsOnPlane(m_MovedSurface->GetVtkPolyData(), planegeo); //read access violation + vtkSmartPointer movedPointsOnPlane = getPointsOnPlane(m_MovedSurface->GetVtkPolyData(), planegeo); vtkSmartPointer targetPointsOnPlane = getPointsOnPlane(m_TargetSurface->GetVtkPolyData(), planegeo); if (movedPointsOnPlane->GetPoints()->GetNumberOfPoints() != 0 && targetPointsOnPlane->GetPoints()->GetNumberOfPoints() != 0) { - m_OutputFile << "PointsOnPlane: " << movedPointsOnPlane->GetPoints()->GetNumberOfPoints() << " / " << targetPointsOnPlane->GetPoints()->GetNumberOfPoints() << std::endl; mitk::PointShortestDistanceCalculator *calculator = new PointShortestDistanceCalculator(movedPointsOnPlane, targetPointsOnPlane); calculator->calculateShortestDistance(); - m_OutputFile << " Mean: " << calculator->getMean() << " STD: " << calculator->getStandardDeviation() << - // " Range " << calculator->getRangeMin() << - std::endl; + m_OutputFile << " Mean: " << calculator->getMean() << " STD: " << calculator->getStandardDeviation() <m_MovedSurface = surface; } void mitk::ShapeComparisonUtil::setTargetSurface(mitk::Surface::Pointer surface) { this->m_TargetSurface = surface; } +void mitk::ShapeComparisonUtil::setOutputPath(std::string path) +{ + this->path = path; + path = path + m_MovedSurface->GetObjectName() + "TO" + m_TargetSurface->GetObjectName() + ".txt"; + m_OutputFile.open(path); +} + vtkSmartPointer mitk::ShapeComparisonUtil::getPointsOnPlane(vtkSmartPointer pointset, mitk::PlaneGeometry::Pointer planegeo) { vtkSmartPointer pointsOnPlane = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); - // set Vertices // Create the topology of the point (a vertex) vtkSmartPointer vertices = vtkSmartPointer::New(); vtkIdType pid[1]; - double tempPoint[3] = { 0, 0, 0 }; int pointcounter = 0; double searchingRange = 0.475 / 2; //double searchingRange = 0.475; int pointSetSize = pointset->GetPoints()->GetNumberOfPoints(); for (int i = 0; i < pointSetSize; ++i) { pointset->GetPoints()->GetPoint(i, tempPoint); if(planegeo->Distance(tempPoint) InsertNextPoint(tempPoint); pid[0] = points->InsertNextPoint(tempPoint); vertices->InsertNextCell(1, pid); } } MITK_INFO << "Anzahl Points near plane: " << pointcounter; pointsOnPlane->SetPoints(points); pointsOnPlane->SetVerts(vertices); - - // Visualize -// vtkSmartPointer mapper = -// vtkSmartPointer::New(); -//#if VTK_MAJOR_VERSION <= 5 -// mapper->SetInput(point); -//#else -// mapper->SetInputData(pointsOnPlane); -//#endif -// -// vtkSmartPointer actor = -// vtkSmartPointer::New(); -// actor->SetMapper(mapper); -// actor->GetProperty()->SetPointSize(2); -// -// vtkSmartPointer renderer = -// vtkSmartPointer::New(); -// vtkSmartPointer renderWindow = -// vtkSmartPointer::New(); -// renderWindow->AddRenderer(renderer); -// vtkSmartPointer renderWindowInteractor = -// vtkSmartPointer::New(); -// renderWindowInteractor->SetRenderWindow(renderWindow); -// -// renderer->AddActor(actor); -// -// renderWindow->Render(); -// renderWindowInteractor->Start(); -// -// - return pointsOnPlane; } diff --git a/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp b/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp index 0a1ef252c9..f9858f692a 100644 --- a/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp +++ b/Modules/SurfaceRegistration/src/DataManagement/mitkSurfaceRegistrationICP.cpp @@ -1,73 +1,79 @@ #include "mitkSurfaceRegistrationICP.h" #include #include #include #include #include #include #include mitk::SurfaceRegistrationICP::SurfaceRegistrationICP() { } mitk::SurfaceRegistrationICP::~SurfaceRegistrationICP() { } mitk::Surface::Pointer mitk::SurfaceRegistrationICP::CalculateICP(mitk::Surface::Pointer movingSurface, mitk::Surface::Pointer targetSurface) { MITK_INFO << "start registration"; vtkSmartPointer icp = vtkSmartPointer::New(); icp->SetCheckMeanDistance(1); mitk::Surface::Pointer movedData = mitk::Surface::New(); icp->SetSource(movingSurface->GetVtkPolyData()); icp->SetTarget(targetSurface->GetVtkPolyData()); icp->SetMaximumNumberOfIterations(1000); icp->SetMaximumMeanDistance(0.01); icp->SetMeanDistanceModeToRMS(); icp->StartByMatchingCentroidsOn(); icp->SetMaximumNumberOfLandmarks(100000); + //icp->GetLandmarkTransform()->SetModeToRigidBody(); icp->Modified(); vtkSmartPointer transform = vtkSmartPointer::New(); transform = icp->GetLandmarkTransform(); vtkSmartPointer icpTransformFilter = vtkSmartPointer::New(); icpTransformFilter->SetInputData(movingSurface->GetVtkPolyData()); icpTransformFilter->SetTransform(icp); icpTransformFilter->Update(); - vtkSmartPointer m = icp->GetMatrix(); - MITK_INFO << "The resulting matrix is: " << *m; + m_Transformation = icp->GetMatrix(); + MITK_INFO << "The resulting matrix is: " << *m_Transformation; MITK_INFO << "The mean distance is: " << icp->GetMeanDistance(); movedData->SetVtkPolyData(icpTransformFilter->GetOutput()); movedData->Modified(); MITK_INFO << "registration done"; //save TransformationMatrix std::string path = "D:/ShapeComparison/TestCase/ICPtrafo" + movingSurface->GetObjectName() + "To" + targetSurface->GetObjectName() + ".txt"; - SafeTransformationMatrix(m,path); + SafeTransformationMatrix(m_Transformation,path); return movedData; } +vtkSmartPointer mitk::SurfaceRegistrationICP::getTransformation() +{ + return m_Transformation; +} + void mitk::SurfaceRegistrationICP::SafeTransformationMatrix(vtkMatrix4x4 *matrix, std::string path) { //transform vtkmatrix to vnl vnl_matrix_fixed vnlmatrix; for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) vnlmatrix(i, j) = matrix->GetElement(i,j); mitk::WriteVNLMatrixToFile(path, vnlmatrix); } diff --git a/Modules/SurfaceRegistration/src/mitkSurfaceRegistrationManager.cpp b/Modules/SurfaceRegistration/src/mitkSurfaceRegistrationManager.cpp index b8fcfc7f08..9e657a32d4 100644 --- a/Modules/SurfaceRegistration/src/mitkSurfaceRegistrationManager.cpp +++ b/Modules/SurfaceRegistration/src/mitkSurfaceRegistrationManager.cpp @@ -1,224 +1,230 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::SurfaceRegistrationManager::SurfaceRegistrationManager(mitk::Surface::Pointer moving, mitk::Surface::Pointer target) { this->m_MovingSurface = moving; this->m_TargetSurface = target; this->m_Mirroring = false; createLookUpTable(); } mitk::SurfaceRegistrationManager::~SurfaceRegistrationManager() { m_MovingSurface->Delete(); m_TargetSurface->Delete(); m_RegisteredSurface->Delete(); m_LookupTable->Delete(); } mitk::Surface::Pointer mitk::SurfaceRegistrationManager::performRegistration() { if (m_Mirroring) { MitkSurfaceMirroringHelper *mirroringHelper = new MitkSurfaceMirroringHelper(); m_MirroredSurface = mirroringHelper->performMirroring(m_MovingSurface); } //printPoints(); //after mirroring manageICPCalculation(); return m_RegisteredSurface; } void mitk::SurfaceRegistrationManager::performComparison() { if (m_Mirroring) { MitkSurfaceMirroringHelper *mirroringHelper = new MitkSurfaceMirroringHelper(); m_MirroredSurface = mirroringHelper->performMirroring(m_MovingSurface); } manageCalculateDistances(); } vtkSmartPointer mitk::SurfaceRegistrationManager::getTable() { return m_LookupTable; } mitk::DataNode::Pointer mitk::SurfaceRegistrationManager::getColourTransformedDataNode() { mitk::Surface::Pointer currentSurface; //if (m_RegisteredSurface != nullptr) //{ // currentSurface = m_RegisteredSurface; //} //else if(m_MirroredSurface!= nullptr) //{ // currentSurface = m_MirroredSurface; //} //else //{ // currentSurface = m_MovingSurface; //} //set named Scalars currentSurface = m_TargetSurface; m_DistanceCalculator->getDistances()->SetName("Distances"); currentSurface->GetVtkPolyData()->GetPointData()->SetScalars(m_DistanceCalculator->getDistances()); m_CurvatureResults->SetName("Curvatures"); currentSurface->GetVtkPolyData()->GetPointData()->AddArray(m_CurvatureResults); //currentSurface->GetVtkPolyData()->GetPointData()->SetScalars(m_CurvatureResults); currentSurface->GetVtkPolyData()->GetPointData()->Update(); //convert m_LookUpTable to mitk LookUpTable mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetVtkLookupTable(m_LookupTable); mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(lut); currentSurface->GetVtkPolyData()->GetPointData()->Update(); mitk::DataNode::Pointer transformedNode = mitk::DataNode::New(); transformedNode->SetProperty("LookupTable", prop); transformedNode->SetBoolProperty("scalar visibility", true); transformedNode->SetBoolProperty("color mode", true); //set Range of Lut double range = m_DistanceCalculator->getDistanceRange(); //transformedNode->SetFloatProperty("ScalarsRangeMinimum", range*-1); //transformedNode->SetFloatProperty("ScalarsRangeMaximum", range); transformedNode->SetFloatProperty("ScalarsRangeMinimum", -3.5); transformedNode->SetFloatProperty("ScalarsRangeMaximum", 3.5); // Configure material so that only scalar colors are shown transformedNode->SetColor(1.0f, 1.0f, 1.0f); transformedNode->SetOpacity(1.0f); transformedNode->SetFloatProperty("material.wireframeLineWidth", 2.0f); //Set view of plane to VTK_SURFACE transformedNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New());//VTK_SURFACE currently default // save colored surface node transformedNode->SetData(currentSurface); return transformedNode; } void mitk::SurfaceRegistrationManager::setMirroring(bool mirroring) { this->m_Mirroring = mirroring; } bool mitk::SurfaceRegistrationManager::getMirroring() { return m_Mirroring; } mitk::Surface::Pointer mitk::SurfaceRegistrationManager::getRegisteredSurface() { return m_RegisteredSurface; } std::map mitk::SurfaceRegistrationManager::getDistanceResults() { return m_DistanceResults; } +vtkSmartPointer mitk::SurfaceRegistrationManager::getTransformation() +{ + return m_ICPTransformation; +} + void mitk::SurfaceRegistrationManager::manageICPCalculation() { MITK_INFO << "Starting registration"; m_RegisteredSurface = mitk::Surface::New(); mitk::SurfaceRegistrationICP *registrationHelper = new SurfaceRegistrationICP(); if (m_Mirroring) { m_RegisteredSurface = registrationHelper->CalculateICP(m_MirroredSurface, m_TargetSurface); } else { m_RegisteredSurface = registrationHelper->CalculateICP(m_MovingSurface, m_TargetSurface); } + m_ICPTransformation = registrationHelper->getTransformation(); } void mitk::SurfaceRegistrationManager::manageCalculateDistances() { if (m_RegisteredSurface != nullptr) { m_DistanceCalculator = new ShortestDistanceCalculator(m_RegisteredSurface->GetVtkPolyData(), m_TargetSurface->GetVtkPolyData()); } else if(m_Mirroring) { m_DistanceCalculator = new ShortestDistanceCalculator(m_MirroredSurface->GetVtkPolyData(), m_TargetSurface->GetVtkPolyData()); } else { m_DistanceCalculator = new ShortestDistanceCalculator(m_MovingSurface->GetVtkPolyData(), m_TargetSurface->GetVtkPolyData()); } m_DistanceCalculator->calculateShortestDistance(); m_DistanceResults = m_DistanceCalculator->getResults(); - m_CurvatureResults = m_DistanceCalculator->calculateCurvature(); //TODO refactor in seperated class + m_CurvatureResults = m_DistanceCalculator->calculateCurvature(); } void mitk::SurfaceRegistrationManager::createLookUpTable() { m_LookupTable = vtkSmartPointer::New(); m_LookupTable->SetNumberOfTableValues(25); m_LookupTable->Build(); } void mitk::SurfaceRegistrationManager::printPoints(mitk::Surface::Pointer surfaceA, mitk::Surface::Pointer surfaceB) { MITK_INFO << "printing Points"; std::ofstream OutputFileMoving; OutputFileMoving.open("movingPoints.txt"); int pointNumber = surfaceA->GetVtkPolyData()->GetPoints()->GetNumberOfPoints(); double printPoint[3] = { 0,0,0 }; for (int i = 0; i < pointNumber; ++i) { surfaceA->GetVtkPolyData()->GetPoints()->GetPoint(i, printPoint); OutputFileMoving << printPoint[0]<<" " << printPoint[1] << " " << printPoint[2] <GetVtkPolyData()->GetPoints()->GetNumberOfPoints(); double printPoint2[3] = { 0,0,0 }; for (int i = 0; i < pointNumber2; ++i) { surfaceB->GetVtkPolyData()->GetPoints()->GetPoint(i, printPoint2); OutputFileTarget << printPoint2[0] << " " << printPoint2[1] << " " << printPoint2[2] << std::endl; } OutputFileTarget.close(); } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp index 99819c50ef..fd270953e1 100644 --- a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp @@ -1,1129 +1,1299 @@ /*========================================================================= 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 "QmitkSurfaceRegistration.h" //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "org_mitk_gui_qt_surfaceregistration_Activator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "itkCastImageFilter.h" +#include +#include +#include "itkCastImageFilter.h" +#include "itkImage.h" +#include "itkImageRegistrationMethod.h" +#include "itkLinearInterpolateImageFunction.h" +#include "itkMeanSquaresImageToImageMetric.h" +#include "itkRegularStepGradientDescentOptimizer.h" +#include "itkResampleImageFilter.h" +#include "itkRescaleIntensityImageFilter.h" +#include "itkSpatialObjectToImageFilter.h" +#include "itkTranslationTransform.h" + #define _USE_MATH_DEFINES #include const std::string QmitkSurfaceRegistration::VIEW_ID = "org.mitk.views.surfaceregistration"; QmitkSurfaceRegistration::QmitkSurfaceRegistration(QObject *parent) : m_ParentWidget(0) { } QmitkSurfaceRegistration::~QmitkSurfaceRegistration() { m_movingSurface = nullptr; m_targetSurface = nullptr; } void QmitkSurfaceRegistration::SetFocus() { m_Controls.registerAndComparePushButton->setFocus(); } QWidget * QmitkSurfaceRegistration::GetControls() { return nullptr; } void QmitkSurfaceRegistration::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.movingSurfaceNameComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.movingSurfaceNameComboBox->SetPredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType::New(), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); m_Controls.targetSurfaceNameComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.targetSurfaceNameComboBox->SetPredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType::New(), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); m_Controls.imageSelectorComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.imageSelectorComboBox->SetPredicate(mitk::NodePredicateAnd::New( mitk::TNodePredicateDataType::New(), mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); connect(m_Controls.registerAndComparePushButton, SIGNAL(clicked()), this, SLOT(doRegisterAndCompare())); connect(m_Controls.movingSurfaceNameComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSelectedMovingSurfaceChanged(const mitk::DataNode *))); connect(m_Controls.targetSurfaceNameComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSelectedTargetSurfaceChanged(const mitk::DataNode *))); connect(m_Controls.imageSelectorComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSelectedImageChanged(const mitk::DataNode *))); connect(m_Controls.registerAndCompareAllPushButton, SIGNAL(clicked()), this, SLOT(doRegisterAndCompareAll())); connect(m_Controls.comparePushButton, SIGNAL(clicked()), this, SLOT(doCompare())); mitk::RenderingManager::GetInstance()->SetDataStorage(this->GetDataStorageReference()->GetDataStorage()); mitk::RenderingManager::GetInstance()->InitializeViews(); m_Controls.automatizedGroupBox->setEnabled(true); m_Controls.OutputLineEdit->setEnabled(true); m_Controls.registerAndCompareAllPushButton->setEnabled(true); m_Controls.comparePushButton->setEnabled(true); //initializeWithSceneFile(); m_SurfaceRegistrationManager = new mitk::SurfaceRegistrationManager(nullptr, nullptr); m_ShapeComparisonManager = new mitk::ShapeComparisonManager(); m_ParentWidget = parent; } void QmitkSurfaceRegistration::OnSelectedMovingSurfaceChanged(const mitk::DataNode *node) { if (node != nullptr) { m_movingSurface = dynamic_cast(node->GetData()); m_movingSurface->SetObjectName(node->GetObjectName()); m_Controls.selectMovingSurfaceLabel->setText("Selected moving surface:"); m_Controls.mirroringCheckBox->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (m_targetSurface != nullptr && m_targetSurface.GetPointer() != m_movingSurface.GetPointer()) { m_Controls.registerAndComparePushButton->setEnabled(true); m_Controls.comparePushButton->setEnabled(true); } } } void QmitkSurfaceRegistration::OnSelectedTargetSurfaceChanged(const mitk::DataNode *node) { if (node != nullptr) { m_targetSurface = dynamic_cast(node->GetData()); - m_targetSurface->SetObjectName(node->GetObjectName()); + m_targetSurface->SetObjectName(node->GetName()); m_Controls.selectTargetSurfaceLabel->setText("Selected target surface:"); m_Controls.mappedDataGroupBox->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (m_movingSurface != nullptr && m_targetSurface.GetPointer() != m_movingSurface.GetPointer()) { m_Controls.registerAndComparePushButton->setEnabled(true); m_Controls.comparePushButton->setEnabled(true); } } } void QmitkSurfaceRegistration::OnSelectedImageChanged(const mitk::DataNode *) { //TODO? } void QmitkSurfaceRegistration::doRegisterAndCompare() { mitk::ProgressBar::GetInstance()->AddStepsToDo(2); mitk::ProgressBar::GetInstance()->Progress(); MITK_INFO << "Moving Name: " + m_movingSurface->GetObjectName(); MITK_INFO << "Target Name: " + m_targetSurface->GetObjectName(); m_SurfaceRegistrationManager = new mitk::SurfaceRegistrationManager(m_movingSurface, m_targetSurface); m_SurfaceRegistrationManager->setMirroring(m_Controls.mirroringCheckBox->isChecked()); m_SurfaceRegistrationManager->performRegistration(); - m_SurfaceRegistrationManager->setMirroring(false); + //m_SurfaceRegistrationManager->setMirroring(false); m_registeredSurface = m_SurfaceRegistrationManager->getRegisteredSurface(); //make sure to automatically select orig img mitk::DataNode::Pointer origImgNode = getGeometryNodeFromTarget(m_targetSurface); MITK_INFO << "Original name of target: " + origImgNode->GetName(); m_Controls.imageSelectorComboBox->SetSelectedNode(origImgNode); //mitk::Image::Pointer currentlySelectedImage =dynamic_cast(m_Controls.imageSelectorComboBox->GetSelectedNode()->GetData()); mitk::Image::Pointer currentlySelectedImage = dynamic_cast(origImgNode->GetData()); - mitk::Image::Pointer registeredImg = ConvertSurfaceToImage(currentlySelectedImage, m_registeredSurface); - mitk::Image::Pointer targetImg = ConvertSurfaceToImage(currentlySelectedImage, m_targetSurface); - - mitk::DataNode::Pointer registerdNode = mitk::DataNode::New(); - registerdNode->SetData(registeredImg); - registerdNode->SetVisibility(true); - registerdNode->SetName(m_movingSurface->GetObjectName()+ "_Registered"); - registerdNode->SetColor(1.0, 1.0, 0.0); - - - mitk::DataNode::Pointer targetNode = mitk::DataNode::New(); - targetNode->SetData(targetImg); - targetNode->SetVisibility(true); - targetNode->SetName(m_targetSurface->GetObjectName() + "_Target"); - this->GetDataStorage()->Add(registerdNode); - this->GetDataStorage()->Add(targetNode); this->GetDataStorageReference()->GetDataStorage()->Modified(); m_SurfaceRegistrationManager->performComparison(); mitk::DataNode::Pointer colouredData = mitk::DataNode::New(); colouredData = m_SurfaceRegistrationManager->getColourTransformedDataNode(); colouredData->SetName(m_Controls.mappedDataNameLineEdit->text().toStdString()); this->GetDataStorage()->Add(colouredData); this->GetDataStorageReference()->GetDataStorage()->Modified(); mitk::RenderingManager::GetInstance()->InitializeViews(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); vtkSmartPointer lut = m_SurfaceRegistrationManager->getTable(); showLookUpTable(lut); mitk::ProgressBar::GetInstance()->Progress(); } void QmitkSurfaceRegistration::doRegisterAndCompareAll() { MITK_INFO << "Compare all surfaces in Storage "; mitk::ProgressBar::GetInstance()->AddStepsToDo(2); mitk::ProgressBar::GetInstance()->Progress(); auto datastorage = this->GetDataStorage(); mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); QString leftOrigName; QString rightOrigName; if (!images->empty()) { - for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) - { - mitk::DataNode::Pointer node = (*iter); - if (QString(node->GetName().c_str()).contains(QString("orig"), Qt::CaseSensitive)) + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) { - if (leftOrigName == "") - { - leftOrigName = QString(node->GetName().c_str()).remove("_orig"); - } - else if (rightOrigName == "" && rightOrigName != leftOrigName) + mitk::DataNode::Pointer node = (*iter); + if (QString(node->GetName().c_str()).contains(QString("orig"), Qt::CaseSensitive)) { - rightOrigName = QString(node->GetName().c_str()).remove("_orig"); + if (leftOrigName == "") + { + leftOrigName = QString(node->GetName().c_str()).remove("_orig"); + } + else if (rightOrigName == "" && rightOrigName != leftOrigName) + { + rightOrigName = QString(node->GetName().c_str()).remove("_orig"); + } } } } - } mitk::NodePredicateDataType::Pointer isSurface = mitk::NodePredicateDataType::New("Surface"); mitk::DataStorage::SetOfObjects::ConstPointer surfaces = datastorage->GetSubset(isSurface); if (!surfaces->empty()) { //initialize variables mitk::Surface::Pointer tibiaLeft = nullptr; mitk::Surface::Pointer fibulaLeft = nullptr; mitk::Surface::Pointer talusLeft = nullptr; mitk::Surface::Pointer tibiaRight = nullptr; mitk::Surface::Pointer fibulaRight = nullptr; mitk::Surface::Pointer talusRight = nullptr; //iterate over all child nodes with NodePredicateProperty for (mitk::DataStorage::SetOfObjects::const_iterator iter = surfaces->begin(); iter != surfaces->end(); ++iter) { mitk::DataNode::Pointer node = (*iter); //check for left if (QString(node->GetName().c_str()).contains(QString(leftOrigName), Qt::CaseSensitive)) { if (QString(node->GetName().c_str()).contains(QString("Tibia"), Qt::CaseSensitive)) { mitk::DataNode* tibiaNode(this->GetDataStorage()->GetNamedNode(node->GetName())); tibiaLeft = dynamic_cast(tibiaNode->GetData()); - tibiaLeft->SetObjectName("Tibia_" + leftOrigName.toStdString()); + tibiaLeft->SetObjectName(leftOrigName.toStdString() + "_Tibia"); } else if (QString(node->GetName().c_str()).contains(QString("Fibula"), Qt::CaseSensitive)) { mitk::DataNode* fibulaNode(this->GetDataStorage()->GetNamedNode(node->GetName())); fibulaLeft = dynamic_cast(fibulaNode->GetData()); - fibulaLeft->SetObjectName("Fibula_" + leftOrigName.toStdString()); + fibulaLeft->SetObjectName(leftOrigName.toStdString() + "_Fibula"); } else if (QString(node->GetName().c_str()).contains(QString("Talus"), Qt::CaseSensitive)) { mitk::DataNode* talusNode(this->GetDataStorage()->GetNamedNode(node->GetName())); talusLeft = dynamic_cast(talusNode->GetData()); - talusLeft->SetObjectName("Talus_" + leftOrigName.toStdString()); + talusLeft->SetObjectName(leftOrigName.toStdString() + "_Talus"); } }//check for right else if (QString(node->GetName().c_str()).contains(QString(rightOrigName), Qt::CaseSensitive)) { if (QString(node->GetName().c_str()).contains(QString("Tibia"), Qt::CaseSensitive)) { mitk::DataNode* tibiaMovingNode(this->GetDataStorage()->GetNamedNode(node->GetName())); tibiaRight = dynamic_cast(tibiaMovingNode->GetData()); - tibiaRight->SetObjectName("Tibia_" + rightOrigName.toStdString()); + tibiaRight->SetObjectName(rightOrigName.toStdString() + "_Tibia"); } else if (QString(node->GetName().c_str()).contains(QString("Fibula"), Qt::CaseSensitive)) { mitk::DataNode* fibulaMovingNode(this->GetDataStorage()->GetNamedNode(node->GetName())); fibulaRight = dynamic_cast(fibulaMovingNode->GetData()); - fibulaRight->SetObjectName("Fibula_" + rightOrigName.toStdString()); + fibulaRight->SetObjectName(rightOrigName.toStdString() + "_Fibula"); } else if (QString(node->GetName().c_str()).contains(QString("Talus"), Qt::CaseSensitive)) { mitk::DataNode* talusMovingNode(this->GetDataStorage()->GetNamedNode(node->GetName())); talusRight = dynamic_cast(talusMovingNode->GetData()); - talusRight->SetObjectName("Talus_" + rightOrigName.toStdString()); + talusRight->SetObjectName(rightOrigName.toStdString() + "_Talus"); } } } - //fillHoles(tibiaLeft); - //fillHoles(tibiaRight); - //fillHoles(fibulaLeft); - //fillHoles(fibulaRight); - //fillHoles(talusLeft); - //fillHoles(talusRight); - //TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA//TIBIA m_ShapeComparisonManager = new mitk::ShapeComparisonManager(); - m_ShapeComparisonManager->setOutputpath("D:/ShapeComparison/TestCase/" + tibiaLeft->GetObjectName() + tibiaRight->GetObjectName() + ".txt"); + m_ShapeComparisonManager->setOutputpath("D:/ShapeComparison/Rechtsmedizin/" + tibiaLeft->GetObjectName() + tibiaRight->GetObjectName() + ".txt"); m_ShapeComparisonManager->startOutputGeneration(); //calculate Tibia differences performTwoSidedComparison(tibiaLeft, tibiaRight, "Tibia"); - mitk::DataNode::Pointer geometryNode = getGeometryNodeFromTarget(tibiaRight); + mitk::DataNode::Pointer geometryNode = getGeometryNodeFromTarget(tibiaLeft); m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); testloadPosition(); iteratePlanePositionImages(axial); mitk::Surface::Pointer tibiaMovingLeft = dynamic_cast(this->GetDataStorage()->GetNamedNode("TibiaMovingL")->GetData()); mitk::Surface::Pointer tibiaMovingRight = dynamic_cast(this->GetDataStorage()->GetNamedNode("TibiaMovingR")->GetData()); m_SurfaceRegistrationManager = new mitk::SurfaceRegistrationManager(tibiaMovingLeft, tibiaMovingRight); if (QString(tibiaLeft->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive) && QString(tibiaRight->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive) ) { + MITK_INFO << "Mirroring false"; m_SurfaceRegistrationManager->setMirroring(false); + m_Controls.mirroringCheckBox->setChecked(false); } else if (QString(tibiaLeft->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive) && QString(tibiaRight->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive)) { + MITK_INFO << "Mirroring false"; m_SurfaceRegistrationManager->setMirroring(false); + m_Controls.mirroringCheckBox->setChecked(false); } else { + MITK_INFO << "Mirroring true"; m_SurfaceRegistrationManager->setMirroring(true); + m_Controls.mirroringCheckBox->setChecked(true); } m_SurfaceRegistrationManager->performRegistration(); mitk::Surface::Pointer registeredTibia = m_SurfaceRegistrationManager->getRegisteredSurface(); registeredTibia->GetVtkPolyData()->GetPointData()->SetScalars(tibiaMovingLeft->GetVtkPolyData()->GetPointData()->GetScalars()); mitk::DataNode::Pointer registeredTibiaMovingL = mitk::DataNode::New(); registeredTibiaMovingL->SetData(registeredTibia); registeredTibiaMovingL->SetName("registeredTibiaMovingL"); this->GetDataStorage()->Add(registeredTibiaMovingL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); std::map distanceMetricsResultsTibia = m_ShapeComparisonManager->calculateDistanceMetrics(tibiaMovingLeft, tibiaMovingRight); geometryNode = getGeometryNodeFromTarget(tibiaLeft); m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); testloadPosition(); iteratePlanePositionSurfaces(registeredTibia, tibiaMovingRight, axial); testloadPosition(); iteratePlanePositionSurfaces(registeredTibia, tibiaMovingRight, coronal); testloadPosition(); iteratePlanePositionSurfaces(registeredTibia, tibiaMovingRight, saggital); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - m_ShapeComparisonManager->closeOutputGeneration(); - // m_SurfaceRegistrationManager->~SurfaceRegistrationManager(); testloadPosition(); - //FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA + ////////FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA//FIBULA - m_ShapeComparisonManager->setOutputpath("D:/ShapeComparison/TestCase/" + fibulaLeft->GetObjectName() + fibulaRight->GetObjectName() + ".txt"); + m_ShapeComparisonManager->setOutputpath("D:/ShapeComparison/Rechtsmedizin/" + fibulaLeft->GetObjectName() + fibulaRight->GetObjectName() + ".txt"); m_ShapeComparisonManager->startOutputGeneration(); //calculate Fibula differences performTwoSidedComparison(fibulaLeft, fibulaRight, "Fibula"); - geometryNode = getGeometryNodeFromTarget(tibiaLeft); + geometryNode = getGeometryNodeFromTarget(fibulaLeft); m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); testloadPosition(); iteratePlanePositionImages(axial); mitk::Surface::Pointer fibulaMovingLeft = dynamic_cast(this->GetDataStorage()->GetNamedNode("FibulaMovingL")->GetData()); mitk::Surface::Pointer fibulaMovingRight = dynamic_cast(this->GetDataStorage()->GetNamedNode("FibulaMovingR")->GetData()); std::map distanceMetricsResultsFibula = m_ShapeComparisonManager->calculateDistanceMetrics(fibulaMovingLeft, fibulaMovingRight); m_SurfaceRegistrationManager = new mitk::SurfaceRegistrationManager(fibulaMovingLeft, fibulaMovingRight); if (QString(fibulaLeft->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive) && QString(fibulaRight->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive)) { m_SurfaceRegistrationManager->setMirroring(false); } else if (QString(fibulaLeft->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive) && QString(fibulaRight->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive)) { m_SurfaceRegistrationManager->setMirroring(false); } else { m_SurfaceRegistrationManager->setMirroring(true); } m_SurfaceRegistrationManager->performRegistration(); mitk::Surface::Pointer registeredFibula = m_SurfaceRegistrationManager->getRegisteredSurface(); geometryNode = getGeometryNodeFromTarget(tibiaLeft); m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); testloadPosition(); iteratePlanePositionSurfaces(registeredFibula, fibulaMovingRight, axial); testloadPosition(); iteratePlanePositionSurfaces(registeredFibula, fibulaMovingRight, coronal); testloadPosition(); iteratePlanePositionSurfaces(registeredFibula, fibulaMovingRight, saggital); + m_ShapeComparisonManager->closeOutputGeneration(); + + //TALUS//TALUS//TALUS//TALUS//TALUS//TALUS//TALUS//TALUS//TALUS//TALUS//TALUS//TALUS + m_ShapeComparisonManager->setOutputpath("D:/ShapeComparison/Rechtsmedizin/" + talusLeft->GetObjectName() + talusRight->GetObjectName() + ".txt"); + m_ShapeComparisonManager->startOutputGeneration(); + + //calculate Fibula differences + performTwoSidedComparison(talusLeft, talusRight, "Talus"); + + geometryNode = getGeometryNodeFromTarget(talusLeft); + m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); + testloadPosition(); + iteratePlanePositionImages(axial); + + mitk::Surface::Pointer talusMovingLeft = dynamic_cast(this->GetDataStorage()->GetNamedNode("TalusMovingL")->GetData()); + mitk::Surface::Pointer talusMovingRight = dynamic_cast(this->GetDataStorage()->GetNamedNode("TalusMovingR")->GetData()); + + std::map distanceMetricsResultsTalus = m_ShapeComparisonManager->calculateDistanceMetrics(talusMovingLeft, talusMovingRight); + + m_SurfaceRegistrationManager = new mitk::SurfaceRegistrationManager(talusMovingLeft, talusMovingRight); + if (QString(talusLeft->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive) && QString(talusRight->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive)) + { + m_SurfaceRegistrationManager->setMirroring(false); + } + else if (QString(talusLeft->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive) && QString(talusRight->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive)) + { + m_SurfaceRegistrationManager->setMirroring(false); + } + else + { + m_SurfaceRegistrationManager->setMirroring(true); + } + m_SurfaceRegistrationManager->performRegistration(); + mitk::Surface::Pointer registeredTalus = m_SurfaceRegistrationManager->getRegisteredSurface(); + + geometryNode = getGeometryNodeFromTarget(talusLeft); + m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); + + testloadPosition(); + iteratePlanePositionSurfaces(registeredTalus, talusMovingRight, axial); + testloadPosition(); + iteratePlanePositionSurfaces(registeredTalus, talusMovingRight, coronal); + testloadPosition(); + iteratePlanePositionSurfaces(registeredTalus, talusMovingRight, saggital); m_ShapeComparisonManager->closeOutputGeneration(); - //m_SurfaceRegistrationManager->~SurfaceRegistrationManager(); - ////resultOutput << "Calculating Talus..." << std::endl; - // performTwoSidedComparison(talusLeft, talusRight, "Target", resultOutput); } mitk::ProgressBar::GetInstance()->Progress(); } void QmitkSurfaceRegistration::doCompare() { - mitk::Surface::Pointer testFillHoles = dynamic_cast(m_Controls.movingSurfaceNameComboBox->GetSelectedNode()->GetData()); - fillHoles(testFillHoles); - mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(testFillHoles); - node->SetName("NoHoles"); - this->GetDataStorage()->Add(node); - this->GetDataStorageReference()->GetDataStorage()->Modified(); + //Fill Holes test + // mitk::DataNode::Pointer dn = getGeometryNodeFromTarget(m_targetSurface); + + //mitk::Surface::Pointer testFillHoles = dynamic_cast(m_Controls.movingSurfaceNameComboBox->GetSelectedNode()->GetData()); + //fillHoles(testFillHoles); + + //mitk::DataNode::Pointer node = mitk::DataNode::New(); + //node->SetData(testFillHoles); + //node->SetName("NoHoles"); + //this->GetDataStorage()->Add(node); + //this->GetDataStorageReference()->GetDataStorage()->Modified(); + + //mitk::RenderingManager::GetInstance()->InitializeViews(); + //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + - mitk::RenderingManager::GetInstance()->InitializeViews(); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - //TODO - /*m_SurfaceRegistrationManager->setMirroring(m_Controls.mirroringCheckBox->isChecked()); + //TODO berechnet alle Comparison initializeDirectoryList(); - automatizedEvaluation();*/ + automatizedEvaluation(); + + //TODO berechnet den ausgewaehlten Comparison mit den Nodes in der Combobox //mitk::ProgressBar::GetInstance()->AddStepsToDo(2); //mitk::ProgressBar::GetInstance()->Progress(); //m_SurfaceRegistrationManager = new mitk::SurfaceRegistrationManager(m_movingSurface, m_targetSurface); //m_SurfaceRegistrationManager->performComparison(); //mitk::DataNode::Pointer colouredData = mitk::DataNode::New(); //colouredData = m_SurfaceRegistrationManager->getColourTransformedDataNode(); //colouredData->SetName(m_Controls.mappedDataNameLineEdit->text().toStdString()); //this->GetDataStorage()->Add(colouredData); //this->GetDataStorageReference()->GetDataStorage()->Modified(); //mitk::RenderingManager::GetInstance()->InitializeViews(); //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //vtkSmartPointer lut = m_SurfaceRegistrationManager->getTable(); //showLookUpTable(lut); //testloadPosition(); //iteratePlanePosition(axial); //iteratePlanePosition(coronal); //iteratePlanePosition(saggital); //mitk::ProgressBar::GetInstance()->Progress(); } void QmitkSurfaceRegistration::initializeDirectoryList() { // QDir directory = QDir(m_mainDirectory); QStringList foundDirs = directory.entryList(QDir::AllDirs); m_Directories = QStringList(); if (foundDirs.first() == "." ) { foundDirs.pop_front(); } if (foundDirs.first() == "..") { foundDirs.pop_front(); } for (int i = 0; i < foundDirs.size() ; ++i) { m_Directories.insert(i,m_mainDirectory +foundDirs[i]); MITK_INFO << m_Directories.at(i); } MITK_INFO << " *...............................*"; } void QmitkSurfaceRegistration::automatizedEvaluation() { QStringList allFeetDirs; QStringList::const_iterator constIterator; for (int i = 0; i < m_Directories.size(); ++i) { allFeetDirs.append((m_Directories.at(i)+ "/Left")); allFeetDirs.append((m_Directories.at(i) + "/Right")); } for (int i = 0; i < allFeetDirs.size() - 1; ++i) { for (int j = i + 1; j < allFeetDirs.size(); ++j) { - MITK_INFO << allFeetDirs.at(i).toStdString(); + /* MITK_INFO << allFeetDirs.at(i).toStdString(); MITK_INFO << allFeetDirs.at(j).toStdString(); if (allFeetDirs.at(i).contains("Left") && allFeetDirs.at(j).contains("Left")) { m_Controls.mirroringCheckBox->setChecked(false); m_SurfaceRegistrationManager->setMirroring(false); + MITK_INFO << "Mirroring false"; } else if (allFeetDirs.at(i).contains("Right") && allFeetDirs.at(j).contains("Right")) { m_Controls.mirroringCheckBox->setChecked(false); m_SurfaceRegistrationManager->setMirroring(false); + MITK_INFO << "Mirroring false"; } else { m_Controls.mirroringCheckBox->setChecked(true); m_SurfaceRegistrationManager->setMirroring(true); - } + MITK_INFO << "Mirroring true"; + }*/ compareAnklePath(allFeetDirs.at(i), allFeetDirs.at(j)); } } } void QmitkSurfaceRegistration::compareAnklePath(QString pathA, QString pathB) { //load scene Files QString pathAtemplate = pathA + "/template.mitk"; QString pathBtemplate = pathB + "/template.mitk"; mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); sceneIO->LoadScene(pathAtemplate.toStdString(), this->GetDataStorageReference()->GetDataStorage(), false); sceneIO->LoadScene(pathBtemplate.toStdString(), this->GetDataStorageReference()->GetDataStorage(), false); this->GetDataStorageReference()->GetDataStorage()->Modified(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorageReference()->GetDataStorage()); //evaluate doRegisterAndCompareAll(); std::string filename = pathA.toStdString() + "/Results/" + pathB.remove(m_mainDirectory).remove("/").toStdString()+ "results.mitk"; // MITK_INFO << "Filename: " << filename; //sceneIO->SaveScene(this->GetDataStorage()->GetAll(), this->GetDataStorage(), filename); //Close Project auto allItems = this->GetDataStorage()->GetAll(); int size = allItems->Size(); for (int i = 0; i < size; ++i) { this->GetDataStorage()->Remove(allItems->at(i)); } - // MITK_INFO << "DS size: " << this->GetDataStorage()->GetAll()->Size(); } void QmitkSurfaceRegistration::performTwoSidedComparison(mitk::Surface::Pointer left, mitk::Surface::Pointer right, QString resultName) { //set the mirroring if ( QString(left->GetObjectName().c_str()).contains("L") && QString(right->GetObjectName().c_str()).contains("L")) { m_Controls.mirroringCheckBox->setChecked(false); m_SurfaceRegistrationManager->setMirroring(false); + MITK_INFO << "Mirroring false"; } else if (QString(left->GetObjectName().c_str()).contains("R") && QString(right->GetObjectName().c_str()).contains("R")) { m_Controls.mirroringCheckBox->setChecked(false); m_SurfaceRegistrationManager->setMirroring(false); + MITK_INFO << "Mirroring false"; } else { m_Controls.mirroringCheckBox->setChecked(true); m_SurfaceRegistrationManager->setMirroring(true); + MITK_INFO << "Mirroring true"; } - if (left != nullptr && right != nullptr) { - //m_Controls.mirroringCheckBox->setChecked(true); m_movingSurface = left; m_targetSurface = right; m_Controls.mappedDataNameLineEdit->setText(resultName +"MovingL"); doRegisterAndCompare(); - //double meanA = m_SurfaceRegistrationManager->getDistanceResults()["Mean"]; + + vtkSmartPointer trafo = m_SurfaceRegistrationManager->getTransformation(); + performLabelOverlapComparison(left, right, trafo); m_movingSurface = right; m_targetSurface = left; m_Controls.mappedDataNameLineEdit->setText(resultName + "MovingR"); doRegisterAndCompare(); - performTwoSidedLabelOverlapComparison(left, right); - //double meanB = m_SurfaceRegistrationManager->getDistanceResults()["Mean"]; - //double ASSD = calculateASSD(meanA, meanB); - /*resultOutput << " ASSD: " << ASSD << std::endl;*/ + trafo = m_SurfaceRegistrationManager->getTransformation(); + performLabelOverlapComparison(right, left, trafo); } } -void QmitkSurfaceRegistration::performTwoSidedLabelOverlapComparison(mitk::Surface::Pointer left, mitk::Surface::Pointer right) +void QmitkSurfaceRegistration::performLabelOverlapComparison(mitk::Surface::Pointer left, mitk::Surface::Pointer right, vtkSmartPointer trafo) { auto datastorage = this->GetDataStorage(); - mitk::Image::Pointer registeredImg; - mitk::Image::Pointer targetImg; + mitk::Image::Pointer rightImg; + mitk::Image::Pointer leftImg; mitk::DataNode::Pointer origImgNode; - if (QString(left->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive)) - { - auto registeredNode = datastorage->GetNamedNode(left->GetObjectName() + "_Registered"); - registeredImg = dynamic_cast(registeredNode->GetData()); - auto targetNode = datastorage->GetNamedNode(right->GetObjectName() + "_Target"); - targetImg = dynamic_cast(targetNode->GetData()); - origImgNode = getGeometryNodeFromTarget(right); - } - else if (QString(left->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive)) - { - auto registeredNode = datastorage->GetNamedNode(right->GetObjectName() + "_Registered"); - registeredImg = dynamic_cast(registeredNode->GetData()); - auto targetNode = datastorage->GetNamedNode(left->GetObjectName() + "_Target"); - targetImg = dynamic_cast(targetNode->GetData()); - origImgNode = getGeometryNodeFromTarget(left); - } - m_Controls.imageSelectorComboBox->SetSelectedNode(origImgNode); - testloadPosition(); + QString rightImgName = QString::fromStdString(right->GetObjectName()).remove("_Surface"); + MITK_INFO << "RightImgName: " << rightImgName; + MITK_INFO << "Moving Name: " << left->GetObjectName(); + rightImg = dynamic_cast(datastorage->GetNamedNode(rightImgName.toStdString())->GetData()); + origImgNode = getGeometryNodeFromTarget(right); - std::map labelOverlapResults = m_ShapeComparisonManager->calculateLabelOverlapMetrics(registeredImg, targetImg); - - //MITK_INFO << "Volume Similarity: " << QString::number(labelOverlapResults[""]); - - //TODO calculate SurfaceDistanceMetrics + leftImg = transformMovingSegm(left, right, trafo); } mitk::DataNode::Pointer QmitkSurfaceRegistration::getGeometryNodeFromTarget(mitk::Surface::Pointer target) { - mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); - auto datastorage = this->GetDataStorage(); - mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); mitk::DataNode::Pointer origImgNode = mitk::DataNode::New(); - if (!images->empty()) + + //if contains Tibia, Fibula, Talus + std::string targetName = target->GetObjectName(); + QString origName; + if (QString(targetName.c_str()).contains(QString("Tibia"), Qt::CaseSensitive)) { - //iterate over all child nodes with NodePredicateProperty - for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) - { - mitk::DataNode::Pointer node = (*iter); - std::string name = node->GetObjectName(); - //check for for orig - if (QString(node->GetName().c_str()).contains(QString("orig"), Qt::CaseSensitive)) - { - if (QString(target->GetObjectName().c_str()).contains(QString("R"), Qt::CaseSensitive) && QString(node->GetName().c_str()).contains(QString("R"), Qt::CaseSensitive)) - { - origImgNode = node; - } - else if (QString(target->GetObjectName().c_str()).contains(QString("L"), Qt::CaseSensitive) && QString(node->GetName().c_str()).contains(QString("L"), Qt::CaseSensitive)) - { - origImgNode = node; - } - } - } + origName = QString::fromStdString(targetName).remove("_Tibia").remove("_Surface"); + } + else if (QString(targetName.c_str()).contains(QString("Fibula"), Qt::CaseSensitive)) + { + origName = QString::fromStdString(targetName).remove("_Fibula").remove("_Surface"); } + else if (QString(targetName.c_str()).contains(QString("Talus"), Qt::CaseSensitive)) + { + origName = QString::fromStdString(targetName).remove("_Talus").remove("_Surface"); + } + origName.append("_orig"); + MITK_INFO << "Original Name: " << origName; + origImgNode = this->GetDataStorage()->GetNamedNode(origName.toStdString()); m_Controls.imageSelectorComboBox->SetSelectedNode(origImgNode); - MITK_INFO << m_Controls.imageSelectorComboBox->GetSelectedNode()->GetName(); + MITK_INFO << "Original Node: " << origImgNode->GetObjectName(); return origImgNode; } void QmitkSurfaceRegistration::showLookUpTable(vtkSmartPointer lut) { mitk::BaseRenderer::Pointer renderer = mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4")); m_colorBarAnnotation = mitk::ColorBarAnnotation::New(); mitk::LookupTable::Pointer mitkTable = mitk::LookupTable::New(); mitkTable->SetVtkLookupTable(lut); mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(mitkTable); m_colorBarAnnotation->SetProperty("ColorBarAnnotation.LookupTable", prop.GetPointer()); //MITK_INFO<GetPropertyList(); m_colorBarAnnotation->SetNumberOfLabels(9); m_colorBarAnnotation->SetAnnotationTextScaling(true); m_colorBarAnnotation->SetDrawAnnotations(true); m_colorBarAnnotation->SetDrawTickLabels(true); mitk::LayoutAnnotationRenderer::AddAnnotation( m_colorBarAnnotation, renderer, mitk::LayoutAnnotationRenderer::Right, 10, 10, 10); } mitk::Surface::Pointer QmitkSurfaceRegistration::fillHoles(mitk::Surface::Pointer surface) { - mitk::Surface::Pointer filledSurface = surface->Clone(); + mitk::Surface::Pointer filledSurface = mitk::Surface::New(); vtkSmartPointer polyData = surface->GetVtkPolyData(); vtkSmartPointer fillHolesFilter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 fillHolesFilter->SetInputData(surface->GetVtkPolyData()); #else fillHolesFilter->SetInputData(input); #endif - fillHolesFilter->SetHoleSize(1.0); + fillHolesFilter->SetHoleSize(1000.0); filledSurface->SetVtkPolyData(fillHolesFilter->GetOutput()); // Make the triangle windong order consistent vtkSmartPointer normals = vtkSmartPointer::New(); normals->SetInputData(filledSurface->GetVtkPolyData()); normals->ConsistencyOn(); normals->SplittingOff(); normals->Update(); // Restore the original normals normals->GetOutput()->GetPointData()-> SetNormals(surface->GetVtkPolyData()->GetPointData()->GetNormals()); polyData = normals->GetOutput(); - filledSurface->SetVtkPolyData(fillHolesFilter->GetOutput()); + filledSurface->SetVtkPolyData(polyData); + return filledSurface; } void QmitkSurfaceRegistration::initializeWithSceneFile() { std::string fileNameRight= "D:/ShapeComparison/TestCase/AA246/Right/template.mitk"; std::string fileNameLeft = "D:/ShapeComparison/TestCase/AA246/Left/template.mitk"; mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); sceneIO->LoadScene(fileNameRight, this->GetDataStorageReference()->GetDataStorage(), false); sceneIO->LoadScene(fileNameLeft, this->GetDataStorageReference()->GetDataStorage(), false); this->GetDataStorageReference()->GetDataStorage()->Modified(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorageReference()->GetDataStorage()); } void QmitkSurfaceRegistration::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(); } } +mitk::Image::Pointer QmitkSurfaceRegistration::transformMovingSegm(mitk::Surface::Pointer moving, mitk::Surface::Pointer target, vtkSmartPointer trafo) +{ + MITK_INFO << "transformMovingSegmentation"; + + QString leftOrigName = QString::fromStdString(moving->GetObjectName()); + QString rightOrigName = QString::fromStdString(target->GetObjectName()); + leftOrigName.remove("_Surface"); + rightOrigName.remove("_Surface"); + + MITK_INFO << "Left: " << leftOrigName; + MITK_INFO << "Right: " << rightOrigName; + + // get Binary Images + mitk::Image::Pointer tibiaLeftSeg = dynamic_cast(this->GetDataStorage()->GetNamedNode(leftOrigName.toStdString())->GetData()); + MITK_INFO << "Left: " << leftOrigName; + mitk::Image::Pointer tibiaRightSeg = dynamic_cast(this->GetDataStorage()->GetNamedNode(rightOrigName.toStdString())->GetData()); + MITK_INFO << "Right: " << rightOrigName; + mitk::Image::Pointer tibiaLeftSegFlip = mitk::Image::New(); + tibiaLeftSegFlip = tibiaLeftSeg->Clone(); + + MITK_INFO << "Get Transformation"; + if (m_Controls.mirroringCheckBox->isChecked()) + { + auto flipMatrix = vtkSmartPointer::New(); + flipMatrix->Identity(); + flipMatrix->SetElement(0, 0, -1); + auto flipTransform = vtkSmartPointer::New(); + flipTransform->SetMatrix(flipMatrix); + flipTransform->Concatenate(tibiaLeftSegFlip->GetGeometry()->GetVtkMatrix()); + flipTransform->Update(); + tibiaLeftSegFlip->GetGeometry()->SetIndexToWorldTransformByVtkMatrixWithoutChangingSpacing(flipTransform->GetMatrix()); + } + else + { + auto flipMatrix = vtkSmartPointer::New(); + flipMatrix->Identity(); + flipMatrix->SetElement(0, 0, 1); + auto flipTransform = vtkSmartPointer::New(); + flipTransform->SetMatrix(flipMatrix); + flipTransform->Concatenate(tibiaLeftSegFlip->GetGeometry()->GetVtkMatrix()); + flipTransform->Update(); + tibiaLeftSegFlip->GetGeometry()->SetIndexToWorldTransformByVtkMatrixWithoutChangingSpacing(flipTransform->GetMatrix()); + } + trafo->Invert(); + trafo->Modified(); + + MITK_INFO << "Cast Images to ITK"; + //cast To Itk Image + const unsigned int Dimension = 3; + typedef unsigned char PixelTypeChar; + typedef unsigned short PixelTypeUShort; + typedef double ScalarType; + typedef itk::Image< PixelTypeChar, Dimension > ImageType; + typedef itk::Image< PixelTypeUShort, Dimension > ImageTypeUShort; + + ImageType::Pointer tibiaLeftSegITK = ImageType::New(); + mitk::CastToItkImage(tibiaLeftSegFlip, tibiaLeftSegITK); + + ImageTypeUShort::Pointer tibiaRightSegITK = ImageTypeUShort::New(); + mitk::CastToItkImage(tibiaRightSeg, tibiaRightSegITK); + + ImageTypeUShort::Pointer movingImageITK = ImageTypeUShort::New(); + mitk::Image::Pointer leftImg = dynamic_cast(getGeometryNodeFromTarget(moving)->GetData()); + mitk::CastToItkImage(leftImg, movingImageITK); + + ImageTypeUShort::Pointer fixedImageITK = ImageTypeUShort::New(); + mitk::Image::Pointer rightImg = dynamic_cast(getGeometryNodeFromTarget(target)->GetData()); + mitk::CastToItkImage(rightImg, fixedImageITK); + + //get Trafo + + MITK_INFO << "Use affine transform"; + //Affine Transform + typedef itk::AffineTransform< ScalarType, Dimension > TransformType; + TransformType::Pointer transform = TransformType::New(); + typedef TransformType::MatrixType MatrixType; + + MatrixType matrix; + double offset[3]; + offset[0] = trafo->GetElement(0, 3); + offset[1] = trafo->GetElement(1, 3); + offset[2] = trafo->GetElement(2, 3); + transform->SetOffset(offset); + MITK_INFO << offset[0] << " " << offset[1] << " " << offset[2]; + for (unsigned int i = 0; i < Dimension; i++) + for (unsigned int j = 0; j < Dimension; j++) + { + matrix[i][j] = trafo->GetElement(i, j); + MITK_INFO << matrix[i][j]; + } + transform->SetMatrix(matrix); + transform->Modified(); + MITK_INFO << "resampling"; + typedef itk::BSplineInterpolateImageFunction< ImageTypeUShort, double > BSplineInterpolatorType; + BSplineInterpolatorType::Pointer bSpline_interpolator = BSplineInterpolatorType::New(); + typedef itk::ResampleImageFilter ResampleFilterType; + typedef itk::ResampleImageFilter ResampleFilterTypeUShort; + + ResampleFilterType::Pointer resamplerTibia = ResampleFilterType::New(); + resamplerTibia->SetInput(tibiaLeftSegITK); + resamplerTibia->SetTransform(transform); + resamplerTibia->SetSize(fixedImageITK->GetLargestPossibleRegion().GetSize()); + resamplerTibia->SetOutputOrigin(fixedImageITK->GetOrigin()); + resamplerTibia->SetOutputSpacing(fixedImageITK->GetSpacing()); + resamplerTibia->SetOutputDirection(fixedImageITK->GetDirection()); + resamplerTibia->SetDefaultPixelValue(0); + resamplerTibia->Update(); + mitk::Image::Pointer outputTibiaMITK; + ImageType::Pointer movingTibiaR = resamplerTibia->GetOutput(); + + MITK_INFO << "Cast To MITK Images"; + //cast To mitk images + mitk::CastToMitkImage(resamplerTibia->GetOutput(), outputTibiaMITK); + + mitk::DataNode::Pointer outSeg = mitk::DataNode::New(); + outSeg->SetData(outputTibiaMITK); + QString name = QString::fromStdString(moving->GetObjectName()).remove("_Surface"); + outSeg->SetName(name.toStdString() + "_Registered"); + + //this->GetDataStorage()->Add(outImg); TODO + this->GetDataStorage()->Add(outSeg); + + return outputTibiaMITK; +} + bool QmitkSurfaceRegistration::loadPlanePositions() { // MITK_INFO << m_Controls.imageSelectorComboBox->currentIndex(); if (m_Controls.imageSelectorComboBox->currentIndex() < 0) { return false; } 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.imageSelectorComboBox->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* QmitkSurfaceRegistration::getPlanePositionManagerService() { ctkPluginContext* context = mitk::org_mitk_gui_qt_surfaceregistration_Activator::GetContext(); ctkServiceReference ppmRef = context->getServiceReference(); mitk::PlanePositionManagerService* service = nullptr; service = context->getService(ppmRef); context->ungetService(ppmRef); return service; } void QmitkSurfaceRegistration::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()); } } } void QmitkSurfaceRegistration::iteratePlanePositionImages(Plane plane) { - //mitk::ShapeComparisonUtil *shapeComparerUtil = new mitk::ShapeComparisonUtil(m_registeredSurface, m_targetSurface); - auto datastorage = this->GetDataStorage(); - mitk::Image::Pointer registeredImg = dynamic_cast(datastorage->GetNamedNode(m_movingSurface->GetObjectName() + "_Registered")->GetData()); - registeredImg->SetObjectName(m_movingSurface->GetObjectName() + "_Registered"); - mitk::Image::Pointer targetImg = dynamic_cast(datastorage->GetNamedNode(m_targetSurface->GetObjectName() + "_Target")->GetData()); //moving? - targetImg->SetObjectName(m_targetSurface->GetObjectName() + "_Target"); + QString regImgName = QString::fromStdString(m_targetSurface->GetObjectName()).remove("Surface"); + MITK_INFO << "RegImgName: " << regImgName << "_Registered"; + mitk::Image::Pointer registeredImg = dynamic_cast(datastorage->GetNamedNode(regImgName.toStdString() + "_Registered")->GetData()); + + QString tarImgName = QString::fromStdString(m_movingSurface->GetObjectName()).remove("Surface"); + MITK_INFO << "TarImgName: " << tarImgName; + mitk::Image::Pointer targetImg = dynamic_cast(datastorage->GetNamedNode(tarImgName.toStdString())->GetData()); + + mitk::DataNode::Pointer geometryNode = getGeometryNodeFromTarget(m_movingSurface); + m_Controls.imageSelectorComboBox->SetSelectedNode(geometryNode); + testloadPosition(); + + //global Results + std::map labelOverlapResults = m_ShapeComparisonManager->calculateLabelOverlapMetrics(registeredImg, targetImg); std::vector startToStop = { 0,0 }; std::vector maxDistanceMoving = calculateMaxDistanceFromStandardPlane(plane, m_movingSurface);// TODO registered may be different in size due to ICP std::vector maxDistanceTarget = calculateMaxDistanceFromStandardPlane(plane, m_targetSurface); + double spacing = std::abs(registeredImg->GetGeometry()->GetSpacing()[0]); MITK_INFO << "Spacing Img: " << spacing; startToStop[0] = std::ceil(std::max(maxDistanceMoving[0], maxDistanceTarget[0])); startToStop[1] = std::ceil(std::max(maxDistanceMoving[1], maxDistanceTarget[1])); std::map currentSliceResults; int margin = 5; int stopper = int(startToStop[1] / spacing) + margin; int start = int(startToStop[0] / spacing) - margin; m_ShapeComparisonManager->resetSliceCounter("axial", start); MITK_INFO << "start: " << start; MITK_INFO << "stopper: " << stopper; for (int i = start; i < stopper; ++i) { MITK_INFO << "Current plane number: " << i; //mitk::PlaneGeometry::Pointer planeGeo = translatePlane(-i, plane)->Clone(); mitk::PlaneGeometry::Pointer sliceGeometry = translatePlane(-i, plane)->Clone(); sliceGeometry->ChangeImageGeometryConsideringOriginOffset(true); sliceGeometry->SetImageGeometry(true); currentSliceResults = m_ShapeComparisonManager->calculateLabelOverlapMetricsSlices(registeredImg, targetImg, sliceGeometry); } MITK_INFO << "finished"; m_Renderer->ForceImmediateUpdate(); } void QmitkSurfaceRegistration::iteratePlanePositionSurfaces(mitk::Surface::Pointer first, mitk::Surface::Pointer second, Plane plane) { auto datastorage = this->GetDataStorage(); std::vector startToStop = { 0,0 }; std::vector maxDistanceMoving = calculateMaxDistanceFromStandardPlane(plane, first);// TODO registered may be different in size due to ICP std::vector maxDistanceTarget = calculateMaxDistanceFromStandardPlane(plane, second); mitk::Image::Pointer geometryNode = dynamic_cast(getGeometryNodeFromTarget(second)->GetData()); double spacing = geometryNode->GetGeometry()->GetSpacing()[0]; MITK_INFO << "Spacing Surf: " << spacing; int margin = 5; startToStop[0] = std::ceil(std::max(maxDistanceMoving[0], maxDistanceTarget[0])); startToStop[1] = std::ceil(std::max(maxDistanceMoving[1], maxDistanceTarget[1])); int stopper = int(startToStop[1] / spacing) + margin; std::map currentSliceResults; int start = int(startToStop[0] / spacing) - margin; MITK_INFO << "start: " << start; MITK_INFO << "stopper: " << stopper; switch (plane) { case axial: m_ShapeComparisonManager->resetSliceCounter("axial", start); break; case coronal: m_ShapeComparisonManager->resetSliceCounter("coronal", start); break; case saggital: m_ShapeComparisonManager->resetSliceCounter("sagittal", start); break; default: break; } for (int i = start; i < stopper; ++i) { MITK_INFO << "Current plane number: " << i; mitk::PlaneGeometry::Pointer planeGeo = translatePlane(-i, plane)->Clone(); planeGeo->ChangeImageGeometryConsideringOriginOffset(true); planeGeo->SetImageGeometry(true); currentSliceResults = m_ShapeComparisonManager->calculateDistanceMetricsSlices(first, second, planeGeo); } MITK_INFO << "finished"; } std::vector QmitkSurfaceRegistration::calculateMaxDistanceFromStandardPlane(Plane plane, mitk::Surface::Pointer surface) { std::vector maxDistances = { 0 , 0 }; //get the current plane position testloadPosition(); mitk::PlaneGeometry::Pointer myPlaneGeo; switch (plane) { case QmitkSurfaceRegistration::axial: myPlaneGeo = translatePlane(0, axial); break; case QmitkSurfaceRegistration::coronal: myPlaneGeo = translatePlane(0, coronal); break; case QmitkSurfaceRegistration::saggital: myPlaneGeo = translatePlane(0, saggital); break; default: break; } // for all points from polydata // project it on axialplane depending on normal auto polyData = surface->GetVtkPolyData(); for (int i = 0; i < polyData->GetNumberOfPoints(); ++i) { double point[3]; polyData->GetPoint(i, point); //estimate maximal length mitk::Point3D projectedPoint = myPlaneGeo->ProjectPointOntoPlane(point); mitk::Line3D line; line.SetPoint1(point); line.SetPoint2(projectedPoint); double angle = myPlaneGeo->Angle(line) / (M_PI/180); //calculate distance between projected and unprojected point double distance = std::sqrt((point[0] - projectedPoint[0])*(point[0] - projectedPoint[0]) + (point[1] - projectedPoint[1])*(point[1] - projectedPoint[1]) + (point[2] - projectedPoint[2])*(point[2] - projectedPoint[2])); if (angle < 0) { distance = distance * (-1); } if (QString(surface->GetObjectName().c_str()).contains(QString("Fibula"), Qt::CaseSensitive) && plane != axial) { //calc min max distance cor sag if (distance < maxDistances[0]) { maxDistances[0] = distance; /*if (maxDistances[1] == 0) maxDistances[1] = maxDistances[0];*/ } if (distance > maxDistances[1]) { maxDistances[1] = distance; } } - else if (QString(surface->GetObjectName().c_str()).contains(QString("Talus"), Qt::CaseSensitive) && plane == axial) + else if (QString(surface->GetObjectName().c_str()).contains(QString("Talus"), Qt::CaseSensitive) && plane == axial) { - if (std::abs(distance) > maxDistances[0]) + if (distance < maxDistances[0]) { maxDistances[0] = distance; } - if (std::abs(distance) < maxDistances[1]) + if (distance > maxDistances[1]) { maxDistances[1] = distance; } } - else + else //Tibia { if (angle < 0 && distance < maxDistances[0]) { maxDistances[0] = distance; } if (angle > 0 && distance > maxDistances[1]) { maxDistances[1] = distance; } } } return maxDistances; } //TODO calculateSurfaceDistanceMetricsSlices mitk::PlaneGeometry::Pointer QmitkSurfaceRegistration::translatePlane(int id, Plane plane) { mitk::DataNode::Pointer dataNode = m_Controls.imageSelectorComboBox->GetSelectedNode(); std::stringstream multiWidgetStream; multiWidgetStream << "stdmulti.widget"; switch (plane) { case QmitkSurfaceRegistration::axial: multiWidgetStream << 1; break; case QmitkSurfaceRegistration::coronal: multiWidgetStream << 2; break; case QmitkSurfaceRegistration::saggital: multiWidgetStream << 3; break; default: break; } std::string multiWidgetString = multiWidgetStream.str(); mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); mitk::PlaneGeometry::ConstPointer 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); newPlaneGeo->Translate(normal * id); //MITK_INFO << "Center der neuen Plane: " << newPlaneGeo->GetCenter(); renderer->RequestUpdate(); m_Renderer = renderer; m_Renderer->RequestUpdate(); mitk::DataNode::Pointer imageNode(m_Controls.imageSelectorComboBox->GetSelectedNode()); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); return newPlaneGeo; } +//TODO mitk::Image::Pointer QmitkSurfaceRegistration::ConvertSurfaceToImage(mitk::Image::Pointer image, mitk::Surface::Pointer surface) { mitk::ProgressBar::GetInstance()->AddStepsToDo(1); mitk::ProgressBar::GetInstance()->Progress(); mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New(); surfaceToImageFilter->MakeOutputBinaryOn(); surfaceToImageFilter->SetInput(surface); surfaceToImageFilter->SetImage(image); try { surfaceToImageFilter->Update(); } catch (itk::ExceptionObject& excpt) { MITK_ERROR << excpt.GetDescription(); return nullptr; } mitk::ProgressBar::GetInstance()->Progress(); mitk::Image::Pointer resultImage = surfaceToImageFilter->GetOutput(); return resultImage; } void QmitkSurfaceRegistration::testloadPosition() { //MITK_INFO << "testload Position"; mitk::DataNode::Pointer selectedNode = m_Controls.imageSelectorComboBox->GetSelectedNode(); mitk::DataNode::Pointer leftOrigNode = nullptr; mitk::DataNode::Pointer rightOrigNode = nullptr; if (QString(selectedNode->GetName().c_str()).contains(QString("L"), Qt::CaseSensitive)) { GetAxisPositions(selectedNode); leftOrigNode = selectedNode.GetPointer(); } else if (QString(selectedNode->GetName().c_str()).contains(QString("R"), Qt::CaseSensitive)) { GetAxisPositions(selectedNode); rightOrigNode = selectedNode.GetPointer(); } mitk::RenderingManager::GetInstance()->InitializeViews(); } diff --git a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h index 94e1f59389..7885f2a6b0 100644 --- a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.h @@ -1,201 +1,210 @@ /*========================================================================= 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 QmitkSurfaceRegistration_h #define QmitkSurfaceRegistration_h #include #ifdef WIN32 #pragma warning( disable : 4250 ) #endif #include "QVTKWidget.h" #include "QmitkRegisterClasses.h" #include #include #include #include "ui_SurfaceRegistrationControls.h" #include "usServiceRegistration.h" #include "mitkAnnotation.h" #include "mitkColorBarAnnotation.h" #include "mitkDataStorage.h" #include #include #include #include #include #include /*! @brief QmitkSurfaceRegistrationView \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 QmitkSurfaceRegistration : 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) */ QmitkSurfaceRegistration(QObject *parent = 0); virtual ~QmitkSurfaceRegistration(); 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: /*! * @brief executes registration of moving and target surface, * then calculates the closest distances and displays them through a lookuptable. * TODO comparison */ void doRegisterAndCompare(); /*! * @brief Iterates through all files in the data storage and executes for all pairs of tibia, fibula and talus */ void doRegisterAndCompareAll(); + void doCompare(); void OnSelectedMovingSurfaceChanged(const mitk::DataNode *); void OnSelectedTargetSurfaceChanged(const mitk::DataNode *); void OnSelectedImageChanged(const mitk::DataNode *); protected: private: /*! * The parent QWidget */ QWidget* m_ParentWidget; mitk::BaseRenderer *m_Renderer; /*! * @brief A pointer to the node of the moving surface. */ mitk::Surface::Pointer m_movingSurface; /*! * @brief A pointer to the node of the target surface. */ mitk::Surface::Pointer m_targetSurface; mitk::Surface::Pointer m_registeredSurface; mitk::SurfaceRegistrationManager *m_SurfaceRegistrationManager; mitk::ShapeComparisonManager *m_ShapeComparisonManager; Ui::SurfaceRegistrationControls m_Controls; mitk::ColorBarAnnotation::Pointer m_colorBarAnnotation; QStringList m_Directories; - QString m_mainDirectory = "D:/ShapeComparison/TestCase/"; + QString m_mainDirectory = "D:/ShapeComparison/Rechtsmedizin/"; //automatization void initializeDirectoryList(); void automatizedEvaluation(); void compareAnklePath(QString pathA, QString pathB); void performTwoSidedComparison(mitk::Surface::Pointer left, mitk::Surface::Pointer right, QString resultName); - void performTwoSidedLabelOverlapComparison(mitk::Surface::Pointer left, mitk::Surface::Pointer right); + void performLabelOverlapComparison(mitk::Surface::Pointer left, mitk::Surface::Pointer right, vtkSmartPointer trafo); mitk::DataNode::Pointer getGeometryNodeFromTarget(mitk::Surface::Pointer target); //testing void initializeWithSceneFile(); 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); + /*! + @brief Uses the transformation matrix to transform the moving surface to align with the target surface + * @param int id Id of the markerID corresponding to the rendering window + * @param const DataNode::Pointer node + */ + mitk::Image::Pointer transformMovingSegm(mitk::Surface::Pointer moving, mitk::Surface::Pointer target, vtkSmartPointer trafo); + + 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 iteratePlanePositionImages(Plane plane); void iteratePlanePositionSurfaces(mitk::Surface::Pointer first, mitk::Surface::Pointer second, Plane plane); std::vector calculateMaxDistanceFromStandardPlane(Plane plane, mitk::Surface::Pointer surface); // double calculateASSD(double meanA, double meanB); /*! * @brief translates the plane in direction of its normal by the length of the id */ mitk::PlaneGeometry::Pointer translatePlane(int id, Plane plane); mitk::Image::Pointer ConvertSurfaceToImage(mitk::Image::Pointer image, mitk::Surface::Pointer surface); void showLookUpTable(vtkSmartPointer lut); mitk::Surface::Pointer fillHoles(mitk::Surface::Pointer surface); }; #endif // QmitkSurfaceRegistration_h \ No newline at end of file