diff --git a/Modules/SurfaceRegistration/files.cmake b/Modules/SurfaceRegistration/files.cmake index e5c7436b9b..2a5c0e1d88 100644 --- a/Modules/SurfaceRegistration/files.cmake +++ b/Modules/SurfaceRegistration/files.cmake @@ -1,11 +1,11 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES - #mitkShapeComparisonManager.cpp + mitkShapeComparisonManager.cpp ) set(RESOURCE_FILES Interactions/Paint.xml Interactions/PaintConfig.xml ) diff --git a/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h b/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h index 3a72b9e7fe..d532a4eaf2 100644 --- a/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h +++ b/Modules/SurfaceRegistration/include/MitkShapeComparisonManager.h @@ -1,60 +1,49 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MitkShapeComparisonManager_h #define MitkShapeComparisonManager_h #include "mitkSurface.h" #include #include "mitkDataNode.h" #include -// The following header file is generated by CMake and thus it's located in -// the build directory. It provides an export macro for classes and functions -// that you want to be part of the public interface of your module. + #include namespace mitk { - // While you are free to derive directly from ITK filter base classes, - // MITK filter base classes provide typed accessor methods for the inputs - // and outputs, which will save you and your clients lots of manual casting. - class MITKSURFACEREGISTRATION_EXPORT ShapeComparisonManager final : public mitk::SurfaceToSurfaceFilter + + class MITKSURFACEREGISTRATION_EXPORT ShapeComparisonManager { public: - // All classes that derive from an ITK-based MITK class need at least the - // following two macros. Make sure you don't declare the constructor public - // to force clients of your class to follow the ITK convention for - // instantiating classes via the static New() method. - mitkClassMacro(ShapeComparisonManager, mitk::SurfaceToSurfaceFilter) - itkFactorylessNewMacro(Self) - - /* itkSetMacro(Offset, int) - itkGetMacro(Offset, int)*/ + ShapeComparisonManager(); ~ShapeComparisonManager(); + void setMovingSurface(mitk::Surface::Pointer moving); + void setTargetSurface(mitk::Surface::Pointer target); + private: - void GenerateData() override; - const mitk::Surface *m_MovingSurface; - const mitk::Surface *m_TargetSurface; - // mitk::Surface::Pointer + mitk::Surface::Pointer m_MovingSurface; + mitk::Surface::Pointer m_TargetSurface; }; } #endif diff --git a/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.cpp b/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.cpp new file mode 100644 index 0000000000..26294a2fd4 --- /dev/null +++ b/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.cpp @@ -0,0 +1,35 @@ +/*=================================================================== + +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 "MitkShortestDistanceCalculator.h" + + +MitkShortestDistanceCalculator::MitkShortestDistanceCalculator(const mitk::Surface *moving, const mitk::Surface *target) +{ + m_PointsMoving->DeepCopy(moving->GetVtkPolyData()->GetPoints()); + m_PointsTarget->DeepCopy(target->GetVtkPolyData()->GetPoints()); +} + + +MitkShortestDistanceCalculator::~MitkShortestDistanceCalculator() +{ + m_PointsMoving = nullptr; + m_PointsTarget = nullptr; +} + +void MitkShortestDistanceCalculator::calculateShortestDistance() +{ + MITK_INFO << "calculate shortest distance ..."; +} \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.h b/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.h new file mode 100644 index 0000000000..b4319c4e72 --- /dev/null +++ b/Modules/SurfaceRegistration/src/DataManagement/MitkShortestDistanceCalculator.h @@ -0,0 +1,37 @@ +/*=================================================================== + +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 MitkShortestDistanceCalculator_h +#define MitkShortestDistanceCalculator_h + +#include +#include + +class MitkShortestDistanceCalculator +{ +public: + MitkShortestDistanceCalculator(const mitk::Surface *moving, const mitk::Surface *target); + ~MitkShortestDistanceCalculator(); + + void calculateShortestDistance(); + +private: + vtkPoints *m_PointsMoving; + vtkPoints *m_PointsTarget; + + +}; +#endif \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/DataManagement/SurfaceRegistrationICP.cpp b/Modules/SurfaceRegistration/src/DataManagement/SurfaceRegistrationICP.cpp new file mode 100644 index 0000000000..e7df59f35c --- /dev/null +++ b/Modules/SurfaceRegistration/src/DataManagement/SurfaceRegistrationICP.cpp @@ -0,0 +1,16 @@ +#include "SurfaceRegistrationICP.h" + + +mitk::SurfaceRegistrationICP::SurfaceRegistrationICP() +{ +} + + +mitk::SurfaceRegistrationICP::~SurfaceRegistrationICP() +{ +} + +vtkSmartPointer SurfaceRegistrationICPCalculateICP(mitk::Surface &moving, mitk::Surface &target){ + vtkSmartPointer registeredData; + return registeredData; +} \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/DataManagement/SurfaceRegistrationICP.h b/Modules/SurfaceRegistration/src/DataManagement/SurfaceRegistrationICP.h new file mode 100644 index 0000000000..88af26be45 --- /dev/null +++ b/Modules/SurfaceRegistration/src/DataManagement/SurfaceRegistrationICP.h @@ -0,0 +1,36 @@ +/*=================================================================== + +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 + +namespace mitk{ + +#ifndef MitkSurfaceRegistrationICP_h +#define MitkSurfaceRegistrationICP_h +class SurfaceRegistrationICP +{ +public: + SurfaceRegistrationICP(); + ~SurfaceRegistrationICP(); + + vtkSmartPointer CalculateICP(mitk::Surface &moving, mitk::Surface &target); +private: + +}; + +#endif +}; \ No newline at end of file diff --git a/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp b/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp index 8496aa7304..e018fc4cce 100644 --- a/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp +++ b/Modules/SurfaceRegistration/src/mitkShapeComparisonManager.cpp @@ -1,80 +1,41 @@ /*=================================================================== 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 - -// See definition of AwesomeImageFilter::GenerateData() further below for -// a rationale behind this function template. -//template -//static void AddOffset(const itk::Image* inputImage, int offset, mitk::Image::Pointer outputImage) -//{ -// typedef itk::Image ImageType; -// typedef itk::ShiftScaleImageFilter FilterType; -// -// auto filter = FilterType::New(); -// filter->SetInput(inputImage); -// filter->SetShift(offset); -// -// filter->Update(); -// -// // This is the tricky part that is done wrong very often. As the image data -// // of ITK images and MITK images are binary compatible, we don't need to -// // cast or copy the ITK output image. Instead, we just want to reference -// // the image data and tell ITK that we took the ownership. -// mitk::GrabItkImageMemory(filter->GetOutput(), outputImage); -//} mitk::ShapeComparisonManager::ShapeComparisonManager() { - this->SetNumberOfRequiredInputs(2); - this->SetNumberOfRequiredOutputs(1); - //TODO set number of outputs + } mitk::ShapeComparisonManager::~ShapeComparisonManager() { } - -void mitk::ShapeComparisonManager::GenerateData() +void mitk::ShapeComparisonManager::setMovingSurface(mitk::Surface::Pointer moving) { - MITK_INFO << "shapecomparison"; - m_MovingSurface = this->GetInput(0); - m_TargetSurface = this->GetInput(1); - - auto shortestDistanceCalc = MitkShortestDistanceCalculator(m_MovingSurface, m_TargetSurface); - //TODO Calc and output - - //auto filter = FilterType::New(); - //filter->SetInput(inputImage); - //filter->SetShift(offset); + this->m_MovingSurface = moving; +} - //filter->Update(); +void mitk::ShapeComparisonManager::setTargetSurface(mitk::Surface::Pointer target) +{ + this->m_TargetSurface = target; +} - //// This is the tricky part that is done wrong very often. As the image data - //// of ITK images and MITK images are binary compatible, we don't need to - //// cast or copy the ITK output image. Instead, we just want to reference - //// the image data and tell ITK that we took the ownership. - //mitk::GrabItkImageMemory(filter->GetOutput(), outputImage); -} 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 86a886a7f9..32d0e647a0 100644 --- a/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp +++ b/Plugins/org.mitk.gui.qt.surfaceregistration/src/internal/QmitkSurfaceRegistration.cpp @@ -1,241 +1,240 @@ /*========================================================================= 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 // Includes for image casting between ITK and MITK: added after using Plugin Generator #include // added for surface dynamic cast #include #include #include #include #include #include #include #include #include #include #include const std::string QmitkSurfaceRegistration::VIEW_ID = "org.mitk.views.qmitksurfaceregistration"; QmitkSurfaceRegistration::QmitkSurfaceRegistration(QObject *parent) : m_ParentWidget(0), m_movingSurfaceNode(nullptr), m_targetSurfaceNode(nullptr) { } QmitkSurfaceRegistration::~QmitkSurfaceRegistration() { // delete pointer objects m_movingSurfaceNode = nullptr; m_targetSurfaceNode = nullptr; } // void QmitkSurfaceRegistration::SetFocus(){ m_Controls.groupBoxMoving->setFocus(); } void QmitkSurfaceRegistration::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); connect(m_Controls.pushButtonExecute, SIGNAL(clicked()), this, SLOT(doExecute())); mitk::RenderingManager::GetInstance()->SetDataStorage(this->GetDataStorageReference()->GetDataStorage()); mitk::RenderingManager::GetInstance()->InitializeViews(); m_ParentWidget = parent; } void QmitkSurfaceRegistration::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList &nodes) { MITK_INFO << "On Selection Changed"; bool rotationEnabled = false; if (nodes.empty()) { MITK_INFO << "Nothing selected yet"; m_Controls.labelSelectMovingSurface->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); m_Controls.labelSelectTargetSurface->setStyleSheet(" QLabel { color: rgb(255, 0, 0) }"); m_Controls.labelMovingSurfaceName->setText(QString::fromStdString("No moving surface selected")); m_Controls.labelTargetSurfaceName->setText(QString::fromStdString("No target surface selected")); m_Controls.groupBoxMoving->setEnabled(true); m_Controls.groupBoxMappedData->setEnabled(false); if (m_useTestConfig) { m_Controls.pushButtonExecute->setEnabled(true); } else{ m_Controls.pushButtonExecute->setEnabled(false); } m_Controls.radioButtonMirroring->setEnabled(false); return; } else { if (nodes.size() == 1) { if (nodes[0].IsNotNull() && dynamic_cast(nodes[0]->GetData())) { MITK_INFO << "There is exactly one image selected"; m_movingSurfaceNode = nodes[0]; m_Controls.labelSelectMovingSurface->setText("Selected moving surface:"); m_Controls.labelSelectMovingSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); m_Controls.labelMovingSurfaceName->setText( QString::fromStdString("File name: " + m_movingSurfaceNode->GetName())); m_Controls.radioButtonMirroring->setEnabled(true); m_Controls.groupBoxTarget->setEnabled(true); m_Controls.groupBoxMappedData->setEnabled(true); m_Controls.groupBoxTarget->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else { QMessageBox::information(nullptr, "Warning", "Are you sure? - I dont think this is a Surface! Try again!"); } } else if (nodes.size() == 2) { if (nodes[1].IsNotNull() && dynamic_cast(nodes[1]->GetData())) { MITK_INFO << "There are two images selected"; m_targetSurfaceNode = nodes[1]; m_Controls.labelSelectTargetSurface->setText("Selected target surface:"); m_Controls.labelSelectTargetSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); m_Controls.labelTargetSurfaceName->setText( QString::fromStdString("File name: " + m_targetSurfaceNode->GetName())); m_Controls.textMappedDataName->setEnabled(true); m_Controls.pushButtonExecute->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_useTestConfig = false; } else { QMessageBox::information(nullptr, "Warning", "Are you sure? - I dont think this is a Surface!"); } } else { QMessageBox::information(nullptr, "Warning", "You do know that it only works with two surfaces, right? If you continue to click execute, this might crash one day!"); //wie kann ich die Auswahl zurueck setzen? } } } void QmitkSurfaceRegistration::doExecute() { if (m_useTestConfig ) { mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); mitk::IOUtil::Load("//ad/fs/E130-Projekte/BGLU/Fibula/Python/DataGAN/Registered/Surface/Tibia/tibia01_q0.stl", *ds); mitk::IOUtil::Load("//ad/fs/E130-Projekte/BGLU/Fibula/Python/DataGAN/Registered/Surface/Tibia/tibia02_q0.stl", *ds); m_movingSurfaceNode = ds->GetAll()->at(0); m_targetSurfaceNode = ds->GetAll()->at(1); this->GetDataStorageReference()->GetDataStorage()->Add(mitk::DataNode::Pointer(ds->GetAll()->at(0))); this->GetDataStorageReference()->GetDataStorage()->Add(mitk::DataNode::Pointer(ds->GetAll()->at(1))); this->GetDataStorageReference()->GetDataStorage()->Modified(); mitk::RenderingManager::GetInstance()->SetDataStorage(this->GetDataStorageReference()->GetDataStorage()); mitk::RenderingManager::GetInstance()->InitializeViews(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_Controls.pushButtonExecute->setEnabled(true); m_Controls.labelMovingSurfaceName->setText("tibia01_q0"); m_Controls.labelTargetSurfaceName->setText("tibia02_q0"); m_Controls.labelSelectMovingSurface->setText("Selected moving surface:"); m_Controls.labelSelectMovingSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); m_Controls.labelSelectTargetSurface->setText("Selected target surface:"); m_Controls.labelSelectTargetSurface->setStyleSheet(" QLabel { color: rgb(0, 0, 0) }"); } MITK_INFO << "pushButtonExecute clicked"; /*mitk::Surface *movingSurface = dynamic_cast(m_movingSurfaceNode); mitk::Surface *targetSurface = dynamic_cast(m_targetSurfaceNode);*/ /*auto manager = MitkShapeComparisonManager::New(); manager->SetInput(0, dynamic_cast(m_movingSurfaceNode->GetData())); manager->SetInput(1, dynamic_cast(m_targetSurfaceNode->GetData()));*/ performICPRegistration(); } void QmitkSurfaceRegistration::performICPRegistration() { vtkSmartPointer icp = vtkSmartPointer::New(); icp->SetCheckMeanDistance(1); - m_movingSurfaceNode.GetPointer(); mitk::Surface::Pointer movingSurface = dynamic_cast (m_movingSurfaceNode->GetData()); mitk::Surface::Pointer targetSurface = dynamic_cast (m_targetSurfaceNode->GetData()); icp->SetSource(movingSurface->GetVtkPolyData()); icp->SetTarget(targetSurface->GetVtkPolyData()); icp->SetMaximumNumberOfIterations(1000); - icp->SetMaximumMeanDistance(0.1); + icp->SetMaximumMeanDistance(0.01); icp->SetMeanDistanceModeToRMS(); icp->StartByMatchingCentroidsOn(); icp->SetMaximumNumberOfLandmarks(100000); icp->Modified(); vtkSmartPointer transform = vtkSmartPointer::New(); transform = icp->GetLandmarkTransform(); - //transform->Inverse(); + vtkSmartPointer m = icp->GetMatrix(); MITK_INFO << "The resulting matrix is: " << *m; vtkSmartPointer icpTransformFilter = - vtkSmartPointer::New(); + vtkSmartPointer::New(); icpTransformFilter->SetInputData(movingSurface->GetVtkPolyData()); icpTransformFilter->SetTransform(icp); icpTransformFilter->Update(); - // movingSurface = mitk::Surface->DeepCopy(icpTransformFilter->GetOutput()); + MITK_INFO << "The mean distance is: " << icp->GetMeanDistance(); mitk::DataNode::Pointer registerdNodeA = mitk::DataNode::New(); //registerdNodeA->SetData(icpTransformFilter->GetOutput()); movingSurface->SetVtkPolyData(icpTransformFilter->GetOutput()); movingSurface->Modified(); registerdNodeA->SetData(movingSurface); this->GetDataStorageReference()->GetDataStorage()->Add(registerdNodeA, m_movingSurfaceNode); mitk::DataNode::Pointer registerdNodeB = mitk::DataNode::New(); registerdNodeB->SetData(targetSurface); this->GetDataStorageReference()->GetDataStorage()->Add(registerdNodeB, m_targetSurfaceNode); registerdNodeA->SetName("Moving"); registerdNodeB->SetName("Target"); this->GetDataStorageReference()->GetDataStorage()->Modified(); mitk::RenderingManager::GetInstance()->InitializeViews(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); MITK_INFO << "registration done"; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); }