diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp index e04072db6c..6caaae4406 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp @@ -1,1119 +1,1119 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //#define MBILOG_ENABLE_DEBUG #include "QmitkQBallReconstructionView.h" // qt includes #include // itk includes #include "itkTimeProbe.h" // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "itkDiffusionQballReconstructionImageFilter.h" #include "itkAnalyticalDiffusionQballReconstructionImageFilter.h" #include "itkDiffusionMultiShellQballReconstructionImageFilter.h" #include "itkVectorContainer.h" #include "itkB0ImageExtractionImageFilter.h" #include #include "mitkQBallImage.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include #include "mitkDiffusionImagingConfigure.h" #include "berryIStructuredSelection.h" #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" #include const std::string QmitkQBallReconstructionView::VIEW_ID = "org.mitk.views.qballreconstruction"; typedef float TTensorPixelType; const int QmitkQBallReconstructionView::nrconvkernels = 252; struct QbrShellSelection { typedef mitk::DiffusionPropertyHelper::GradientDirectionType GradientDirectionType; typedef mitk::DiffusionPropertyHelper::GradientDirectionsContainerType GradientDirectionContainerType; typedef mitk::DiffusionPropertyHelper::BValueMapType BValueMapType; typedef itk::VectorImage< DiffusionPixelType, 3 > ITKDiffusionImageType; QmitkQBallReconstructionView* m_View; mitk::DataNode * m_Node; std::string m_NodeName; std::vector m_CheckBoxes; QLabel * m_Label; mitk::Image * m_Image; QbrShellSelection(QmitkQBallReconstructionView* view, mitk::DataNode * node) : m_View(view), m_Node(node), m_NodeName(node->GetName()) { m_Image = dynamic_cast (node->GetData()); if(!m_Image) { MITK_ERROR << "QmitkQBallReconstructionView::QbrShellSelection : no image selected"; return; } bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_Node->GetData())) ); if( !isDiffusionImage ) { MITK_ERROR << "QmitkQBallReconstructionView::QbrShellSelection : selected image contains no diffusion information"; return; } GenerateCheckboxes(); } void GenerateCheckboxes() { BValueMapType origMap = static_cast(m_Image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); BValueMapType::iterator itStart = origMap.begin(); itStart++; BValueMapType::iterator itEnd = origMap.end(); m_Label = new QLabel(m_NodeName.c_str()); m_Label->setVisible(true); m_View->m_Controls->m_QBallSelectionBox->layout()->addWidget(m_Label); for(BValueMapType::iterator it = itStart ; it!= itEnd; it++) { QCheckBox * box = new QCheckBox(QString::number(it->first)); m_View->m_Controls->m_QBallSelectionBox->layout()->addWidget(box); box->setChecked(true); box->setCheckable(true); // box->setVisible(true); m_CheckBoxes.push_back(box); } } void SetVisible(bool vis) { foreach(QCheckBox * box, m_CheckBoxes) { box->setVisible(vis); } } BValueMapType GetBValueSelctionMap() { BValueMapType inputMap = static_cast(m_Image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); BValueMapType outputMap; unsigned int val = 0; if(inputMap.find(0) == inputMap.end()){ MITK_INFO << "QbrShellSelection: return empty BValueMap from GUI Selection"; return outputMap; }else{ outputMap[val] = inputMap[val]; MITK_INFO << val; } foreach(QCheckBox * box, m_CheckBoxes) { if(box->isChecked()){ val = box->text().toDouble(); outputMap[val] = inputMap[val]; MITK_INFO << val; } } return outputMap; } ~QbrShellSelection() { m_View->m_Controls->m_QBallSelectionBox->layout()->removeWidget(m_Label); delete m_Label; for(std::vector::iterator it = m_CheckBoxes.begin() ; it!= m_CheckBoxes.end(); it++) { m_View->m_Controls->m_QBallSelectionBox->layout()->removeWidget((*it)); delete (*it); } m_CheckBoxes.clear(); } }; using namespace berry; struct QbrSelListener : ISelectionListener { QbrSelListener(QmitkQBallReconstructionView* view) { m_View = view; } void DoSelectionChanged(ISelection::ConstPointer selection) { // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); // do something with the selected items if(m_View->m_CurrentSelection) { bool foundDwiVolume = false; m_View->m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_View->m_Controls->m_InputData->setTitle("Please Select Input Data"); QString selected_images = ""; mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(node->GetData())) ); mitk::Image* diffusionImage = dynamic_cast(node->GetData()); // only look at interesting types if(diffusionImage && isDiffusionImage) { foundDwiVolume = true; selected_images += QString(node->GetName().c_str()); if(i + 1 != m_View->m_CurrentSelection->End()) selected_images += "\n"; set->InsertElement(at++, node); } } } m_View->GenerateShellSelectionUI(set); m_View->m_Controls->m_DiffusionImageLabel->setText(selected_images); m_View->m_Controls->m_ButtonStandard->setEnabled(foundDwiVolume); if (foundDwiVolume) m_View->m_Controls->m_InputData->setTitle("Input Data"); else m_View->m_Controls->m_DiffusionImageLabel->setText("mandatory"); } } void SelectionChanged(const IWorkbenchPart::Pointer& part, - const ISelection::ConstPointer& selection) override + const ISelection::ConstPointer& selection) { // check, if selection comes from datamanager if (part) { QString partname = part->GetPartName(); if(partname == "Data Manager") { // apply selection DoSelectionChanged(selection); } } } QmitkQBallReconstructionView* m_View; }; // --------------- QmitkQBallReconstructionView----------------- // QmitkQBallReconstructionView::QmitkQBallReconstructionView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { } QmitkQBallReconstructionView::~QmitkQBallReconstructionView() { this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener.data()); } void QmitkQBallReconstructionView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkQBallReconstructionViewControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_DiffusionImageLabel->setText("mandatory"); QStringList items; items << "2" << "4" << "6" << "8" << "10" << "12"; m_Controls->m_QBallReconstructionMaxLLevelComboBox->addItems(items); m_Controls->m_QBallReconstructionMaxLLevelComboBox->setCurrentIndex(1); MethodChoosen(m_Controls->m_QBallReconstructionMethodComboBox->currentIndex()); #ifndef DIFFUSION_IMAGING_EXTENDED m_Controls->m_QBallReconstructionMethodComboBox->removeItem(3); #endif AdvancedCheckboxClicked(); } m_SelListener.reset(new QbrSelListener(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener.data()); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); static_cast(m_SelListener.data())->DoSelectionChanged(sel); } void QmitkQBallReconstructionView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkQBallReconstructionView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkQBallReconstructionView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_ButtonStandard), SIGNAL(clicked()), this, SLOT(ReconstructStandard()) ); connect( (QObject*)(m_Controls->m_AdvancedCheckbox), SIGNAL(clicked()), this, SLOT(AdvancedCheckboxClicked()) ); connect( (QObject*)(m_Controls->m_QBallReconstructionMethodComboBox), SIGNAL(currentIndexChanged(int)), this, SLOT(MethodChoosen(int)) ); connect( (QObject*)(m_Controls->m_QBallReconstructionThreasholdEdit), SIGNAL(valueChanged(int)), this, SLOT(PreviewThreshold(int)) ); } } void QmitkQBallReconstructionView::OnSelectionChanged( std::vector ) { } void QmitkQBallReconstructionView::Activated() { QmitkFunctionality::Activated(); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); static_cast(m_SelListener.data())->DoSelectionChanged(sel); } void QmitkQBallReconstructionView::Deactivated() { mitk::DataStorage::SetOfObjects::ConstPointer objects = this->GetDefaultDataStorage()->GetAll(); mitk::DataStorage::SetOfObjects::const_iterator itemiter( objects->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( objects->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DataNode::Pointer node = *itemiter; if (node.IsNull()) continue; // only look at interesting types bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(node->GetData())) ); if( isDiffusionImage ) { if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter)) { node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter); this->GetDefaultDataStorage()->Remove(node); } } itemiter++; } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Deactivated(); } void QmitkQBallReconstructionView::ReconstructStandard() { int index = m_Controls->m_QBallReconstructionMethodComboBox->currentIndex(); #ifndef DIFFUSION_IMAGING_EXTENDED if(index>=3) { index = index + 1; } #endif switch(index) { case 0: { // Numerical Reconstruct(0,0); break; } case 1: { // Standard Reconstruct(1,0); break; } case 2: { // Solid Angle Reconstruct(1,6); break; } case 3: { // Constrained Solid Angle Reconstruct(1,7); break; } case 4: { // ADC Reconstruct(1,4); break; } case 5: { // Raw Signal Reconstruct(1,5); break; } case 6: { // Q-Ball reconstruction Reconstruct(2,0); break; } } } void QmitkQBallReconstructionView::MethodChoosen(int method) { #ifndef DIFFUSION_IMAGING_EXTENDED if(method>=3) { method = method + 1; } #endif m_Controls->m_QBallSelectionBox->setHidden(true); m_Controls->m_OutputCoeffsImage->setHidden(true); if (method==0) m_Controls->m_ShFrame->setVisible(false); else m_Controls->m_ShFrame->setVisible(true); switch(method) { case 0: m_Controls->m_Description->setText("Numerical recon. (Tuch 2004)"); break; case 1: m_Controls->m_Description->setText("Spherical harmonics recon. (Descoteaux 2007)"); m_Controls->m_OutputCoeffsImage->setHidden(false); break; case 2: m_Controls->m_Description->setText("SH recon. with solid angle consideration (Aganj 2009)"); m_Controls->m_OutputCoeffsImage->setHidden(false); break; case 3: m_Controls->m_Description->setText("SH solid angle with non-neg. constraint (Goh 2009)"); break; case 4: m_Controls->m_Description->setText("SH recon. of the plain ADC-profiles"); break; case 5: m_Controls->m_Description->setText("SH recon. of the raw diffusion signal"); break; case 6: m_Controls->m_Description->setText("SH recon. of the multi shell diffusion signal (Aganj 2010)"); m_Controls->m_QBallSelectionBox->setHidden(false); m_Controls->m_OutputCoeffsImage->setHidden(false); break; } } void QmitkQBallReconstructionView::AdvancedCheckboxClicked() { bool check = m_Controls->m_AdvancedCheckbox->isChecked(); m_Controls->m_QBallReconstructionMaxLLevelTextLabel_2->setVisible(check); m_Controls->m_QBallReconstructionMaxLLevelComboBox->setVisible(check); m_Controls->m_QBallReconstructionLambdaTextLabel_2->setVisible(check); m_Controls->m_QBallReconstructionLambdaLineEdit->setVisible(check); m_Controls->m_QBallReconstructionThresholdLabel_2->setVisible(check); m_Controls->m_QBallReconstructionThreasholdEdit->setVisible(check); m_Controls->label_2->setVisible(check); m_Controls->frame_2->setVisible(check); } void QmitkQBallReconstructionView::Reconstruct(int method, int normalization) { if (m_CurrentSelection) { mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; for (IStructuredSelection::iterator i = m_CurrentSelection->Begin(); i != m_CurrentSelection->End(); ++i) { if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(node->GetData())) ); if ( isDiffusionImage ) { set->InsertElement(at++, node); } } } if(method == 0) { NumericalQBallReconstruction(set, normalization); } else { #if BOOST_VERSION / 100000 > 0 #if BOOST_VERSION / 100 % 1000 > 34 if(method == 1) { AnalyticalQBallReconstruction(set, normalization); } if(method == 2) { MultiQBallReconstruction(set); } #else std::cout << "ERROR: Boost 1.35 minimum required" << std::endl; QMessageBox::warning(NULL,"ERROR","Boost 1.35 minimum required"); #endif #else std::cout << "ERROR: Boost 1.35 minimum required" << std::endl; QMessageBox::warning(NULL,"ERROR","Boost 1.35 minimum required"); #endif } } } void QmitkQBallReconstructionView::NumericalQBallReconstruction (mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::Image* vols = static_cast( (*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); // QBALL RECONSTRUCTION clock.Start(); MITK_INFO << "QBall reconstruction "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( "QBall reconstruction for %s", nodename.c_str()).toLatin1()); typedef itk::DiffusionQballReconstructionImageFilter QballReconstructionImageFilterType; ITKDiffusionImageType::Pointer itkVectorImagePointer = ITKDiffusionImageType::New(); mitk::CastToItkImage(vols, itkVectorImagePointer); QballReconstructionImageFilterType::Pointer filter = QballReconstructionImageFilterType::New(); filter->SetGradientImage( static_cast( vols->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(), itkVectorImagePointer ); filter->SetBValue( static_cast(vols->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() ); std::string nodePostfix; switch(normalization) { case 0: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD); nodePostfix = "_Numerical_Qball"; break; } case 1: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO_B_VALUE); nodePostfix = "_Numerical_ZeroBvalueNormalization_Qball"; break; } case 2: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO); nodePostfix = "_NumericalQball_ZeroNormalization_Qball"; break; } case 3: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_NONE); nodePostfix = "_NumericalQball_NoNormalization_Qball"; break; } default: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD); nodePostfix = "_NumericalQball_Qball"; } } filter->Update(); clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s." ; // ODFs TO DATATREE mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, nodename+nodePostfix); mitk::ProgressBar::GetInstance()->Progress(); GetDefaultDataStorage()->Add(node, *itemiter); ++itemiter; } mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return ; } } void QmitkQBallReconstructionView::AnalyticalQBallReconstruction( mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; std::vector lambdas; float minLambda = m_Controls->m_QBallReconstructionLambdaLineEdit->value(); lambdas.push_back(minLambda); int nLambdas = lambdas.size(); QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector* nodes = new std::vector(); while ( itemiter != itemiterend ) // for all items { // QBALL RECONSTRUCTION clock.Start(); MITK_INFO << "QBall reconstruction "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", (*itemiter)->GetName().c_str()).toLatin1()); for(int i=0; im_QBallReconstructionMaxLLevelComboBox->currentIndex()) { case 0: { TemplatedAnalyticalQBallReconstruction<2>(*itemiter, currentLambda, normalization); break; } case 1: { TemplatedAnalyticalQBallReconstruction<4>(*itemiter, currentLambda, normalization); break; } case 2: { TemplatedAnalyticalQBallReconstruction<6>(*itemiter, currentLambda, normalization); break; } case 3: { TemplatedAnalyticalQBallReconstruction<8>(*itemiter, currentLambda, normalization); break; } case 4: { TemplatedAnalyticalQBallReconstruction<10>(*itemiter, currentLambda, normalization); break; } case 5: { TemplatedAnalyticalQBallReconstruction<12>(*itemiter, currentLambda, normalization); break; } } clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s." ; mitk::ProgressBar::GetInstance()->Progress(); itemiter++; } } std::vector::iterator nodeIt; for(nodeIt = nodes->begin(); nodeIt != nodes->end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); m_MultiWidget->RequestUpdate(); mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return; } } template void QmitkQBallReconstructionView::TemplatedAnalyticalQBallReconstruction(mitk::DataNode* dataNodePointer, float lambda, int normalization) { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); mitk::Image* vols = dynamic_cast(dataNodePointer->GetData()); ITKDiffusionImageType::Pointer itkVectorImagePointer = ITKDiffusionImageType::New(); mitk::CastToItkImage(vols, itkVectorImagePointer); filter->SetGradientImage( static_cast( vols->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(), itkVectorImagePointer ); filter->SetBValue( static_cast(vols->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() ); filter->SetLambda(lambda); std::string nodePostfix; switch(normalization) { case 0: { filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); nodePostfix = "_SphericalHarmonics_Qball"; break; } case 1: { filter->SetNormalizationMethod(FilterType::QBAR_B_ZERO_B_VALUE); nodePostfix = "_SphericalHarmonics_1_Qball"; break; } case 2: { filter->SetNormalizationMethod(FilterType::QBAR_B_ZERO); nodePostfix = "_SphericalHarmonics_2_Qball"; break; } case 3: { filter->SetNormalizationMethod(FilterType::QBAR_NONE); nodePostfix = "_SphericalHarmonics_3_Qball"; break; } case 4: { filter->SetNormalizationMethod(FilterType::QBAR_ADC_ONLY); nodePostfix = "_AdcProfile"; break; } case 5: { filter->SetNormalizationMethod(FilterType::QBAR_RAW_SIGNAL); nodePostfix = "_RawSignal"; break; } case 6: { filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); nodePostfix = "_SphericalHarmonics_CSA_Qball"; break; } case 7: { filter->SetNormalizationMethod(FilterType::QBAR_NONNEG_SOLID_ANGLE); nodePostfix = "_SphericalHarmonics_NonNegCSA_Qball"; break; } default: { filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); } } filter->Update(); // ODFs TO DATATREE mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, dataNodePointer->GetName()+nodePostfix); GetDefaultDataStorage()->Add(node, dataNodePointer); if(m_Controls->m_OutputCoeffsImage->isChecked()) { mitk::Image::Pointer coeffsImage = mitk::Image::New(); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); mitk::DataNode::Pointer coeffsNode=mitk::DataNode::New(); coeffsNode->SetData( coeffsImage ); coeffsNode->SetProperty( "name", mitk::StringProperty::New(dataNodePointer->GetName()+"_SH-Coeffs") ); coeffsNode->SetVisibility(false); GetDefaultDataStorage()->Add(coeffsNode, node); } } void QmitkQBallReconstructionView::MultiQBallReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; std::vector lambdas; float minLambda = m_Controls->m_QBallReconstructionLambdaLineEdit->value(); lambdas.push_back(minLambda); int nLambdas = lambdas.size(); QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DataNode* nodePointer = (*itemiter).GetPointer(); std::string nodename; (*itemiter)->GetStringProperty("name",nodename); itemiter++; // QBALL RECONSTRUCTION clock.Start(); MITK_INFO << "QBall reconstruction "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", nodename.c_str()).toLatin1()); for(int i=0; im_QBallReconstructionMaxLLevelComboBox->currentIndex()) { case 0: { TemplatedMultiQBallReconstruction<2>(currentLambda, nodePointer); break; } case 1: { TemplatedMultiQBallReconstruction<4>(currentLambda, nodePointer); break; } case 2: { TemplatedMultiQBallReconstruction<6>(currentLambda, nodePointer); break; } case 3: { TemplatedMultiQBallReconstruction<8>(currentLambda, nodePointer); break; } case 4: { TemplatedMultiQBallReconstruction<10>(currentLambda, nodePointer); break; } case 5: { TemplatedMultiQBallReconstruction<12>(currentLambda, nodePointer); break; } } clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s." ; mitk::ProgressBar::GetInstance()->Progress(); } } m_MultiWidget->RequestUpdate(); mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return ; } } template void QmitkQBallReconstructionView::TemplatedMultiQBallReconstruction(float lambda, mitk::DataNode* dataNodePointer) { typedef itk::DiffusionMultiShellQballReconstructionImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); std::string nodename; dataNodePointer->GetStringProperty("name",nodename); mitk::Image* dwi = dynamic_cast(dataNodePointer->GetData()); BValueMapType currSelectionMap = m_ShellSelectorMap[dataNodePointer]->GetBValueSelctionMap(); if(currSelectionMap.size() != 4 && currSelectionMap.find(0) != currSelectionMap.end()) { QMessageBox::information(0, "Reconstruction not possible:" ,QString("Only three shells in a equidistant configuration is supported. (ImageName: " + QString(nodename.c_str()) + ")")); return; } BValueMapType::reverse_iterator it1 = currSelectionMap.rbegin(); BValueMapType::reverse_iterator it2 = currSelectionMap.rbegin(); ++it2; // Get average distance int avdistance = 0; for(; it2 != currSelectionMap.rend(); ++it1,++it2) avdistance += (int)it1->first - (int)it2->first; avdistance /= currSelectionMap.size()-1; // Check if all shells are using the same averae distance it1 = currSelectionMap.rbegin(); it2 = currSelectionMap.rbegin(); ++it2; for(; it2 != currSelectionMap.rend(); ++it1,++it2) if(avdistance != (int)it1->first - (int)it2->first) { QMessageBox::information(0, "Reconstruction not possible:" ,QString("Selected Shells are not in a equidistant configuration. (ImageName: " + QString(nodename.c_str()) + ")")); return; } ITKDiffusionImageType::Pointer itkVectorImagePointer = ITKDiffusionImageType::New(); mitk::CastToItkImage(dwi, itkVectorImagePointer); filter->SetBValueMap(m_ShellSelectorMap[dataNodePointer]->GetBValueSelctionMap()); filter->SetGradientImage( static_cast( dwi->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(), itkVectorImagePointer, static_cast(dwi->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() ); filter->SetLambda(lambda); filter->Update(); // ODFs TO DATATREE mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, nodename+"_SphericalHarmonics_MultiShell_Qball"); GetDefaultDataStorage()->Add(node, dataNodePointer); if(m_Controls->m_OutputCoeffsImage->isChecked()) { mitk::Image::Pointer coeffsImage = mitk::Image::New(); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); mitk::DataNode::Pointer coeffsNode=mitk::DataNode::New(); coeffsNode->SetData( coeffsImage ); coeffsNode->SetProperty( "name", mitk::StringProperty::New( QString(nodename.c_str()).append("_SH-Coefficients").toStdString()) ); coeffsNode->SetVisibility(false); GetDefaultDataStorage()->Add(coeffsNode, node); } } void QmitkQBallReconstructionView::SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name) { node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 500 ) ); node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) ); node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New()); node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New()); node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2)); node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1)); node->SetProperty( "visible", mitk::BoolProperty::New( true ) ); node->SetProperty( "VisibleOdfs", mitk::BoolProperty::New( false ) ); node->SetProperty ("layer", mitk::IntProperty::New(100)); node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) ); node->SetProperty( "name", mitk::StringProperty::New(name) ); } void QmitkQBallReconstructionView::GenerateShellSelectionUI(mitk::DataStorage::SetOfObjects::Pointer set) { m_DiffusionImages = set; std::map tempMap; const mitk::DataStorage::SetOfObjects::iterator setEnd( set->end() ); mitk::DataStorage::SetOfObjects::iterator NodeIt( set->begin() ); while(NodeIt != setEnd) { if(m_ShellSelectorMap.find( (*NodeIt).GetPointer() ) != m_ShellSelectorMap.end()) { tempMap[(*NodeIt).GetPointer()] = m_ShellSelectorMap[(*NodeIt).GetPointer()]; m_ShellSelectorMap.erase((*NodeIt).GetPointer()); }else { tempMap[(*NodeIt).GetPointer()] = new QbrShellSelection(this, (*NodeIt) ); tempMap[(*NodeIt).GetPointer()]->SetVisible(true); } NodeIt++; } for(std::map::iterator it = m_ShellSelectorMap.begin(); it != m_ShellSelectorMap.end();it ++) { delete it->second; } m_ShellSelectorMap.clear(); m_ShellSelectorMap = tempMap; } void QmitkQBallReconstructionView::PreviewThreshold(int threshold) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_DiffusionImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_DiffusionImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::Image* vols = static_cast( (*itemiter)->GetData()); // Extract b0 image ITKDiffusionImageType::Pointer itkVectorImagePointer = ITKDiffusionImageType::New(); mitk::CastToItkImage(vols, itkVectorImagePointer); typedef itk::B0ImageExtractionImageFilter FilterType; FilterType::Pointer filterB0 = FilterType::New(); filterB0->SetInput( itkVectorImagePointer ); filterB0->SetDirections( static_cast( vols->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); filterB0->Update(); mitk::Image::Pointer mitkImage = mitk::Image::New(); typedef itk::Image ImageType; typedef itk::Image SegmentationType; typedef itk::BinaryThresholdImageFilter ThresholdFilterType; // apply threshold ThresholdFilterType::Pointer filterThreshold = ThresholdFilterType::New(); filterThreshold->SetInput(filterB0->GetOutput()); filterThreshold->SetLowerThreshold(threshold); filterThreshold->SetInsideValue(0); filterThreshold->SetOutsideValue(1); // mark cut off values red filterThreshold->Update(); mitkImage->InitializeByItk( filterThreshold->GetOutput() ); mitkImage->SetVolume( filterThreshold->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node; if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter)) { node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter); } else { // create a new node, to show thresholded values node = mitk::DataNode::New(); GetDefaultDataStorage()->Add( node, *itemiter ); node->SetProperty( "name", mitk::StringProperty::New("ThresholdOverlay")); node->SetBoolProperty("helper object", true); } node->SetData( mitkImage ); itemiter++; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp index c08648b13a..eaad1a609c 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp @@ -1,1327 +1,1327 @@ /*=================================================================== 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 "QmitkPointBasedRegistrationView.h" #include "ui_QmitkPointBasedRegistrationViewControls.h" #include "QmitkPointListWidget.h" #include #include #include #include "vtkPolyData.h" #include #include #include "qradiobutton.h" #include "qapplication.h" #include #include #include #include #include "qmessagebox.h" #include "mitkLandmarkWarping.h" #include #include #include "mitkOperationEvent.h" #include "mitkUndoController.h" #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateProperty.h" #include "mitkNodePredicateAnd.h" #include "mitkNodePredicateNot.h" #include #include #include #include "mitkDataNodeObject.h" #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" const std::string QmitkPointBasedRegistrationView::VIEW_ID = "org.mitk.views.pointbasedregistration"; using namespace berry; struct SelListenerPointBasedRegistration : ISelectionListener { berryObjectMacro(SelListenerPointBasedRegistration); SelListenerPointBasedRegistration(QmitkPointBasedRegistrationView* view) { m_View = view; } void DoSelectionChanged(ISelection::ConstPointer selection) { // if(!m_View->IsVisible()) // return; // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); // do something with the selected items if(m_View->m_CurrentSelection) { if (m_View->m_CurrentSelection->Size() != 2) { if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); m_View->m_Controls.TextLabelFixed->hide(); m_View->m_Controls.m_FixedLabel->hide(); m_View->m_Controls.line2->hide(); m_View->m_Controls.m_FixedPointListWidget->hide(); m_View->m_Controls.TextLabelMoving->hide(); m_View->m_Controls.m_MovingLabel->hide(); m_View->m_Controls.line1->hide(); m_View->m_Controls.m_MovingPointListWidget->hide(); m_View->m_Controls.m_OpacityLabel->hide(); m_View->m_Controls.m_OpacitySlider->hide(); m_View->m_Controls.label->hide(); m_View->m_Controls.label_2->hide(); m_View->m_Controls.m_SwitchImages->hide(); m_View->m_Controls.m_ShowRedGreenValues->setEnabled(false); } } else { m_View->m_Controls.m_StatusLabel->hide(); bool foundFixedImage = false; mitk::DataNode::Pointer fixedNode; // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::TNodePredicateDataType::Pointer isBaseData(mitk::TNodePredicateDataType::New()); mitk::TNodePredicateDataType::Pointer isPointSet(mitk::TNodePredicateDataType::New()); mitk::NodePredicateNot::Pointer notPointSet = mitk::NodePredicateNot::New(isPointSet); mitk::TNodePredicateDataType::Pointer isPlaneGeometryData(mitk::TNodePredicateDataType::New()); mitk::NodePredicateNot::Pointer notPlaneGeometryData = mitk::NodePredicateNot::New(isPlaneGeometryData); mitk::NodePredicateAnd::Pointer notPointSetAndNotPlaneGeometryData = mitk::NodePredicateAnd::New( notPointSet, notPlaneGeometryData ); mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New( isBaseData, notPointSetAndNotPlaneGeometryData ); mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects = m_View->GetDataStorage()->GetSubset(predicate); mitk::DataNode::Pointer node = nodeObj->GetDataNode(); // only look at interesting types for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin() ; nodeIt != setOfObjects->End(); ++nodeIt) // for each node { if(nodeIt->Value().GetPointer() == node.GetPointer()) { // was - compare() // use contain to allow other Image types to be selected, i.e. a diffusion image if (QString( node->GetData()->GetNameOfClass() ).contains("Image") ) { // verify that the node selected by name is really an image or derived class mitk::Image* _image = dynamic_cast(node->GetData()); if (_image != NULL) { if( _image->GetDimension() == 4) { m_View->m_Controls.m_StatusLabel->show(); QMessageBox::information( NULL, "PointBasedRegistration", "Only 2D or 3D images can be processed.", QMessageBox::Ok ); return; } if (foundFixedImage == false) { fixedNode = node; foundFixedImage = true; } else { // method deleted for more information see bug-18492 // m_View->SetImagesVisible(selection); m_View->FixedSelected(fixedNode); m_View->MovingSelected(node); m_View->m_Controls.m_StatusLabel->hide(); m_View->m_Controls.TextLabelFixed->show(); m_View->m_Controls.m_FixedLabel->show(); m_View->m_Controls.line2->show(); m_View->m_Controls.m_FixedPointListWidget->show(); m_View->m_Controls.TextLabelMoving->show(); m_View->m_Controls.m_MovingLabel->show(); m_View->m_Controls.line1->show(); m_View->m_Controls.m_MovingPointListWidget->show(); m_View->m_Controls.m_OpacityLabel->show(); m_View->m_Controls.m_OpacitySlider->show(); m_View->m_Controls.label->show(); m_View->m_Controls.label_2->show(); m_View->m_Controls.m_SwitchImages->show(); m_View->m_Controls.m_ShowRedGreenValues->setEnabled(true); } } } else { m_View->m_Controls.m_StatusLabel->show(); return; } } } } } if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); } } } else if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); } } void SelectionChanged(const IWorkbenchPart::Pointer& part, - const ISelection::ConstPointer& selection) override + const ISelection::ConstPointer& selection) { // check, if selection comes from datamanager if (part) { QString partname = part->GetPartName(); if(partname == "Data Manager") { // apply selection DoSelectionChanged(selection); } } } QmitkPointBasedRegistrationView* m_View; }; QmitkPointBasedRegistrationView::QmitkPointBasedRegistrationView(QObject * /*parent*/, const char * /*name*/) : QmitkFunctionality(), m_MultiWidget(NULL), m_FixedLandmarks(NULL), m_MovingLandmarks(NULL), m_MovingNode(NULL), m_FixedNode(NULL), m_ShowRedGreen(false), m_Opacity(0.5), m_OriginalOpacity(1.0), m_Transformation(0), m_HideFixedImage(false), m_HideMovingImage(false), m_OldFixedLabel(""), m_OldMovingLabel(""), m_Deactivated (false), m_CurrentFixedLandmarksObserverID(0), m_CurrentMovingLandmarksObserverID(0) { m_FixedLandmarksChangedCommand = itk::SimpleMemberCommand::New(); m_FixedLandmarksChangedCommand->SetCallbackFunction(this, &QmitkPointBasedRegistrationView::updateFixedLandmarksList); m_MovingLandmarksChangedCommand = itk::SimpleMemberCommand::New(); m_MovingLandmarksChangedCommand->SetCallbackFunction(this, &QmitkPointBasedRegistrationView::updateMovingLandmarksList); this->GetDataStorage()->RemoveNodeEvent.AddListener(mitk::MessageDelegate1 ( this, &QmitkPointBasedRegistrationView::DataNodeHasBeenRemoved )); } QmitkPointBasedRegistrationView::~QmitkPointBasedRegistrationView() { if(m_SelListener) { berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener.data()); } if (m_FixedPointSetNode.IsNotNull()) { m_Controls.m_FixedPointListWidget->DeactivateInteractor(true); m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); } if (m_MovingPointSetNode.IsNotNull()) { m_Controls.m_MovingPointListWidget->DeactivateInteractor(true); m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); } m_Controls.m_FixedPointListWidget->SetPointSetNode(NULL); m_Controls.m_MovingPointListWidget->SetPointSetNode(NULL); } void QmitkPointBasedRegistrationView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Parent->setEnabled(false); m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); m_Controls.m_ShowRedGreenValues->setEnabled(false); this->CreateConnections(); // let the point set widget know about the multi widget (cross hair updates) m_Controls.m_FixedPointListWidget->SetMultiWidget( m_MultiWidget ); m_Controls.m_MovingPointListWidget->SetMultiWidget( m_MultiWidget ); } void QmitkPointBasedRegistrationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_Parent->setEnabled(true); m_MultiWidget = &stdMultiWidget; m_MultiWidget->SetWidgetPlanesVisibility(true); m_Controls.m_FixedPointListWidget->SetMultiWidget( m_MultiWidget ); m_Controls.m_MovingPointListWidget->SetMultiWidget( m_MultiWidget ); } void QmitkPointBasedRegistrationView::StdMultiWidgetNotAvailable() { m_Parent->setEnabled(false); m_MultiWidget = NULL; m_Controls.m_FixedPointListWidget->SetMultiWidget( NULL ); m_Controls.m_MovingPointListWidget->SetMultiWidget( NULL ); } void QmitkPointBasedRegistrationView::CreateConnections() { connect( (QObject*)(m_Controls.m_FixedPointListWidget), SIGNAL(EditPointSets(bool)), (QObject*)(m_Controls.m_MovingPointListWidget), SLOT(DeactivateInteractor(bool))); connect( (QObject*)(m_Controls.m_MovingPointListWidget), SIGNAL(EditPointSets(bool)), (QObject*)(m_Controls.m_FixedPointListWidget), SLOT(DeactivateInteractor(bool))); connect( (QObject*)(m_Controls.m_FixedPointListWidget), SIGNAL(EditPointSets(bool)), this, SLOT(HideMovingImage(bool))); connect( (QObject*)(m_Controls.m_MovingPointListWidget), SIGNAL(EditPointSets(bool)), this, SLOT(HideFixedImage(bool))); connect( (QObject*)(m_Controls.m_FixedPointListWidget), SIGNAL(PointListChanged()), this, SLOT(updateFixedLandmarksList())); connect( (QObject*)(m_Controls.m_MovingPointListWidget), SIGNAL(PointListChanged()), this, SLOT(updateMovingLandmarksList())); connect((QObject*)(m_Controls.m_Calculate),SIGNAL(clicked()),this,SLOT(calculate())); connect((QObject*)(m_Controls.m_SwitchImages),SIGNAL(clicked()),this,SLOT(SwitchImages())); connect((QObject*)(m_Controls.m_UndoTransformation),SIGNAL(clicked()),this,SLOT(UndoTransformation())); connect((QObject*)(m_Controls.m_RedoTransformation),SIGNAL(clicked()),this,SLOT(RedoTransformation())); connect((QObject*)(m_Controls.m_ShowRedGreenValues),SIGNAL(toggled(bool)),this,SLOT(showRedGreen(bool))); connect((QObject*)(m_Controls.m_OpacitySlider),SIGNAL(valueChanged(int)),this,SLOT(OpacityUpdate(int))); connect((QObject*)(m_Controls.m_SelectedTransformationClass),SIGNAL(activated(int)), this,SLOT(transformationChanged(int))); connect((QObject*)(m_Controls.m_UseICP),SIGNAL(toggled(bool)), this,SLOT(checkCalculateEnabled())); connect((QObject*)(m_Controls.m_UseICP),SIGNAL(toggled(bool)), this,SLOT(checkLandmarkError())); } void QmitkPointBasedRegistrationView::Activated() { m_Deactivated = false; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Activated(); this->clearTransformationLists(); if (m_SelListener.isNull()) { m_SelListener.reset(new SelListenerPointBasedRegistration(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener.data()); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); static_cast(m_SelListener.data())->DoSelectionChanged(sel); } this->OpacityUpdate(m_Controls.m_OpacitySlider->value()); this->showRedGreen(m_Controls.m_ShowRedGreenValues->isChecked()); } void QmitkPointBasedRegistrationView::Visible() { } void QmitkPointBasedRegistrationView::Deactivated() { m_Deactivated = true; if (m_FixedPointSetNode.IsNotNull()) m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); m_Controls.m_FixedPointListWidget->SetPointSetNode(NULL); m_Controls.m_FixedPointListWidget->DeactivateInteractor(true); if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_Controls.m_MovingPointListWidget->SetPointSetNode(NULL); m_Controls.m_MovingPointListWidget->DeactivateInteractor(true); this->setImageColor(false); if (m_FixedNode.IsNotNull()) m_FixedNode->SetOpacity(1.0); if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_OriginalOpacity); } this->clearTransformationLists(); if (m_FixedPointSetNode.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_FixedLandmarks->GetSize() == 0) { this->GetDataStorage()->Remove(m_FixedPointSetNode); } if (m_MovingPointSetNode.IsNotNull() && m_MovingLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() == 0) { this->GetDataStorage()->Remove(m_MovingPointSetNode); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_FixedNode = NULL; m_MovingNode = NULL; if(m_FixedLandmarks.IsNotNull()) m_FixedLandmarks->RemoveObserver(m_CurrentFixedLandmarksObserverID); m_FixedLandmarks = NULL; if(m_MovingLandmarks.IsNotNull()) m_MovingLandmarks->RemoveObserver(m_CurrentMovingLandmarksObserverID); m_MovingLandmarks = NULL; m_FixedPointSetNode = NULL; m_MovingPointSetNode = NULL; m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener.data()); m_SelListener.reset(); } void QmitkPointBasedRegistrationView::Hidden() { /* m_Deactivated = true; if (m_FixedPointSetNode.IsNotNull()) m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); m_Controls.m_FixedPointListWidget->SetPointSetNode(NULL); m_Controls.m_FixedPointListWidget->DeactivateInteractor(true); if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_Controls.m_MovingPointListWidget->SetPointSetNode(NULL); m_Controls.m_MovingPointListWidget->DeactivateInteractor(true); this->setImageColor(false); if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_OriginalOpacity); } this->clearTransformationLists(); if (m_FixedPointSetNode.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_FixedLandmarks->GetSize() == 0) { this->GetDataStorage()->Remove(m_FixedPointSetNode); } if (m_MovingPointSetNode.IsNotNull() && m_MovingLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() == 0) { this->GetDataStorage()->Remove(m_MovingPointSetNode); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_FixedNode = NULL; m_MovingNode = NULL; if(m_FixedLandmarks.IsNotNull()) m_FixedLandmarks->RemoveObserver(m_CurrentFixedLandmarksObserverID); m_FixedLandmarks = NULL; if(m_MovingLandmarks.IsNotNull()) m_MovingLandmarks->RemoveObserver(m_CurrentMovingLandmarksObserverID); m_MovingLandmarks = NULL; m_FixedPointSetNode = NULL; m_MovingPointSetNode = NULL; m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener); m_SelListener = NULL; //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //QmitkFunctionality::Deactivated();*/ } void QmitkPointBasedRegistrationView::DataNodeHasBeenRemoved(const mitk::DataNode* node) { if(node == m_FixedNode || node == m_MovingNode) { m_Controls.m_StatusLabel->show(); m_Controls.TextLabelFixed->hide(); m_Controls.m_FixedLabel->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); m_Controls.m_SwitchImages->hide(); m_Controls.m_ShowRedGreenValues->setEnabled(false); } } void QmitkPointBasedRegistrationView::FixedSelected(mitk::DataNode::Pointer fixedImage) { if(m_FixedLandmarks.IsNotNull()) m_FixedLandmarks->RemoveObserver(m_CurrentFixedLandmarksObserverID); if (fixedImage.IsNotNull()) { if (m_FixedNode != fixedImage) { // remove changes on previous selected node if (m_FixedNode.IsNotNull()) { this->setImageColor(false); m_FixedNode->SetOpacity(1.0); if (m_FixedPointSetNode.IsNotNull()) { m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); } } // get selected node m_FixedNode = fixedImage; m_FixedNode->SetOpacity(0.5); m_FixedNode->SetVisibility(true); m_Controls.m_FixedLabel->setText(QString::fromStdString(m_FixedNode->GetName())); m_Controls.m_FixedLabel->show(); m_Controls.m_SwitchImages->show(); m_Controls.TextLabelFixed->show(); m_Controls.line2->show(); m_Controls.m_FixedPointListWidget->show(); mitk::ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(m_FixedNode->GetProperty("color")); if ( colorProperty.IsNotNull() ) { m_FixedColor = colorProperty->GetColor(); } this->setImageColor(m_ShowRedGreen); bool hasPointSetNode = false; mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_FixedNode); unsigned long size; size = children->Size(); for (unsigned long i = 0; i < size; ++i) { mitk::StringProperty::Pointer nameProp = dynamic_cast(children->GetElement(i)->GetProperty("name")); if(nameProp.IsNotNull() && nameProp->GetValueAsString()=="PointBasedRegistrationNode") { m_FixedPointSetNode=children->GetElement(i); m_FixedLandmarks = dynamic_cast (m_FixedPointSetNode->GetData()); this->GetDataStorage()->Remove(m_FixedPointSetNode); hasPointSetNode = true; break; } } if (!hasPointSetNode) { m_FixedLandmarks = mitk::PointSet::New(); m_FixedPointSetNode = mitk::DataNode::New(); m_FixedPointSetNode->SetData(m_FixedLandmarks); m_FixedPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); } m_FixedPointSetNode->GetStringProperty("label", m_OldFixedLabel); m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New("F ")); m_FixedPointSetNode->SetProperty("color", mitk::ColorProperty::New(0.0f, 1.0f, 1.0f)); m_FixedPointSetNode->SetVisibility(true); m_Controls.m_FixedPointListWidget->SetPointSetNode(m_FixedPointSetNode); this->GetDataStorage()->Add(m_FixedPointSetNode, m_FixedNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } if (m_FixedPointSetNode.IsNull()) { m_FixedLandmarks = mitk::PointSet::New(); m_FixedPointSetNode = mitk::DataNode::New(); m_FixedPointSetNode->SetData(m_FixedLandmarks); m_FixedPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); m_FixedPointSetNode->GetStringProperty("label", m_OldFixedLabel); m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New("F ")); m_FixedPointSetNode->SetProperty("color", mitk::ColorProperty::New(0.0f, 1.0f, 1.0f)); m_FixedPointSetNode->SetVisibility(true); m_Controls.m_FixedPointListWidget->SetPointSetNode(m_FixedPointSetNode); this->GetDataStorage()->Add(m_FixedPointSetNode, m_FixedNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else { m_FixedNode = NULL; if (m_FixedPointSetNode.IsNotNull()) m_FixedPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldFixedLabel)); m_FixedPointSetNode = NULL; m_FixedLandmarks = NULL; m_Controls.m_FixedPointListWidget->SetPointSetNode(m_FixedPointSetNode); m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.line2->hide(); m_Controls.m_FixedPointListWidget->hide(); m_Controls.m_SwitchImages->hide(); } if(m_FixedLandmarks.IsNotNull()) m_CurrentFixedLandmarksObserverID = m_FixedLandmarks->AddObserver(itk::ModifiedEvent(), m_FixedLandmarksChangedCommand); } void QmitkPointBasedRegistrationView::MovingSelected(mitk::DataNode::Pointer movingImage) { if(m_MovingLandmarks.IsNotNull()) m_MovingLandmarks->RemoveObserver(m_CurrentMovingLandmarksObserverID); if (movingImage.IsNotNull()) { if (m_MovingNode != movingImage) { if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_OriginalOpacity); if (m_FixedNode == m_MovingNode) m_FixedNode->SetOpacity(0.5); this->setImageColor(false); if (m_MovingNode != m_FixedNode) { m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); } else { m_OldFixedLabel = m_OldMovingLabel; } } if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_MovingNode = movingImage; m_MovingNode->SetVisibility(true); m_Controls.m_MovingLabel->setText(QString::fromStdString(m_MovingNode->GetName())); m_Controls.m_MovingLabel->show(); m_Controls.TextLabelMoving->show(); m_Controls.line1->show(); m_Controls.m_MovingPointListWidget->show(); m_Controls.m_OpacityLabel->show(); m_Controls.m_OpacitySlider->show(); m_Controls.label->show(); m_Controls.label_2->show(); mitk::ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(m_MovingNode->GetProperty("color")); if ( colorProperty.IsNotNull() ) { m_MovingColor = colorProperty->GetColor(); } this->setImageColor(m_ShowRedGreen); m_MovingNode->GetFloatProperty("opacity", m_OriginalOpacity); this->OpacityUpdate(m_Opacity); bool hasPointSetNode = false; mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); unsigned long size; size = children->Size(); for (unsigned long i = 0; i < size; ++i) { mitk::StringProperty::Pointer nameProp = dynamic_cast(children->GetElement(i)->GetProperty("name")); if(nameProp.IsNotNull() && nameProp->GetValueAsString()=="PointBasedRegistrationNode") { m_MovingPointSetNode=children->GetElement(i); m_MovingLandmarks = dynamic_cast (m_MovingPointSetNode->GetData()); this->GetDataStorage()->Remove(m_MovingPointSetNode); hasPointSetNode = true; break; } } if (!hasPointSetNode) { m_MovingLandmarks = mitk::PointSet::New(); m_MovingPointSetNode = mitk::DataNode::New(); m_MovingPointSetNode->SetData(m_MovingLandmarks); m_MovingPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); } this->GetDataStorage()->Add(m_MovingPointSetNode, m_MovingNode); m_MovingPointSetNode->GetStringProperty("label", m_OldMovingLabel); m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New("M ")); m_MovingPointSetNode->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f)); m_MovingPointSetNode->SetVisibility(true); m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->clearTransformationLists(); this->OpacityUpdate(m_Opacity); } if (m_MovingPointSetNode.IsNull()) { m_MovingLandmarks = mitk::PointSet::New(); m_MovingPointSetNode = mitk::DataNode::New(); m_MovingPointSetNode->SetData(m_MovingLandmarks); m_MovingPointSetNode->SetProperty("name", mitk::StringProperty::New("PointBasedRegistrationNode")); m_MovingPointSetNode->GetStringProperty("label", m_OldMovingLabel); m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New("M ")); m_MovingPointSetNode->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f)); m_MovingPointSetNode->SetVisibility(true); m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); this->GetDataStorage()->Add(m_MovingPointSetNode, m_MovingNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else { m_MovingNode = NULL; if (m_MovingPointSetNode.IsNotNull()) m_MovingPointSetNode->SetProperty("label", mitk::StringProperty::New(m_OldMovingLabel)); m_MovingPointSetNode = NULL; m_MovingLandmarks = NULL; m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); m_Controls.m_MovingLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.line1->hide(); m_Controls.m_MovingPointListWidget->hide(); m_Controls.m_OpacityLabel->hide(); m_Controls.m_OpacitySlider->hide(); m_Controls.label->hide(); m_Controls.label_2->hide(); } if(m_MovingLandmarks.IsNotNull()) m_CurrentMovingLandmarksObserverID = m_MovingLandmarks->AddObserver(itk::ModifiedEvent(), m_MovingLandmarksChangedCommand); } void QmitkPointBasedRegistrationView::updateMovingLandmarksList() { // mitk::PointSet* ps = mitk::PointSet::New(); // ps = dynamic_cast(m_MovingPointSetNode->GetData()); // mitk::DataNode::Pointer tmpPtr = m_MovingPointSetNode; // m_MovingLandmarks = 0; // m_MovingLandmarks = (ps); m_MovingLandmarks = dynamic_cast(m_MovingPointSetNode->GetData()); // m_Controls.m_MovingPointListWidget->SetPointSetNode(m_MovingPointSetNode); //Workaround: m_MovingPointListWidget->m_PointListView->m_PointListModel loses the pointer on the pointsetnode this->checkLandmarkError(); this->CheckCalculate(); } void QmitkPointBasedRegistrationView::updateFixedLandmarksList() { m_FixedLandmarks = dynamic_cast(m_FixedPointSetNode->GetData()); this->checkLandmarkError(); this->CheckCalculate(); } void QmitkPointBasedRegistrationView::HideFixedImage(bool hide) { m_HideFixedImage = hide; if(m_FixedNode.IsNotNull()) { m_FixedNode->SetVisibility(!hide); } if (hide) { //this->reinitMovingClicked(); } if (!m_HideMovingImage && !m_HideFixedImage) { //this->globalReinitClicked(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointBasedRegistrationView::HideMovingImage(bool hide) { m_HideMovingImage = hide; if(m_MovingNode.IsNotNull()) { m_MovingNode->SetVisibility(!hide); } if (hide) { //this->reinitFixedClicked(); } if (!m_HideMovingImage && !m_HideFixedImage) { //this->globalReinitClicked(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } bool QmitkPointBasedRegistrationView::CheckCalculate() { if((m_MovingPointSetNode.IsNull())||(m_FixedPointSetNode.IsNull()||m_FixedLandmarks.IsNull()||m_MovingLandmarks.IsNull())) return false; if(m_MovingNode==m_FixedNode) return false; return this->checkCalculateEnabled(); } void QmitkPointBasedRegistrationView::UndoTransformation() { if(!m_UndoPointsGeometryList.empty()) { mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_RedoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); m_MovingLandmarks->SetGeometry(m_UndoPointsGeometryList.back()); m_UndoPointsGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingPointSetNode->SetMapper(1, NULL); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0)->Clone(); m_RedoGeometryList.push_back(movingGeometry.GetPointer()); movingData->SetGeometry(m_UndoGeometryList.back()); m_UndoGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingNode->SetMapper(1, NULL); mitk::RenderingManager::GetInstance()->RequestUpdate(m_MultiWidget->mitkWidget4->GetRenderWindow()); movingData->GetTimeGeometry()->Update(); m_MovingLandmarks->GetTimeGeometry()->Update(); m_Controls.m_RedoTransformation->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } if(!m_UndoPointsGeometryList.empty()) { m_Controls.m_UndoTransformation->setEnabled(true); } else { m_Controls.m_UndoTransformation->setEnabled(false); } } void QmitkPointBasedRegistrationView::RedoTransformation() { if(!m_RedoPointsGeometryList.empty()) { mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); m_MovingLandmarks->SetGeometry(m_RedoPointsGeometryList.back()); m_RedoPointsGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingPointSetNode->SetMapper(1, NULL); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0)->Clone(); m_UndoGeometryList.push_back(movingGeometry.GetPointer()); movingData->SetGeometry(m_RedoGeometryList.back()); m_RedoGeometryList.pop_back(); //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper m_MovingNode->SetMapper(1, NULL); mitk::RenderingManager::GetInstance()->RequestUpdate(m_MultiWidget->mitkWidget4->GetRenderWindow()); movingData->GetTimeGeometry()->Update(); m_MovingLandmarks->GetTimeGeometry()->Update(); m_Controls.m_UndoTransformation->setEnabled(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } if(!m_RedoPointsGeometryList.empty()) { m_Controls.m_RedoTransformation->setEnabled(true); } else { m_Controls.m_RedoTransformation->setEnabled(false); } } void QmitkPointBasedRegistrationView::showRedGreen(bool redGreen) { m_ShowRedGreen = redGreen; this->setImageColor(m_ShowRedGreen); } void QmitkPointBasedRegistrationView::setImageColor(bool redGreen) { if (!redGreen && m_FixedNode.IsNotNull()) { m_FixedNode->SetColor(m_FixedColor); } if (!redGreen && m_MovingNode.IsNotNull()) { m_MovingNode->SetColor(m_MovingColor); } if (redGreen && m_FixedNode.IsNotNull()) { m_FixedNode->SetColor(1.0f, 0.0f, 0.0f); } if (redGreen && m_MovingNode.IsNotNull()) { m_MovingNode->SetColor(0.0f, 1.0f, 0.0f); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointBasedRegistrationView::OpacityUpdate(float opacity) { if (opacity > 1) { opacity = opacity/100.0f; } m_Opacity = opacity; if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_Opacity); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointBasedRegistrationView::OpacityUpdate(int opacity) { float fValue = ((float)opacity)/100.0f; this->OpacityUpdate(fValue); } void QmitkPointBasedRegistrationView::clearTransformationLists() { m_Controls.m_UndoTransformation->setEnabled(false); m_Controls.m_RedoTransformation->setEnabled(false); m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); m_UndoGeometryList.clear(); m_UndoPointsGeometryList.clear(); m_RedoGeometryList.clear(); m_RedoPointsGeometryList.clear(); } void QmitkPointBasedRegistrationView::checkLandmarkError() { double totalDist = 0, dist = 0, dist2 = 0; mitk::Point3D point1, point2, point3; double p1[3], p2[3]; if(m_Transformation < 3) { if (m_Controls.m_UseICP->isChecked()) { if (m_MovingLandmarks.IsNotNull() && m_FixedLandmarks.IsNotNull()&& m_MovingLandmarks->GetSize() != 0 && m_FixedLandmarks->GetSize() != 0) { for(int pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { point1 = m_MovingLandmarks->GetPoint(pointId); point2 = m_FixedLandmarks->GetPoint(0); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = point1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = point2[2]; dist = vtkMath::Distance2BetweenPoints(p1, p2); for(int pointId2 = 1; pointId2 < m_FixedLandmarks->GetSize(); ++pointId2) { point2 = m_FixedLandmarks->GetPoint(pointId2); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = p1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = p2[2]; dist2 = vtkMath::Distance2BetweenPoints(p1, p2); if (dist2 < dist) { dist = dist2; } } totalDist += dist; } m_Controls.m_MeanErrorLCD->display(sqrt(totalDist/m_FixedLandmarks->GetSize())); m_Controls.m_MeanErrorLCD->show(); m_Controls.m_MeanError->show(); } else { m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); } } else { if (m_MovingLandmarks.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() != 0 && m_FixedLandmarks->GetSize() != 0 && m_MovingLandmarks->GetSize() == m_FixedLandmarks->GetSize()) { for(int pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { point1 = m_MovingLandmarks->GetPoint(pointId); point2 = m_FixedLandmarks->GetPoint(pointId); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = point1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = point2[2]; totalDist += vtkMath::Distance2BetweenPoints(p1, p2); } m_Controls.m_MeanErrorLCD->display(sqrt(totalDist/m_FixedLandmarks->GetSize())); m_Controls.m_MeanErrorLCD->show(); m_Controls.m_MeanError->show(); } else { m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); } } } else { if (m_MovingLandmarks.IsNotNull() && m_FixedLandmarks.IsNotNull() && m_MovingLandmarks->GetSize() != 0 && m_FixedLandmarks->GetSize() != 0 && m_MovingLandmarks->GetSize() == m_FixedLandmarks->GetSize()) { for(int pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { point1 = m_MovingLandmarks->GetPoint(pointId); point2 = m_FixedLandmarks->GetPoint(pointId); p1[0] = point1[0]; p1[1] = point1[1]; p1[2] = point1[2]; p2[0] = point2[0]; p2[1] = point2[1]; p2[2] = point2[2]; totalDist += vtkMath::Distance2BetweenPoints(p1, p2); } m_Controls.m_MeanErrorLCD->display(sqrt(totalDist/m_FixedLandmarks->GetSize())); m_Controls.m_MeanErrorLCD->show(); m_Controls.m_MeanError->show(); } else { m_Controls.m_MeanErrorLCD->hide(); m_Controls.m_MeanError->hide(); } } } void QmitkPointBasedRegistrationView::transformationChanged(int transform) { m_Transformation = transform; this->checkCalculateEnabled(); this->checkLandmarkError(); } // ICP with vtkLandmarkTransformation void QmitkPointBasedRegistrationView::calculateLandmarkbasedWithICP() { if(CheckCalculate()) { mitk::BaseGeometry::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); mitk::BaseData::Pointer originalData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer originalDataGeometry = originalData->GetGeometry(0)->Clone(); m_UndoGeometryList.push_back(originalDataGeometry.GetPointer()); vtkIdType pointId; vtkPoints* vPointsSource=vtkPoints::New(); vtkCellArray* vCellsSource=vtkCellArray::New(); for(pointId=0; pointIdGetSize();++pointId) { mitk::Point3D pointSource=m_MovingLandmarks->GetPoint(pointId); vPointsSource->InsertNextPoint(pointSource[0],pointSource[1],pointSource[2]); vCellsSource->InsertNextCell(1, &pointId); } vtkPoints* vPointsTarget=vtkPoints::New(); vtkCellArray* vCellsTarget = vtkCellArray::New(); for(pointId=0; pointIdGetSize();++pointId) { mitk::Point3D pointTarget=m_FixedLandmarks->GetPoint(pointId); vPointsTarget->InsertNextPoint(pointTarget[0],pointTarget[1],pointTarget[2]); vCellsTarget->InsertNextCell(1, &pointId); } vtkPolyData* vPointSetSource=vtkPolyData::New(); vtkPolyData* vPointSetTarget=vtkPolyData::New(); vPointSetTarget->SetPoints(vPointsTarget); vPointSetTarget->SetVerts(vCellsTarget); vPointSetSource->SetPoints(vPointsSource); vPointSetSource->SetVerts(vCellsSource); vtkIterativeClosestPointTransform * icp=vtkIterativeClosestPointTransform::New(); icp->SetCheckMeanDistance(1); icp->SetSource(vPointSetSource); icp->SetTarget(vPointSetTarget); icp->SetMaximumNumberOfIterations(50); icp->StartByMatchingCentroidsOn(); vtkLandmarkTransform * transform=icp->GetLandmarkTransform(); if(m_Transformation==0) { transform->SetModeToRigidBody(); } if(m_Transformation==1) { transform->SetModeToSimilarity(); } if(m_Transformation==2) { transform->SetModeToAffine(); } vtkMatrix4x4 * matrix=icp->GetMatrix(); double determinant = fabs(matrix->Determinant()); if((determinant < mitk::eps) || (determinant > 100) || (determinant < 0.01) || (determinant==itk::NumericTraits::infinity()) || (determinant==itk::NumericTraits::quiet_NaN()) || (determinant==itk::NumericTraits::signaling_NaN()) || (determinant==-itk::NumericTraits::infinity()) || (determinant==-itk::NumericTraits::quiet_NaN()) || (determinant==-itk::NumericTraits::signaling_NaN()) || (!(determinant <= 0) && !(determinant > 0))) { QMessageBox msgBox; msgBox.setText("Suspicious determinant of matrix calculated by ICP.\n" "Please select more points or other points!" ); msgBox.exec(); return; } pointsGeometry->Compose(matrix); m_MovingLandmarks->GetTimeGeometry()->Update(); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0); movingGeometry->Compose(matrix); movingData->GetTimeGeometry()->Update(); m_Controls.m_UndoTransformation->setEnabled(true); m_Controls.m_RedoTransformation->setEnabled(false); m_RedoGeometryList.clear(); m_RedoPointsGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } } // only vtkLandmarkTransformation void QmitkPointBasedRegistrationView::calculateLandmarkbased() { if(CheckCalculate()) { mitk::BaseGeometry::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); mitk::BaseGeometry::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); mitk::BaseData::Pointer originalData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer originalDataGeometry = originalData->GetGeometry(0)->Clone(); m_UndoGeometryList.push_back(originalDataGeometry.GetPointer()); vtkIdType pointId; vtkPoints* vPointsSource=vtkPoints::New(); for(pointId = 0; pointId < m_MovingLandmarks->GetSize(); ++pointId) { mitk::Point3D sourcePoint = m_MovingLandmarks->GetPoint(pointId); vPointsSource->InsertNextPoint(sourcePoint[0],sourcePoint[1],sourcePoint[2]); } vtkPoints* vPointsTarget=vtkPoints::New(); for(pointId=0; pointIdGetSize();++pointId) { mitk::Point3D targetPoint=m_FixedLandmarks->GetPoint(pointId); vPointsTarget->InsertNextPoint(targetPoint[0],targetPoint[1],targetPoint[2]); } vtkLandmarkTransform * transform= vtkLandmarkTransform::New(); transform->SetSourceLandmarks(vPointsSource); transform->SetTargetLandmarks(vPointsTarget); if(m_Transformation==0) { transform->SetModeToRigidBody(); } if(m_Transformation==1) { transform->SetModeToSimilarity(); } if(m_Transformation==2) { transform->SetModeToAffine(); } vtkMatrix4x4 * matrix=transform->GetMatrix(); double determinant = fabs(matrix->Determinant()); if((determinant < mitk::eps) || (determinant > 100) || (determinant < 0.01) || (determinant==itk::NumericTraits::infinity()) || (determinant==itk::NumericTraits::quiet_NaN()) || (determinant==itk::NumericTraits::signaling_NaN()) || (determinant==-itk::NumericTraits::infinity()) || (determinant==-itk::NumericTraits::quiet_NaN()) || (determinant==-itk::NumericTraits::signaling_NaN()) || (!(determinant <= 0) && !(determinant > 0))) { QMessageBox msgBox; msgBox.setText("Suspicious determinant of matrix calculated.\n" "Please select more points or other points!" ); msgBox.exec(); return; } pointsGeometry->Compose(matrix); m_MovingLandmarks->GetTimeGeometry()->Update(); mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); mitk::BaseGeometry::Pointer movingGeometry = movingData->GetGeometry(0); movingGeometry->Compose(matrix); movingData->GetTimeGeometry()->Update(); m_Controls.m_UndoTransformation->setEnabled(true); m_Controls.m_RedoTransformation->setEnabled(false); m_RedoGeometryList.clear(); m_RedoPointsGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->checkLandmarkError(); } } void QmitkPointBasedRegistrationView::calculateLandmarkWarping() { mitk::LandmarkWarping* registration = new mitk::LandmarkWarping(); mitk::LandmarkWarping::FixedImageType::Pointer fixedImage = mitk::LandmarkWarping::FixedImageType::New(); mitk::Image::Pointer fimage = dynamic_cast(m_FixedNode->GetData()); mitk::LandmarkWarping::MovingImageType::Pointer movingImage = mitk::LandmarkWarping::MovingImageType::New(); mitk::Image::Pointer mimage = dynamic_cast(m_MovingNode->GetData()); if (fimage.IsNotNull() && /*fimage->GetDimension() == 2 || */ fimage->GetDimension() == 3 && mimage.IsNotNull() && mimage->GetDimension() == 3) { mitk::CastToItkImage(fimage, fixedImage); mitk::CastToItkImage(mimage, movingImage); registration->SetFixedImage(fixedImage); registration->SetMovingImage(movingImage); unsigned int pointId; mitk::Point3D sourcePoint, targetPoint; mitk::LandmarkWarping::LandmarkContainerType::Pointer fixedLandmarks = mitk::LandmarkWarping::LandmarkContainerType::New(); mitk::LandmarkWarping::LandmarkPointType point; for(pointId = 0; pointId < (unsigned int)m_FixedLandmarks->GetSize(); ++pointId) { fimage->GetGeometry(0)->WorldToItkPhysicalPoint(m_FixedLandmarks->GetPoint(pointId), point); fixedLandmarks->InsertElement( pointId, point); } mitk::LandmarkWarping::LandmarkContainerType::Pointer movingLandmarks = mitk::LandmarkWarping::LandmarkContainerType::New(); for(pointId = 0; pointId < (unsigned int)m_MovingLandmarks->GetSize(); ++pointId) { mitk::BaseData::Pointer fixedData = m_FixedNode->GetData(); mitk::BaseGeometry::Pointer fixedGeometry = fixedData->GetGeometry(0); fixedGeometry->WorldToItkPhysicalPoint(m_MovingLandmarks->GetPoint(pointId), point); movingLandmarks->InsertElement( pointId, point); } registration->SetLandmarks(fixedLandmarks.GetPointer(), movingLandmarks.GetPointer()); mitk::LandmarkWarping::MovingImageType::Pointer output = registration->Register(); if (output.IsNotNull()) { mitk::Image::Pointer image = mitk::Image::New(); mitk::CastToMitkImage(output, image); m_MovingNode->SetData(image); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelWindow; levelWindow.SetAuto( image ); levWinProp->SetLevelWindow(levelWindow); m_MovingNode->GetPropertyList()->SetProperty("levelwindow",levWinProp); movingLandmarks = registration->GetTransformedTargetLandmarks(); mitk::PointSet::PointDataIterator it; it = m_MovingLandmarks->GetPointSet()->GetPointData()->Begin(); //increase the eventId to encapsulate the coming operations mitk::OperationEvent::IncCurrObjectEventId(); mitk::OperationEvent::ExecuteIncrement(); for(pointId=0; pointIdSize();++pointId, ++it) { int position = it->Index(); mitk::PointSet::PointType pt = m_MovingLandmarks->GetPoint(position); mitk::Point3D undoPoint = ( pt ); point = movingLandmarks->GetElement(pointId); fimage->GetGeometry(0)->ItkPhysicalPointToWorld(point, pt); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVE, pt, position); //undo operation mitk::PointOperation* undoOp = new mitk::PointOperation(mitk::OpMOVE, undoPoint, position); mitk::OperationEvent* operationEvent = new mitk::OperationEvent(m_MovingLandmarks, doOp, undoOp, "Move point"); mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent(operationEvent); //execute the Operation m_MovingLandmarks->ExecuteOperation(doOp); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->clearTransformationLists(); this->checkLandmarkError(); } } } bool QmitkPointBasedRegistrationView::checkCalculateEnabled() { if (m_FixedLandmarks.IsNotNull() && m_MovingLandmarks.IsNotNull()) { int fixedPoints = m_FixedLandmarks->GetSize(); int movingPoints = m_MovingLandmarks->GetSize(); if (m_Transformation == 0 || m_Transformation == 1 || m_Transformation == 2) { if (m_Controls.m_UseICP->isChecked()) { if((movingPoints > 0 && fixedPoints > 0)) { m_Controls.m_Calculate->setEnabled(true); return true; } else { m_Controls.m_Calculate->setEnabled(false); return false; } } else { if ((movingPoints == fixedPoints) && movingPoints > 0) { m_Controls.m_Calculate->setEnabled(true); return true; } else { m_Controls.m_Calculate->setEnabled(false); return false; } } } else { m_Controls.m_Calculate->setEnabled(true); return true; } } else { return false; } } void QmitkPointBasedRegistrationView::calculate() { if (m_Transformation == 0 || m_Transformation == 1 || m_Transformation == 2) { if (m_Controls.m_UseICP->isChecked()) { if (m_MovingLandmarks->GetSize() == 1 && m_FixedLandmarks->GetSize() == 1) { this->calculateLandmarkbased(); } else { this->calculateLandmarkbasedWithICP(); } } else { this->calculateLandmarkbased(); } } else { this->calculateLandmarkWarping(); } } void QmitkPointBasedRegistrationView::SwitchImages() { mitk::DataNode::Pointer newMoving = m_FixedNode; mitk::DataNode::Pointer newFixed = m_MovingNode; this->FixedSelected(newFixed); this->MovingSelected(newMoving); } diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp index c7dad79144..a80e7ad21f 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationView.cpp @@ -1,1465 +1,1465 @@ /*=================================================================== 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. ===================================================================*/ // Qmitk includes #include "QmitkRigidRegistrationView.h" #include "QmitkStdMultiWidget.h" // MITK includes #include "mitkDataNodeObject.h" #include #include "mitkManualSegmentationToSurfaceFilter.h" #include #include #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateAnd.h" #include "mitkNodePredicateProperty.h" // QT includes #include "qinputdialog.h" #include "qmessagebox.h" #include "qcursor.h" #include "qapplication.h" #include "qradiobutton.h" #include "qslider.h" #include "qtooltip.h" // VTK includes #include // ITK includes #include // BlueBerry includes #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" const std::string QmitkRigidRegistrationView::VIEW_ID = "org.mitk.views.rigidregistration"; using namespace berry; struct SelListenerRigidRegistration : ISelectionListener { berryObjectMacro(SelListenerRigidRegistration); SelListenerRigidRegistration(QmitkRigidRegistrationView* view) { m_View = view; } void DoSelectionChanged(ISelection::ConstPointer selection) { // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); // do something with the selected items if(m_View->m_CurrentSelection) { if (m_View->m_CurrentSelection->Size() != 2) { if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); m_View->m_Controls.TextLabelFixed->hide(); m_View->m_Controls.m_FixedLabel->hide(); m_View->m_Controls.TextLabelMoving->hide(); m_View->m_Controls.m_MovingLabel->hide(); m_View->m_Controls.m_UseMaskingCB->hide(); m_View->m_Controls.m_OpacityLabel->setEnabled(false); m_View->m_Controls.m_OpacitySlider->setEnabled(false); m_View->m_Controls.label->setEnabled(false); m_View->m_Controls.label_2->setEnabled(false); m_View->m_Controls.m_ShowRedGreenValues->setEnabled(false); m_View->m_Controls.m_SwitchImages->hide(); } } else { m_View->m_Controls.m_StatusLabel->hide(); bool foundFixedImage = false; mitk::DataNode::Pointer fixedNode; // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); // only look at interesting types if(QString("Image").compare(node->GetData()->GetNameOfClass())==0) { if (dynamic_cast(node->GetData())->GetDimension() == 4) { m_View->m_Controls.m_StatusLabel->show(); QMessageBox::information( NULL, "RigidRegistration", "Only 2D or 3D images can be processed.", QMessageBox::Ok ); return; } if (foundFixedImage == false) { fixedNode = node; foundFixedImage = true; } else { // m_View->SetImagesVisible(selection); m_View->FixedSelected(fixedNode); m_View->MovingSelected(node); m_View->m_Controls.m_StatusLabel->hide(); m_View->m_Controls.TextLabelFixed->show(); m_View->m_Controls.m_FixedLabel->show(); m_View->m_Controls.TextLabelMoving->show(); m_View->m_Controls.m_MovingLabel->show(); m_View->m_Controls.m_UseMaskingCB->show(); m_View->m_Controls.m_OpacityLabel->setEnabled(true); m_View->m_Controls.m_OpacitySlider->setEnabled(true); m_View->m_Controls.label->setEnabled(true); m_View->m_Controls.label_2->setEnabled(true); m_View->m_Controls.m_ShowRedGreenValues->setEnabled(true); } } else { m_View->m_Controls.m_StatusLabel->show(); return; } } } } } else if (m_View->m_FixedNode.IsNull() || m_View->m_MovingNode.IsNull()) { m_View->m_Controls.m_StatusLabel->show(); } } void SelectionChanged(const IWorkbenchPart::Pointer& part, - const ISelection::ConstPointer& selection) override + const ISelection::ConstPointer& selection) { // check, if selection comes from datamanager if (part) { QString partname = part->GetPartName(); if(partname == "Data Manager") { // apply selection DoSelectionChanged(selection); } } } QmitkRigidRegistrationView* m_View; }; QmitkRigidRegistrationView::QmitkRigidRegistrationView(QObject * /*parent*/, const char * /*name*/) : QmitkFunctionality(), m_MultiWidget(NULL), m_MovingNode(NULL), m_MovingMaskNode(NULL), m_FixedNode(NULL), m_FixedMaskNode(NULL), m_ShowRedGreen(false), m_Opacity(0.5), m_OriginalOpacity(1.0), m_Deactivated(false),m_FixedDimension(0), m_MovingDimension(0) { m_TranslateSliderPos[0] = 0; m_TranslateSliderPos[1] = 0; m_TranslateSliderPos[2] = 0; m_RotateSliderPos[0] = 0; m_RotateSliderPos[1] = 0; m_RotateSliderPos[2] = 0; m_ScaleSliderPos[0] = 0; m_ScaleSliderPos[1] = 0; m_ScaleSliderPos[2] = 0; translationParams = new int[3]; rotationParams = new int[3]; scalingParams = new int[3]; m_TimeStepperAdapter = NULL; this->GetDataStorage()->RemoveNodeEvent.AddListener(mitk::MessageDelegate1 ( this, &QmitkRigidRegistrationView::DataNodeHasBeenRemoved )); } QmitkRigidRegistrationView::~QmitkRigidRegistrationView() { if(m_SelListener) { berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener.data()); } this->GetDataStorage()->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1 ( this, &QmitkRigidRegistrationView::DataNodeHasBeenRemoved )); } void QmitkRigidRegistrationView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Controls.m_ManualFrame->hide(); m_Controls.timeSlider->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_MovingLabel->hide(); //m_Controls.m_UseFixedImageMask->hide(); //m_Controls.m_UseMovingImageMask->hide(); m_Controls.m_UseMaskingCB->hide(); m_Controls.m_OpacityLabel->setEnabled(false); m_Controls.m_OpacitySlider->setEnabled(false); m_Controls.label->setEnabled(false); m_Controls.label_2->setEnabled(false); m_Controls.m_ShowRedGreenValues->setEnabled(false); m_Controls.m_SwitchImages->hide(); if (m_Controls.m_RigidTransform->currentIndex() == 1) { m_Controls.frame->show(); } else { m_Controls.frame->hide(); } m_Controls.m_ManualFrame->setEnabled(false); m_Parent->setEnabled(false); mitk::NodePredicateAnd::Pointer andPred = // we want binary images in the selectors mitk::NodePredicateAnd::New(mitk::NodePredicateDataType::New("Image"), mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true))); m_Controls.m_FixedImageCB->SetPredicate(andPred); m_Controls.m_FixedImageCB->SetDataStorage(this->GetDataStorage()); m_Controls.m_FixedImageCB->hide(); m_Controls.m_FixedMaskLB->hide(); m_Controls.m_MovingImageCB->SetPredicate(andPred); m_Controls.m_MovingImageCB->SetDataStorage(this->GetDataStorage()); m_Controls.m_MovingImageCB->hide(); m_Controls.m_MovingMaskLB->hide(); this->CreateConnections(); this->CheckCalculateEnabled(); } void QmitkRigidRegistrationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_Parent->setEnabled(true); m_MultiWidget = &stdMultiWidget; m_MultiWidget->SetWidgetPlanesVisibility(true); } void QmitkRigidRegistrationView::StdMultiWidgetNotAvailable() { m_Parent->setEnabled(false); m_MultiWidget = NULL; } void QmitkRigidRegistrationView::CreateConnections() { connect( m_Controls.m_ManualRegistrationCheckbox, SIGNAL(toggled(bool)), this, SLOT(ShowManualRegistrationFrame(bool))); connect((QObject*)(m_Controls.m_SwitchImages),SIGNAL(clicked()),this,SLOT(SwitchImages())); connect(m_Controls.m_ShowRedGreenValues, SIGNAL(toggled(bool)), this, SLOT(ShowRedGreen(bool))); connect(m_Controls.m_ShowContour, SIGNAL(toggled(bool)), this, SLOT(EnableContour(bool))); //connect(m_Controls.m_UseFixedImageMask, SIGNAL(toggled(bool)), this, SLOT(UseFixedMaskImageChecked(bool))); //connect(m_Controls.m_UseMovingImageMask, SIGNAL(toggled(bool)), this, SLOT(UseMovingMaskImageChecked(bool))); connect(m_Controls.m_RigidTransform, SIGNAL(currentChanged(int)), this, SLOT(TabChanged(int))); connect(m_Controls.m_OpacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OpacityUpdate(int))); connect(m_Controls.m_ContourSlider, SIGNAL(sliderReleased()), this, SLOT(ShowContour())); connect(m_Controls.m_CalculateTransformation, SIGNAL(clicked()), this, SLOT(Calculate())); connect(m_Controls.m_UndoTransformation,SIGNAL(clicked()),this,SLOT(UndoTransformation())); connect(m_Controls.m_RedoTransformation,SIGNAL(clicked()),this,SLOT(RedoTransformation())); connect(m_Controls.m_AutomaticTranslation,SIGNAL(clicked()),this,SLOT(AlignCenters())); connect(m_Controls.m_StopOptimization,SIGNAL(clicked()), this , SLOT(StopOptimizationClicked())); connect(m_Controls.m_XTransSlider, SIGNAL(valueChanged(int)), this, SLOT(xTrans_valueChanged(int))); connect(m_Controls.m_YTransSlider, SIGNAL(valueChanged(int)), this, SLOT(yTrans_valueChanged(int))); connect(m_Controls.m_ZTransSlider, SIGNAL(valueChanged(int)), this, SLOT(zTrans_valueChanged(int))); connect(m_Controls.m_XRotSlider, SIGNAL(valueChanged(int)), this, SLOT(xRot_valueChanged(int))); connect(m_Controls.m_YRotSlider, SIGNAL(valueChanged(int)), this, SLOT(yRot_valueChanged(int))); connect(m_Controls.m_ZRotSlider, SIGNAL(valueChanged(int)), this, SLOT(zRot_valueChanged(int))); connect(m_Controls.m_XScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(xScale_valueChanged(int))); connect(m_Controls.m_YScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(yScale_valueChanged(int))); connect(m_Controls.m_ZScaleSlider, SIGNAL(valueChanged(int)), this, SLOT(zScale_valueChanged(int))); connect(m_Controls.m_LoadRigidRegistrationParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(LoadRigidRegistrationParameter())); connect(m_Controls.m_SaveRigidRegistrationParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(SaveRigidRegistrationParameter())); connect(m_Controls.m_LoadRigidRegistrationTestParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(LoadRigidRegistrationTestParameter())); connect(m_Controls.m_SaveRigidRegistrationTestParameter, SIGNAL(clicked()), m_Controls.qmitkRigidRegistrationSelector1, SLOT(SaveRigidRegistrationTestParameter())); connect(m_Controls.qmitkRigidRegistrationSelector1,SIGNAL(OptimizerChanged(double)),this,SLOT(SetOptimizerValue( double ))); connect(m_Controls.qmitkRigidRegistrationSelector1,SIGNAL(TransformChanged()),this,SLOT(CheckCalculateEnabled())); connect(m_Controls.qmitkRigidRegistrationSelector1,SIGNAL(AddNewTransformationToUndoList()),this,SLOT(AddNewTransformationToUndoList())); connect(m_Controls.m_UseMaskingCB, SIGNAL(stateChanged(int)),this,SLOT(OnUseMaskingChanged(int))); connect(m_Controls.m_FixedImageCB, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),this,SLOT(OnFixedMaskImageChanged(const mitk::DataNode*))); connect(m_Controls.m_MovingImageCB, SIGNAL(OnSelectionChanged(const mitk::DataNode*)),this,SLOT(OnMovingMaskImageChanged(const mitk::DataNode*))); } void QmitkRigidRegistrationView::Activated() { m_Deactivated = false; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Activated(); if (m_SelListener.isNull()) { m_SelListener.reset(new SelListenerRigidRegistration(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener.data()); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); static_cast(m_SelListener.data())->DoSelectionChanged(sel); } this->OpacityUpdate(m_Controls.m_OpacitySlider->value()); this->ShowRedGreen(m_Controls.m_ShowRedGreenValues->isChecked()); this->ClearTransformationLists(); this->CheckCalculateEnabled(); /* m_Deactivated = false; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Activated(); if (m_SelListener.IsNull()) { m_SelListener = berry::ISelectionListener::Pointer(new SelListenerRigidRegistration(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/ *"org.mitk.views.datamanager",* / m_SelListener); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); } this->OpacityUpdate(m_Controls.m_OpacitySlider->value()); this->ShowRedGreen(m_Controls.m_ShowRedGreenValues->isChecked()); this->ClearTransformationLists(); this->CheckCalculateEnabled();*/ } void QmitkRigidRegistrationView::Visible() { /* m_Deactivated = false; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Activated(); if (m_SelListener.IsNull()) { m_SelListener = berry::ISelectionListener::Pointer(new SelListenerRigidRegistration(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener("org.mitk.views.datamanager", m_SelListener); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); } this->OpacityUpdate(m_Controls.m_OpacitySlider->value()); this->ShowRedGreen(m_Controls.m_ShowRedGreenValues->isChecked()); this->ClearTransformationLists(); this->CheckCalculateEnabled();*/ } void QmitkRigidRegistrationView::Deactivated() { m_Deactivated = true; this->SetImageColor(false); if (m_FixedNode.IsNotNull()) m_FixedNode->SetOpacity(1.0); m_FixedNode = NULL; m_MovingNode = NULL; this->ClearTransformationLists(); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener.data()); m_SelListener.reset(); /* m_Deactivated = true; this->SetImageColor(false); m_FixedNode = NULL; m_MovingNode = NULL; this->ClearTransformationLists(); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener); m_SelListener = NULL; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Deactivated();*/ } void QmitkRigidRegistrationView::Hidden() { /*m_Deactivated = true; this->SetImageColor(false); m_FixedNode = NULL; m_MovingNode = NULL; this->ClearTransformationLists(); berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener); m_SelListener = NULL; //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //QmitkFunctionality::Deactivated();*/ } void QmitkRigidRegistrationView::DataNodeHasBeenRemoved(const mitk::DataNode* node) { if(node == m_FixedNode || node == m_MovingNode) { m_Controls.m_StatusLabel->show(); m_Controls.TextLabelFixed->hide(); m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_MovingLabel->hide(); m_Controls.m_OpacityLabel->setEnabled(false); m_Controls.m_OpacitySlider->setEnabled(false); m_Controls.label->setEnabled(false); m_Controls.label_2->setEnabled(false); m_Controls.m_ShowRedGreenValues->setEnabled(false); m_Controls.m_SwitchImages->hide(); } else if(node == m_ContourHelperNode) { // can this cause a memory leak? m_ContourHelperNode = NULL; } } void QmitkRigidRegistrationView::FixedSelected(mitk::DataNode::Pointer fixedImage) { if (m_FixedNode.IsNotNull()) { this->SetImageColor(false); m_FixedNode->SetOpacity(1.0); } m_FixedNode = fixedImage; if (m_FixedNode.IsNotNull()) { m_FixedNode->SetOpacity(0.5); m_FixedNode->SetVisibility(true); m_Controls.TextLabelFixed->setText(QString::fromStdString(m_FixedNode->GetName())); m_Controls.m_FixedLabel->show(); m_Controls.TextLabelFixed->show(); m_Controls.m_SwitchImages->show(); mitk::ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(m_FixedNode->GetProperty("color")); if ( colorProperty.IsNotNull() ) { m_FixedColor = colorProperty->GetColor(); } this->SetImageColor(m_ShowRedGreen); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (dynamic_cast(m_FixedNode->GetData())) { m_FixedDimension = dynamic_cast(m_FixedNode->GetData())->GetDimension(); m_Controls.qmitkRigidRegistrationSelector1->SetFixedDimension(m_FixedDimension); m_Controls.qmitkRigidRegistrationSelector1->SetFixedNode(m_FixedNode); } // what's about masking? m_Controls.m_UseMaskingCB->show(); // Modify slider range mitk::Image::Pointer image = dynamic_cast(m_FixedNode->GetData()); int min = (int)image->GetStatistics()->GetScalarValueMin(); int max = (int)image->GetStatistics()->GetScalarValueMax(); m_Controls.m_ContourSlider->setRange(min, max); // Set slider to a default value int avg = (min+max) / 2; m_Controls.m_ContourSlider->setSliderPosition(avg); m_Controls.m_ThresholdLabel->setText(QString::number(avg)); } else { m_Controls.m_FixedLabel->hide(); m_Controls.TextLabelFixed->hide(); m_Controls.m_SwitchImages->hide(); } this->CheckCalculateEnabled(); if(this->GetActiveStdMultiWidget()) { m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls.timeSlider, m_MultiWidget->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromRigidRegistration"); connect( m_TimeStepperAdapter, SIGNAL( Refetch() ), this, SLOT( UpdateTimestep() ) ); } } void QmitkRigidRegistrationView::MovingSelected(mitk::DataNode::Pointer movingImage) { if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_OriginalOpacity); if (m_FixedNode == m_MovingNode) m_FixedNode->SetOpacity(0.5); this->SetImageColor(false); } // selection did not change - do onot reset if( m_MovingNode.IsNotNull() && m_MovingNode == movingImage) { } else { m_MovingNode = movingImage; if (m_MovingNode.IsNotNull()) { m_MovingNode->SetVisibility(true); m_Controls.TextLabelMoving->setText(QString::fromStdString(m_MovingNode->GetName())); m_Controls.m_MovingLabel->show(); m_Controls.TextLabelMoving->show(); mitk::ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(m_MovingNode->GetProperty("color")); if ( colorProperty.IsNotNull() ) { m_MovingColor = colorProperty->GetColor(); } this->SetImageColor(m_ShowRedGreen); m_MovingNode->GetFloatProperty("opacity", m_OriginalOpacity); this->OpacityUpdate(m_Opacity); // what's about masking? m_Controls.m_UseMaskingCB->show(); } else { m_Controls.m_MovingLabel->hide(); m_Controls.TextLabelMoving->hide(); m_Controls.m_UseMaskingCB->hide(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->MovingImageChanged(); this->CheckCalculateEnabled(); } } bool QmitkRigidRegistrationView::CheckCalculate() { if(m_MovingNode==m_FixedNode) return false; return true; } void QmitkRigidRegistrationView::AddNewTransformationToUndoList() { mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); m_UndoGeometryList.push_back(static_cast(movingData->GetGeometry()->Clone().GetPointer())); GeometryMapType childGeometries = GeometryMapType(); if(m_MovingMaskNode.IsNotNull()) { childGeometries.insert(std::pair(m_MovingMaskNode, static_cast(m_MovingMaskNode->GetData()->GetGeometry()->Clone().GetPointer()))); } mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); if(children.IsNotNull() && children->Size() != 0) { unsigned long size; size = children->Size(); for (unsigned long i = 0; i < size; ++i) { childGeometries.insert(std::pair(children->GetElement(i), static_cast(children->GetElement(i)->GetData()->GetGeometry()->Clone().GetPointer()))); } } m_UndoChildGeometryList.push_back(childGeometries); m_RedoGeometryList.clear(); m_RedoChildGeometryList.clear(); this->SetUndoEnabled(true); this->SetRedoEnabled(false); } void QmitkRigidRegistrationView::UndoTransformation() { if(!m_UndoGeometryList.empty()) { mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); m_RedoGeometryList.push_back(static_cast(movingData->GetGeometry(0)->Clone().GetPointer())); unsigned long size = 0; GeometryMapType childGeometries = GeometryMapType(); if(m_MovingMaskNode.IsNotNull()) { ++size; } mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); size += children->Size(); for (unsigned long i = 0; i < size; ++i) { if(i==0) { childGeometries.insert(std::pair(m_MovingMaskNode, static_cast(m_MovingMaskNode->GetData()->GetGeometry()->Clone().GetPointer()))); } else { childGeometries.insert(std::pair(children->GetElement(i), static_cast(children->GetElement(i)->GetData()->GetGeometry()->Clone().GetPointer()))); } } m_RedoChildGeometryList.push_back(childGeometries); movingData->SetGeometry(m_UndoGeometryList.back()); m_UndoGeometryList.pop_back(); GeometryMapType oldChildGeometries; oldChildGeometries = m_UndoChildGeometryList.back(); m_UndoChildGeometryList.pop_back(); GeometryMapType::iterator iter; for (unsigned long j = 0; j < size; ++j) { if(j == 0) // we have put the geometry for the moving mask at position one { iter = oldChildGeometries.find(m_MovingMaskNode); mitk::Geometry3D* geo = static_cast((*iter).second); m_MovingMaskNode->GetData()->SetGeometry(geo); m_MovingMaskNode->GetData()->GetTimeGeometry()->Update(); } else { iter = oldChildGeometries.find(children->GetElement(j)); children->GetElement(j)->GetData()->SetGeometry((*iter).second); } } //\FIXME when geometry is substituted the matrix referenced by the actor created by the mapper //is still pointing to the old one. Workaround: delete mapper //m_MovingNode->SetMapper(1, NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->SetRedoEnabled(true); } if(!m_UndoGeometryList.empty()) { this->SetUndoEnabled(true); } else { this->SetUndoEnabled(false); } this->CheckCalculateEnabled(); } void QmitkRigidRegistrationView::RedoTransformation() { if(!m_RedoGeometryList.empty()) { mitk::BaseData::Pointer movingData = m_MovingNode->GetData(); m_UndoGeometryList.push_back(static_cast(movingData->GetGeometry(0)->Clone().GetPointer())); unsigned long size = 0; GeometryMapType childGeometries = GeometryMapType(); if(m_MovingMaskNode.IsNotNull()) { ++size; } mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); size += children->Size(); for (unsigned long i = 0; i < size; ++i) { if(i == 0) { childGeometries.insert(std::pair(m_MovingMaskNode, static_cast(m_MovingMaskNode->GetData()->GetGeometry()->Clone().GetPointer()))); } else { childGeometries.insert(std::pair(children->GetElement(i), static_cast(children->GetElement(i)->GetData()->GetGeometry()->Clone().GetPointer()))); } } m_UndoChildGeometryList.push_back(childGeometries); movingData->SetGeometry(m_RedoGeometryList.back()); m_RedoGeometryList.pop_back(); GeometryMapType oldChildGeometries; oldChildGeometries = m_RedoChildGeometryList.back(); m_RedoChildGeometryList.pop_back(); GeometryMapType::iterator iter; for (unsigned long j = 0; j < size; ++j) { if(j == 0) { iter = oldChildGeometries.find(m_MovingMaskNode); m_MovingMaskNode->GetData()->SetGeometry((*iter).second); } else { iter = oldChildGeometries.find(children->GetElement(j)); children->GetElement(j)->GetData()->SetGeometry((*iter).second); } } movingData->GetTimeGeometry()->Update(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->SetUndoEnabled(true); } if(!m_RedoGeometryList.empty()) { this->SetRedoEnabled(true); } else { this->SetRedoEnabled(false); } } void QmitkRigidRegistrationView::ShowRedGreen(bool redGreen) { m_ShowRedGreen = redGreen; this->SetImageColor(m_ShowRedGreen); } void QmitkRigidRegistrationView::EnableContour(bool show) { if(show) ShowContour(); // Can happen when the m_ContourHelperNode was deleted before and now the show contour checkbox is turned off if(m_ContourHelperNode.IsNull()) return; m_Controls.m_ContourSlider->setEnabled(show); m_ContourHelperNode->SetProperty("visible", mitk::BoolProperty::New(show)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } void QmitkRigidRegistrationView::ShowContour() { int threshold = m_Controls.m_ContourSlider->value(); bool show = m_Controls.m_ShowContour->isChecked(); if(m_FixedNode.IsNull() || !show) return; // Update the label next to the slider m_Controls.m_ThresholdLabel->setText(QString::number(threshold)); mitk::Image::Pointer image = dynamic_cast(m_FixedNode->GetData()); typedef itk::Image FloatImageType; typedef itk::Image ShortImageType; // Create a binary image using the given treshold typedef itk::BinaryThresholdImageFilter ThresholdFilterType; FloatImageType::Pointer floatImage = FloatImageType::New(); mitk::CastToItkImage(image, floatImage); ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New(); thresholdFilter->SetInput(floatImage); thresholdFilter->SetLowerThreshold(threshold); thresholdFilter->SetUpperThreshold((int)image->GetStatistics()->GetScalarValueMax()); thresholdFilter->SetInsideValue(1); thresholdFilter->SetOutsideValue(0); thresholdFilter->Update(); ShortImageType::Pointer binaryImage = thresholdFilter->GetOutput(); mitk::Image::Pointer mitkBinaryImage = mitk::Image::New(); mitk::CastToMitkImage(binaryImage, mitkBinaryImage); // Create a contour from the binary image mitk::ManualSegmentationToSurfaceFilter::Pointer surfaceFilter = mitk::ManualSegmentationToSurfaceFilter::New(); surfaceFilter->SetInput( mitkBinaryImage ); surfaceFilter->SetThreshold( 1 ); //expects binary image with zeros and ones surfaceFilter->SetUseGaussianImageSmooth(false); // apply gaussian to thresholded image ? surfaceFilter->SetMedianFilter3D(false); // apply median to segmentation before marching cubes ? surfaceFilter->SetDecimate( mitk::ImageToSurfaceFilter::NoDecimation ); surfaceFilter->UpdateLargestPossibleRegion(); // calculate normals for nicer display mitk::Surface::Pointer surface = surfaceFilter->GetOutput(); if(m_ContourHelperNode.IsNull()) { m_ContourHelperNode = mitk::DataNode::New(); m_ContourHelperNode->SetData(surface); m_ContourHelperNode->SetProperty("opacity", mitk::FloatProperty::New(1.0) ); m_ContourHelperNode->SetProperty("line width", mitk::IntProperty::New(2) ); m_ContourHelperNode->SetProperty("scalar visibility", mitk::BoolProperty::New(false) ); m_ContourHelperNode->SetProperty( "name", mitk::StringProperty::New("surface") ); m_ContourHelperNode->SetProperty("color", mitk::ColorProperty::New(1.0, 0.0, 0.0)); m_ContourHelperNode->SetBoolProperty("helper object", true); this->GetDataStorage()->Add(m_ContourHelperNode); } else { m_ContourHelperNode->SetData(surface); } mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } void QmitkRigidRegistrationView::SetImageColor(bool redGreen) { if (!redGreen && m_FixedNode.IsNotNull()) { m_FixedNode->SetColor(m_FixedColor); } if (!redGreen && m_MovingNode.IsNotNull()) { m_MovingNode->SetColor(m_MovingColor); } if (redGreen && m_FixedNode.IsNotNull()) { m_FixedNode->SetColor(1.0f, 0.0f, 0.0f); } if (redGreen && m_MovingNode.IsNotNull()) { m_MovingNode->SetColor(0.0f, 1.0f, 0.0f); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkRigidRegistrationView::OpacityUpdate(float opacity) { m_Opacity = opacity; if (m_MovingNode.IsNotNull()) { m_MovingNode->SetOpacity(m_Opacity); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkRigidRegistrationView::OpacityUpdate(int opacity) { float fValue = ((float)opacity)/100.0f; this->OpacityUpdate(fValue); } void QmitkRigidRegistrationView::ClearTransformationLists() { this->SetUndoEnabled(false); this->SetRedoEnabled(false); m_UndoGeometryList.clear(); m_UndoChildGeometryList.clear(); m_RedoGeometryList.clear(); m_RedoChildGeometryList.clear(); } void QmitkRigidRegistrationView::Translate(int* translateVector) { if (m_MovingNode.IsNotNull()) { mitk::Vector3D translateVec; mitk::ScalarType sliderSensitivity = 0.1; translateVec[0] = sliderSensitivity * (translateVector[0] - m_TranslateSliderPos[0]); translateVec[1] = sliderSensitivity * (translateVector[1] - m_TranslateSliderPos[1]); translateVec[2] = sliderSensitivity * (translateVector[2] - m_TranslateSliderPos[2]); m_TranslateSliderPos[0] = translateVector[0]; m_TranslateSliderPos[1] = translateVector[1]; m_TranslateSliderPos[2] = translateVector[2]; vtkMatrix4x4* translationMatrix = vtkMatrix4x4::New(); translationMatrix->Identity(); double (*transMatrix)[4] = translationMatrix->Element; transMatrix[0][3] = -translateVec[0]; transMatrix[1][3] = -translateVec[1]; transMatrix[2][3] = -translateVec[2]; translationMatrix->Invert(); m_MovingNode->GetData()->GetGeometry()->Compose( translationMatrix ); m_MovingNode->GetData()->Modified(); mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); unsigned long size; size = children->Size(); mitk::DataNode::Pointer childNode; for (unsigned long i = 0; i < size; ++i) { childNode = children->GetElement(i); childNode->GetData()->GetGeometry()->Compose( translationMatrix ); childNode->GetData()->Modified(); } m_RedoGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkRigidRegistrationView::Rotate(int* rotateVector) { if (m_MovingNode.IsNotNull()) { mitk::Vector3D rotateVec; rotateVec[0] = rotateVector[0] - m_RotateSliderPos[0]; rotateVec[1] = rotateVector[1] - m_RotateSliderPos[1]; rotateVec[2] = rotateVector[2] - m_RotateSliderPos[2]; m_RotateSliderPos[0] = rotateVector[0]; m_RotateSliderPos[1] = rotateVector[1]; m_RotateSliderPos[2] = rotateVector[2]; vtkMatrix4x4* rotationMatrix = vtkMatrix4x4::New(); vtkMatrix4x4* translationMatrix = vtkMatrix4x4::New(); rotationMatrix->Identity(); translationMatrix->Identity(); double (*rotMatrix)[4] = rotationMatrix->Element; double (*transMatrix)[4] = translationMatrix->Element; mitk::Point3D centerBB = m_MovingNode->GetData()->GetGeometry()->GetCenter(); transMatrix[0][3] = centerBB[0]; transMatrix[1][3] = centerBB[1]; transMatrix[2][3] = centerBB[2]; translationMatrix->Invert(); m_MovingNode->GetData()->GetGeometry()->Compose( translationMatrix ); mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); unsigned long size; size = children->Size(); mitk::DataNode::Pointer childNode; for (unsigned long i = 0; i < size; ++i) { childNode = children->GetElement(i); childNode->GetData()->GetGeometry()->Compose( translationMatrix ); childNode->GetData()->Modified(); } double radianX = rotateVec[0] * vnl_math::pi / 180; double radianY = rotateVec[1] * vnl_math::pi / 180; double radianZ = rotateVec[2] * vnl_math::pi / 180; if ( rotateVec[0] != 0 ) { rotMatrix[1][1] = cos( radianX ); rotMatrix[1][2] = -sin( radianX ); rotMatrix[2][1] = sin( radianX ); rotMatrix[2][2] = cos( radianX ); } else if ( rotateVec[1] != 0 ) { rotMatrix[0][0] = cos( radianY ); rotMatrix[0][2] = sin( radianY ); rotMatrix[2][0] = -sin( radianY ); rotMatrix[2][2] = cos( radianY ); } else if ( rotateVec[2] != 0 ) { rotMatrix[0][0] = cos( radianZ ); rotMatrix[0][1] = -sin( radianZ ); rotMatrix[1][0] = sin( radianZ ); rotMatrix[1][1] = cos( radianZ ); } m_MovingNode->GetData()->GetGeometry()->Compose( rotationMatrix ); for (unsigned long i = 0; i < size; ++i) { childNode = children->GetElement(i); childNode->GetData()->GetGeometry()->Compose( rotationMatrix ); childNode->GetData()->Modified(); } translationMatrix->Invert(); m_MovingNode->GetData()->GetGeometry()->Compose( translationMatrix ); for (unsigned long i = 0; i < size; ++i) { childNode = children->GetElement(i); childNode->GetData()->GetGeometry()->Compose( translationMatrix ); childNode->GetData()->Modified(); } m_MovingNode->GetData()->Modified(); m_RedoGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkRigidRegistrationView::Scale(int* scaleVector) { if (m_MovingNode.IsNotNull()) { mitk::Vector3D scaleVec; scaleVec[0] = scaleVector[0] - m_ScaleSliderPos[0]; scaleVec[1] = scaleVector[1] - m_ScaleSliderPos[1]; scaleVec[2] = scaleVector[2] - m_ScaleSliderPos[2]; m_ScaleSliderPos[0] = scaleVector[0]; m_ScaleSliderPos[1] = scaleVector[1]; m_ScaleSliderPos[2] = scaleVector[2]; vtkMatrix4x4* scalingMatrix = vtkMatrix4x4::New(); scalingMatrix->Identity(); double (*scaleMatrix)[4] = scalingMatrix->Element; if (scaleVec[0] >= 0) { for(int i = 0; i= 0) { for(int i = 0; i= 0) { for(int i = 0; iInvert(); m_MovingNode->GetData()->GetGeometry()->Compose( scalingMatrix ); m_MovingNode->GetData()->Modified(); mitk::DataStorage::SetOfObjects::ConstPointer children = this->GetDataStorage()->GetDerivations(m_MovingNode); unsigned long size; size = children->Size(); mitk::DataNode::Pointer childNode; for (unsigned long i = 0; i < size; ++i) { childNode = children->GetElement(i); childNode->GetData()->GetGeometry()->Compose( scalingMatrix ); childNode->GetData()->Modified(); } m_RedoGeometryList.clear(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkRigidRegistrationView::AlignCenters() { if (m_FixedNode.IsNotNull() && m_MovingNode.IsNotNull()) { mitk::Point3D fixedPoint = m_FixedNode->GetData()->GetGeometry()->GetCenter(); mitk::Point3D movingPoint = m_MovingNode->GetData()->GetGeometry()->GetCenter(); mitk::Vector3D translateVec; translateVec = fixedPoint - movingPoint; m_Controls.m_XTransSlider->setValue((int)m_Controls.m_XTransSlider->value() + (int)translateVec[0]); m_Controls.m_YTransSlider->setValue((int)m_Controls.m_YTransSlider->value() + (int)translateVec[1]); m_Controls.m_ZTransSlider->setValue((int)m_Controls.m_ZTransSlider->value() + (int)translateVec[2]); } } void QmitkRigidRegistrationView::SetUndoEnabled( bool enable ) { m_Controls.m_UndoTransformation->setEnabled(enable); } void QmitkRigidRegistrationView::SetRedoEnabled( bool enable ) { m_Controls.m_RedoTransformation->setEnabled(enable); } void QmitkRigidRegistrationView::CheckCalculateEnabled() { if (m_FixedNode.IsNotNull() && m_MovingNode.IsNotNull()) { m_Controls.m_ManualFrame->setEnabled(true); m_Controls.m_CalculateTransformation->setEnabled(true); if ( (m_FixedDimension != m_MovingDimension && std::max(m_FixedDimension, m_MovingDimension) != 4) || m_FixedDimension < 2 /*|| m_FixedDimension > 3*/) { m_Controls.m_CalculateTransformation->setEnabled(false); } else if (m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() < 5 && (m_FixedDimension < 2) /*|| m_FixedDimension > 3)*/) { m_Controls.m_CalculateTransformation->setEnabled(false); } else if ((m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() > 4 && m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() < 13) && !(m_FixedDimension > 2)) { m_Controls.m_CalculateTransformation->setEnabled(false); } else if (m_Controls.qmitkRigidRegistrationSelector1->GetSelectedTransform() > 12 && m_FixedDimension != 2) { m_Controls.m_CalculateTransformation->setEnabled(false); } } else { m_Controls.m_CalculateTransformation->setEnabled(false); m_Controls.m_ManualFrame->setEnabled(false); } } void QmitkRigidRegistrationView::xTrans_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { translationParams[0]=v; translationParams[1]=m_Controls.m_YTransSlider->value(); translationParams[2]=m_Controls.m_ZTransSlider->value(); Translate(translationParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::yTrans_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { translationParams[0]=m_Controls.m_XTransSlider->value(); translationParams[1]=v; translationParams[2]=m_Controls.m_ZTransSlider->value(); Translate(translationParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::zTrans_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { translationParams[0]=m_Controls.m_XTransSlider->value(); translationParams[1]=m_Controls.m_YTransSlider->value(); translationParams[2]=v; Translate(translationParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::xRot_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { rotationParams[0]=v; rotationParams[1]=m_Controls.m_YRotSlider->value(); rotationParams[2]=m_Controls.m_ZRotSlider->value(); Rotate(rotationParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::yRot_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { rotationParams[0]=m_Controls.m_XRotSlider->value(); rotationParams[1]=v; rotationParams[2]=m_Controls.m_ZRotSlider->value(); Rotate(rotationParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::zRot_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { rotationParams[0]=m_Controls.m_XRotSlider->value(); rotationParams[1]=m_Controls.m_YRotSlider->value(); rotationParams[2]=v; Rotate(rotationParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::xScale_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { scalingParams[0]=v; scalingParams[1]=m_Controls.m_YScaleSlider->value(); scalingParams[2]=m_Controls.m_ZScaleSlider->value(); Scale(scalingParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::yScale_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { scalingParams[0]=m_Controls.m_XScaleSlider->value(); scalingParams[1]=v; scalingParams[2]=m_Controls.m_ZScaleSlider->value(); Scale(scalingParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::zScale_valueChanged( int v ) { if (m_MovingNode.IsNotNull()) { scalingParams[0]=m_Controls.m_XScaleSlider->value(); scalingParams[1]=m_Controls.m_YScaleSlider->value(); scalingParams[2]=v; Scale(scalingParams); } else { MovingImageChanged(); } } void QmitkRigidRegistrationView::MovingImageChanged() { if (dynamic_cast(m_MovingNode->GetData())) { m_Controls.m_XTransSlider->setValue(0); m_Controls.m_YTransSlider->setValue(0); m_Controls.m_ZTransSlider->setValue(0); translationParams[0]=0; translationParams[1]=0; translationParams[2]=0; m_Controls.m_XRotSlider->setValue(0); m_Controls.m_YRotSlider->setValue(0); m_Controls.m_ZRotSlider->setValue(0); rotationParams[0]=0; rotationParams[1]=0; rotationParams[2]=0; m_Controls.m_XScaleSlider->setValue(0); m_Controls.m_YScaleSlider->setValue(0); m_Controls.m_ZScaleSlider->setValue(0); scalingParams[0]=0; scalingParams[1]=0; scalingParams[2]=0; m_MovingDimension = dynamic_cast(m_MovingNode->GetData())->GetDimension(); m_Controls.qmitkRigidRegistrationSelector1->SetMovingDimension(m_MovingDimension); m_Controls.qmitkRigidRegistrationSelector1->SetMovingNode(m_MovingNode); this->CheckCalculateEnabled(); } } void QmitkRigidRegistrationView::Calculate() { m_Controls.qmitkRigidRegistrationSelector1->SetFixedNode(m_FixedNode); m_Controls.qmitkRigidRegistrationSelector1->SetMovingNode(m_MovingNode); if (m_FixedMaskNode.IsNotNull() && m_Controls.m_UseMaskingCB->isChecked()) { m_Controls.qmitkRigidRegistrationSelector1->SetFixedMaskNode(m_FixedMaskNode); } else { m_Controls.qmitkRigidRegistrationSelector1->SetFixedMaskNode(NULL); } if (m_MovingMaskNode.IsNotNull() && m_Controls.m_UseMaskingCB->isChecked()) { m_Controls.qmitkRigidRegistrationSelector1->SetMovingMaskNode(m_MovingMaskNode); } else { m_Controls.qmitkRigidRegistrationSelector1->SetMovingMaskNode(NULL); } m_Controls.frame_2->setEnabled(false); m_Controls.frame_3->setEnabled(false); m_Controls.m_CalculateTransformation->setEnabled(false); m_Controls.m_StopOptimization->setEnabled(true); m_Controls.qmitkRigidRegistrationSelector1->CalculateTransformation(((QmitkSliderNavigatorWidget*)m_Controls.timeSlider)->GetPos()); m_Controls.m_StopOptimization->setEnabled(false); m_Controls.frame_2->setEnabled(true); m_Controls.frame_3->setEnabled(true); m_Controls.m_CalculateTransformation->setEnabled(true); m_Controls.qmitkRigidRegistrationSelector1->StopOptimization(false); } void QmitkRigidRegistrationView::SetOptimizerValue( double value ) { m_Controls.m_OptimizerValueLCD->display(value); } void QmitkRigidRegistrationView::StopOptimizationClicked() { m_Controls.qmitkRigidRegistrationSelector1->StopOptimization(true); } void QmitkRigidRegistrationView::UpdateTimestep() { mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkRigidRegistrationView::ShowManualRegistrationFrame(bool show) { if (show) { m_Controls.m_ManualFrame->show(); } else { m_Controls.m_ManualFrame->hide(); } } void QmitkRigidRegistrationView::SetImagesVisible(berry::ISelection::ConstPointer /*selection*/) { if (this->m_CurrentSelection->Size() == 0) { // show all images mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects = this->GetDataStorage()->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin() ; nodeIt != setOfObjects->End(); ++nodeIt) // for each node { if ( (nodeIt->Value().IsNotNull()) && (nodeIt->Value()->GetProperty("visible")) && dynamic_cast(nodeIt->Value()->GetData())==NULL) { nodeIt->Value()->SetVisibility(true); } } } else { // hide all images mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects = this->GetDataStorage()->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin() ; nodeIt != setOfObjects->End(); ++nodeIt) // for each node { if ( (nodeIt->Value().IsNotNull()) && (nodeIt->Value()->GetProperty("visible")) && dynamic_cast(nodeIt->Value()->GetData())==NULL) { nodeIt->Value()->SetVisibility(false); } } } } void QmitkRigidRegistrationView::TabChanged(int index) { if (index == 0) { m_Controls.frame->hide(); } else { m_Controls.frame->show(); } } void QmitkRigidRegistrationView::SwitchImages() { mitk::DataNode::Pointer newMoving = m_FixedNode; mitk::DataNode::Pointer newFixed = m_MovingNode; this->FixedSelected(newFixed); this->MovingSelected(newMoving); if(m_ContourHelperNode.IsNotNull()) { // Update the contour ShowContour(); } if(m_Controls.m_UseMaskingCB->isChecked()) { mitk::DataNode::Pointer tempMovingMask = NULL; mitk::DataNode::Pointer tempFixedMask = NULL; if(m_FixedMaskNode.IsNotNull()) // it is initialized { tempFixedMask = m_Controls.m_FixedImageCB->GetSelectedNode(); } if(m_MovingMaskNode.IsNotNull()) // it is initialized { tempMovingMask = m_Controls.m_MovingImageCB->GetSelectedNode(); } m_Controls.m_FixedImageCB->SetSelectedNode(tempMovingMask); m_Controls.m_MovingImageCB->SetSelectedNode(tempFixedMask); } } void QmitkRigidRegistrationView::OnUseMaskingChanged( int state ) { if(state == Qt::Checked) { m_Controls.m_FixedImageCB->show(); m_Controls.m_MovingImageCB->show(); m_Controls.m_MovingMaskLB->show(); m_Controls.m_FixedMaskLB->show(); } else { m_Controls.m_FixedImageCB->hide(); m_Controls.m_MovingImageCB->hide(); m_Controls.m_MovingMaskLB->hide(); m_Controls.m_FixedMaskLB->hide(); m_FixedMaskNode = NULL; m_MovingMaskNode = NULL; } } void QmitkRigidRegistrationView::OnFixedMaskImageChanged( const mitk::DataNode* node ) { if(m_Controls.m_UseMaskingCB->isChecked()) m_FixedMaskNode = const_cast(node); else m_FixedMaskNode = NULL; } void QmitkRigidRegistrationView::OnMovingMaskImageChanged( const mitk::DataNode* node ) { if(m_Controls.m_UseMaskingCB->isChecked()) m_MovingMaskNode = const_cast(node); else m_MovingMaskNode = NULL; }