diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp index cd056aa261..2485196434 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp @@ -1,649 +1,665 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date: 2009-05-28 17:19:30 +0200 (Do, 28 Mai 2009) $ Version: $Revision: 17495 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkDiffusionQuantificationView.h" #include "mitkDiffusionImagingConfigure.h" #include "itkTimeProbe.h" #include "itkImage.h" #include "mitkNodePredicateDataType.h" #include "mitkDataNodeObject.h" #include "mitkQBallImage.h" #include "mitkImageCast.h" #include "mitkStatusBar.h" #include "itkDiffusionQballGeneralizedFaImageFilter.h" #include "itkShiftScaleImageFilter.h" #include "itkTensorFractionalAnisotropyImageFilter.h" #include "itkTensorRelativeAnisotropyImageFilter.h" #include "itkTensorDerivedMeasurementsFilter.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" const std::string QmitkDiffusionQuantificationView::VIEW_ID = "org.mitk.views.diffusionquantification"; using namespace berry; const float QmitkDiffusionQuantificationView::m_ScaleDAIValues = 100.0; struct DqSelListener : ISelectionListener { berryObjectMacro(DqSelListener); DqSelListener(QmitkDiffusionQuantificationView* view) { m_View = view; } void DoSelectionChanged(ISelection::ConstPointer selection) { // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); // do something with the selected items if(m_View->m_CurrentSelection) { bool foundQBIVolume = false; bool foundTensorVolume = false; // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); // only look at interesting types if(QString("QBallImage").compare(node->GetData()->GetNameOfClass())==0) { foundQBIVolume = true; } if(QString("TensorImage").compare(node->GetData()->GetNameOfClass())==0) { foundTensorVolume = true; } } } m_View->m_Controls->m_GFAButton->setEnabled(foundQBIVolume); m_View->m_Controls->m_CurvatureButton->setEnabled(foundQBIVolume); m_View->m_Controls->m_FAButton->setEnabled(foundTensorVolume); m_View->m_Controls->m_RAButton->setEnabled(foundTensorVolume); m_View->m_Controls->m_ADButton->setEnabled(foundTensorVolume); m_View->m_Controls->m_RDButton->setEnabled(foundTensorVolume); + m_View->m_Controls->m_MDButton->setEnabled(foundTensorVolume); m_View->m_Controls->m_ClusteringAnisotropy->setEnabled(foundTensorVolume); } } 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("Datamanager")==0) { // apply selection DoSelectionChanged(selection); } } } QmitkDiffusionQuantificationView* m_View; }; QmitkDiffusionQuantificationView::QmitkDiffusionQuantificationView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { } QmitkDiffusionQuantificationView::~QmitkDiffusionQuantificationView() { this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); } void QmitkDiffusionQuantificationView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkDiffusionQuantificationViewControls; m_Controls->setupUi(parent); this->CreateConnections(); GFACheckboxClicked(); #ifndef DIFFUSION_IMAGING_EXTENDED m_Controls->m_StandardGFACheckbox->setVisible(false); m_Controls->frame_3->setVisible(false); m_Controls->m_CurvatureButton->setVisible(false); #endif } m_SelListener = berry::ISelectionListener::Pointer(new DqSelListener(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); } void QmitkDiffusionQuantificationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkDiffusionQuantificationView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkDiffusionQuantificationView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_StandardGFACheckbox), SIGNAL(clicked()), this, SLOT(GFACheckboxClicked()) ); connect( (QObject*)(m_Controls->m_GFAButton), SIGNAL(clicked()), this, SLOT(GFA()) ); connect( (QObject*)(m_Controls->m_CurvatureButton), SIGNAL(clicked()), this, SLOT(Curvature()) ); connect( (QObject*)(m_Controls->m_FAButton), SIGNAL(clicked()), this, SLOT(FA()) ); connect( (QObject*)(m_Controls->m_RAButton), SIGNAL(clicked()), this, SLOT(RA()) ); connect( (QObject*)(m_Controls->m_ADButton), SIGNAL(clicked()), this, SLOT(AD()) ); connect( (QObject*)(m_Controls->m_RDButton), SIGNAL(clicked()), this, SLOT(RD()) ); + connect( (QObject*)(m_Controls->m_MDButton), SIGNAL(clicked()), this, SLOT(MD()) ); connect( (QObject*)(m_Controls->m_ClusteringAnisotropy), SIGNAL(clicked()), this, SLOT(ClusterAnisotropy()) ); } } void QmitkDiffusionQuantificationView::Activated() { berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); QmitkFunctionality::Activated(); } void QmitkDiffusionQuantificationView::Deactivated() { QmitkFunctionality::Deactivated(); } void QmitkDiffusionQuantificationView::GFACheckboxClicked() { m_Controls->frame_2->setVisible(m_Controls-> m_StandardGFACheckbox->isChecked()); } void QmitkDiffusionQuantificationView::GFA() { if(m_Controls->m_StandardGFACheckbox->isChecked()) { QBIQuantify(13); } else { QBIQuantify(0); } } void QmitkDiffusionQuantificationView::Curvature() { QBIQuantify(12); } void QmitkDiffusionQuantificationView::FA() { TensorQuantify(0); } void QmitkDiffusionQuantificationView::RA() { TensorQuantify(1); } void QmitkDiffusionQuantificationView::AD() { TensorQuantify(2); } void QmitkDiffusionQuantificationView::RD() { TensorQuantify(3); } void QmitkDiffusionQuantificationView::ClusterAnisotropy() { TensorQuantify(4); } +void QmitkDiffusionQuantificationView::MD() +{ + TensorQuantify(5); +} + void QmitkDiffusionQuantificationView::QBIQuantify(int method) { if (m_CurrentSelection) { mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; for (IStructuredSelection::iterator i = m_CurrentSelection->Begin(); i != m_CurrentSelection->End(); ++i) { if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); if(QString("QBallImage").compare(node->GetData()->GetNameOfClass())==0) { set->InsertElement(at++, node); } } } QBIQuantification(set, method); } } void QmitkDiffusionQuantificationView::TensorQuantify(int method) { if (m_CurrentSelection) { mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; for (IStructuredSelection::iterator i = m_CurrentSelection->Begin(); i != m_CurrentSelection->End(); ++i) { if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); if(QString("TensorImage").compare(node->GetData()->GetNameOfClass())==0) { set->InsertElement(at++, node); } } } TensorQuantification(set, method); } } void QmitkDiffusionQuantificationView::QBIQuantification( mitk::DataStorage::SetOfObjects::Pointer inImages, int method) { itk::TimeProbe clock; QString status; int nrFiles = inImages->size(); if (!nrFiles) return; mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector nodes; while ( itemiter != itemiterend ) // for all items { typedef float TOdfPixelType; const int odfsize = QBALL_ODFSIZE; typedef itk::Vector OdfVectorType; typedef itk::Image OdfVectorImgType; mitk::Image* vol = static_cast((*itemiter)->GetData()); OdfVectorImgType::Pointer itkvol = OdfVectorImgType::New(); mitk::CastToItkImage(vol, itkvol); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); ++itemiter; float p1 = m_Controls->m_ParamKEdit->text().toFloat(); float p2 = m_Controls->m_ParamPEdit->text().toFloat(); // COMPUTE RA clock.Start(); MBI_INFO << "Computing GFA "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( "Computing GFA for %s", nodename.c_str()).toAscii()); typedef OdfVectorType::ValueType RealValueType; typedef itk::Image< RealValueType, 3 > RAImageType; typedef itk::DiffusionQballGeneralizedFaImageFilter GfaFilterType; GfaFilterType::Pointer gfaFilter = GfaFilterType::New(); gfaFilter->SetInput(itkvol); gfaFilter->SetNumberOfThreads(8); double scale = 1; std::string newname; newname.append(nodename); switch(method) { case 0: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); newname.append("GFA"); scale = m_ScaleDAIValues; break; } case 1: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_HIGH_LOW); newname.append("01"); scale = m_ScaleDAIValues; break; } case 2: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_HIGH); newname.append("02"); scale = m_ScaleDAIValues; break; } case 3: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_MAX_ODF_VALUE); newname.append("03"); scale = m_ScaleDAIValues; break; } case 4: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_DECONVOLUTION_COEFFS); newname.append("04"); scale = m_ScaleDAIValues; break; } case 5: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_MAX_NORMALIZED_STANDARD); newname.append("05"); scale = m_ScaleDAIValues; break; } case 6: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_NORMALIZED_ENTROPY); newname.append("06"); break; } case 7: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_NEMATIC_ORDER_PARAMETER); newname.append("07"); scale = m_ScaleDAIValues; break; } case 8: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_LOW_HIGH); newname.append("08"); scale = m_ScaleDAIValues; break; } case 9: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_LOW); newname.append("09"); scale = m_ScaleDAIValues; break; } case 10: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_ODF_VALUE); newname.append("10"); scale = m_ScaleDAIValues; break; } case 11: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_STD_BY_MAX); newname.append("11"); scale = m_ScaleDAIValues; break; } case 12: { p1 = m_Controls->MinAngle->text().toFloat(); p2 = m_Controls->MaxAngle->text().toFloat(); gfaFilter->SetComputationMethod(GfaFilterType::GFA_PRINCIPLE_CURVATURE); QString paramString; paramString = paramString.append("PC%1-%2").arg(p1).arg(p2); newname.append(paramString.toAscii()); gfaFilter->SetParam1(p1); gfaFilter->SetParam2(p2); scale = m_ScaleDAIValues; break; } case 13: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_GENERALIZED_GFA); QString paramString; paramString = paramString.append("GFAK%1P%2").arg(p1).arg(p2); newname.append(paramString.toAscii()); gfaFilter->SetParam1(p1); gfaFilter->SetParam2(p2); scale = m_ScaleDAIValues; break; } default: { newname.append("0"); gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); scale = m_ScaleDAIValues; } } gfaFilter->Update(); clock.Stop(); MBI_DEBUG << "took " << clock.GetMeanTime() << "s."; typedef itk::Image ImgType; ImgType::Pointer img = ImgType::New(); img->SetSpacing( gfaFilter->GetOutput()->GetSpacing() ); // Set the image spacing img->SetOrigin( gfaFilter->GetOutput()->GetOrigin() ); // Set the image origin img->SetDirection( gfaFilter->GetOutput()->GetDirection() ); // Set the image direction img->SetLargestPossibleRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion()); img->SetBufferedRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion() ); img->Allocate(); itk::ImageRegionIterator ot (img, img->GetLargestPossibleRegion() ); ot = ot.Begin(); itk::ImageRegionConstIterator it (gfaFilter->GetOutput(), gfaFilter->GetOutput()->GetLargestPossibleRegion() ); it = it.Begin(); for (it = it.Begin(); !it.IsAtEnd(); ++it) { GfaFilterType::OutputImageType::PixelType val = it.Get(); ot.Set(val * scale); ++ot; } // GFA TO DATATREE mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( img.GetPointer() ); image->SetVolume( img->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetProperty( "name", mitk::StringProperty::New(newname) ); nodes.push_back(node); mitk::StatusBar::GetInstance()->DisplayText("Computation complete."); } std::vector::iterator nodeIt; for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); m_MultiWidget->RequestUpdate(); } void QmitkDiffusionQuantificationView::TensorQuantification( mitk::DataStorage::SetOfObjects::Pointer inImages, int method) { itk::TimeProbe clock; QString status; int nrFiles = inImages->size(); if (!nrFiles) return; mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector nodes; while ( itemiter != itemiterend ) // for all items { typedef float TTensorPixelType; typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; mitk::Image* vol = static_cast((*itemiter)->GetData()); TensorImageType::Pointer itkvol = TensorImageType::New(); mitk::CastToItkImage(vol, itkvol); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); ++itemiter; // COMPUTE FA clock.Start(); MBI_INFO << "Computing FA "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( "Computing FA for %s", nodename.c_str()).toAscii()); typedef itk::Image< TTensorPixelType, 3 > FAImageType; typedef itk::ShiftScaleImageFilter ShiftScaleFilterType; ShiftScaleFilterType::Pointer multi = ShiftScaleFilterType::New(); multi->SetShift(0.0); multi->SetScale(m_ScaleDAIValues);//itk::NumericTraits::max() typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; if(method == 0) //FA { /* typedef itk::TensorFractionalAnisotropyImageFilter< TensorImageType, FAImageType > FilterType; FilterType::Pointer anisotropyFilter = FilterType::New(); anisotropyFilter->SetInput( itkvol.GetPointer() ); anisotropyFilter->Update(); multi->SetInput(anisotropyFilter->GetOutput()); nodename = QString(nodename.c_str()).append("_FA").toStdString();*/ MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::FA); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_FA").toStdString(); } else if(method == 1) //RA { /*typedef itk::TensorRelativeAnisotropyImageFilter< TensorImageType, FAImageType > FilterType; FilterType::Pointer anisotropyFilter = FilterType::New(); anisotropyFilter->SetInput( itkvol.GetPointer() ); anisotropyFilter->Update(); multi->SetInput(anisotropyFilter->GetOutput()); nodename = QString(nodename.c_str()).append("_RA").toStdString();*/ MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::RA); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_RA").toStdString(); } else if(method == 2) // AD (Axial diffusivity) { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::AD); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_AD").toStdString(); } else if(method == 3) // RD (Radial diffusivity, (Lambda2+Lambda3)/2 { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::RD); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_RD").toStdString(); } else if(method == 4) // 1-(Lambda2+Lambda3)/(2*Lambda1) { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::CA); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_CA").toStdString(); } + else if(method == 5) // MD (Mean Diffusivity, (Lambda1+Lambda2+Lambda3)/3 ) + { + MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); + measurementsCalculator->SetInput(itkvol.GetPointer() ); + measurementsCalculator->SetMeasure(MeasurementsType::MD); + measurementsCalculator->Update(); + multi->SetInput(measurementsCalculator->GetOutput()); + nodename = QString(nodename.c_str()).append("_MD").toStdString(); + } multi->Update(); clock.Stop(); MBI_DEBUG << "took " << clock.GetMeanTime() << "s."; // FA TO DATATREE mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( multi->GetOutput() ); image->SetVolume( multi->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetProperty( "name", mitk::StringProperty::New(nodename) ); nodes.push_back(node); mitk::StatusBar::GetInstance()->DisplayText("Computation complete."); } std::vector::iterator nodeIt; for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); m_MultiWidget->RequestUpdate(); } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.h b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.h index 96aa65ae8f..cc0bce87f5 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.h +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.h @@ -1,106 +1,107 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date: 2009-05-28 17:19:30 +0200 (Do, 28 Mai 2009) $ Version: $Revision: 17495 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _QMITKDIFFUSIONQUANTIFICATIONVIEW_H_INCLUDED #define _QMITKDIFFUSIONQUANTIFICATIONVIEW_H_INCLUDED #include #include #include "berryISelectionListener.h" #include "berryIStructuredSelection.h" #include "ui_QmitkDiffusionQuantificationViewControls.h" /*! * \ingroup org_mitk_gui_qt_diffusionquantification_internal * * \brief QmitkDiffusionQuantificationView * * Document your class here. * * \sa QmitkFunctionality */ class QmitkDiffusionQuantificationView : public QObject, public QmitkFunctionality { friend struct DqSelListener; // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkDiffusionQuantificationView(); virtual ~QmitkDiffusionQuantificationView(); virtual void CreateQtPartControl(QWidget *parent); /// \brief Creation of the connections of main and control widget virtual void CreateConnections(); /// \brief Called when the functionality is activated virtual void Activated(); virtual void Deactivated(); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: void GFACheckboxClicked(); void GFA(); void Curvature(); void FA(); void RA(); void AD(); void RD(); void ClusterAnisotropy(); + void MD(); void QBIQuantify(int method); void QBIQuantification(mitk::DataStorage::SetOfObjects::Pointer inImages, int method) ; void TensorQuantify(int method); void TensorQuantification(mitk::DataStorage::SetOfObjects::Pointer inImages, int method) ; protected: Ui::QmitkDiffusionQuantificationViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; berry::ISelectionListener::Pointer m_SelListener; berry::IStructuredSelection::ConstPointer m_CurrentSelection; static const float m_ScaleDAIValues; }; #endif // _QMITKDIFFUSIONQUANTIFICATIONVIEW_H_INCLUDED diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationViewControls.ui b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationViewControls.ui index e1f31ace5f..6b96d2516b 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationViewControls.ui +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationViewControls.ui @@ -1,241 +1,251 @@ QmitkDiffusionQuantificationViewControls 0 0 281 - 402 + 443 0 0 QmitkTemplate Q-Ball Imaging QFrame::NoFrame QFrame::Raised 0 Generalized GFA QFrame::NoFrame QFrame::Raised 0 true k true true p true false GFA QFrame::NoFrame QFrame::Raised 0 Min. angle Max. angle false Curvature Tensor Imaging false FA (Fractional Anisotropy) false RA (Relative Anisotropy) false AD (Axial Diffusivity) false RD (Radial Diffusivity) + + + + false + + + MD (Mean Diffusivity) + + + false 1-(λ2+λ3)/(2*λ1) Qt::Vertical QSizePolicy::Expanding 20 220 QmitkDataStorageComboBox.h diff --git a/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.h b/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.h index 73b0c7c590..2ea5300502 100644 --- a/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.h +++ b/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.h @@ -1,86 +1,87 @@ /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkDiffusionTensor3DReconstructionImageFilter.h,v $ Language: C++ Date: $Date: 2006-03-27 17:01:06 $ Version: $Revision: 1.12 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkTensorDerivedMeasurementsFilter_h_ #define __itkTensorDerivedMeasurementsFilter_h_ #include "itkDiffusionTensor3D.h" #include "itkImageToImageFilter.h" namespace itk{ /** \class TensorDerivedMeasurementsFilter */ template class TensorDerivedMeasurementsFilter : public ImageToImageFilter< itk::Image< itk::DiffusionTensor3D, 3 >, itk::Image< TPixel, 3 > > { public: enum Measure { FA,// Fractional anisotropy RA,// Relative anisotropy AD,// Axial diffusivity RD,// Radial diffusivity CA, // Clustering anisotropy 1-(λ2+λ3)/(2*λ1) L2, - L3 + L3, + MD // mean diffusivity }; typedef itk::DiffusionTensor3D TensorType; typedef itk::Image< TensorType, 3 > TensorImageType; typedef itk::Image< TPixel, 3 > OutputImageType; typedef TensorDerivedMeasurementsFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< TensorType, OutputImageType > SuperClass; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(TensorDerivedMeasurementsFilter, ImageToImageFilter); itkSetMacro(Measure, Measure); protected: TensorDerivedMeasurementsFilter(); ~TensorDerivedMeasurementsFilter() {}; //void PrintSelf(std::ostream& os, Indent indent) const; Measure m_Measure; void GenerateData(); }; // end class } // end namespace #ifndef ITK_MANUAL_INSTANTIATION #include "itkTensorDerivedMeasurementsFilter.txx" #endif #endif //__itkTensorDerivedMeasurements_h_ diff --git a/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.txx b/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.txx index aa93328b30..19dd22cd8a 100644 --- a/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.txx +++ b/Modules/DiffusionImaging/Algorithms/itkTensorDerivedMeasurementsFilter.txx @@ -1,123 +1,130 @@ #ifndef __itkTensorDerivedMeasurementsFilter_txx #define __itkTensorDerivedMeasurementsFilter_txx namespace itk { template TensorDerivedMeasurementsFilter::TensorDerivedMeasurementsFilter() : m_Measure(AD) { } template void TensorDerivedMeasurementsFilter::GenerateData() { typename TensorImageType::Pointer tensorImage = static_cast< TensorImageType * >( this->ProcessObject::GetInput(0) ); typedef ImageRegionConstIterator< TensorImageType > TensorImageIteratorType; typedef ImageRegionIterator< OutputImageType > OutputImageIteratorType; typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); typename TensorImageType::RegionType region = tensorImage->GetLargestPossibleRegion(); outputImage->SetSpacing( tensorImage->GetSpacing() ); // Set the image spacing outputImage->SetOrigin( tensorImage->GetOrigin() ); // Set the image origin outputImage->SetDirection( tensorImage->GetDirection() ); // Set the image direction outputImage->SetRegions( tensorImage->GetLargestPossibleRegion()); outputImage->Allocate(); TensorImageIteratorType tensorIt(tensorImage, tensorImage->GetLargestPossibleRegion()); OutputImageIteratorType outputIt(outputImage, outputImage->GetLargestPossibleRegion()); tensorIt.GoToBegin(); outputIt.GoToBegin(); while(!tensorIt.IsAtEnd() && !outputIt.IsAtEnd()){ TensorType tensor = tensorIt.Get(); switch(m_Measure) { case FA: { TPixel diffusionIndex = tensor.GetFractionalAnisotropy(); outputIt.Set(diffusionIndex); break; } case RA: { TPixel diffusionIndex = tensor.GetRelativeAnisotropy(); outputIt.Set(diffusionIndex); break; } case AD: { // eigenvalues are sorted in ascending order by default because the // itk::SymmetricEigenAnalysis defaults are not touched in the tensor implementation typename TensorType::EigenValuesArrayType evs; tensor.ComputeEigenValues(evs); outputIt.Set(evs[2]); break; } case RD: { // eigenvalues are sorted in ascending order by default because the // itk::SymmetricEigenAnalysis defaults are not touched in the tensor implementation typename TensorType::EigenValuesArrayType evs; tensor.ComputeEigenValues(evs); - outputIt.Set((evs[0]+evs[1])/2); + outputIt.Set((evs[0]+evs[1])/2.0); break; } case CA: { // eigenvalues are sorted in ascending order by default because the // itk::SymmetricEigenAnalysis defaults are not touched in the tensor implementation typename TensorType::EigenValuesArrayType evs; tensor.ComputeEigenValues(evs); if (evs[2] == 0) { outputIt.Set(0); break; } - outputIt.Set(1-(evs[0]+evs[1])/(2*evs[2])); + outputIt.Set(1.0-(evs[0]+evs[1])/(2.0*evs[2])); break; } case L2: { // eigenvalues are sorted in ascending order by default because the // itk::SymmetricEigenAnalysis defaults are not touched in the tensor implementation typename TensorType::EigenValuesArrayType evs; tensor.ComputeEigenValues(evs); outputIt.Set(evs[1]); break; } case L3: { // eigenvalues are sorted in ascending order by default because the // itk::SymmetricEigenAnalysis defaults are not touched in the tensor implementation typename TensorType::EigenValuesArrayType evs; tensor.ComputeEigenValues(evs); outputIt.Set(evs[0]); break; } + case MD: + { + typename TensorType::EigenValuesArrayType evs; + tensor.ComputeEigenValues(evs); + outputIt.Set((evs[0]+evs[0]+evs[0])/3.0); + break; + } } ++tensorIt; ++outputIt; } } } #endif // __itkTensorDerivedMeasurements_txx