diff --git a/Core/Code/DataManagement/mitkMatrixConvert.h b/Core/Code/DataManagement/mitkMatrixConvert.h index b549a10fbc..3b5428d6a6 100644 --- a/Core/Code/DataManagement/mitkMatrixConvert.h +++ b/Core/Code/DataManagement/mitkMatrixConvert.h @@ -1,152 +1,152 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKMATRIXCONVERT_H_HEADER_INCLUDED_C1EBD0AD #define MITKMATRIXCONVERT_H_HEADER_INCLUDED_C1EBD0AD #include "mitkGeometry3D.h" #include "mitkBaseGeometry.h" #include "mitkItkMatrixHack.h" #include namespace mitk { template void TransferVtkMatrixToItkTransform(const vtkMatrix4x4* vtkmatrix, TTransformType * itkTransform) { if(itkTransform==NULL) return; typename TTransformType::MatrixType::InternalMatrixType& vnlMatrix = const_cast(itkTransform->GetMatrix().GetVnlMatrix()); for ( int i=0; i < 3; ++i) for( int j=0; j < 3; ++j ) vnlMatrix[i][j] = vtkmatrix->GetElement( i, j ); // *This* ensures m_MatrixMTime.Modified(), which is therewith not equal to // m_InverseMatrixMTime, thus a new inverse will be calculated (when // requested). static_cast*>(itkTransform)->MatrixChanged(); typename TTransformType::OffsetType offset; offset[0] = vtkmatrix->GetElement( 0, 3 ); offset[1] = vtkmatrix->GetElement( 1, 3 ); offset[2] = vtkmatrix->GetElement( 2, 3 ); itkTransform->SetOffset( offset ); } template void TransferItkTransformToVtkMatrix(const TTransformType * itkTransform, vtkMatrix4x4* vtkmatrix) { int i,j; for(i=0;i<3;++i) for(j=0;j<3;++j) vtkmatrix->SetElement(i, j, itkTransform->GetMatrix().GetVnlMatrix().get(i, j)); for(i=0;i<3;++i) vtkmatrix->SetElement(i, 3, itkTransform->GetOffset()[i]); for(i=0;i<3;++i) vtkmatrix->SetElement(3, i, 0.0); vtkmatrix->SetElement(3, 3, 1); } template void ConvertItkTransform(const TTransformType1* sourceTransform, TTransformType2* destTransform) { if((sourceTransform==NULL) || (destTransform==NULL)) return; // transfer offset const typename TTransformType1::OutputVectorType& sourceOffset = sourceTransform->GetOffset(); typename TTransformType2::OutputVectorType offset; offset[0] = sourceOffset[0]; offset[1] = sourceOffset[1]; offset[2] = sourceOffset[2]; destTransform->SetOffset( offset ); typename TTransformType1::MatrixType::InternalMatrixType& sourceVnlMatrix = const_cast(sourceTransform->GetMatrix().GetVnlMatrix()); //transfer matrix typename TTransformType2::MatrixType::InternalMatrixType& destVnlMatrix = const_cast(destTransform->GetMatrix().GetVnlMatrix()); for ( int i=0; i < 3; ++i) for( int j=0; j < 3; ++j ) destVnlMatrix[i][j] = sourceVnlMatrix[i][j]; // *This* ensures m_MatrixMTime.Modified(), which is therewith not equal to // m_InverseMatrixMTime, thus a new inverse will be calculated (when // requested). static_cast*>(destTransform)->MatrixChanged(); } template void GetRotation(const mitk::BaseGeometry * geometry, TMatrixType& itkmatrix) { const mitk::Vector3D& spacing = geometry->GetSpacing(); typename mitk::BaseGeometry::TransformType::MatrixType::InternalMatrixType& geometryVnlMatrix = const_cast(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix()); typename TMatrixType::InternalMatrixType& outputVnlMatrix = const_cast(itkmatrix.GetVnlMatrix()); for ( int i=0; i < 3; ++i) for( int j=0; j < 3; ++j ) outputVnlMatrix [i][j] = geometryVnlMatrix [i][j] / spacing[j]; } template - void GetWorldToItkPhysicalTransform(const mitk::Geometry3D * geometry, TTransformType* itkTransform) + void GetWorldToItkPhysicalTransform(const mitk::BaseGeometry * geometry, TTransformType* itkTransform) { if(itkTransform==NULL) return; // get rotation matrix and offset from Geometry and transfer in TTransformType types typename TTransformType::MatrixType rotationMatrix; GetRotation(geometry, rotationMatrix); const typename mitk::Geometry3D::TransformType::OffsetType& geometryOffset = geometry->GetIndexToWorldTransform()->GetOffset(); vnl_vector vnlOffset(3); vnlOffset[0] = geometryOffset[0]; vnlOffset[1] = geometryOffset[1]; vnlOffset[2] = geometryOffset[2]; // do calculations typename TTransformType::MatrixType::InternalMatrixType inverseRotationVnlMatrix = rotationMatrix.GetTranspose(); vnlOffset -= inverseRotationVnlMatrix*vnlOffset; typename TTransformType::OutputVectorType offset;//vnl_vector offset; offset[0] = vnlOffset[0]; offset[1] = vnlOffset[1]; offset[2] = vnlOffset[2]; itkTransform->SetOffset( offset ); // copy in destination itkTransform typename TTransformType::MatrixType::InternalMatrixType& destVnlMatrix = const_cast(itkTransform->GetMatrix().GetVnlMatrix()); for ( int i=0; i < 3; ++i) for( int j=0; j < 3; ++j ) destVnlMatrix[i][j] = inverseRotationVnlMatrix[i][j]; // *This* ensures m_MatrixMTime.Modified(), which is therewith not equal to // m_InverseMatrixMTime, thus a new inverse will be calculated (when // requested). static_cast*>(itkTransform)->MatrixChanged(); } } #endif /* MITKMATRIXCONVERT_H_HEADER_INCLUDED_C1EBD0AD */ diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp index 56cd32ee5e..0fa6f2ae69 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp @@ -1,897 +1,897 @@ /*=================================================================== 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 "QmitkImageStatisticsView.h" // Qt includes #include #include // berry includes #include // mitk includes #include "mitkNodePredicateDataType.h" #include "mitkPlanarFigureInteractor.h" // itk includes #include "itksys/SystemTools.hxx" #include #include const std::string QmitkImageStatisticsView::VIEW_ID = "org.mitk.views.imagestatistics"; const int QmitkImageStatisticsView::STAT_TABLE_BASE_HEIGHT = 180; QmitkImageStatisticsView::QmitkImageStatisticsView(QObject* /*parent*/, const char* /*name*/) : m_Controls( NULL ), m_TimeStepperAdapter( NULL ), m_SelectedImage( NULL ), m_SelectedImageMask( NULL ), m_SelectedPlanarFigure( NULL ), m_ImageObserverTag( -1 ), m_ImageMaskObserverTag( -1 ), m_PlanarFigureObserverTag( -1 ), m_TimeObserverTag( -1 ), m_CurrentStatisticsValid( false ), m_StatisticsUpdatePending( false ), m_DataNodeSelectionChanged ( false ), m_Visible(false) { this->m_CalculationThread = new QmitkImageStatisticsCalculationThread; } QmitkImageStatisticsView::~QmitkImageStatisticsView() { if ( m_SelectedImage != NULL ) m_SelectedImage->RemoveObserver( m_ImageObserverTag ); if ( m_SelectedImageMask != NULL ) m_SelectedImageMask->RemoveObserver( m_ImageMaskObserverTag ); if ( m_SelectedPlanarFigure != NULL ) m_SelectedPlanarFigure->RemoveObserver( m_PlanarFigureObserverTag ); while(this->m_CalculationThread->isRunning()) // wait until thread has finished { itksys::SystemTools::Delay(100); } delete this->m_CalculationThread; } void QmitkImageStatisticsView::CreateQtPartControl(QWidget *parent) { if (m_Controls == NULL) { m_Controls = new Ui::QmitkImageStatisticsViewControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_ErrorMessageLabel->hide(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); } } void QmitkImageStatisticsView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(this->m_Controls->m_ButtonCopyHistogramToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(OnClipboardHistogramButtonClicked()) ); connect( (QObject*)(this->m_Controls->m_ButtonCopyStatisticsToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(OnClipboardStatisticsButtonClicked()) ); connect( (QObject*)(this->m_Controls->m_IgnoreZerosCheckbox), SIGNAL(clicked()),(QObject*) this, SLOT(OnIgnoreZerosCheckboxClicked()) ); connect( (QObject*) this->m_CalculationThread, SIGNAL(finished()),this, SLOT( OnThreadedStatisticsCalculationEnds()),Qt::QueuedConnection); connect( (QObject*) this, SIGNAL(StatisticsUpdate()),this, SLOT( RequestStatisticsUpdate()), Qt::QueuedConnection); connect( (QObject*) this->m_Controls->m_StatisticsTable, SIGNAL(cellDoubleClicked(int,int)),this, SLOT( JumpToCoordinates(int,int)) ); connect( (QObject*) (this->m_Controls->m_barRadioButton), SIGNAL(clicked()), (QObject*) (this->m_Controls->m_JSHistogram), SLOT(OnBarRadioButtonSelected())); connect( (QObject*) (this->m_Controls->m_lineRadioButton), SIGNAL(clicked()), (QObject*) (this->m_Controls->m_JSHistogram), SLOT(OnLineRadioButtonSelected())); } } void QmitkImageStatisticsView::PartClosed( berry::IWorkbenchPartReference::Pointer ) { } void QmitkImageStatisticsView::OnTimeChanged(const itk::EventObject& e) { if (this->m_SelectedDataNodes.isEmpty() || this->m_SelectedImage == NULL) return; const mitk::SliceNavigationController::GeometryTimeEvent* timeEvent = dynamic_cast(&e); assert(timeEvent != NULL); unsigned int timestep = timeEvent->GetPos(); if (this->m_SelectedImage->GetTimeSteps() > 1) { for (unsigned int x = 0; x < this->m_Controls->m_StatisticsTable->columnCount(); x++) { for (unsigned int y = 0; y < this->m_Controls->m_StatisticsTable->rowCount(); y++) { QTableWidgetItem* item = this->m_Controls->m_StatisticsTable->item(y, x); if (item == NULL) break; if (x == timestep) { item->setBackgroundColor(Qt::yellow); } else { if (y % 2 == 0) item->setBackground(this->m_Controls->m_StatisticsTable->palette().base()); else item->setBackground(this->m_Controls->m_StatisticsTable->palette().alternateBase()); } } } this->m_Controls->m_StatisticsTable->viewport()->update(); } if ((this->m_SelectedImage->GetTimeSteps() == 1 && timestep == 0) || this->m_SelectedImage->GetTimeSteps() > 1) { // display histogram for selected timestep this->m_Controls->m_JSHistogram->ClearHistogram(); QmitkImageStatisticsCalculationThread::HistogramType::Pointer histogram = this->m_CalculationThread->GetTimeStepHistogram(timestep); if (histogram.IsNotNull()) { this->m_Controls->m_JSHistogram->ComputeHistogram(histogram.GetPointer()); // this->m_Controls->m_JSHistogram->SignalGraphChanged(); // hacky way to make sure the protected SignalGraphChanged() is called if (this->m_Controls->m_JSHistogram->GetUseLineGraph()) { this->m_Controls->m_JSHistogram->OnBarRadioButtonSelected(); this->m_Controls->m_JSHistogram->OnLineRadioButtonSelected(); } else { this->m_Controls->m_JSHistogram->OnLineRadioButtonSelected(); this->m_Controls->m_JSHistogram->OnBarRadioButtonSelected(); } } } } void QmitkImageStatisticsView::JumpToCoordinates(int row ,int col) { if(m_SelectedDataNodes.isEmpty()) { MITK_WARN("QmitkImageStatisticsView") << "No data node selected for statistics calculation." ; return; } mitk::Point3D world; if (row==4) world = m_WorldMinList[col]; else if (row==3) world = m_WorldMaxList[col]; else return; mitk::IRenderWindowPart* part = this->GetRenderWindowPart(); if (part) { part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SelectSliceByPoint(world); part->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SelectSliceByPoint(world); part->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SelectSliceByPoint(world); mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), col); part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetGeometryTime(timeEvent); } } void QmitkImageStatisticsView::OnIgnoreZerosCheckboxClicked() { emit StatisticsUpdate(); } void QmitkImageStatisticsView::OnClipboardHistogramButtonClicked() { if ( m_CurrentStatisticsValid ) { const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); typedef mitk::ImageStatisticsCalculator::HistogramType HistogramType; const HistogramType *histogram = this->m_CalculationThread->GetTimeStepHistogram(t).GetPointer(); QString clipboard( "Measurement \t Frequency\n" ); for ( HistogramType::ConstIterator it = histogram->Begin(); it != histogram->End(); ++it ) { clipboard = clipboard.append( "%L1 \t %L2\n" ) .arg( it.GetMeasurementVector()[0], 0, 'f', 2 ) .arg( it.GetFrequency() ); } QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkImageStatisticsView::OnClipboardStatisticsButtonClicked() { QLocale tempLocal; QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); if ( this->m_CurrentStatisticsValid ) { const std::vector &statistics = this->m_CalculationThread->GetStatisticsData(); const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()-> GetPos(); // Copy statistics to clipboard ("%Ln" will use the default locale for // number formatting) QString clipboard( "Mean \t StdDev \t RMS \t Max \t Min \t N \t V (mm³)\n" ); clipboard = clipboard.append( "%L1 \t %L2 \t %L3 \t %L4 \t %L5 \t %L6 \t %L7" ) .arg( statistics[t].Mean, 0, 'f', 10 ) .arg( statistics[t].Sigma, 0, 'f', 10 ) .arg( statistics[t].RMS, 0, 'f', 10 ) .arg( statistics[t].Max, 0, 'f', 10 ) .arg( statistics[t].Min, 0, 'f', 10 ) .arg( statistics[t].N ) .arg( m_Controls->m_StatisticsTable->item( 0, 6 )->text().toDouble(), 0, 'f', 10 ); QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } QLocale::setDefault(tempLocal); } void QmitkImageStatisticsView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*part*/, const QList &selectedNodes ) { if (this->m_Visible) { this->SelectionChanged( selectedNodes ); } else { this->m_DataNodeSelectionChanged = true; } } void QmitkImageStatisticsView::SelectionChanged(const QList &selectedNodes) { if( this->m_StatisticsUpdatePending ) { this->m_DataNodeSelectionChanged = true; return; // not ready for new data now! } if (selectedNodes.size() == this->m_SelectedDataNodes.size()) { int i = 0; for (; i < selectedNodes.size(); ++i) { if (selectedNodes.at(i) != this->m_SelectedDataNodes.at(i)) { break; } } // node selection did not change if (i == selectedNodes.size()) return; } this->ReinitData(); if (selectedNodes.isEmpty()) { m_Controls->m_JSHistogram->ClearHistogram(); m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); // m_Controls->horizontalLayout_3->setEnabled(false); m_Controls->groupBox->setEnabled(false); m_Controls->groupBox_3->setEnabled(false); } else { // m_Controls->horizontalLayout_3->setEnabled(true); m_Controls->groupBox->setEnabled(true); m_Controls->groupBox_3->setEnabled(true); } if(selectedNodes.size() == 1 || selectedNodes.size() == 2) { bool isBinary = false; selectedNodes.value(0)->GetBoolProperty("binary",isBinary); if(isBinary) { m_Controls->m_JSHistogram->ClearHistogram(); m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); } for (int i= 0; i< selectedNodes.size(); ++i) { this->m_SelectedDataNodes.push_back(selectedNodes.at(i)); } this->m_DataNodeSelectionChanged = false; this->m_Controls->m_ErrorMessageLabel->setText( "" ); this->m_Controls->m_ErrorMessageLabel->hide(); emit StatisticsUpdate(); } else { this->m_DataNodeSelectionChanged = false; } } void QmitkImageStatisticsView::ReinitData() { while( this->m_CalculationThread->isRunning()) // wait until thread has finished { itksys::SystemTools::Delay(100); } if(this->m_SelectedImage != NULL) { this->m_SelectedImage->RemoveObserver( this->m_ImageObserverTag); this->m_SelectedImage = NULL; } if(this->m_SelectedImageMask != NULL) { this->m_SelectedImageMask->RemoveObserver( this->m_ImageMaskObserverTag); this->m_SelectedImageMask = NULL; } if(this->m_SelectedPlanarFigure != NULL) { this->m_SelectedPlanarFigure->RemoveObserver( this->m_PlanarFigureObserverTag); this->m_SelectedPlanarFigure = NULL; } this->m_SelectedDataNodes.clear(); this->m_StatisticsUpdatePending = false; m_Controls->m_ErrorMessageLabel->setText( "" ); m_Controls->m_ErrorMessageLabel->hide(); this->InvalidateStatisticsTableView(); m_Controls->m_JSHistogram->ClearHistogram(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); } void QmitkImageStatisticsView::OnThreadedStatisticsCalculationEnds() { std::stringstream message; message << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->hide(); this->WriteStatisticsToGUI(); } void QmitkImageStatisticsView::UpdateStatistics() { mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart(); if ( renderPart == NULL ) { this->m_StatisticsUpdatePending = false; return; } m_WorldMinList.clear(); m_WorldMaxList.clear(); // classify selected nodes mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image"); std::string maskName = std::string(); std::string maskType = std::string(); unsigned int maskDimension = 0; // reset data from last run ITKCommandType::Pointer changeListener = ITKCommandType::New(); changeListener->SetCallbackFunction( this, &QmitkImageStatisticsView::SelectedDataModified ); mitk::DataNode::Pointer planarFigureNode; for( int i= 0 ; i < this->m_SelectedDataNodes.size(); ++i) { mitk::PlanarFigure::Pointer planarFig = dynamic_cast(this->m_SelectedDataNodes.at(i)->GetData()); if( imagePredicate->CheckNode(this->m_SelectedDataNodes.at(i)) ) { bool isMask = false; this->m_SelectedDataNodes.at(i)->GetPropertyValue("binary", isMask); if( this->m_SelectedImageMask == NULL && isMask) { this->m_SelectedImageMask = dynamic_cast(this->m_SelectedDataNodes.at(i)->GetData()); this->m_ImageMaskObserverTag = this->m_SelectedImageMask->AddObserver(itk::ModifiedEvent(), changeListener); maskName = this->m_SelectedDataNodes.at(i)->GetName(); maskType = m_SelectedImageMask->GetNameOfClass(); maskDimension = 3; } else if( !isMask ) { if(this->m_SelectedImage == NULL) { this->m_SelectedImage = static_cast(this->m_SelectedDataNodes.at(i)->GetData()); this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener); } } } else if (planarFig.IsNotNull()) { if(this->m_SelectedPlanarFigure == NULL) { this->m_SelectedPlanarFigure = planarFig; this->m_PlanarFigureObserverTag = this->m_SelectedPlanarFigure->AddObserver(mitk::EndInteractionPlanarFigureEvent(), changeListener); maskName = this->m_SelectedDataNodes.at(i)->GetName(); maskType = this->m_SelectedPlanarFigure->GetNameOfClass(); maskDimension = 2; planarFigureNode = m_SelectedDataNodes.at(i); } } else { std::stringstream message; message << "" << "Invalid data node type!" << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); } } if(maskName == "") { maskName = "None"; maskType = ""; maskDimension = 0; } if (m_SelectedPlanarFigure != NULL && m_SelectedImage == NULL) { mitk::DataStorage::SetOfObjects::ConstPointer parentSet = this->GetDataStorage()->GetSources(planarFigureNode); for (int i=0; iSize(); i++) { mitk::DataNode::Pointer node = parentSet->ElementAt(i); if( imagePredicate->CheckNode(node) ) { bool isMask = false; node->GetPropertyValue("binary", isMask); if( !isMask ) { if(this->m_SelectedImage == NULL) { this->m_SelectedImage = static_cast(node->GetData()); this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener); } } } } } unsigned int timeStep = renderPart->GetTimeNavigationController()->GetTime()->GetPos(); if ( m_SelectedImage != NULL && m_SelectedImage->IsInitialized()) { // Check if a the selected image is a multi-channel image. If yes, statistics // cannot be calculated currently. if ( m_SelectedImage->GetPixelType().GetNumberOfComponents() > 1 ) { std::stringstream message; message << "Multi-component images not supported."; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->InvalidateStatisticsTableView(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); m_Controls->m_JSHistogram->ClearHistogram(); m_CurrentStatisticsValid = false; this->m_StatisticsUpdatePending = false; m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); return; } std::stringstream maskLabel; maskLabel << maskName; if ( maskDimension > 0 ) { maskLabel << " [" << maskDimension << "D " << maskType << "]"; } m_Controls->m_SelectedMaskLabel->setText( maskLabel.str().c_str() ); // check time step validity if(m_SelectedImage->GetDimension() <= 3 && timeStep > m_SelectedImage->GetDimension(3)-1) { timeStep = m_SelectedImage->GetDimension(3)-1; } // Add the used mask time step to the mask label so the user knows which mask time step was used // if the image time step is bigger than the total number of mask time steps (see // ImageStatisticsCalculator::ExtractImageAndMask) if (m_SelectedImageMask != NULL) { unsigned int maskTimeStep = timeStep; if (maskTimeStep >= m_SelectedImageMask->GetTimeSteps()) { maskTimeStep = m_SelectedImageMask->GetTimeSteps() - 1; } m_Controls->m_SelectedMaskLabel->setText(m_Controls->m_SelectedMaskLabel->text() + QString(" (t=") + QString::number(maskTimeStep) + QString(")")); } //// initialize thread and trigger it this->m_CalculationThread->SetIgnoreZeroValueVoxel( m_Controls->m_IgnoreZerosCheckbox->isChecked() ); this->m_CalculationThread->Initialize( m_SelectedImage, m_SelectedImageMask, m_SelectedPlanarFigure ); this->m_CalculationThread->SetTimeStep( timeStep ); std::stringstream message; message << "Calculating statistics..."; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); try { // Compute statistics this->m_CalculationThread->start(); } catch ( const mitk::Exception& e) { std::stringstream message; message << "" << e.GetDescription() << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->m_StatisticsUpdatePending = false; } catch ( const std::runtime_error &e ) { // In case of exception, print error message on GUI std::stringstream message; message << "" << e.what() << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->m_StatisticsUpdatePending = false; } catch ( const std::exception &e ) { MITK_ERROR << "Caught exception: " << e.what(); // In case of exception, print error message on GUI std::stringstream message; message << "Error! Unequal Dimensions of Image and Segmentation. No recompute possible "; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->m_StatisticsUpdatePending = false; } } else { this->m_StatisticsUpdatePending = false; } } void QmitkImageStatisticsView::SelectedDataModified() { if( !m_StatisticsUpdatePending ) { emit StatisticsUpdate(); } } void QmitkImageStatisticsView::NodeRemoved(const mitk::DataNode *node) { while(this->m_CalculationThread->isRunning()) // wait until thread has finished { itksys::SystemTools::Delay(100); } if (node->GetData() == m_SelectedImage) { m_SelectedImage = NULL; } } void QmitkImageStatisticsView::RequestStatisticsUpdate() { if ( !m_StatisticsUpdatePending ) { if(this->m_DataNodeSelectionChanged) { this->SelectionChanged(this->GetCurrentSelection()); } else { this->m_StatisticsUpdatePending = true; this->UpdateStatistics(); } } if (this->GetRenderWindowPart()) this->GetRenderWindowPart()->RequestUpdate(); } void QmitkImageStatisticsView::WriteStatisticsToGUI() { m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); if(m_DataNodeSelectionChanged) { this->m_StatisticsUpdatePending = false; this->RequestStatisticsUpdate(); return; // stop visualization of results and calculate statistics of new selection } if ( this->m_CalculationThread->GetStatisticsUpdateSuccessFlag()) { if ( this->m_CalculationThread->GetStatisticsChangedFlag() ) { // Do not show any error messages m_Controls->m_ErrorMessageLabel->hide(); m_CurrentStatisticsValid = true; } if (m_Controls->m_barRadioButton->isChecked()) { m_Controls->m_JSHistogram->OnBarRadioButtonSelected(); } m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); //m_Controls->m_JSHistogram->ComputeHistogram( this->m_CalculationThread->GetTimeStepHistogram(this->m_CalculationThread->GetTimeStep()).GetPointer() ); this->FillStatisticsTableView( this->m_CalculationThread->GetStatisticsData(), this->m_CalculationThread->GetStatisticsImage()); } else { m_Controls->m_SelectedMaskLabel->setText( "None" ); m_Controls->m_ErrorMessageLabel->setText( m_CalculationThread->GetLastErrorMessage().c_str() ); m_Controls->m_ErrorMessageLabel->show(); // Clear statistics and histogram this->InvalidateStatisticsTableView(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); //m_Controls->m_JSHistogram->clearHistogram(); m_CurrentStatisticsValid = false; // If a (non-closed) PlanarFigure is selected, display a line profile widget if ( m_SelectedPlanarFigure != NULL ) { // Check if the (closed) planar figure is out of bounds and so no image mask could be calculated--> Intensity Profile can not be calculated bool outOfBounds = false; if ( m_SelectedPlanarFigure->IsClosed() && m_SelectedImageMask == NULL) { outOfBounds = true; std::stringstream message; message << "Planar figure is outside the images bounds."; m_Controls->m_InfoLabel->setText(message.str().c_str()); } // check whether PlanarFigure is initialized - const mitk::Geometry2D *planarFigureGeometry2D = m_SelectedPlanarFigure->GetGeometry2D(); + const mitk::PlaneGeometry *planarFigureGeometry2D = m_SelectedPlanarFigure->GetGeometry2D(); if ( planarFigureGeometry2D == NULL || outOfBounds) { // Clear statistics, histogram, and GUI this->InvalidateStatisticsTableView(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); m_Controls->m_JSHistogram->ClearHistogram(); m_CurrentStatisticsValid = false; m_Controls->m_ErrorMessageLabel->hide(); m_Controls->m_SelectedMaskLabel->setText( "None" ); this->m_StatisticsUpdatePending = false; m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); if (!outOfBounds) m_Controls->m_InfoLabel->setText(QString("")); return; } unsigned int timeStep = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); m_Controls->m_JSHistogram->SetImage(this->m_CalculationThread->GetStatisticsImage()); m_Controls->m_JSHistogram->SetPlanarFigure(m_SelectedPlanarFigure); m_Controls->m_JSHistogram->ComputeIntensityProfile(timeStep); m_Controls->m_lineRadioButton->setEnabled(false); m_Controls->m_barRadioButton->setEnabled(false); std::stringstream message; message << "Only linegraph available for an intesityprofile!"; m_Controls->m_InfoLabel->setText(message.str().c_str()); } } this->m_StatisticsUpdatePending = false; } void QmitkImageStatisticsView::FillStatisticsTableView( const std::vector &s, const mitk::Image *image ) { this->m_Controls->m_StatisticsTable->setColumnCount(image->GetTimeSteps()); this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(image->GetTimeSteps() > 1); for (unsigned int t = 0; t < image->GetTimeSteps(); t++) { this->m_Controls->m_StatisticsTable->setHorizontalHeaderItem(t, new QTableWidgetItem(QString::number(t))); if (s[t].MaxIndex.size()==3) { mitk::Point3D index, max, min; index[0] = s[t].MaxIndex[0]; index[1] = s[t].MaxIndex[1]; index[2] = s[t].MaxIndex[2]; m_SelectedImage->GetGeometry()->IndexToWorld(index, max); this->m_WorldMaxList.push_back(max); index[0] = s[t].MinIndex[0]; index[1] = s[t].MinIndex[1]; index[2] = s[t].MinIndex[2]; m_SelectedImage->GetGeometry()->IndexToWorld(index, min); this->m_WorldMinList.push_back(min); } int decimals = 2; mitk::PixelType doublePix = mitk::MakeScalarPixelType< double >(); mitk::PixelType floatPix = mitk::MakeScalarPixelType< float >(); if (image->GetPixelType()==doublePix || image->GetPixelType()==floatPix) decimals = 5; this->m_Controls->m_StatisticsTable->setItem( 0, t, new QTableWidgetItem( QString("%1").arg(s[t].Mean, 0, 'f', decimals) ) ); this->m_Controls->m_StatisticsTable->setItem( 1, t, new QTableWidgetItem( QString("%1").arg(s[t].Sigma, 0, 'f', decimals) ) ); this->m_Controls->m_StatisticsTable->setItem( 2, t, new QTableWidgetItem( QString("%1").arg(s[t].RMS, 0, 'f', decimals) ) ); QString max; max.append(QString("%1").arg(s[t].Max, 0, 'f', decimals)); max += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 3, t, new QTableWidgetItem( max ) ); QString min; min.append(QString("%1").arg(s[t].Min, 0, 'f', decimals)); min += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 4, t, new QTableWidgetItem( min ) ); this->m_Controls->m_StatisticsTable->setItem( 5, t, new QTableWidgetItem( QString("%1").arg(s[t].N) ) ); - const mitk::Geometry3D *geometry = image->GetGeometry(); + const mitk::BaseGeometry *geometry = image->GetGeometry(); if ( geometry != NULL ) { const mitk::Vector3D &spacing = image->GetGeometry()->GetSpacing(); double volume = spacing[0] * spacing[1] * spacing[2] * (double) s[t].N; this->m_Controls->m_StatisticsTable->setItem( 6, t, new QTableWidgetItem( QString("%1").arg(volume, 0, 'f', decimals) ) ); } else { this->m_Controls->m_StatisticsTable->setItem( 6, t, new QTableWidgetItem( "NA" ) ); } } this->m_Controls->m_StatisticsTable->resizeColumnsToContents(); int height = STAT_TABLE_BASE_HEIGHT; if (this->m_Controls->m_StatisticsTable->horizontalHeader()->isVisible()) height += this->m_Controls->m_StatisticsTable->horizontalHeader()->height(); if (this->m_Controls->m_StatisticsTable->horizontalScrollBar()->isVisible()) height += this->m_Controls->m_StatisticsTable->horizontalScrollBar()->height(); this->m_Controls->m_StatisticsTable->setMinimumHeight(height); // make sure the current timestep's column is highlighted (and the correct histogram is displayed) unsigned int timestep = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()-> GetPos(); mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), timestep); this->OnTimeChanged(timeEvent); } void QmitkImageStatisticsView::InvalidateStatisticsTableView() { this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(false); this->m_Controls->m_StatisticsTable->setColumnCount(1); for ( unsigned int i = 0; i < this->m_Controls->m_StatisticsTable->rowCount(); ++i ) { { this->m_Controls->m_StatisticsTable->setItem( i, 0, new QTableWidgetItem( "NA" ) ); } } this->m_Controls->m_StatisticsTable->setMinimumHeight(STAT_TABLE_BASE_HEIGHT); } void QmitkImageStatisticsView::Activated() { } void QmitkImageStatisticsView::Deactivated() { } void QmitkImageStatisticsView::Visible() { m_Visible = true; mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart(); if (renderWindow) { itk::ReceptorMemberCommand::Pointer cmdTimeEvent = itk::ReceptorMemberCommand::New(); cmdTimeEvent->SetCallbackFunction(this, &QmitkImageStatisticsView::OnTimeChanged); // It is sufficient to add the observer to the axial render window since the GeometryTimeEvent // is always triggered by all views. m_TimeObserverTag = renderWindow->GetQmitkRenderWindow("axial")-> GetSliceNavigationController()-> AddObserver(mitk::SliceNavigationController::GeometryTimeEvent(NULL, 0), cmdTimeEvent); } if (m_DataNodeSelectionChanged) { if (this->IsCurrentSelectionValid()) { this->SelectionChanged(this->GetCurrentSelection()); } else { this->SelectionChanged(this->GetDataManagerSelection()); } m_DataNodeSelectionChanged = false; } } void QmitkImageStatisticsView::Hidden() { m_Visible = false; // The slice navigation controller observer is removed here instead of in the destructor. // If it was called in the destructor, the application would freeze because the view's // destructor gets called after the render windows have been destructed. if ( m_TimeObserverTag != NULL ) { mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart(); if (renderWindow) { renderWindow->GetQmitkRenderWindow("axial")->GetSliceNavigationController()-> RemoveObserver( m_TimeObserverTag ); } m_TimeObserverTag = NULL; } } void QmitkImageStatisticsView::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp index 652391506d..bfffdcf0fd 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp @@ -1,914 +1,911 @@ /*=================================================================== 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 MEASUREMENT_DEBUG MITK_DEBUG("QmitkMeasurementView") << __LINE__ << ": " #include "QmitkMeasurementView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkPluginActivator.h" #include "usModuleRegistry.h" template static T* GetService() { ctkPluginContext* context = mitk::PluginActivator::GetContext(); ctkServiceReference serviceRef = context->getServiceReference(); return serviceRef ? context->getService(serviceRef) : NULL; } struct QmitkPlanarFigureData { QmitkPlanarFigureData() : m_Figure(0), m_EndPlacementObserverTag(0), m_SelectObserverTag(0), m_StartInteractionObserverTag(0), m_EndInteractionObserverTag(0) { } mitk::PlanarFigure* m_Figure; unsigned int m_EndPlacementObserverTag; unsigned int m_SelectObserverTag; unsigned int m_StartInteractionObserverTag; unsigned int m_EndInteractionObserverTag; }; struct QmitkMeasurementViewData { QmitkMeasurementViewData() : m_LineCounter(0), m_PathCounter(0), m_AngleCounter(0), m_FourPointAngleCounter(0), m_EllipseCounter(0), m_DoubleEllipseCounter(0), m_RectangleCounter(0), m_PolygonCounter(0), m_BezierCurveCounter(0), m_UnintializedPlanarFigure(false) { } // internal vars unsigned int m_LineCounter; unsigned int m_PathCounter; unsigned int m_AngleCounter; unsigned int m_FourPointAngleCounter; unsigned int m_EllipseCounter; unsigned int m_DoubleEllipseCounter; unsigned int m_RectangleCounter; unsigned int m_PolygonCounter; unsigned int m_BezierCurveCounter; QList m_CurrentSelection; std::map m_DataNodeToPlanarFigureData; mitk::WeakPointer m_SelectedImageNode; bool m_UnintializedPlanarFigure; // WIDGETS QWidget* m_Parent; QLabel* m_SelectedImageLabel; QAction* m_DrawLine; QAction* m_DrawPath; QAction* m_DrawAngle; QAction* m_DrawFourPointAngle; QAction* m_DrawDoubleEllipse; QAction* m_DrawRectangle; QAction* m_DrawPolygon; QAction* m_DrawEllipse; QAction* m_DrawBezierCurve; QToolBar* m_DrawActionsToolBar; QActionGroup* m_DrawActionsGroup; QTextBrowser* m_SelectedPlanarFiguresText; QPushButton* m_CopyToClipboard; QGridLayout* m_Layout; }; const std::string QmitkMeasurementView::VIEW_ID = "org.mitk.views.measurement"; QmitkMeasurementView::QmitkMeasurementView() : d( new QmitkMeasurementViewData ) { } QmitkMeasurementView::~QmitkMeasurementView() { this->RemoveAllInteractors(); delete d; } void QmitkMeasurementView::CreateQtPartControl(QWidget* parent) { d->m_Parent = parent; // image label QLabel* selectedImageLabel = new QLabel("Reference Image: "); d->m_SelectedImageLabel = new QLabel; d->m_SelectedImageLabel->setStyleSheet("font-weight: bold;"); d->m_DrawActionsToolBar = new QToolBar; d->m_DrawActionsGroup = new QActionGroup(this); d->m_DrawActionsGroup->setExclusive(true); //# add actions MEASUREMENT_DEBUG << "Draw Line"; QAction* currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/line.png"), "Draw Line"); currentAction->setCheckable(true); d->m_DrawLine = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Path"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/path.png"), "Draw Path"); currentAction->setCheckable(true); d->m_DrawPath = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Angle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/angle.png"), "Draw Angle"); currentAction->setCheckable(true); d->m_DrawAngle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Four Point Angle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/four-point-angle.png"), "Draw Four Point Angle"); currentAction->setCheckable(true); d->m_DrawFourPointAngle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Circle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/circle.png"), "Draw Circle"); currentAction->setCheckable(true); d->m_DrawEllipse = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Rectangle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/rectangle.png"), "Draw Rectangle"); currentAction->setCheckable(true); d->m_DrawRectangle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Polygon"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/polygon.png"), "Draw Polygon"); currentAction->setCheckable(true); d->m_DrawPolygon = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Double Ellipse"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/doubleellipse.png"), "Draw Double Ellipse"); currentAction->setCheckable(true); d->m_DrawDoubleEllipse = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Bezier Curve"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/beziercurve.png"), "Draw Bezier Curve"); currentAction->setCheckable(true); d->m_DrawBezierCurve = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); // planar figure details text d->m_SelectedPlanarFiguresText = new QTextBrowser; // copy to clipboard button d->m_CopyToClipboard = new QPushButton("Copy to Clipboard"); d->m_Layout = new QGridLayout; d->m_Layout->addWidget(selectedImageLabel, 0, 0, 1, 1); d->m_Layout->addWidget(d->m_SelectedImageLabel, 0, 1, 1, 1); d->m_Layout->addWidget(d->m_DrawActionsToolBar, 1, 0, 1, 2); d->m_Layout->addWidget(d->m_SelectedPlanarFiguresText, 2, 0, 1, 2); d->m_Layout->addWidget(d->m_CopyToClipboard, 3, 0, 1, 2); d->m_Parent->setLayout(d->m_Layout); // create connections this->CreateConnections(); // readd interactors and observers this->AddAllInteractors(); } void QmitkMeasurementView::CreateConnections() { QObject::connect( d->m_DrawLine, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawLineTriggered(bool) ) ); QObject::connect( d->m_DrawPath, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPathTriggered(bool) ) ); QObject::connect( d->m_DrawAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawAngleTriggered(bool) ) ); QObject::connect( d->m_DrawFourPointAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawFourPointAngleTriggered(bool) ) ); QObject::connect( d->m_DrawEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawEllipseTriggered(bool) ) ); QObject::connect( d->m_DrawDoubleEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawDoubleEllipseTriggered(bool) ) ); QObject::connect( d->m_DrawRectangle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawRectangleTriggered(bool) ) ); QObject::connect( d->m_DrawPolygon, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPolygonTriggered(bool) ) ); QObject::connect( d->m_DrawBezierCurve, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawBezierCurveTriggered(bool) ) ); QObject::connect( d->m_CopyToClipboard, SIGNAL( clicked(bool) ), this, SLOT( CopyToClipboard(bool) ) ); } void QmitkMeasurementView::NodeAdded( const mitk::DataNode* node ) { // add observer for selection in renderwindow mitk::PlanarFigure* figure = dynamic_cast(node->GetData()); bool isPositionMarker (false); node->GetBoolProperty("isContourMarker", isPositionMarker); if( figure && !isPositionMarker ) { MEASUREMENT_DEBUG << "figure added. will add interactor if needed."; mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer() ); mitk::DataNode* nonConstNode = const_cast( node ); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( nonConstNode ); // nonConstNode->SetBoolProperty( "planarfigure.isextendable", true ); } else { // just to be sure that the interactor is not added twice // mitk::GlobalInteraction::GetInstance()->RemoveInteractor(figureInteractor); } MEASUREMENT_DEBUG << "adding interactor to globalinteraction"; // mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); MEASUREMENT_DEBUG << "will now add observers for planarfigure"; QmitkPlanarFigureData data; data.m_Figure = figure; // add observer for event when figure has been placed typedef itk::SimpleMemberCommand< QmitkMeasurementView > SimpleCommandType; SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New(); initializationCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureInitialized ); data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand ); // add observer for event when figure is picked (selected) typedef itk::MemberCommand< QmitkMeasurementView > MemberCommandType; MemberCommandType::Pointer selectCommand = MemberCommandType::New(); selectCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureSelected ); data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New(); startInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::DisableCrosshairNavigation); data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New(); endInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::EnableCrosshairNavigation); data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand ); // adding to the map of tracked planarfigures d->m_DataNodeToPlanarFigureData[nonConstNode] = data; } this->CheckForTopMostVisibleImage(); } void QmitkMeasurementView::NodeChanged(const mitk::DataNode* node) { // DETERMINE IF WE HAVE TO RENEW OUR DETAILS TEXT (ANY NODE CHANGED IN OUR SELECTION?) bool renewText = false; for( int i=0; i < d->m_CurrentSelection.size(); ++i ) { if( node == d->m_CurrentSelection.at(i) ) { renewText = true; break; } } if(renewText) { MEASUREMENT_DEBUG << "Selected nodes changed. Refreshing text."; this->UpdateMeasurementText(); } this->CheckForTopMostVisibleImage(); } void QmitkMeasurementView::CheckForTopMostVisibleImage(mitk::DataNode* _NodeToNeglect) { d->m_SelectedImageNode = this->DetectTopMostVisibleImage().GetPointer(); if( d->m_SelectedImageNode.GetPointer() == _NodeToNeglect ) d->m_SelectedImageNode = 0; if( d->m_SelectedImageNode.IsNotNull() && d->m_UnintializedPlanarFigure == false ) { MEASUREMENT_DEBUG << "Reference image found"; d->m_SelectedImageLabel->setText( QString::fromStdString( d->m_SelectedImageNode->GetName() ) ); d->m_DrawActionsToolBar->setEnabled(true); MEASUREMENT_DEBUG << "Updating Measurement text"; } else { MEASUREMENT_DEBUG << "No reference image available. Will disable actions for creating new planarfigures"; if( d->m_UnintializedPlanarFigure == false ) d->m_SelectedImageLabel->setText( "No visible image available." ); d->m_DrawActionsToolBar->setEnabled(false); } } void QmitkMeasurementView::NodeRemoved(const mitk::DataNode* node) { MEASUREMENT_DEBUG << "node removed from data storage"; mitk::DataNode* nonConstNode = const_cast(node); std::map::iterator it = d->m_DataNodeToPlanarFigureData.find(nonConstNode); bool isFigureFinished = false; bool isPlaced = false; if( it != d->m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; // remove observers data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag ); data.m_Figure->RemoveObserver( data.m_SelectObserverTag ); data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag ); data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag ); MEASUREMENT_DEBUG << "removing from the list of tracked planar figures"; isFigureFinished = data.m_Figure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced); if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons } d->m_DataNodeToPlanarFigureData.erase( it ); } mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = GetDataStorage()->GetDerivations(node,isPlanarFigure); for (unsigned int x = 0; x < nodes->size(); x++) { mitk::PlanarFigure* planarFigure = dynamic_cast (nodes->at(x)->GetData()); if (planarFigure != NULL) { isFigureFinished = planarFigure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced); if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode GetDataStorage()->Remove(nodes->at(x)); if( !d->m_DataNodeToPlanarFigureData.empty() ) { std::map::iterator it2 = d->m_DataNodeToPlanarFigureData.find(nodes->at(x)); //check if returned it2 valid if( it2 != d->m_DataNodeToPlanarFigureData.end() ) { d->m_DataNodeToPlanarFigureData.erase( it2 );// removing planar figure from tracked figure list PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons EnableCrosshairNavigation(); } } } } } this->CheckForTopMostVisibleImage(nonConstNode); } void QmitkMeasurementView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& ) { MEASUREMENT_DEBUG << "planar figure " << object << " selected"; std::map::iterator it = d->m_DataNodeToPlanarFigureData.begin(); d->m_CurrentSelection.clear(); while( it != d->m_DataNodeToPlanarFigureData.end()) { mitk::DataNode* node = it->first; QmitkPlanarFigureData& data = it->second; if( data.m_Figure == object ) { MITK_DEBUG << "selected node found. enabling selection"; node->SetSelected(true); d->m_CurrentSelection.push_back( node ); } else { node->SetSelected(false); } ++it; } this->UpdateMeasurementText(); this->RequestRenderWindowUpdate(); } void QmitkMeasurementView::PlanarFigureInitialized() { MEASUREMENT_DEBUG << "planar figure initialized"; d->m_UnintializedPlanarFigure = false; d->m_DrawActionsToolBar->setEnabled(true); d->m_DrawLine->setChecked(false); d->m_DrawPath->setChecked(false); d->m_DrawAngle->setChecked(false); d->m_DrawFourPointAngle->setChecked(false); d->m_DrawEllipse->setChecked(false); d->m_DrawRectangle->setChecked(false); d->m_DrawPolygon->setChecked(false); d->m_DrawDoubleEllipse->setChecked(false); d->m_DrawBezierCurve->setChecked(false); } void QmitkMeasurementView::SetFocus() { d->m_SelectedImageLabel->setFocus(); } void QmitkMeasurementView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList &nodes) { MEASUREMENT_DEBUG << "Determine the top most visible image"; MEASUREMENT_DEBUG << "The PlanarFigure interactor will take the currently visible PlaneGeometry from the slice navigation controller"; this->CheckForTopMostVisibleImage(); MEASUREMENT_DEBUG << "refreshing selection and detailed text"; d->m_CurrentSelection = nodes; this->UpdateMeasurementText(); // bug 16600: deselecting all planarfigures by clicking on datamanager when no node is selected if(d->m_CurrentSelection.size() == 0) { mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetDataStorage()->GetSubset( isPlanarFigure ); // setting all planar figures which are not helper objects not selected for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++) { mitk::DataNode* node = it.Value(); bool isHelperObject(false); node->GetBoolProperty("helper object", isHelperObject); if(!isHelperObject) { node->SetSelected(false); } } } for( int i=d->m_CurrentSelection.size()-1; i>= 0; --i) { mitk::DataNode* node = d->m_CurrentSelection.at(i); mitk::PlanarFigure* _PlanarFigure = dynamic_cast (node->GetData()); // the last selected planar figure if (_PlanarFigure && _PlanarFigure->GetGeometry2D()) { QmitkRenderWindow* selectedRenderWindow = 0; bool PlanarFigureInitializedWindow = false; mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart()); if(! linkedRenderWindow ) { return; } QmitkRenderWindow* RenderWindow1 = linkedRenderWindow->GetQmitkRenderWindow( "axial") ; QmitkRenderWindow* RenderWindow2 = linkedRenderWindow->GetQmitkRenderWindow( "sagittal") ; QmitkRenderWindow* RenderWindow3 = linkedRenderWindow->GetQmitkRenderWindow( "coronal") ; QmitkRenderWindow* RenderWindow4 = linkedRenderWindow->GetQmitkRenderWindow( "3d") ; if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } const mitk::PlaneGeometry* _PlaneGeometry = dynamic_cast (_PlanarFigure->GetGeometry2D()); mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl(); - mitk::Geometry2D::ConstPointer worldGeometry1 = RenderWindow1->GetRenderer()->GetCurrentWorldGeometry2D(); - mitk::PlaneGeometry::ConstPointer _Plane1 = dynamic_cast( worldGeometry1.GetPointer() ); + mitk::PlaneGeometry::ConstPointer _Plane1 = RenderWindow1->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::VnlVector normal1 = _Plane1->GetNormalVnl(); - mitk::Geometry2D::ConstPointer worldGeometry2 = RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D(); - mitk::PlaneGeometry::ConstPointer _Plane2 = dynamic_cast( worldGeometry2.GetPointer() ); + mitk::PlaneGeometry::ConstPointer _Plane2 = RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); - mitk::Geometry2D::ConstPointer worldGeometry3 = RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D(); - mitk::PlaneGeometry::ConstPointer _Plane3 = dynamic_cast( worldGeometry3.GetPointer() ); + mitk::PlaneGeometry::ConstPointer _Plane3 = RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::VnlVector normal3 = _Plane3->GetNormalVnl(); normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]); normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]); normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]); normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]); double ang1 = angle(normal, normal1); double ang2 = angle(normal, normal2); double ang3 = angle(normal, normal3); if(ang1 < ang2 && ang1 < ang3) { selectedRenderWindow = RenderWindow1; } else { if(ang2 < ang3) { selectedRenderWindow = RenderWindow2; } else { selectedRenderWindow = RenderWindow3; } } // re-orient view if (selectedRenderWindow) { const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin(); selectedRenderWindow->GetSliceNavigationController()->ReorientSlices(centerP, _PlaneGeometry->GetNormal()); } } break; } this->RequestRenderWindowUpdate(); } void QmitkMeasurementView::ActionDrawLineTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarLine::Pointer figure = mitk::PlanarLine::New(); QString qString = QString("Line%1").arg(++d->m_LineCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarLine initialized..."; } void QmitkMeasurementView::ActionDrawPathTriggered(bool checked) { Q_UNUSED(checked) mitk::IPropertyFilters* propertyFilters = GetService(); if (propertyFilters != NULL) { mitk::PropertyFilter filter; filter.AddEntry("ClosedPlanarPolygon", mitk::PropertyFilter::Blacklist); propertyFilters->AddFilter(filter, "PlanarPolygon"); } mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOff(); QString qString = QString("Path%1").arg(++d->m_PathCounter); mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString); mitk::BoolProperty::Pointer closedProperty = mitk::BoolProperty::New( false ); node->SetProperty("ClosedPlanarPolygon", closedProperty); node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); MEASUREMENT_DEBUG << "PlanarPath initialized..."; } void QmitkMeasurementView::ActionDrawAngleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarAngle::Pointer figure = mitk::PlanarAngle::New(); QString qString = QString("Angle%1").arg(++d->m_AngleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarAngle initialized..."; } void QmitkMeasurementView::ActionDrawFourPointAngleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarFourPointAngle::Pointer figure = mitk::PlanarFourPointAngle::New(); QString qString = QString("Four Point Angle%1").arg(++d->m_FourPointAngleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarFourPointAngle initialized..."; } void QmitkMeasurementView::ActionDrawEllipseTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New(); QString qString = QString("Circle%1").arg(++d->m_EllipseCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarCircle initialized..."; } void QmitkMeasurementView::ActionDrawDoubleEllipseTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarDoubleEllipse::Pointer figure = mitk::PlanarDoubleEllipse::New(); QString qString = QString("DoubleEllipse%1").arg(++d->m_DoubleEllipseCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarDoubleEllipse initialized..."; } void QmitkMeasurementView::ActionDrawBezierCurveTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarBezierCurve::Pointer figure = mitk::PlanarBezierCurve::New(); QString qString = QString("BezierCurve%1").arg(++d->m_BezierCurveCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarBezierCurve initialized..."; } void QmitkMeasurementView::ActionDrawRectangleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarRectangle::Pointer figure = mitk::PlanarRectangle::New(); QString qString = QString("Rectangle%1").arg(++d->m_RectangleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarRectangle initialized..."; } void QmitkMeasurementView::ActionDrawPolygonTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOn(); QString qString = QString("Polygon%1").arg(++d->m_PolygonCounter); mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString); node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); MEASUREMENT_DEBUG << "PlanarPolygon initialized..."; } void QmitkMeasurementView::CopyToClipboard( bool checked ) { Q_UNUSED(checked) MEASUREMENT_DEBUG << "Copying current Text to clipboard..."; QString clipboardText = d->m_SelectedPlanarFiguresText->toPlainText(); QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard); } mitk::DataNode::Pointer QmitkMeasurementView::AddFigureToDataStorage( mitk::PlanarFigure* figure, const QString& name) { // add as MEASUREMENT_DEBUG << "Adding new figure to datastorage..."; if( d->m_SelectedImageNode.IsNull() ) { MITK_ERROR << "No reference image available"; return 0; } mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetName(name.toStdString()); newNode->SetData(figure); // set as selected newNode->SetSelected( true ); this->GetDataStorage()->Add(newNode, d->m_SelectedImageNode); // set all others in selection as deselected for( int i=0; im_CurrentSelection.size(); ++i) d->m_CurrentSelection.at(i)->SetSelected(false); d->m_CurrentSelection.clear(); d->m_CurrentSelection.push_back( newNode ); this->UpdateMeasurementText(); this->DisableCrosshairNavigation(); d->m_DrawActionsToolBar->setEnabled(false); d->m_UnintializedPlanarFigure = true; return newNode; } void QmitkMeasurementView::UpdateMeasurementText() { d->m_SelectedPlanarFiguresText->clear(); QString infoText; QString plainInfoText; int j = 1; mitk::PlanarFigure* _PlanarFigure = 0; mitk::PlanarAngle* planarAngle = 0; mitk::PlanarFourPointAngle* planarFourPointAngle = 0; mitk::DataNode::Pointer node = 0; for (int i=0; im_CurrentSelection.size(); ++i, ++j) { plainInfoText.clear(); node = d->m_CurrentSelection.at(i); _PlanarFigure = dynamic_cast (node->GetData()); if( !_PlanarFigure ) continue; if(j>1) infoText.append("
"); infoText.append(QString("%1
").arg(QString::fromStdString( node->GetName()))); plainInfoText.append(QString("%1").arg(QString::fromStdString( node->GetName()))); planarAngle = dynamic_cast (_PlanarFigure); if(!planarAngle) { planarFourPointAngle = dynamic_cast (_PlanarFigure); } double featureQuantity = 0.0; for (unsigned int k = 0; k < _PlanarFigure->GetNumberOfFeatures(); ++k) { if ( !_PlanarFigure->IsFeatureActive( k ) ) continue; featureQuantity = _PlanarFigure->GetQuantity(k); if ((planarAngle && k == planarAngle->FEATURE_ID_ANGLE) || (planarFourPointAngle && k == planarFourPointAngle->FEATURE_ID_ANGLE)) featureQuantity = featureQuantity * 180 / vnl_math::pi; infoText.append( QString("%1: %2 %3") .arg(QString( _PlanarFigure->GetFeatureName(k))) .arg(featureQuantity, 0, 'f', 2) .arg(QString(_PlanarFigure->GetFeatureUnit(k)))); plainInfoText.append( QString("\n%1: %2 %3") .arg(QString(_PlanarFigure->GetFeatureName(k))) .arg( featureQuantity, 0, 'f', 2) .arg(QString( _PlanarFigure->GetFeatureUnit(k)))); if(k+1 != _PlanarFigure->GetNumberOfFeatures()) infoText.append("
"); } if (j != d->m_CurrentSelection.size()) infoText.append("
"); } d->m_SelectedPlanarFiguresText->setHtml(infoText); } void QmitkMeasurementView::AddAllInteractors() { MEASUREMENT_DEBUG << "Adding interactors and observers to all planar figures"; mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetAllPlanarFigures(); for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++) { this->NodeAdded( it.Value() ); } } void QmitkMeasurementView::RemoveAllInteractors() { MEASUREMENT_DEBUG << "Removing interactors and observers from all planar figures"; mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetAllPlanarFigures(); for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++) { this->NodeRemoved( it.Value() ); } } mitk::DataNode::Pointer QmitkMeasurementView::DetectTopMostVisibleImage() { // get all images from the data storage which are not a segmentation mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinary = mitk::NodePredicateNot::New( isBinary ); mitk::NodePredicateAnd::Pointer isNormalImage = mitk::NodePredicateAnd::New( isImage, isNotBinary ); mitk::DataStorage::SetOfObjects::ConstPointer Images = this->GetDataStorage()->GetSubset( isNormalImage ); mitk::DataNode::Pointer currentNode; int maxLayer = itk::NumericTraits::min(); // iterate over selection for (mitk::DataStorage::SetOfObjects::ConstIterator sofIt = Images->Begin(); sofIt != Images->End(); ++sofIt) { mitk::DataNode::Pointer node = sofIt->Value(); if ( node.IsNull() ) continue; if (node->IsVisible(NULL) == false) continue; // we also do not want to assign planar figures to helper objects ( even if they are of type image ) if (node->GetProperty("helper object")) continue; int layer = 0; node->GetIntProperty("layer", layer); if ( layer < maxLayer ) { continue; } else { maxLayer = layer; currentNode = node; } } return currentNode; } void QmitkMeasurementView::EnableCrosshairNavigation() { MEASUREMENT_DEBUG << "EnableCrosshairNavigation"; // enable the crosshair navigation if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MEASUREMENT_DEBUG << "enabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(true); linkedRenderWindow->EnableSlicingPlanes(true); } } void QmitkMeasurementView::DisableCrosshairNavigation() { MEASUREMENT_DEBUG << "DisableCrosshairNavigation"; // disable the crosshair navigation during the drawing if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MEASUREMENT_DEBUG << "disabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(false); linkedRenderWindow->EnableSlicingPlanes(false); } } mitk::DataStorage::SetOfObjects::ConstPointer QmitkMeasurementView::GetAllPlanarFigures() const { mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isNotHelperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(false)); mitk::NodePredicateAnd::Pointer isNotHelperButPlanarFigure = mitk::NodePredicateAnd::New( isPlanarFigure, isNotHelperObject ); return this->GetDataStorage()->GetSubset( isPlanarFigure ); } 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 35a2b9f717..64293e2587 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.cpp @@ -1,1360 +1,1368 @@ /*=================================================================== 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 #include #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 isGeometry2DData(mitk::TNodePredicateDataType::New()); mitk::NodePredicateNot::Pointer notGeometry2DData = mitk::NodePredicateNot::New(isGeometry2DData); mitk::NodePredicateAnd::Pointer notPointSetAndNotGeometry2DData = mitk::NodePredicateAnd::New( notPointSet, notGeometry2DData ); mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New( isBaseData, notPointSetAndNotGeometry2DData ); 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 { 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(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection) { // check, if selection comes from datamanager if (part) { QString partname(part->GetPartName().c_str()); if(partname.compare("Data Manager")==0) { // apply selection DoSelectionChanged(selection); } } } QmitkPointBasedRegistrationView* m_View; }; QmitkPointBasedRegistrationView::QmitkPointBasedRegistrationView(QObject * /*parent*/, const char * /*name*/) : QmitkFunctionality(), m_SelListener(0), 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.IsNotNull()) { berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); if(s) s->RemovePostSelectionListener(m_SelListener); m_SelListener = NULL; } 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 = berry::ISelectionListener::Pointer(new SelListenerPointBasedRegistration(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()); } 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); m_SelListener = NULL; } 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::Geometry3D::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); + itk::LightObject::Pointer lopointer = m_MovingLandmarks->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer movingLandmarksGeometry = dynamic_cast(lopointer.GetPointer()); 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::Geometry3D::Pointer movingGeometry = movingData->GetGeometry(0)->Clone(); + itk::LightObject::Pointer lopointer2 = movingData->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer movingGeometry = dynamic_cast(lopointer2.GetPointer()); 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::Geometry3D::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); + itk::LightObject::Pointer lopointer = m_MovingLandmarks->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer movingLandmarksGeometry = dynamic_cast(lopointer.GetPointer()); 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::Geometry3D::Pointer movingGeometry = movingData->GetGeometry(0)->Clone(); + itk::LightObject::Pointer lopointer2 = movingData->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer movingGeometry = dynamic_cast(lopointer2.GetPointer()); 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::Geometry3D::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); - mitk::Geometry3D::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); + itk::LightObject::Pointer lopointer = m_MovingLandmarks->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer movingLandmarksGeometry = dynamic_cast(lopointer.GetPointer()); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); mitk::BaseData::Pointer originalData = m_MovingNode->GetData(); - mitk::Geometry3D::Pointer originalDataGeometry = originalData->GetGeometry(0)->Clone(); + itk::LightObject::Pointer lopointer2 = originalData->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer originalDataGeometry = dynamic_cast(lopointer2.GetPointer()); 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::Geometry3D::Pointer movingGeometry = movingData->GetGeometry(0); + 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::Geometry3D::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); - mitk::Geometry3D::Pointer movingLandmarksGeometry = m_MovingLandmarks->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer pointsGeometry = m_MovingLandmarks->GetGeometry(0); + itk::LightObject::Pointer lopointer = m_MovingLandmarks->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer movingLandmarksGeometry = dynamic_cast(lopointer.GetPointer()); m_UndoPointsGeometryList.push_back(movingLandmarksGeometry.GetPointer()); mitk::BaseData::Pointer originalData = m_MovingNode->GetData(); - mitk::Geometry3D::Pointer originalDataGeometry = originalData->GetGeometry(0)->Clone(); + itk::LightObject::Pointer lopointer2 = originalData->GetGeometry(0)->Clone(); + mitk::BaseGeometry::Pointer originalDataGeometry = dynamic_cast(lopointer2.GetPointer()); 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::Geometry3D::Pointer movingGeometry = movingData->GetGeometry(0); + 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::Geometry3D::Pointer fixedGeometry = fixedData->GetGeometry(0); + 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::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 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/QmitkPointBasedRegistrationView.h b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h index eb166f9efd..cf6161ee2c 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkPointBasedRegistrationView.h @@ -1,297 +1,297 @@ /*=================================================================== 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. ===================================================================*/ #if !defined(QMITK_POINTBASEDREGISTRATION_H__INCLUDED) #define QMITK_POINTBASEDREGISTRATION_H__INCLUDED #include "QmitkFunctionality.h" #include "berryISelectionListener.h" #include "berryIStructuredSelection.h" //#include "mitkTestingConfig.h" // IMPORTANT: this defines or undefines BUILD_TESTING ! #include #include #include #include #include #include //#include "QmitkMessageBoxHelper.h" #include "ui_QmitkPointBasedRegistrationViewControls.h" #include /*! \brief The PointBasedRegistration functionality is used to perform point based registration. This functionality allows you to register 2D as well as 3D images in a rigid and deformable manner via corresponding PointSets. Register means to align two images, so that they become as similar as possible. Therefore you have to set corresponding points in both images, which will be matched. The movement, which has to be performed on the points to align them will be performed on the moving image as well. The result is shown in the multi-widget. For more informations see: \ref QmitkPointBasedRegistrationUserManual \sa QmitkFunctionality \ingroup Functionalities \ingroup PointBasedRegistration */ class REGISTRATION_EXPORT QmitkPointBasedRegistrationView : public QmitkFunctionality { friend struct SelListenerPointBasedRegistration; Q_OBJECT public: static const std::string VIEW_ID; /*! \brief Default constructor */ QmitkPointBasedRegistrationView(QObject *parent=0, const char *name=0); /*! \brief Default destructor */ virtual ~QmitkPointBasedRegistrationView(); /*! \brief method for creating the applications main widget */ virtual void CreateQtPartControl(QWidget *parent); /*! \brief Sets the StdMultiWidget and connects it to the functionality. */ virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); /*! \brief Removes the StdMultiWidget and disconnects it from the functionality. */ virtual void StdMultiWidgetNotAvailable(); /*! \brief Method for creating the connections of main and control widget */ virtual void CreateConnections(); virtual void Activated(); virtual void Deactivated(); virtual void Visible(); virtual void Hidden(); // // #ifdef BUILD_TESTING // / ** // \brief Testing entry point // * / // virtual int TestYourself(); // // / ** // \brief Helper method for testing // * / // bool TestAllTools(); // // // protected slots: // /** // \brief Helper method for testing // */ // void RegistrationErrorDialogFound( QWidget* widget ); // // /** // \brief Helper method for testing // */ // void ClearPointSetDialogFound( QWidget* widget ); // // private: // bool m_MessageBox; // // // public: // #else // // slot function is needed, because moc ignores our #ifdefs // void RegistrationErrorDialogFound( QWidget* widget ) {} // // slot function is needed, because moc ignores our #ifdefs // void ClearPointSetDialogFound(QWidget* widget){} // #endif void DataNodeHasBeenRemoved(const mitk::DataNode* node); protected slots: /*! \brief Sets the fixed Image according to TreeNodeSelector widget */ void FixedSelected(mitk::DataNode::Pointer fixedImage); /*! \brief Sets the moving Image according to TreeNodeSelector widget */ void MovingSelected(mitk::DataNode::Pointer movingImage); /*! \brief Calculates registration with vtkLandmarkTransform */ void calculateLandmarkbased(); /*! \brief Calculates registration with itkLandmarkWarping */ void calculateLandmarkWarping(); /*! \brief Calculates registration with ICP and vtkLandmarkTransform */ void calculateLandmarkbasedWithICP(); /*! \brief lets the fixed image become invisible and the moving image visible */ void HideMovingImage(bool hide); /*! \brief lets the moving image become invisible and the fixed image visible */ void HideFixedImage(bool hide); /*! \brief Checks if registration is possible */ bool CheckCalculate(); /*! \brief Performs an undo for the last transform. */ void UndoTransformation(); /*! \brief Performs a redo for the last undo transform. */ void RedoTransformation(); /*! \brief Stores whether the image will be shown in grayvalues or in red for fixed image and green for moving image @param show if true, then images will be shown in red and green */ void showRedGreen(bool show); /*! \brief Sets the selected opacity for moving image @param opacity the selected opacity */ void OpacityUpdate(float opacity); /*! \brief Sets the selected opacity for moving image @param opacity the selected opacity */ void OpacityUpdate(int opacity); /*! \brief Updates the moving landmarks */ void updateMovingLandmarksList(); /*! \brief Updates the fixed landmarks */ void updateFixedLandmarksList(); /*! \brief Sets the images to gray values or fixed image to red and moving image to green @param redGreen if true, then images will be shown in red and green */ void setImageColor(bool redGreen); /*! \brief Clears the undo and redo transformation lists. */ void clearTransformationLists(); /*! \brief Calculates the landmark error for the selected transformation. */ void checkLandmarkError(); /*! \brief Changes the transformation type and calls checkLandmarkError(). */ void transformationChanged(int transform); /*! \brief Checks whether the registration can be performed. */ bool checkCalculateEnabled(); /*! \brief Performs the registration. */ void calculate(); void SetImagesVisible(berry::ISelection::ConstPointer /*selection*/); void SwitchImages(); protected: berry::ISelectionListener::Pointer m_SelListener; berry::IStructuredSelection::ConstPointer m_CurrentSelection; /*! * default main widget containing 4 windows showing 3 * orthogonal slices of the volume and a 3d render window */ QmitkStdMultiWidget * m_MultiWidget; /*! * control widget to make all changes for point based registration */ Ui::QmitkPointBasedRegistrationControls m_Controls; mitk::PointSet::Pointer m_FixedLandmarks; mitk::PointSet::Pointer m_MovingLandmarks; mitk::DataNode::Pointer m_MovingPointSetNode; mitk::DataNode::Pointer m_FixedPointSetNode; mitk::DataNode::Pointer m_MovingNode; mitk::DataNode::Pointer m_FixedNode; - std::list m_UndoGeometryList; - std::list m_UndoPointsGeometryList; - std::list m_RedoGeometryList; - std::list m_RedoPointsGeometryList; + std::list m_UndoGeometryList; + std::list m_UndoPointsGeometryList; + std::list m_RedoGeometryList; + std::list m_RedoPointsGeometryList; bool m_ShowRedGreen; float m_Opacity; float m_OriginalOpacity; mitk::Color m_FixedColor; mitk::Color m_MovingColor; int m_Transformation; bool m_HideFixedImage; bool m_HideMovingImage; std::string m_OldFixedLabel; std::string m_OldMovingLabel; bool m_Deactivated; int m_CurrentFixedLandmarksObserverID; int m_CurrentMovingLandmarksObserverID; itk::SimpleMemberCommand::Pointer m_FixedLandmarksChangedCommand; itk::SimpleMemberCommand::Pointer m_MovingLandmarksChangedCommand; }; #endif // !defined(QMITK_POINTBASEDREGISTRATION_H__INCLUDED) diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp index e1f4827627..ecb1ff7d00 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp @@ -1,783 +1,786 @@ /*=================================================================== 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 "mitkImageTimeSelector.h" #include #include #include #include "mitkMatrixConvert.h" #include #include #include "QmitkLoadPresetDialog.h" #include #include "mitkRigidRegistrationPreset.h" #include "mitkProgressBar.h" #include "QmitkRigidRegistrationSelectorView.h" #include "QmitkTranslationTransformView.h" #include "QmitkScaleTransformView.h" #include "QmitkScaleLogarithmicTransformView.h" #include "QmitkAffineTransformView.h" #include "QmitkFixedCenterOfRotationAffineTransformView.h" #include "QmitkEuler3DTransformView.h" #include "QmitkCenteredEuler3DTransformView.h" #include "QmitkQuaternionRigidTransformView.h" #include "QmitkVersorTransformView.h" #include "QmitkVersorRigid3DTransformView.h" #include "QmitkScaleSkewVersor3DTransformView.h" #include "QmitkSimilarity3DTransformView.h" #include "QmitkRigid2DTransformView.h" #include "QmitkCenteredRigid2DTransformView.h" #include "QmitkEuler2DTransformView.h" #include "QmitkSimilarity2DTransformView.h" #include "QmitkCenteredSimilarity2DTransformView.h" #include "QmitkMeanSquaresMetricView.h" #include "QmitkNormalizedCorrelationMetricView.h" #include "QmitkGradientDifferenceMetricView.h" #include "QmitkKullbackLeiblerCompareHistogramMetricView.h" #include "QmitkCorrelationCoefficientHistogramMetricView.h" #include "QmitkMeanSquaresHistogramMetricView.h" #include "QmitkMutualInformationHistogramMetricView.h" #include "QmitkNormalizedMutualInformationHistogramMetricView.h" #include "QmitkMattesMutualInformationMetricView.h" #include "QmitkMeanReciprocalSquareDifferenceMetricView.h" #include "QmitkMutualInformationMetricView.h" #include "QmitkMatchCardinalityMetricView.h" #include "QmitkKappaStatisticMetricView.h" #include "QmitkExhaustiveOptimizerView.h" #include "QmitkGradientDescentOptimizerView.h" #include "QmitkQuaternionRigidTransformGradientDescentOptimizerView.h" #include "QmitkLBFGSBOptimizerView.h" #include "QmitkOnePlusOneEvolutionaryOptimizerView.h" #include "QmitkPowellOptimizerView.h" #include "QmitkFRPROptimizerView.h" #include "QmitkRegularStepGradientDescentOptimizerView.h" #include "QmitkVersorTransformOptimizerView.h" #include "QmitkAmoebaOptimizerView.h" #include "QmitkConjugateGradientOptimizerView.h" #include "QmitkLBFGSOptimizerView.h" #include "QmitkSPSAOptimizerView.h" #include "QmitkVersorRigid3DTransformOptimizerView.h" QmitkRigidRegistrationSelectorView::QmitkRigidRegistrationSelectorView(QWidget* parent, Qt::WindowFlags f ) : QWidget( parent, f ), m_FixedNode(NULL), m_FixedMaskNode(NULL), m_MovingNode(NULL), m_MovingMaskNode(NULL), m_FixedDimension(0), m_MovingDimension(0), m_StopOptimization(false), m_GeometryItkPhysicalToWorldTransform(NULL), m_GeometryWorldToItkPhysicalTransform(NULL), m_MovingGeometry(NULL), m_ImageGeometry(NULL) { m_Controls.setupUi(parent); this->AddTransform(new QmitkTranslationTransformView(this, f)); this->AddTransform(new QmitkScaleTransformView(this, f)); this->AddTransform(new QmitkScaleLogarithmicTransformView(this, f)); this->AddTransform(new QmitkAffineTransformView(this, f)); this->AddTransform(new QmitkFixedCenterOfRotationAffineTransformView(this, f)); this->AddTransform(new QmitkEuler3DTransformView(this, f)); this->AddTransform(new QmitkCenteredEuler3DTransformView(this, f)); this->AddTransform(new QmitkQuaternionRigidTransformView(this, f)); this->AddTransform(new QmitkVersorTransformView(this, f)); this->AddTransform(new QmitkVersorRigid3DTransformView(this, f)); this->AddTransform(new QmitkScaleSkewVersor3DTransformView(this, f)); this->AddTransform(new QmitkSimilarity3DTransformView(this, f)); this->AddTransform(new QmitkRigid2DTransformView(this, f)); this->AddTransform(new QmitkCenteredRigid2DTransformView(this, f)); this->AddTransform(new QmitkEuler2DTransformView(this, f)); this->AddTransform(new QmitkSimilarity2DTransformView(this, f)); this->AddTransform(new QmitkCenteredSimilarity2DTransformView(this, f)); this->AddMetric(new QmitkMeanSquaresMetricView(this, f)); this->AddMetric(new QmitkNormalizedCorrelationMetricView(this, f)); this->AddMetric(new QmitkGradientDifferenceMetricView(this, f)); this->AddMetric(new QmitkKullbackLeiblerCompareHistogramMetricView(this, f)); this->AddMetric(new QmitkCorrelationCoefficientHistogramMetricView(this, f)); this->AddMetric(new QmitkMeanSquaresHistogramMetricView(this, f)); this->AddMetric(new QmitkMutualInformationHistogramMetricView(this, f)); this->AddMetric(new QmitkNormalizedMutualInformationHistogramMetricView(this, f)); this->AddMetric(new QmitkMattesMutualInformationMetricView(this, f)); this->AddMetric(new QmitkMeanReciprocalSquareDifferenceMetricView(this, f)); this->AddMetric(new QmitkMutualInformationMetricView(this, f)); this->AddMetric(new QmitkMatchCardinalityMetricView(this, f)); this->AddMetric(new QmitkKappaStatisticMetricView(this, f)); this->AddOptimizer(new QmitkExhaustiveOptimizerView(this, f)); this->AddOptimizer(new QmitkGradientDescentOptimizerView(this, f)); this->AddOptimizer(new QmitkQuaternionRigidTransformGradientDescentOptimizerView(this, f)); this->AddOptimizer(new QmitkLBFGSBOptimizerView(this, f)); this->AddOptimizer(new QmitkOnePlusOneEvolutionaryOptimizerView(this, f)); this->AddOptimizer(new QmitkPowellOptimizerView(this, f)); this->AddOptimizer(new QmitkFRPROptimizerView(this, f)); this->AddOptimizer(new QmitkRegularStepGradientDescentOptimizerView(this, f)); this->AddOptimizer(new QmitkVersorTransformOptimizerView(this, f)); this->AddOptimizer(new QmitkAmoebaOptimizerView(this, f)); this->AddOptimizer(new QmitkConjugateGradientOptimizerView(this, f)); this->AddOptimizer(new QmitkLBFGSOptimizerView(this, f)); this->AddOptimizer(new QmitkSPSAOptimizerView(this, f)); this->AddOptimizer(new QmitkVersorRigid3DTransformOptimizerView(this, f)); m_Observer = mitk::RigidRegistrationObserver::New(); m_Controls.m_TransformFrame->setEnabled(true); m_Controls.m_MetricFrame->setEnabled(true); m_Controls.m_OptimizerFrame->setEnabled(true); m_Controls.m_InterpolatorFrame->setEnabled(true); m_Controls.m_TransformFrame->hide(); m_Controls.m_MetricFrame->hide(); m_Controls.m_OptimizerFrame->hide(); m_Controls.m_InterpolatorFrame->hide(); m_Controls.m_TransformBox->setCurrentIndex(0); m_Controls.m_MetricBox->setCurrentIndex(0); m_Controls.m_OptimizerBox->setCurrentIndex(0); m_Controls.m_TransformWidgetStack->setCurrentIndex(0); m_Controls.m_MetricWidgetStack->setCurrentIndex(0); m_Controls.m_OptimizerWidgetStack->setCurrentIndex(0); /// and show the selected views this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); this->MetricSelected(m_Controls.m_MetricBox->currentIndex()); this->OptimizerSelected(m_Controls.m_OptimizerBox->currentIndex()); //// create connections connect( m_Controls.m_TransformGroup, SIGNAL(clicked(bool)), m_Controls.m_TransformFrame, SLOT(setVisible(bool))); connect( m_Controls.m_TransformBox, SIGNAL(activated(int)), m_Controls.m_TransformWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_TransformBox, SIGNAL(activated(int)), this, SLOT(TransformSelected(int))); connect( m_Controls.m_MetricBox, SIGNAL(activated(int)), this, SLOT(MetricSelected(int))); connect( m_Controls.m_OptimizerBox, SIGNAL(activated(int)), this, SLOT(OptimizerSelected(int))); connect( m_Controls.m_MetricGroup, SIGNAL(clicked(bool)), m_Controls.m_MetricFrame, SLOT(setVisible(bool))); connect( m_Controls.m_MetricBox, SIGNAL(activated(int)), m_Controls.m_MetricWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_OptimizerGroup, SIGNAL(clicked(bool)), m_Controls.m_OptimizerFrame, SLOT(setVisible(bool))); connect( m_Controls.m_OptimizerBox, SIGNAL(activated(int)), m_Controls.m_OptimizerWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_InterpolatorGroup, SIGNAL(toggled(bool)), m_Controls.m_InterpolatorFrame, SLOT(setVisible(bool))); m_Preset = new mitk::RigidRegistrationPreset(); m_Preset->LoadPreset(); this->DoLoadRigidRegistrationPreset("AffineMutualInformationGradientDescent"); } QmitkRigidRegistrationSelectorView::~QmitkRigidRegistrationSelectorView() { } /// this method starts the registration process void QmitkRigidRegistrationSelectorView::CalculateTransformation(unsigned int timestep) { if (m_FixedNode.IsNotNull() && m_MovingNode.IsNotNull()) { emit AddNewTransformationToUndoList(); mitk::Image::Pointer fimage = dynamic_cast(m_FixedNode->GetData())->Clone(); mitk::Image::Pointer mimage = dynamic_cast(m_MovingNode->GetData())->Clone(); mitk::Image::Pointer mmimage = NULL; mitk::Image::Pointer fmimage = NULL; if (m_MovingMaskNode.IsNotNull()) { mmimage = dynamic_cast(m_MovingMaskNode->GetData()); } if (m_FixedMaskNode.IsNotNull()) { fmimage = dynamic_cast(m_FixedMaskNode->GetData()); } mitk::ImageTimeSelector::Pointer its = mitk::ImageTimeSelector::New(); if(fimage->GetDimension()>3) { its->SetInput(fimage); its->SetTimeNr(timestep); its->Update(); fimage = its->GetOutput(); } if(mimage->GetDimension()>3) { its->SetInput(mimage); its->SetTimeNr(timestep); its->Update(); mimage = its->GetOutput(); } // Initial moving image geometry - m_ImageGeometry = m_MovingNode->GetData()->GetGeometry()->Clone(); + itk::LightObject::Pointer lopointer = m_MovingNode->GetData()->GetGeometry()->Clone(); + m_ImageGeometry = dynamic_cast(lopointer.GetPointer()); std::cout << "Moving Image Geometry (IndexToWorldTransform)" << std::endl; std::cout << m_ImageGeometry->GetIndexToWorldTransform()->GetMatrix(); - mitk::Geometry3D::TransformType::InputPointType center = m_ImageGeometry->GetIndexToWorldTransform()->GetCenter(); + mitk::BaseGeometry::TransformType::InputPointType center = m_ImageGeometry->GetIndexToWorldTransform()->GetCenter(); std::cout << "center " << center[0] << " " << center[1] << " " << center[2] << std::endl; - mitk::Geometry3D::TransformType::OutputVectorType offset = m_ImageGeometry->GetIndexToWorldTransform()->GetOffset(); + mitk::BaseGeometry::TransformType::OutputVectorType offset = m_ImageGeometry->GetIndexToWorldTransform()->GetOffset(); std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl; std::cout << std::endl; // Fixed image geometry // mitk::Geometry3D::Pointer m_FixedGeometryCopy = m_FixedNode->GetData()->GetGeometry()->Clone(); // std::cout << "Fixed Image Geometry (IndexToWorldTransform)" << std::endl; // std::cout << m_FixedGeometryCopy->GetIndexToWorldTransform()->GetMatrix(); // center = m_FixedGeometryCopy->GetIndexToWorldTransform()->GetCenter(); // std::cout << "center " << center[0] << " " << center[1] << " " << center[2] << std::endl; // offset = m_FixedGeometryCopy->GetIndexToWorldTransform()->GetOffset(); // std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl; // std::cout << std::endl; // Calculate the World to ITK-Physical transform for the moving image m_MovingGeometry = m_MovingNode->GetData()->GetGeometry(); // container that holds all derived moving data, that needs to be transformed with the transformation found by registration if(m_MovingMaskNode.IsNotNull()) { - m_ChildNodes.insert(std::pair(m_MovingMaskNode, m_MovingMaskNode->GetData()->GetGeometry())); - m_ChildNodes2.insert(std::pair(m_MovingMaskNode, m_MovingMaskNode->GetData()->GetGeometry()->Clone())); + m_ChildNodes.insert(std::pair(m_MovingMaskNode, m_MovingMaskNode->GetData()->GetGeometry())); + itk::LightObject::Pointer lopointer = m_MovingMaskNode->GetData()->GetGeometry()->Clone(); + m_ChildNodes2.insert(std::pair(m_MovingMaskNode, dynamic_cast(lopointer.GetPointer()))); } if(m_MovingNodeChildren.IsNotNull()) { unsigned long size = 0; size = m_MovingNodeChildren->Size(); mitk::DataNode::Pointer childNode; for (unsigned long i = 0; i < size; ++i) { - m_ChildNodes.insert(std::pair(m_MovingNodeChildren->GetElement(i), m_MovingNodeChildren->GetElement(i)->GetData()->GetGeometry())); - m_ChildNodes2.insert(std::pair(m_MovingNodeChildren->GetElement(i), m_MovingNodeChildren->GetElement(i)->GetData()->GetGeometry()->Clone())); + m_ChildNodes.insert(std::pair(m_MovingNodeChildren->GetElement(i), m_MovingNodeChildren->GetElement(i)->GetData()->GetGeometry())); + itk::LightObject::Pointer lopointer = m_MovingNodeChildren->GetElement(i)->GetData()->GetGeometry()->Clone(); + m_ChildNodes2.insert(std::pair(m_MovingNodeChildren->GetElement(i), dynamic_cast(lopointer.GetPointer()))); } } - m_GeometryWorldToItkPhysicalTransform = mitk::Geometry3D::TransformType::New(); + m_GeometryWorldToItkPhysicalTransform = mitk::BaseGeometry::TransformType::New(); GetWorldToItkPhysicalTransform(m_MovingGeometry, m_GeometryWorldToItkPhysicalTransform.GetPointer()); // std::cout << "Moving Image: World to ITK-physical transform" << std::endl; // std::cout << m_GeometryWorldToItkPhysicalTransform->GetMatrix(); // center = m_GeometryWorldToItkPhysicalTransform->GetCenter(); // std::cout << "center " << center[0] << " " << center[1] << " " << center[2] << std::endl; // offset = m_GeometryWorldToItkPhysicalTransform->GetOffset(); // std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl; // std::cout << std::endl; // Calculate the ITK-Physical to World transform for the fixed image - m_GeometryItkPhysicalToWorldTransform = mitk::Geometry3D::TransformType::New(); - mitk::Geometry3D::TransformType::Pointer fixedWorld2Phys = mitk::Geometry3D::TransformType::New(); + m_GeometryItkPhysicalToWorldTransform = mitk::BaseGeometry::TransformType::New(); + mitk::BaseGeometry::TransformType::Pointer fixedWorld2Phys = mitk::BaseGeometry::TransformType::New(); GetWorldToItkPhysicalTransform(m_FixedNode->GetData()->GetGeometry(), fixedWorld2Phys.GetPointer()); fixedWorld2Phys->GetInverse(m_GeometryItkPhysicalToWorldTransform); // std::cout << "Fixed Image: ITK-physical to World transform" << std::endl; // std::cout << m_GeometryItkPhysicalToWorldTransform->GetMatrix(); // center = m_GeometryItkPhysicalToWorldTransform->GetCenter(); // std::cout << "center " << center[0] << " " << center[1] << " " << center[2] << std::endl; // offset = m_GeometryItkPhysicalToWorldTransform->GetOffset(); // std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl; // std::cout << std::endl; // init callback itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkRigidRegistrationSelectorView::SetOptimizerValue); int observer = m_Observer->AddObserver( itk::AnyEvent(), command ); std::vector presets; // init registration method mitk::ImageRegistrationMethod::Pointer registration = mitk::ImageRegistrationMethod::New(); registration->SetObserver(m_Observer); registration->SetInterpolator(m_Controls.m_InterpolatorBox->currentIndex()); registration->SetReferenceImage(fimage); registration->SetInput(mimage); if (mmimage.IsNotNull()) { registration->SetMovingMask(mmimage); } if (fmimage.IsNotNull()) { registration->SetFixedMask(fmimage); } dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->SetFixedImage(dynamic_cast(m_FixedNode->GetData())); dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); registration->SetOptimizerScales(dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetScales()); registration->SetTransform(dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetTransform()); dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); registration->SetMetric(dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->GetMetric()); registration->SetOptimizer(dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->GetOptimizer()); double time(0.0); double tstart(0.0); tstart = clock(); try { registration->Update(); } catch (itk::ExceptionObject e) { MITK_INFO << "Caught exception: "<Progress(20); } time += clock() - tstart; time = time / CLOCKS_PER_SEC; //printOut of the Time MITK_INFO << "Registration Time: " << time; m_Observer->RemoveObserver(observer); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkRigidRegistrationSelectorView::SetFixedNode( mitk::DataNode * fixedNode ) { m_FixedNode = fixedNode; m_Controls.m_TransformBox->setCurrentIndex(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetFixedDimension( int dimension ) { m_FixedDimension = dimension; } void QmitkRigidRegistrationSelectorView::SetMovingNode( mitk::DataNode * movingNode ) { m_MovingNode = movingNode; this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetMovingDimension(int dimension ) { m_MovingDimension = dimension; } // this is a callback function that retrieves the current transformation // parameters after every step of progress in the optimizer. // depending on the choosen transformation, we construct a vtktransform // that will be applied to the geometry of the moving image. // the values are delivered by mitkRigidRgistrationObserver.cpp void QmitkRigidRegistrationSelectorView::SetOptimizerValue( const itk::EventObject & ) { if (m_StopOptimization) { m_Observer->SetStopOptimization(true); m_StopOptimization = false; } // retreive optimizer value for the current transformation double value = m_Observer->GetCurrentOptimizerValue(); // retreive current parameterset of the transformation itk::Array transformParams = m_Observer->GetCurrentTranslation(); // init an empty affine transformation that will be filled with // the corresponding transformation parameters in the following vtkMatrix4x4* vtkmatrix = vtkMatrix4x4::New(); vtkmatrix->Identity(); // init a transform that will be initialized with the vtkmatrix later vtkTransform* vtktransform = vtkTransform::New(); if (m_MovingNode.IsNotNull()) { vtktransform = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->Transform(vtkmatrix, vtktransform, transformParams); // the retrieved transform goes from fixed to moving space. // invert the transform in order to go from moving to fixed space. vtkMatrix4x4* vtkmatrix_inv = vtkMatrix4x4::New(); vtktransform->GetInverse(vtkmatrix_inv); // now adapt the moving geometry accordingly m_MovingGeometry->GetIndexToWorldTransform()->SetIdentity(); // the next view lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // set moving image geometry to registration result m_MovingGeometry->SetIndexToWorldTransformByVtkMatrix(vtkmatrix_inv); /*std::cout << std::endl; std::cout << m_MovingGeometry->GetIndexToWorldTransform()->GetMatrix(); mitk::Geometry3D::TransformType::OutputVectorType offset = m_MovingGeometry->GetIndexToWorldTransform()->GetOffset(); std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl;*/ #if !defined(ITK_IMAGE_BEHAVES_AS_ORIENTED_IMAGE) // the next few lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // go to itk physical space before applying the registration result m_MovingGeometry->Compose(m_GeometryWorldToItkPhysicalTransform, 1); // right in the beginning, transform by initial moving image geometry m_MovingGeometry->Compose(m_ImageGeometry->GetIndexToWorldTransform(), 1); // in the end, go back to world space m_MovingGeometry->Compose(m_GeometryItkPhysicalToWorldTransform, 0); #else m_MovingGeometry->Compose(m_ImageGeometry->GetIndexToWorldTransform(), 1); #endif /*std::cout << std::endl << m_MovingGeometry->GetIndexToWorldTransform()->GetMatrix(); offset = m_MovingGeometry->GetIndexToWorldTransform()->GetOffset(); std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl << std::endl;*/ // now adapt all children geometries accordingly if children exist - std::map::iterator iter; - std::map::iterator iter2; + std::map::iterator iter; + std::map::iterator iter2; mitk::DataNode::Pointer childNode; for( iter = m_ChildNodes.begin(); iter != m_ChildNodes.end(); iter++ ) { childNode = (*iter).first; if (childNode.IsNotNull()) { - mitk::Geometry3D* childGeometry; - mitk::Geometry3D::Pointer childImageGeometry; + mitk::BaseGeometry* childGeometry; + mitk::BaseGeometry::Pointer childImageGeometry; // Calculate the World to ITK-Physical transform for the moving mask childGeometry = (*iter).second; iter2 = m_ChildNodes2.find(childNode); childImageGeometry = (*iter2).second; childGeometry->GetIndexToWorldTransform()->SetIdentity(); // the next view lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // set moving mask geometry to registration result childGeometry->SetIndexToWorldTransformByVtkMatrix(vtkmatrix_inv); #if !defined(ITK_IMAGE_BEHAVES_AS_ORIENTED_IMAGE) // the next few lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // go to itk physical space before applying the registration result childGeometry->Compose(m_GeometryWorldToItkPhysicalTransform, 1); // right in the beginning, transform by initial moving image geometry childGeometry->Compose(childImageGeometry->GetIndexToWorldTransform(), 1); // in the end, go back to world space childGeometry->Compose(m_GeometryItkPhysicalToWorldTransform, 0); #else childGeometry->Compose(childImageGeometry->GetIndexToWorldTransform(), 1); #endif } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } emit OptimizerChanged(value); } /// this method is called whenever the combobox with the selectable transforms changes /// responsible for showing the selected transform parameters void QmitkRigidRegistrationSelectorView::TransformSelected( int transform ) { if (m_FixedNode.IsNotNull()) { dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->SetFixedImage(dynamic_cast(m_FixedNode->GetData())); } if (m_MovingNode.IsNotNull()) { dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); } int numberOfTransformParameters = dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->GetNumberOfTransformParameters(); dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->SetNumberOfTransformParameters(numberOfTransformParameters); //set fixed height m_Controls.m_TransformWidgetStack->setFixedHeight( dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->minimumSizeHint().height() ); this->OptimizerSelected(m_Controls.m_OptimizerWidgetStack->currentIndex()); } /// this method is called whenever the combobox with the selectable metrics changes /// responsible for showing the selected metric parameters void QmitkRigidRegistrationSelectorView::MetricSelected( int metric ) { if (m_FixedNode.IsNotNull()) { dynamic_cast(m_Controls.m_MetricWidgetStack->widget(metric))->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); } //set fixed height m_Controls.m_MetricWidgetStack->setFixedHeight( dynamic_cast(m_Controls.m_MetricWidgetStack->widget(metric))->minimumSizeHint().height() ); } /// this method is called whenever the combobox with the selectable optimizers changes /// responsible for showing the selected optimizer parameters void QmitkRigidRegistrationSelectorView::OptimizerSelected( int optimizer ) { int numberOfTransformParameters = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetNumberOfTransformParameters(); dynamic_cast(m_Controls.m_OptimizerWidgetStack->widget(optimizer))->SetNumberOfTransformParameters(numberOfTransformParameters); //set fixed height m_Controls.m_OptimizerWidgetStack->setFixedHeight( dynamic_cast(m_Controls.m_OptimizerWidgetStack->widget(optimizer))->minimumSizeHint().height() ); } void QmitkRigidRegistrationSelectorView::LoadRigidRegistrationParameter() { this->DoLoadRigidRegistrationParameter(); } void QmitkRigidRegistrationSelectorView::DoLoadRigidRegistrationParameter() { std::map > existingPresets; existingPresets = m_Preset->getTransformValuesPresets(); std::map >::iterator iter; std::list presets; for( iter = existingPresets.begin(); iter != existingPresets.end(); iter++ ) { presets.push_back( (*iter).first ); } if (presets.empty()) { QMessageBox::warning( NULL, "RigidRegistrationParameters.xml", "RigidRegistrationParameters.xml is empty/does not exist. There are no presets to select."); return; } presets.sort(); // ask about the name to load a preset QmitkLoadPresetDialog dialog( this, 0, "Load Preset", presets ); // needs a QWidget as parent int dialogReturnValue = dialog.exec(); if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar this->DoLoadRigidRegistrationPreset(dialog.GetPresetName()); } void QmitkRigidRegistrationSelectorView::DoLoadRigidRegistrationPreset(std::string presetName) { itk::Array transformValues; transformValues = m_Preset->getTransformValues(presetName); m_Controls.m_TransformGroup->setChecked(true); m_Controls.m_TransformFrame->setVisible(true); m_Controls.m_TransformBox->setCurrentIndex((int)transformValues[0]); m_Controls.m_TransformWidgetStack->setCurrentIndex((int)transformValues[0]); this->TransformSelected((int)transformValues[0]); itk::Array transformValuesForGUI; transformValuesForGUI.SetSize(transformValues.Size()); transformValuesForGUI.fill(0); for (unsigned int i = 1; i < transformValues.Size(); i++) { transformValuesForGUI[i-1] = transformValues[i]; } dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->SetTransformParameters(transformValuesForGUI); itk::Array metricValues; metricValues = m_Preset->getMetricValues(presetName); m_Controls.m_MetricGroup->setChecked(true); m_Controls.m_MetricFrame->setVisible(true); m_Controls.m_MetricBox->setCurrentIndex((int)metricValues[0]); m_Controls.m_MetricWidgetStack->setCurrentIndex((int)metricValues[0]); this->MetricSelected((int)metricValues[0]); itk::Array metricValuesForGUI; metricValuesForGUI.SetSize(metricValues.Size()); metricValuesForGUI.fill(0); for (unsigned int i = 1; i < metricValues.Size(); i++) { metricValuesForGUI[i-1] = metricValues[i]; } dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->SetMetricParameters(metricValuesForGUI); itk::Array optimizerValues; optimizerValues = m_Preset->getOptimizerValues(presetName); m_Controls.m_OptimizerGroup->setChecked(true); m_Controls.m_OptimizerFrame->setVisible(true); m_Controls.m_OptimizerBox->setCurrentIndex((int)optimizerValues[0]); m_Controls.m_OptimizerWidgetStack->setCurrentIndex((int)optimizerValues[0]); this->OptimizerSelected((int)optimizerValues[0]); itk::Array optimizerValuesForGUI; optimizerValuesForGUI.SetSize(optimizerValues.Size()); optimizerValuesForGUI.fill(0); for (unsigned int i = 1; i < optimizerValues.Size(); i++) { optimizerValuesForGUI[i-1] = optimizerValues[i]; } dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->SetOptimizerParameters(optimizerValuesForGUI); itk::Array interpolatorValues; interpolatorValues = m_Preset->getInterpolatorValues(presetName); m_Controls.m_InterpolatorGroup->setChecked(true); m_Controls.m_InterpolatorFrame->setVisible(true); m_Controls.m_InterpolatorBox->setCurrentIndex((int)interpolatorValues[0]); } void QmitkRigidRegistrationSelectorView::SaveRigidRegistrationParameter() { this->DoSaveRigidRegistrationParameter(); } void QmitkRigidRegistrationSelectorView::DoSaveRigidRegistrationParameter() { bool ok; QString text = QInputDialog::getText(this, "Save Parameter Preset", "Enter name for preset:", QLineEdit::Normal, QString::null, &ok ); if ( ok ) { std::map > existingPresets; existingPresets = m_Preset->getTransformValuesPresets(); std::map >::iterator iter = existingPresets.find(std::string((const char*)text.toLatin1())); if (iter != existingPresets.end()) { QMessageBox::critical( this, "Preset definition", "Presetname already exists."); return; } if (text.isEmpty()) { QMessageBox::critical( this, "Preset definition", "Presetname has to be set.\n" "You have to enter a Presetname." ); return; } itk::Array transformValues; transformValues.SetSize(25); transformValues.fill(0); transformValues[0] = m_Controls.m_TransformBox->currentIndex(); itk::Array transformValuesFromGUI = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetTransformParameters(); for (unsigned int i = 0; i < transformValuesFromGUI.Size(); i++) { transformValues[i+1] = transformValuesFromGUI[i]; } std::map > transformMap; transformMap = m_Preset->getTransformValuesPresets(); transformMap[std::string((const char*)text.toLatin1())] = transformValues; itk::Array metricValues; metricValues.SetSize(25); metricValues.fill(0); metricValues[0] = m_Controls.m_MetricBox->currentIndex(); itk::Array metricValuesFromGUI = dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->GetMetricParameters(); for (unsigned int i = 0; i < metricValuesFromGUI.Size(); i++) { metricValues[i+1] = metricValuesFromGUI[i]; } std::map > metricMap; metricMap = m_Preset->getMetricValuesPresets(); metricMap[std::string((const char*)text.toLatin1())] = metricValues; itk::Array optimizerValues; optimizerValues.SetSize(25); optimizerValues.fill(0); optimizerValues[0] = m_Controls.m_OptimizerBox->currentIndex(); itk::Array optimizerValuesFromGUI = dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->GetOptimizerParameters(); for (unsigned int i = 0; i < optimizerValuesFromGUI.Size(); i++) { optimizerValues[i+1] = optimizerValuesFromGUI[i]; } std::map > optimizerMap; optimizerMap = m_Preset->getOptimizerValuesPresets(); optimizerMap[std::string((const char*)text.toLatin1())] = optimizerValues; itk::Array interpolatorValues; interpolatorValues.SetSize(25); interpolatorValues.fill(0); interpolatorValues[0] = m_Controls.m_InterpolatorBox->currentIndex(); std::map > interpolatorMap; interpolatorMap = m_Preset->getInterpolatorValuesPresets(); interpolatorMap[std::string((const char*)text.toLatin1())] = interpolatorValues; m_Preset->newPresets(transformMap, metricMap, optimizerMap, interpolatorMap); } else { // user pressed Cancel } } void QmitkRigidRegistrationSelectorView::StopOptimization(bool stopOptimization) { m_StopOptimization = stopOptimization; } int QmitkRigidRegistrationSelectorView::GetSelectedTransform() { return m_Controls.m_TransformBox->currentIndex(); } void QmitkRigidRegistrationSelectorView::SetFixedMaskNode( mitk::DataNode * fixedMaskNode ) { m_FixedMaskNode = fixedMaskNode; this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetMovingMaskNode( mitk::DataNode * movingMaskNode ) { m_MovingMaskNode = movingMaskNode; this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetMovingNodeChildren(mitk::DataStorage::SetOfObjects::ConstPointer children) { m_MovingNodeChildren = children; } void QmitkRigidRegistrationSelectorView::AddTransform(QmitkRigidRegistrationTransformsGUIBase* transform) { m_Controls.m_TransformBox->addItem(transform->GetName()); int i = 0; if (!dynamic_cast(m_Controls.m_TransformWidgetStack->widget(i))) { m_Controls.m_TransformWidgetStack->addWidget(transform); m_Controls.m_TransformWidgetStack->removeWidget(m_Controls.m_TransformWidgetStack->widget(i)); transform->SetupUI(m_Controls.m_TransformWidgetStack->widget(i)); } else { i = m_Controls.m_TransformWidgetStack->addWidget(transform); transform->SetupUI(m_Controls.m_TransformWidgetStack->widget(i)); } } void QmitkRigidRegistrationSelectorView::AddMetric(QmitkRigidRegistrationMetricsGUIBase* metric) { m_Controls.m_MetricBox->addItem(metric->GetName()); int i = 0; if (!dynamic_cast(m_Controls.m_MetricWidgetStack->widget(i))) { m_Controls.m_MetricWidgetStack->addWidget(metric); m_Controls.m_MetricWidgetStack->removeWidget(m_Controls.m_MetricWidgetStack->widget(i)); metric->SetupUI(m_Controls.m_MetricWidgetStack->widget(i)); } else { i = m_Controls.m_MetricWidgetStack->addWidget(metric); metric->SetupUI(m_Controls.m_MetricWidgetStack->widget(i)); } } void QmitkRigidRegistrationSelectorView::AddOptimizer(QmitkRigidRegistrationOptimizerGUIBase* optimizer) { m_Controls.m_OptimizerBox->addItem(optimizer->GetName()); int i = 0; if (!dynamic_cast(m_Controls.m_OptimizerWidgetStack->widget(i))) { m_Controls.m_OptimizerWidgetStack->addWidget(optimizer); m_Controls.m_OptimizerWidgetStack->removeWidget(m_Controls.m_OptimizerWidgetStack->widget(i)); optimizer->SetupUI(m_Controls.m_OptimizerWidgetStack->widget(i)); } else { i = m_Controls.m_OptimizerWidgetStack->addWidget(optimizer); optimizer->SetupUI(m_Controls.m_OptimizerWidgetStack->widget(i)); } } diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.h b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.h index 955fc12807..66fd552fc6 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.h +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.h @@ -1,110 +1,110 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkRigidRegistrationSelectorViewWidgetHIncluded #define QmitkRigidRegistrationSelectorViewWidgetHIncluded #include "mitkDataNode.h" #include "mitkDataStorage.h" #include "ui_QmitkRigidRegistrationSelector.h" #include "qobject.h" #include #include "QmitkRigidRegistrationTransformsGUIBase.h" #include "QmitkRigidRegistrationMetricsGUIBase.h" #include "QmitkRigidRegistrationOptimizerGUIBase.h" /*! * \brief Widget for rigid registration * * Displays options for rigid registration. */ class REGISTRATION_EXPORT QmitkRigidRegistrationSelectorView : public QWidget { Q_OBJECT public: QmitkRigidRegistrationSelectorView( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~QmitkRigidRegistrationSelectorView(); signals: void TransformChanged(); void OptimizerChanged(double value); void AddNewTransformationToUndoList(); public slots: void SetFixedNode( mitk::DataNode * fixedNode ); void SetFixedMaskNode(mitk::DataNode * fixedMaskNode ); void SetFixedDimension( int dimension ); void SetMovingNode( mitk::DataNode * movingNode ); void SetMovingNodeChildren(mitk::DataStorage::SetOfObjects::ConstPointer children); void SetMovingMaskNode(mitk::DataNode * movingMaskNode ); void SetMovingDimension(int dimension ); int GetSelectedTransform(); void CalculateTransformation(unsigned int timestep = 0); void StopOptimization(bool stopOptimization); protected slots: // this is a callback function that retrieves the current transformation // parameters after every step of progress in the optimizer. // depending on the choosen transformation, we construct a vtktransform // that will be applied to the geometry of the moving image. // the values are delivered by mitkRigidRgistrationObserver.cpp void SetOptimizerValue( const itk::EventObject & ); /// this method is called whenever the combobox with the selectable transforms changes /// responsible for showing the selected transformparameters void TransformSelected( int transform ); /// this method is called whenever the combobox with the selectable metrics changes /// responsible for showing the selected metricparameters void MetricSelected( int metric ); /// this method is called whenever the combobox with the selectable optimizer changes /// responsible for showing the selected optimizerparameters void OptimizerSelected( int optimizer ); void LoadRigidRegistrationParameter(); void SaveRigidRegistrationParameter(); //void LoadRigidRegistrationTestParameter(); //void SaveRigidRegistrationTestParameter(); void DoLoadRigidRegistrationParameter(); void DoLoadRigidRegistrationPreset(std::string presetName); void DoSaveRigidRegistrationParameter(); void AddTransform(QmitkRigidRegistrationTransformsGUIBase* transform); void AddMetric(QmitkRigidRegistrationMetricsGUIBase* metric); void AddOptimizer(QmitkRigidRegistrationOptimizerGUIBase* optimizer); protected: Ui::QmitkRigidRegistrationSelector m_Controls; mitk::DataNode::Pointer m_FixedNode; mitk::DataNode::Pointer m_FixedMaskNode; mitk::DataNode::Pointer m_MovingNode; mitk::DataNode::Pointer m_MovingMaskNode; int m_FixedDimension; int m_MovingDimension; bool m_StopOptimization; mitk::RigidRegistrationPreset* m_Preset; - mitk::Geometry3D::TransformType::Pointer m_GeometryItkPhysicalToWorldTransform; - mitk::Geometry3D::TransformType::Pointer m_GeometryWorldToItkPhysicalTransform; - mitk::Geometry3D* m_MovingGeometry; - mitk::Geometry3D::Pointer m_ImageGeometry; + mitk::BaseGeometry::TransformType::Pointer m_GeometryItkPhysicalToWorldTransform; + mitk::BaseGeometry::TransformType::Pointer m_GeometryWorldToItkPhysicalTransform; + mitk::BaseGeometry* m_MovingGeometry; + mitk::BaseGeometry::Pointer m_ImageGeometry; mitk::RigidRegistrationObserver::Pointer m_Observer; mitk::DataStorage::SetOfObjects::ConstPointer m_MovingNodeChildren; - std::map m_ChildNodes; - std::map m_ChildNodes2; + std::map m_ChildNodes; + std::map m_ChildNodes2; }; #endif