diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp index 160ce21217..f4e4043828 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp @@ -1,1718 +1,1710 @@ /*========================================================================= 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 "QmitkControlVisualizationPropertiesView.h" #include "mitkNodePredicateDataType.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkResliceMethodProperty.h" #include "mitkRenderingManager.h" #include "mitkTbssImage.h" #include "mitkTbssGradientImage.h" #include "mitkPlanarFigure.h" -#include "mitkFiberBundle.h" +#include "mitkFiberBundleX.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkFiberBundleInteractor.h" #include "mitkPlanarFigureInteractor.h" #include #include #include #include "mitkGlobalInteraction.h" #include "mitkGeometry2D.h" #include "berryIWorkbenchWindow.h" #include "berryIWorkbenchPage.h" #include "berryISelectionService.h" #include "berryConstants.h" #include "berryPlatformUI.h" #include "itkRGBAPixel.h" -#include "itkTractsToProbabilityImageFilter.h" +#include #include "qwidgetaction.h" #include "qcolordialog.h" const std::string QmitkControlVisualizationPropertiesView::VIEW_ID = "org.mitk.views.controlvisualizationpropertiesview"; using namespace berry; struct CvpSelListener : ISelectionListener { berryObjectMacro(CvpSelListener); CvpSelListener(QmitkControlVisualizationPropertiesView* view) { m_View = view; } void ApplySettings(mitk::DataNode::Pointer node) { bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("ShowMaxNumber", val); m_View->m_Controls->m_ShowMaxNumber->setValue(val); m_View->m_Controls->m_NormalizationDropdown->setCurrentIndex(dynamic_cast(node->GetProperty("Normalization"))->GetValueAsId()); float fval; node->GetFloatProperty("Scaling",fval); m_View->m_Controls->m_ScalingFactor->setValue(fval); m_View->m_Controls->m_AdditionalScaling->setCurrentIndex(dynamic_cast(node->GetProperty("ScaleBy"))->GetValueAsId()); node->GetFloatProperty("IndexParam1",fval); m_View->m_Controls->m_IndexParam1->setValue(fval); node->GetFloatProperty("IndexParam2",fval); m_View->m_Controls->m_IndexParam2->setValue(fval); } void DoSelectionChanged(ISelection::ConstPointer selection) { // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); m_View->m_Controls->m_VisibleOdfsON_T->setVisible(false); m_View->m_Controls->m_VisibleOdfsON_S->setVisible(false); m_View->m_Controls->m_VisibleOdfsON_C->setVisible(false); m_View->m_Controls->m_TextureIntON->setVisible(false); m_View->m_Controls->m_ImageControlsFrame->setVisible(false); m_View->m_Controls->m_PlanarFigureControlsFrame->setVisible(false); m_View->m_Controls->m_BundleControlsFrame->setVisible(false); m_View->m_SelectedNode = 0; if(m_View->m_CurrentSelection.IsNull()) return; if(m_View->m_CurrentSelection->Size() == 1) { mitk::DataNodeObject::Pointer nodeObj = m_View->m_CurrentSelection->Begin()->Cast(); if(nodeObj.IsNotNull()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); if(dynamic_cast(node->GetData()) != 0) { m_View->m_Controls->m_PlanarFigureControlsFrame->setVisible(true); m_View->m_SelectedNode = node; float val; node->GetFloatProperty("planarfigure.line.width", val); m_View->m_Controls->m_PFWidth->setValue((int)(val*10.0)); QString label = "Width %1"; label = label.arg(val); m_View->m_Controls->label_pfwidth->setText(label); float color[3]; node->GetColor( color, NULL, "planarfigure.default.line.color"); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255.0)); styleSheet.append(")"); m_View->m_Controls->m_PFColor->setAutoFillBackground(true); m_View->m_Controls->m_PFColor->setStyleSheet(styleSheet); node->GetColor( color, NULL, "color"); styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255.0)); styleSheet.append(")"); m_View->m_Controls->m_PFColor3D->setAutoFillBackground(true); m_View->m_Controls->m_PFColor3D->setStyleSheet(styleSheet); m_View->PlanarFigureFocus(); } - if(dynamic_cast(node->GetData()) != 0) + if(dynamic_cast(node->GetData()) != 0) { m_View->m_Controls->m_BundleControlsFrame->setVisible(true); m_View->m_SelectedNode = node; if(m_View->m_CurrentPickingNode != 0 && node.GetPointer() != m_View->m_CurrentPickingNode) { m_View->m_Controls->m_Crosshair->setEnabled(false); } else { m_View->m_Controls->m_Crosshair->setEnabled(true); } - + float val; node->GetFloatProperty("TubeRadius", val); m_View->m_Controls->m_TubeRadius->setValue((int)(val * 100.0)); QString label = "Radius %1"; label = label.arg(val); m_View->m_Controls->label_tuberadius->setText(label); int width; node->GetIntProperty("LineWidth", width); m_View->m_Controls->m_LineWidth->setValue(width); label = "Width %1"; label = label.arg(width); m_View->m_Controls->label_linewidth->setText(label); - + float range; node->GetFloatProperty("Fiber2DSliceThickness",range); label = "Range %1"; label = label.arg(range*0.1); m_View->m_Controls->label_range->setText(label); // mitk::ColorProperty* nodecolor= mitk::ColorProperty::New(); // node->GetProperty(nodecolor,"color"); // m_View->m_Controls->m_Color->setAutoFillBackground(true); // QString styleSheet = "background-color:rgb("; // styleSheet.append(QString::number(nodecolor->GetColor().GetRed()*255.0)); // styleSheet.append(","); // styleSheet.append(QString::number(nodecolor->GetColor().GetGreen()*255.0)); // styleSheet.append(","); // styleSheet.append(QString::number(nodecolor->GetColor().GetBlue()*255.0)); // styleSheet.append(")"); // m_View->m_Controls->m_Color->setStyleSheet(styleSheet); } } } if(m_View->m_CurrentSelection->Size() > 0 && m_View->m_SelectedNode == 0) { m_View->m_Controls->m_ImageControlsFrame->setVisible(true); bool foundDiffusionImage = false; bool foundQBIVolume = false; bool foundTensorVolume = false; bool foundImage = false; bool foundMultipleOdfImages = false; bool foundRGBAImage = false; bool foundTbssImage = false; // do something with the selected items if(m_View->m_CurrentSelection) { // 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("DiffusionImage").compare(node->GetData()->GetNameOfClass())==0) { foundDiffusionImage = true; bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("DisplayChannel", val); m_View->m_Controls->m_DisplayIndex->setValue(val); QString label = "Channel %1"; label = label.arg(val); m_View->m_Controls->label_channel->setText(label); int maxVal = (dynamic_cast* >(node->GetData()))->GetVectorImage()->GetVectorLength(); m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1); } if(QString("TbssImage").compare(node->GetData()->GetNameOfClass())==0) { foundTbssImage = true; bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("DisplayChannel", val); m_View->m_Controls->m_DisplayIndex->setValue(val); QString label = "Channel %1"; label = label.arg(val); m_View->m_Controls->label_channel->setText(label); int maxVal = (dynamic_cast(node->GetData()))->GetImage()->GetVectorLength(); m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1); } if(QString("TbssGradientImage").compare(node->GetData()->GetNameOfClass())==0) { foundTbssImage = true; bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("DisplayChannel", val); m_View->m_Controls->m_DisplayIndex->setValue(val); QString label = "Channel %1"; label = label.arg(val); m_View->m_Controls->label_channel->setText(label); int maxVal = (dynamic_cast(node->GetData()))->GetImage()->GetVectorLength(); m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1); } else if(QString("QBallImage").compare(node->GetData()->GetNameOfClass())==0) { foundMultipleOdfImages = foundQBIVolume || foundTensorVolume; foundQBIVolume = true; ApplySettings(node); } else if(QString("TensorImage").compare(node->GetData()->GetNameOfClass())==0) { foundMultipleOdfImages = foundQBIVolume || foundTensorVolume; foundTensorVolume = true; ApplySettings(node); } else if(QString("Image").compare(node->GetData()->GetNameOfClass())==0) { foundImage = true; mitk::Image::Pointer img = dynamic_cast(node->GetData()); if(img.IsNotNull() && img->GetPixelType().GetItkTypeId() == &typeid(itk::RGBAPixel) ) { foundRGBAImage = true; } bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } } } } } if(foundDiffusionImage || foundTbssImage) { m_View->m_Controls->m_DisplayIndex->setVisible(true); m_View->m_Controls->label_channel->setVisible(true); } m_View->m_FoundSingleOdfImage = (foundQBIVolume || foundTensorVolume) && !foundMultipleOdfImages; m_View->m_Controls->m_NumberGlyphsFrame->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_NormalizationDropdown->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->label->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_ScalingFactor->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_AdditionalScaling->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_NormalizationScalingFrame->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->OpacMinFrame->setVisible(foundRGBAImage || m_View->m_FoundSingleOdfImage); // changed for SPIE paper, Principle curvature scaling //m_View->m_Controls->params_frame->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->params_frame->setVisible(false); m_View->m_Controls->m_VisibleOdfsON_T->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_VisibleOdfsON_S->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_VisibleOdfsON_C->setVisible(m_View->m_FoundSingleOdfImage); bool foundAnyImage = foundDiffusionImage || foundQBIVolume || foundTensorVolume || foundImage || foundTbssImage; m_View->m_Controls->m_Reinit->setVisible(foundAnyImage); m_View->m_Controls->m_TextureIntON->setVisible(foundAnyImage); m_View->m_Controls->m_TSMenu->setVisible(foundAnyImage); if(m_View->m_IsInitialized) { //m_View->GetSite()->GetWorkbenchWindow()->GetActivePage() // ->HideView(IViewPart::Pointer(m_View)); //berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage() // ->ShowView(QmitkControlVisualizationPropertiesView::VIEW_ID, // "", berry::IWorkbenchPage::VIEW_VISIBLE); } } } 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); } } } QmitkControlVisualizationPropertiesView* m_View; }; QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_NodeUsedForOdfVisualization(NULL), m_IconTexOFF(new QIcon(":/QmitkDiffusionImaging/texIntOFFIcon.png")), m_IconTexON(new QIcon(":/QmitkDiffusionImaging/texIntONIcon.png")), m_IconGlyOFF_T(new QIcon(":/QmitkDiffusionImaging/glyphsoff_T.png")), m_IconGlyON_T(new QIcon(":/QmitkDiffusionImaging/glyphson_T.png")), m_IconGlyOFF_C(new QIcon(":/QmitkDiffusionImaging/glyphsoff_C.png")), m_IconGlyON_C(new QIcon(":/QmitkDiffusionImaging/glyphson_C.png")), m_IconGlyOFF_S(new QIcon(":/QmitkDiffusionImaging/glyphsoff_S.png")), m_IconGlyON_S(new QIcon(":/QmitkDiffusionImaging/glyphson_S.png")), m_CurrentSelection(0), m_CurrentPickingNode(0), m_GlyIsOn_S(false), m_GlyIsOn_C(false), m_GlyIsOn_T(false) { currentThickSlicesMode = 1; m_MyMenu = NULL; } QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView(const QmitkControlVisualizationPropertiesView& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkControlVisualizationPropertiesView::~QmitkControlVisualizationPropertiesView() { this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); } void QmitkControlVisualizationPropertiesView::OnThickSlicesModeSelected( QAction* action ) { currentThickSlicesMode = action->data().toInt(); switch(currentThickSlicesMode) { default: case 1: this->m_Controls->m_TSMenu->setText("MIP"); break; case 2: this->m_Controls->m_TSMenu->setText("SUM"); break; case 3: this->m_Controls->m_TSMenu->setText("WEIGH"); break; } mitk::DataNode* n; n = GetDataStorage()->GetNamedNode("widget1Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = GetDataStorage()->GetNamedNode("widget2Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = GetDataStorage()->GetNamedNode("widget3Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer->GetRenderingManager()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::OnTSNumChanged(int num) { if(num==0) { mitk::DataNode* n; n = GetDataStorage()->GetNamedNode("widget1Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); n = GetDataStorage()->GetNamedNode("widget2Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); n = GetDataStorage()->GetNamedNode("widget3Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); } else { mitk::DataNode* n; n = GetDataStorage()->GetNamedNode("widget1Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = GetDataStorage()->GetNamedNode("widget2Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = GetDataStorage()->GetNamedNode("widget3Plane"); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = GetDataStorage()->GetNamedNode("widget1Plane"); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); n = GetDataStorage()->GetNamedNode("widget2Plane"); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); n = GetDataStorage()->GetNamedNode("widget3Plane"); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); } m_TSLabel->setText(QString::number(num*2+1)); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer->GetRenderingManager()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); } void QmitkControlVisualizationPropertiesView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkControlVisualizationPropertiesViewControls; m_Controls->setupUi(parent); this->CreateConnections(); m_MyMenu = new QMenu(parent); connect( m_MyMenu, SIGNAL( aboutToShow() ), this, SLOT(OnMenuAboutToShow()) ); // button for changing rotation mode m_Controls->m_TSMenu->setMenu( m_MyMenu ); //m_CrosshairModeButton->setIcon( QIcon( iconCrosshairMode_xpm ) ); m_Controls->params_frame->setVisible(false); QIcon icon5(":/QmitkDiffusionImaging/Refresh_48.png"); m_Controls->m_Reinit->setIcon(icon5); m_Controls->m_Focus->setIcon(icon5); QIcon iconColor(":/QmitkDiffusionImaging/color24.gif"); m_Controls->m_PFColor->setIcon(iconColor); m_Controls->m_PFColor3D->setIcon(iconColor); m_Controls->m_Color->setIcon(iconColor); QIcon iconReset(":/QmitkDiffusionImaging/reset.png"); m_Controls->m_ResetColoring->setIcon(iconReset); m_Controls->m_PFColor->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); m_Controls->m_PFColor3D->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); QIcon iconCrosshair(":/QmitkDiffusionImaging/crosshair.png"); m_Controls->m_Crosshair->setIcon(iconCrosshair); // was is los QIcon iconPaint(":/QmitkDiffusionImaging/paint2.png"); m_Controls->m_TDI->setIcon(iconPaint); - + QIcon iconFiberFade(":/QmitkDiffusionImaging/MapperEfx2D.png"); m_Controls->m_FiberFading2D->setIcon(iconFiberFade); m_Controls->m_TextureIntON->setCheckable(true); #ifndef DIFFUSION_IMAGING_EXTENDED int size = m_Controls->m_AdditionalScaling->count(); for(int t=0; tm_AdditionalScaling->itemText(t).toStdString() == "Scale by ASR") { m_Controls->m_AdditionalScaling->removeItem(t); } } #endif m_Controls->m_OpacitySlider->setRange(0.0,1.0); m_Controls->m_OpacitySlider->setLowerValue(0.0); m_Controls->m_OpacitySlider->setUpperValue(0.0); m_Controls->m_ScalingFrame->setVisible(false); m_Controls->m_NormalizationFrame->setVisible(false); } m_IsInitialized = false; m_SelListener = berry::ISelectionListener::Pointer(new CvpSelListener(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); m_IsInitialized = true; } void QmitkControlVisualizationPropertiesView::OnMenuAboutToShow () { // THICK SLICE SUPPORT QMenu *myMenu = m_MyMenu; myMenu->clear(); QActionGroup* thickSlicesActionGroup = new QActionGroup(myMenu); thickSlicesActionGroup->setExclusive(true); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); int currentTSMode = 0; { mitk::ResliceMethodProperty::Pointer m = dynamic_cast(renderer->GetCurrentWorldGeometry2DNode()->GetProperty( "reslice.thickslices" )); if( m.IsNotNull() ) currentTSMode = m->GetValueAsId(); } const int maxTS = 30; int currentNum = 0; { mitk::IntProperty::Pointer m = dynamic_cast(renderer->GetCurrentWorldGeometry2DNode()->GetProperty( "reslice.thickslices.num" )); if( m.IsNotNull() ) { currentNum = m->GetValue(); if(currentNum < 0) currentNum = 0; if(currentNum > maxTS) currentNum = maxTS; } } if(currentTSMode==0) currentNum=0; QSlider *m_TSSlider = new QSlider(myMenu); m_TSSlider->setMinimum(0); m_TSSlider->setMaximum(maxTS-1); m_TSSlider->setValue(currentNum); m_TSSlider->setOrientation(Qt::Horizontal); connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) ); QHBoxLayout* _TSLayout = new QHBoxLayout; _TSLayout->setContentsMargins(4,4,4,4); _TSLayout->addWidget(m_TSSlider); _TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),myMenu)); QWidget* _TSWidget = new QWidget; _TSWidget->setLayout(_TSLayout); QActionGroup* thickSliceModeActionGroup = new QActionGroup(myMenu); thickSliceModeActionGroup->setExclusive(true); QWidgetAction *m_TSSliderAction = new QWidgetAction(myMenu); m_TSSliderAction->setDefaultWidget(_TSWidget); myMenu->addAction(m_TSSliderAction); QAction* mipThickSlicesAction = new QAction(myMenu); mipThickSlicesAction->setActionGroup(thickSliceModeActionGroup); mipThickSlicesAction->setText("MIP (max. intensity proj.)"); mipThickSlicesAction->setCheckable(true); mipThickSlicesAction->setChecked(currentThickSlicesMode==1); mipThickSlicesAction->setData(1); myMenu->addAction( mipThickSlicesAction ); QAction* sumThickSlicesAction = new QAction(myMenu); sumThickSlicesAction->setActionGroup(thickSliceModeActionGroup); sumThickSlicesAction->setText("SUM (sum intensity proj.)"); sumThickSlicesAction->setCheckable(true); sumThickSlicesAction->setChecked(currentThickSlicesMode==2); sumThickSlicesAction->setData(2); myMenu->addAction( sumThickSlicesAction ); QAction* weightedThickSlicesAction = new QAction(myMenu); weightedThickSlicesAction->setActionGroup(thickSliceModeActionGroup); weightedThickSlicesAction->setText("WEIGHTED (gaussian proj.)"); weightedThickSlicesAction->setCheckable(true); weightedThickSlicesAction->setChecked(currentThickSlicesMode==3); weightedThickSlicesAction->setData(3); myMenu->addAction( weightedThickSlicesAction ); connect( thickSliceModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnThickSlicesModeSelected(QAction*)) ); } void QmitkControlVisualizationPropertiesView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkControlVisualizationPropertiesView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkControlVisualizationPropertiesView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_DisplayIndex), SIGNAL(valueChanged(int)), this, SLOT(DisplayIndexChanged(int)) ); connect( (QObject*)(m_Controls->m_TextureIntON), SIGNAL(clicked()), this, SLOT(TextIntON()) ); connect( (QObject*)(m_Controls->m_Reinit), SIGNAL(clicked()), this, SLOT(Reinit()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_T), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_T()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_S), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_S()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_C), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_C()) ); connect( (QObject*)(m_Controls->m_ShowMaxNumber), SIGNAL(editingFinished()), this, SLOT(ShowMaxNumberChanged()) ); connect( (QObject*)(m_Controls->m_NormalizationDropdown), SIGNAL(currentIndexChanged(int)), this, SLOT(NormalizationDropdownChanged(int)) ); connect( (QObject*)(m_Controls->m_ScalingFactor), SIGNAL(valueChanged(double)), this, SLOT(ScalingFactorChanged(double)) ); connect( (QObject*)(m_Controls->m_AdditionalScaling), SIGNAL(currentIndexChanged(int)), this, SLOT(AdditionalScaling(int)) ); connect( (QObject*)(m_Controls->m_IndexParam1), SIGNAL(valueChanged(double)), this, SLOT(IndexParam1Changed(double)) ); connect( (QObject*)(m_Controls->m_IndexParam2), SIGNAL(valueChanged(double)), this, SLOT(IndexParam2Changed(double)) ); connect( (QObject*)(m_Controls->m_ScalingCheckbox), SIGNAL(clicked()), this, SLOT(ScalingCheckbox()) ); connect( (QObject*)(m_Controls->m_OpacitySlider), SIGNAL(spanChanged(double,double)), this, SLOT(OpacityChanged(double,double)) ); connect((QObject*) m_Controls->m_Wire, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationWire())); connect((QObject*) m_Controls->m_Tube, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationTube())); connect((QObject*) m_Controls->m_Color, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationColor())); connect((QObject*) m_Controls->m_ResetColoring, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationResetColoring())); connect((QObject*) m_Controls->m_Focus, SIGNAL(clicked()), (QObject*) this, SLOT(PlanarFigureFocus())); connect((QObject*) m_Controls->m_FiberFading2D, SIGNAL(clicked()), (QObject*) this, SLOT( Fiber2DfadingEFX() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(sliderReleased()), (QObject*) this, SLOT( FiberSlicingThickness2D() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(valueChanged(int)), (QObject*) this, SLOT( FiberSlicingUpdateLabel(int) )); connect((QObject*) m_Controls->m_Crosshair, SIGNAL(clicked()), (QObject*) this, SLOT(SetInteractor())); connect((QObject*) m_Controls->m_PFWidth, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(PFWidth(int))); connect((QObject*) m_Controls->m_PFColor, SIGNAL(clicked()), (QObject*) this, SLOT(PFColor())); connect((QObject*) m_Controls->m_PFColor3D, SIGNAL(clicked()), (QObject*) this, SLOT(PFColor3D())); connect((QObject*) m_Controls->m_TDI, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateTdi())); connect((QObject*) m_Controls->m_LineWidth, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(LineWidthChanged(int))); connect((QObject*) m_Controls->m_TubeRadius, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(TubeRadiusChanged(int))); connect((QObject*) m_Controls->m_Welcome, SIGNAL(clicked()), (QObject*) this, SLOT(Welcome())); } } void QmitkControlVisualizationPropertiesView::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 QmitkControlVisualizationPropertiesView::Deactivated() { QmitkFunctionality::Deactivated(); } int QmitkControlVisualizationPropertiesView::GetSizeFlags(bool width) { if(!width) { return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL; } else { return 0; } } int QmitkControlVisualizationPropertiesView::ComputePreferredSize(bool width, int /*availableParallel*/, int /*availablePerpendicular*/, int preferredResult) { if(width==false) { return m_FoundSingleOdfImage ? 120 : 80; } else { return preferredResult; } } // set diffusion image channel to b0 volume void QmitkControlVisualizationPropertiesView::NodeAdded(const mitk::DataNode *node) { mitk::DataNode* notConst = const_cast(node); if (dynamic_cast*>(notConst->GetData())) { mitk::DiffusionImage::Pointer dimg = dynamic_cast*>(notConst->GetData()); notConst->SetIntProperty("DisplayChannel", dimg->GetB0Indices().front()); } } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkControlVisualizationPropertiesView::OnSelectionChanged( std::vector nodes ) { if ( !this->IsVisible() ) { // do nothing if nobody wants to see me :-( return; } // deactivate channel slider if no diffusion weighted image is selected m_Controls->m_DisplayIndex->setVisible(false); m_Controls->label_channel->setVisible(false); for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if (node.IsNotNull() && dynamic_cast*>(node->GetData())) { m_Controls->m_DisplayIndex->setVisible(true); m_Controls->label_channel->setVisible(true); } } for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && (dynamic_cast(node->GetData()) || dynamic_cast(node->GetData())) ) { if(m_NodeUsedForOdfVisualization.IsNotNull()) { m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", false); } m_NodeUsedForOdfVisualization = node; m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); m_Controls->m_TSMenu->setVisible(false); // deactivate mip etc. for tensor and q-ball images break; } else m_Controls->m_TSMenu->setVisible(true); } } mitk::DataStorage::SetOfObjects::Pointer QmitkControlVisualizationPropertiesView::ActiveSet(std::string classname) { 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(classname.c_str()).compare(node->GetData()->GetNameOfClass())==0) { set->InsertElement(at++, node); } } } return set; } return 0; } void QmitkControlVisualizationPropertiesView::SetBoolProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, bool value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetBoolProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetIntProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, int value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetIntProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetFloatProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, float value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetFloatProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetLevelWindowProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, mitk::LevelWindow value) { if(set.IsNotNull()) { mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(value); mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetProperty(name.c_str(), prop); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetEnumProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, mitk::EnumerationProperty::Pointer value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::DisplayIndexChanged(int dispIndex) { QString label = "Channel %1"; label = label.arg(dispIndex); m_Controls->label_channel->setText(label); std::vector sets; sets.push_back("DiffusionImage"); sets.push_back("TbssImage"); sets.push_back("TbssGradientImage"); std::vector::iterator it = sets.begin(); while(it != sets.end()) { std::string s = *it; mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet(s); if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetIntProperty("DisplayChannel", dispIndex); ++itemiter; } //m_MultiWidget->RequestUpdate(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } it++; } } void QmitkControlVisualizationPropertiesView::Reinit() { if (m_CurrentSelection) { mitk::DataNodeObject::Pointer nodeObj = m_CurrentSelection->Begin()->Cast(); mitk::DataNode::Pointer node = nodeObj->GetDataNode(); mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkControlVisualizationPropertiesView::TextIntON() { if(m_TexIsOn) { m_Controls->m_TextureIntON->setIcon(*m_IconTexOFF); } else { m_Controls->m_TextureIntON->setIcon(*m_IconTexON); } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("DiffusionImage"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); set = ActiveSet("TensorImage"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); set = ActiveSet("QBallImage"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); set = ActiveSet("Image"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); m_TexIsOn = !m_TexIsOn; if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_S() { m_GlyIsOn_S = m_Controls->m_VisibleOdfsON_S->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); VisibleOdfsON(0); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_T() { m_GlyIsOn_T = m_Controls->m_VisibleOdfsON_T->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); VisibleOdfsON(1); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_C() { m_GlyIsOn_C = m_Controls->m_VisibleOdfsON_C->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); VisibleOdfsON(2); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON(int view) { if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::ShowMaxNumberChanged() { int maxNr = m_Controls->m_ShowMaxNumber->value(); if ( maxNr < 1 ) { m_Controls->m_ShowMaxNumber->setValue( 1 ); maxNr = 1; } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetIntProp(set,"ShowMaxNumber", maxNr); set = ActiveSet("TensorImage"); SetIntProp(set,"ShowMaxNumber", maxNr); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::NormalizationDropdownChanged(int normDropdown) { typedef mitk::OdfNormalizationMethodProperty PropType; PropType::Pointer normMeth = PropType::New(); switch(normDropdown) { case 0: normMeth->SetNormalizationToMinMax(); break; case 1: normMeth->SetNormalizationToMax(); break; case 2: normMeth->SetNormalizationToNone(); break; case 3: normMeth->SetNormalizationToGlobalMax(); break; default: normMeth->SetNormalizationToMinMax(); } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetEnumProp(set,"Normalization", normMeth.GetPointer()); set = ActiveSet("TensorImage"); SetEnumProp(set,"Normalization", normMeth.GetPointer()); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::ScalingFactorChanged(double scalingFactor) { mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetFloatProp(set,"Scaling", scalingFactor); set = ActiveSet("TensorImage"); SetFloatProp(set,"Scaling", scalingFactor); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::AdditionalScaling(int additionalScaling) { typedef mitk::OdfScaleByProperty PropType; PropType::Pointer scaleBy = PropType::New(); switch(additionalScaling) { case 0: scaleBy->SetScaleByNothing(); break; case 1: scaleBy->SetScaleByGFA(); //m_Controls->params_frame->setVisible(true); break; #ifdef DIFFUSION_IMAGING_EXTENDED case 2: scaleBy->SetScaleByPrincipalCurvature(); // commented in for SPIE paper, Principle curvature scaling //m_Controls->params_frame->setVisible(true); break; #endif default: scaleBy->SetScaleByNothing(); } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetEnumProp(set,"ScaleBy", scaleBy.GetPointer()); set = ActiveSet("TensorImage"); SetEnumProp(set,"ScaleBy", scaleBy.GetPointer()); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::IndexParam1Changed(double param1) { mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetFloatProp(set,"IndexParam1", param1); set = ActiveSet("TensorImage"); SetFloatProp(set,"IndexParam1", param1); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::IndexParam2Changed(double param2) { mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetFloatProp(set,"IndexParam2", param2); set = ActiveSet("TensorImage"); SetFloatProp(set,"IndexParam2", param2); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::OpacityChanged(double l, double u) { mitk::LevelWindow olw; olw.SetRangeMinMax(l*255, u*255); mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetLevelWindowProp(set,"opaclevelwindow", olw); set = ActiveSet("TensorImage"); SetLevelWindowProp(set,"opaclevelwindow", olw); set = ActiveSet("Image"); SetLevelWindowProp(set,"opaclevelwindow", olw); m_Controls->m_OpacityMinFaLabel->setText(QString::number(l,'f',2) + " : " + QString::number(u,'f',2)); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::ScalingCheckbox() { m_Controls->m_ScalingFrame->setVisible( m_Controls->m_ScalingCheckbox->isChecked()); if(!m_Controls->m_ScalingCheckbox->isChecked()) { m_Controls->m_AdditionalScaling->setCurrentIndex(0); m_Controls->m_ScalingFactor->setValue(1.0); } } void QmitkControlVisualizationPropertiesView::Fiber2DfadingEFX() { - if (m_SelectedNode) + if (m_SelectedNode) { bool currentMode; m_SelectedNode->GetBoolProperty("Fiber2DfadeEFX", currentMode); m_SelectedNode->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(!currentMode)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } - + } void QmitkControlVisualizationPropertiesView::FiberSlicingThickness2D() { - if (m_SelectedNode) + if (m_SelectedNode) { - - + + float fibThickness = m_Controls->m_FiberThicknessSlider->value() * 0.1; m_SelectedNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(fibThickness)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingUpdateLabel(int value) { QString label = "Range %1"; label = label.arg(value * 0.1); m_Controls->label_range->setText(label); } void QmitkControlVisualizationPropertiesView::BundleRepresentationWire() { if(m_SelectedNode) { int width = m_Controls->m_LineWidth->value(); m_SelectedNode->SetProperty("LineWidth",mitk::IntProperty::New(width)); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(15)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(18)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(1)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(2)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(3)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(4)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(0)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::BundleRepresentationTube() { if(m_SelectedNode) { float radius = m_Controls->m_TubeRadius->value() / 100.0; m_SelectedNode->SetProperty("TubeRadius",mitk::FloatProperty::New(radius)); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(17)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(13)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(16)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(0)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::BundleRepresentationColor() { if(m_SelectedNode) { QColor color = QColorDialog::getColor(); m_Controls->m_Color->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color.red())); styleSheet.append(","); styleSheet.append(QString::number(color.green())); styleSheet.append(","); styleSheet.append(QString::number(color.blue())); styleSheet.append(")"); m_Controls->m_Color->setStyleSheet(styleSheet); m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(14)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(3)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(0)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::BundleRepresentationResetColoring() { if(m_SelectedNode) { m_Controls->m_Color->setAutoFillBackground(true); QString styleSheet = "background-color:rgb(255,255,255)"; m_Controls->m_Color->setStyleSheet(styleSheet); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(4)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); m_SelectedNode->SetProperty("ColorCoding",mitk::IntProperty::New(0)); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::PlanarFigureFocus() { if(m_SelectedNode) { mitk::PlanarFigure* _PlanarFigure = 0; _PlanarFigure = dynamic_cast (m_SelectedNode->GetData()); if (_PlanarFigure) { QmitkRenderWindow* selectedRenderWindow = 0; bool PlanarFigureInitializedWindow = false; QmitkRenderWindow* RenderWindow1 = this->GetActiveStdMultiWidget()->GetRenderWindow1(); if (m_SelectedNode->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } QmitkRenderWindow* RenderWindow2 = this->GetActiveStdMultiWidget()->GetRenderWindow2(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } QmitkRenderWindow* RenderWindow3 = this->GetActiveStdMultiWidget()->GetRenderWindow3(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } QmitkRenderWindow* RenderWindow4 = this->GetActiveStdMultiWidget()->GetRenderWindow4(); if (!selectedRenderWindow && m_SelectedNode->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::VnlVector normal1 = _Plane1->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry2 = RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane2 = dynamic_cast( worldGeometry2.GetPointer() ); mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry3 = RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane3 = dynamic_cast( worldGeometry3.GetPointer() ); 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; } } // make node visible if (selectedRenderWindow) { mitk::Point3D centerP = _PlaneGeometry->GetOrigin(); selectedRenderWindow->GetSliceNavigationController()->ReorientSlices( centerP, _PlaneGeometry->GetNormal()); selectedRenderWindow->GetSliceNavigationController()->SelectSliceByPoint( centerP); } } // set interactor for new node (if not already set) mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(m_SelectedNode->GetInteractor()); if(figureInteractor.IsNull()) figureInteractor = mitk::PlanarFigureInteractor::New("PlanarFigureInteractor", m_SelectedNode); mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); m_SelectedNode->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true)); } } void QmitkControlVisualizationPropertiesView::SetInteractor() { typedef std::vector Container; Container _NodeSet = this->GetDataManagerSelection(); mitk::DataNode* node = 0; - mitk::FiberBundle* bundle = 0; + mitk::FiberBundleX* bundle = 0; mitk::FiberBundleInteractor::Pointer bundleInteractor = 0; // finally add all nodes to the model for(Container::const_iterator it=_NodeSet.begin(); it!=_NodeSet.end() ; it++) { node = const_cast(*it); - bundle = dynamic_cast(node->GetData()); + bundle = dynamic_cast(node->GetData()); if(bundle) { bundleInteractor = dynamic_cast(node->GetInteractor()); if(bundleInteractor.IsNotNull()) mitk::GlobalInteraction::GetInstance()->RemoveInteractor(bundleInteractor); if(!m_Controls->m_Crosshair->isChecked()) { m_Controls->m_Crosshair->setChecked(false); this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::ArrowCursor); m_CurrentPickingNode = 0; } else { m_Controls->m_Crosshair->setChecked(true); bundleInteractor = mitk::FiberBundleInteractor::New("FiberBundleInteractor", node); mitk::GlobalInteraction::GetInstance()->AddInteractor(bundleInteractor); this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::CrossCursor); m_CurrentPickingNode = node; } } } } void QmitkControlVisualizationPropertiesView::PFWidth(int w) { double width = w/10.0; m_SelectedNode->SetProperty("planarfigure.line.width", mitk::FloatProperty::New(width) ); m_SelectedNode->SetProperty("planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(width) ); m_SelectedNode->SetProperty("planarfigure.outline.width", mitk::FloatProperty::New(width) ); m_SelectedNode->SetProperty("planarfigure.helperline.width", mitk::FloatProperty::New(width) ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QString label = "Width %1"; label = label.arg(width); m_Controls->label_pfwidth->setText(label); } void QmitkControlVisualizationPropertiesView::PFColor() { QColor color = QColorDialog::getColor(); m_Controls->m_PFColor->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color.red())); styleSheet.append(","); styleSheet.append(QString::number(color.green())); styleSheet.append(","); styleSheet.append(QString::number(color.blue())); styleSheet.append(")"); m_Controls->m_PFColor->setStyleSheet(styleSheet); m_SelectedNode->SetProperty( "planarfigure.default.line.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.outline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.helperline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) ); m_SelectedNode->SetProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) ); m_SelectedNode->SetProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) ); // m_SelectedNode->SetProperty( "planarfigure.hover.markerline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); // m_SelectedNode->SetProperty( "planarfigure.hover.marker.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); // m_SelectedNode->SetProperty( "planarfigure.selected.line.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); // m_SelectedNode->SetProperty( "planarfigure.selected.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); // m_SelectedNode->SetProperty( "planarfigure.selected.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); // m_SelectedNode->SetProperty( "planarfigure.selected.markerline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); // m_SelectedNode->SetProperty( "planarfigure.selected.marker.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::PFColor3D() { QColor color = QColorDialog::getColor(); m_Controls->m_PFColor3D->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color.red())); styleSheet.append(","); styleSheet.append(QString::number(color.green())); styleSheet.append(","); styleSheet.append(QString::number(color.blue())); styleSheet.append(")"); m_Controls->m_PFColor3D->setStyleSheet(styleSheet); m_SelectedNode->SetProperty( "color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::GenerateTdi() { if(m_SelectedNode) { - mitk::FiberBundle* bundle = dynamic_cast(m_SelectedNode->GetData()); + mitk::FiberBundleX* bundle = dynamic_cast(m_SelectedNode->GetData()); if(!bundle) return; - /////////////////////////////// - // Generate unsigned char Image - typedef unsigned char OutPixType2; + typedef float OutPixType; + typedef itk::Image OutImageType; // run generator - typedef itk::Image< float, 3 > WMPImageType; - typedef itk::TractsToProbabilityImageFilter ImageGeneratorType2; - ImageGeneratorType2::Pointer generator = ImageGeneratorType2::New(); - //generator->SetInput(NULL); + itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(bundle); - generator->SetInvertImage(false); generator->SetUpsamplingFactor(2); - generator->SetBinaryEnvelope(false); generator->Update(); // get result - typedef itk::Image OutType2; - OutType2::Pointer outImg = generator->GetOutput(); + OutImageType::Pointer outImg = generator->GetOutput(); - mitk::Image::Pointer img2 = mitk::Image::New(); - img2->InitializeByItk(outImg.GetPointer()); - img2->SetVolume(outImg->GetBufferPointer()); + mitk::Image::Pointer img = mitk::Image::New(); + img->InitializeByItk(outImg.GetPointer()); + img->SetVolume(outImg->GetBufferPointer()); // to datastorage mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(img2); + node->SetData(img); QString name(m_SelectedNode->GetName().c_str()); name += "_TDI"; node->SetName(name.toStdString()); node->SetVisibility(true); GetDataStorage()->Add(node); } } void QmitkControlVisualizationPropertiesView::LineWidthChanged(int w) { m_SelectedNode->SetIntProperty("LineWidth", w); QString label = "Width %1"; label = label.arg(w); m_Controls->label_linewidth->setText(label); } void QmitkControlVisualizationPropertiesView::TubeRadiusChanged(int r) { m_SelectedNode->SetFloatProperty("TubeRadius", (float) r / 100.0); QString label = "Radius %1"; label = label.arg(r / 100.0); m_Controls->label_tuberadius->setText(label); } void QmitkControlVisualizationPropertiesView::Welcome() { berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro( GetSite()->GetWorkbenchWindow(), false); } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp index 2768268529..718549972f 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingView.cpp @@ -1,1608 +1,1596 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ 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. =========================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkFiberProcessingView.h" #include // Qt #include //MITK #include #include #include #include #include #include #include #include #include #include // ITK #include #include #include #include -#include +#include #include +#include const std::string QmitkFiberProcessingView::VIEW_ID = "org.mitk.views.fiberprocessing"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace mitk; QmitkFiberProcessingView::QmitkFiberProcessingView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_EllipseCounter(0) , m_PolygonCounter(0) , m_UpsamplingFactor(5) { } // Destructor QmitkFiberProcessingView::~QmitkFiberProcessingView() { } void QmitkFiberProcessingView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkFiberProcessingViewControls; m_Controls->setupUi( parent ); m_Controls->doExtractFibersButton->setDisabled(true); m_Controls->PFCompoANDButton->setDisabled(true); m_Controls->PFCompoORButton->setDisabled(true); m_Controls->PFCompoNOTButton->setDisabled(true); m_Controls->m_CircleButton->setEnabled(false); m_Controls->m_PolygonButton->setEnabled(false); m_Controls->m_RectangleButton->setEnabled(false); m_Controls->m_RectangleButton->setVisible(false); connect( m_Controls->doExtractFibersButton, SIGNAL(clicked()), this, SLOT(DoFiberExtraction()) ); connect( m_Controls->m_CircleButton, SIGNAL( clicked() ), this, SLOT( ActionDrawEllipseTriggered() ) ); connect( m_Controls->m_PolygonButton, SIGNAL( clicked() ), this, SLOT( ActionDrawPolygonTriggered() ) ); connect(m_Controls->PFCompoANDButton, SIGNAL(clicked()), this, SLOT(GenerateAndComposite()) ); connect(m_Controls->PFCompoORButton, SIGNAL(clicked()), this, SLOT(GenerateOrComposite()) ); connect(m_Controls->PFCompoNOTButton, SIGNAL(clicked()), this, SLOT(GenerateNotComposite()) ); connect(m_Controls->m_JoinBundles, SIGNAL(clicked()), this, SLOT(JoinBundles()) ); connect(m_Controls->m_SubstractBundles, SIGNAL(clicked()), this, SLOT(SubstractBundles()) ); connect(m_Controls->m_GenerateRoiImage, SIGNAL(clicked()), this, SLOT(GenerateRoiImage()) ); connect( m_Controls->m_ProcessFiberBundleButton, SIGNAL(clicked()), this, SLOT(ProcessSelectedBundles()) ); } } void QmitkFiberProcessingView::GenerateRoiImage(){ if (m_SelectedImage.IsNull() || m_SelectedPF.empty()) return; mitk::Image* image = const_cast(m_SelectedImage.GetPointer()); UCharImageType::Pointer temp = UCharImageType::New(); mitk::CastToItkImage(m_SelectedImage, temp); m_PlanarFigureImage = UCharImageType::New(); m_PlanarFigureImage->SetSpacing( temp->GetSpacing() ); // Set the image spacing m_PlanarFigureImage->SetOrigin( temp->GetOrigin() ); // Set the image origin m_PlanarFigureImage->SetDirection( temp->GetDirection() ); // Set the image direction m_PlanarFigureImage->SetRegions( temp->GetLargestPossibleRegion() ); m_PlanarFigureImage->Allocate(); m_PlanarFigureImage->FillBuffer( 0 ); for (int i=0; iInitializeByItk(m_PlanarFigureImage.GetPointer()); tmpImage->SetVolume(m_PlanarFigureImage->GetBufferPointer()); node->SetData(tmpImage); node->SetName("ROI Image"); this->GetDefaultDataStorage()->Add(node); } void QmitkFiberProcessingView::CompositeExtraction(mitk::DataNode::Pointer node, mitk::Image* image) { if (dynamic_cast(node.GetPointer()->GetData()) && !dynamic_cast(node.GetPointer()->GetData())) { m_PlanarFigure = dynamic_cast(node.GetPointer()->GetData()); AccessFixedDimensionByItk_2( image, InternalReorientImagePlane, 3, m_PlanarFigure->GetGeometry(), -1); // itk::Image< unsigned char, 3 >::Pointer outimage = itk::Image< unsigned char, 3 >::New(); // outimage->SetSpacing( m_PlanarFigure->GetGeometry()->GetSpacing()/m_UpsamplingFactor ); // Set the image spacing // mitk::Point3D origin = m_PlanarFigure->GetGeometry()->GetOrigin(); // mitk::Point3D indexOrigin; // m_PlanarFigure->GetGeometry()->WorldToIndex(origin, indexOrigin); // indexOrigin[0] = indexOrigin[0] - .5 * (1.0-1.0/m_UpsamplingFactor); // indexOrigin[1] = indexOrigin[1] - .5 * (1.0-1.0/m_UpsamplingFactor); // indexOrigin[2] = indexOrigin[2] - .5 * (1.0-1.0/m_UpsamplingFactor); // mitk::Point3D newOrigin; // m_PlanarFigure->GetGeometry()->IndexToWorld(indexOrigin, newOrigin); // outimage->SetOrigin( newOrigin ); // Set the image origin // itk::Matrix matrix; // for (int i=0; i<3; i++) // for (int j=0; j<3; j++) // matrix[j][i] = m_PlanarFigure->GetGeometry()->GetMatrixColumn(i)[j]/m_PlanarFigure->GetGeometry()->GetSpacing().GetElement(i); // outimage->SetDirection( matrix ); // Set the image direction // itk::ImageRegion<3> upsampledRegion; // upsampledRegion.SetSize(0, m_PlanarFigure->GetGeometry()->GetParametricExtentInMM(0)/m_PlanarFigure->GetGeometry()->GetSpacing()[0]); // upsampledRegion.SetSize(1, m_PlanarFigure->GetGeometry()->GetParametricExtentInMM(1)/m_PlanarFigure->GetGeometry()->GetSpacing()[1]); // upsampledRegion.SetSize(2, 1); // typename itk::Image< unsigned char, 3 >::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); // for (unsigned int n = 0; n < 2; n++) // { // upsampledSize[n] = upsampledSize[n] * m_UpsamplingFactor; // } // upsampledRegion.SetSize( upsampledSize ); // outimage->SetRegions( upsampledRegion ); // outimage->Allocate(); // this->m_InternalImage = mitk::Image::New(); // this->m_InternalImage->InitializeByItk( outimage.GetPointer() ); // this->m_InternalImage->SetVolume( outimage->GetBufferPointer() ); AccessFixedDimensionByItk_2( m_InternalImage, InternalCalculateMaskFromPlanarFigure, 3, 2, node->GetName() ); } } template < typename TPixel, unsigned int VImageDimension > void QmitkFiberProcessingView::InternalReorientImagePlane( const itk::Image< TPixel, VImageDimension > *image, mitk::Geometry3D* planegeo3D, int additionalIndex ) { MITK_INFO << "InternalReorientImagePlane() start"; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< float, VImageDimension > FloatImageType; typedef itk::ResampleImageFilter ResamplerType; typename ResamplerType::Pointer resampler = ResamplerType::New(); mitk::PlaneGeometry* planegeo = dynamic_cast(planegeo3D); float upsamp = m_UpsamplingFactor; float gausssigma = 0.5; // Spacing typename ResamplerType::SpacingType spacing = planegeo->GetSpacing(); spacing[0] = image->GetSpacing()[0] / upsamp; spacing[1] = image->GetSpacing()[1] / upsamp; spacing[2] = image->GetSpacing()[2]; resampler->SetOutputSpacing( spacing ); // Size typename ResamplerType::SizeType size; size[0] = planegeo->GetParametricExtentInMM(0) / spacing[0]; size[1] = planegeo->GetParametricExtentInMM(1) / spacing[1]; size[2] = 1; resampler->SetSize( size ); // Origin typename mitk::Point3D orig = planegeo->GetOrigin(); typename mitk::Point3D corrorig; planegeo3D->WorldToIndex(orig,corrorig); corrorig[0] += 0.5/upsamp; corrorig[1] += 0.5/upsamp; corrorig[2] += 0; planegeo3D->IndexToWorld(corrorig,corrorig); resampler->SetOutputOrigin(corrorig ); // Direction typename ResamplerType::DirectionType direction; typename mitk::AffineTransform3D::MatrixType matrix = planegeo->GetIndexToWorldTransform()->GetMatrix(); for(int c=0; cSetOutputDirection( direction ); // Gaussian interpolation if(gausssigma != 0) { double sigma[3]; for( unsigned int d = 0; d < 3; d++ ) { sigma[d] = gausssigma * image->GetSpacing()[d]; } double alpha = 2.0; typedef itk::GaussianInterpolateImageFunction GaussianInterpolatorType; typename GaussianInterpolatorType::Pointer interpolator = GaussianInterpolatorType::New(); interpolator->SetInputImage( image ); interpolator->SetParameters( sigma, alpha ); resampler->SetInterpolator( interpolator ); } else { // typedef typename itk::BSplineInterpolateImageFunction // InterpolatorType; typedef typename itk::LinearInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); interpolator->SetInputImage( image ); resampler->SetInterpolator( interpolator ); } // Other resampling options resampler->SetInput( image ); resampler->SetDefaultPixelValue(0); MITK_INFO << "Resampling requested image plane ... "; resampler->Update(); MITK_INFO << " ... done"; if(additionalIndex < 0) { this->m_InternalImage = mitk::Image::New(); this->m_InternalImage->InitializeByItk( resampler->GetOutput() ); this->m_InternalImage->SetVolume( resampler->GetOutput()->GetBufferPointer() ); } } template < typename TPixel, unsigned int VImageDimension > void QmitkFiberProcessingView::InternalCalculateMaskFromPlanarFigure( itk::Image< TPixel, VImageDimension > *image, unsigned int axis, std::string nodeName ) { MITK_INFO << "InternalCalculateMaskFromPlanarFigure() start"; typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::CastImageFilter< ImageType, UCharImageType > CastFilterType; // Generate mask image as new image with same header as input image and // initialize with "1". UCharImageType::Pointer newMaskImage = UCharImageType::New(); newMaskImage->SetSpacing( image->GetSpacing() ); // Set the image spacing newMaskImage->SetOrigin( image->GetOrigin() ); // Set the image origin newMaskImage->SetDirection( image->GetDirection() ); // Set the image direction newMaskImage->SetRegions( image->GetLargestPossibleRegion() ); newMaskImage->Allocate(); newMaskImage->FillBuffer( 1 ); // Generate VTK polygon from (closed) PlanarFigure polyline // (The polyline points are shifted by -0.5 in z-direction to make sure // that the extrusion filter, which afterwards elevates all points by +0.5 // in z-direction, creates a 3D object which is cut by the the plane z=0) const Geometry2D *planarFigureGeometry2D = m_PlanarFigure->GetGeometry2D(); const PlanarFigure::PolyLineType planarFigurePolyline = m_PlanarFigure->GetPolyLine( 0 ); const Geometry3D *imageGeometry3D = m_InternalImage->GetGeometry( 0 ); vtkPolyData *polyline = vtkPolyData::New(); polyline->Allocate( 1, 1 ); // Determine x- and y-dimensions depending on principal axis int i0, i1; switch ( axis ) { case 0: i0 = 1; i1 = 2; break; case 1: i0 = 0; i1 = 2; break; case 2: default: i0 = 0; i1 = 1; break; } // Create VTK polydata object of polyline contour vtkPoints *points = vtkPoints::New(); PlanarFigure::PolyLineType::const_iterator it; std::vector indices; unsigned int numberOfPoints = 0; for ( it = planarFigurePolyline.begin(); it != planarFigurePolyline.end(); ++it ) { Point3D point3D; // Convert 2D point back to the local index coordinates of the selected // image Point2D point2D = it->Point; planarFigureGeometry2D->WorldToIndex(point2D, point2D); point2D[0] -= 0.5/m_UpsamplingFactor; point2D[1] -= 0.5/m_UpsamplingFactor; planarFigureGeometry2D->IndexToWorld(point2D, point2D); planarFigureGeometry2D->Map( point2D, point3D ); // Polygons (partially) outside of the image bounds can not be processed // further due to a bug in vtkPolyDataToImageStencil if ( !imageGeometry3D->IsInside( point3D ) ) { float bounds[2] = {0,0}; bounds[0] = this->m_InternalImage->GetLargestPossibleRegion().GetSize().GetElement(i0); bounds[1] = this->m_InternalImage->GetLargestPossibleRegion().GetSize().GetElement(i1); imageGeometry3D->WorldToIndex( point3D, point3D ); // if (point3D[i0]<0) // point3D[i0] = 0.5; // else if (point3D[i0]>bounds[0]) // point3D[i0] = bounds[0]-0.5; // if (point3D[i1]<0) // point3D[i1] = 0.5; // else if (point3D[i1]>bounds[1]) // point3D[i1] = bounds[1]-0.5; if (point3D[i0]<0) point3D[i0] = 0.0; else if (point3D[i0]>bounds[0]) point3D[i0] = bounds[0]-0.001; if (point3D[i1]<0) point3D[i1] = 0.0; else if (point3D[i1]>bounds[1]) point3D[i1] = bounds[1]-0.001; points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 ); numberOfPoints++; } else { imageGeometry3D->WorldToIndex( point3D, point3D ); // Add point to polyline array points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 ); numberOfPoints++; } } polyline->SetPoints( points ); points->Delete(); vtkIdType *ptIds = new vtkIdType[numberOfPoints]; for ( vtkIdType i = 0; i < numberOfPoints; ++i ) { ptIds[i] = i; } polyline->InsertNextCell( VTK_POLY_LINE, numberOfPoints, ptIds ); // Extrude the generated contour polygon vtkLinearExtrusionFilter *extrudeFilter = vtkLinearExtrusionFilter::New(); extrudeFilter->SetInput( polyline ); extrudeFilter->SetScaleFactor( 1 ); extrudeFilter->SetExtrusionTypeToNormalExtrusion(); extrudeFilter->SetVector( 0.0, 0.0, 1.0 ); // Make a stencil from the extruded polygon vtkPolyDataToImageStencil *polyDataToImageStencil = vtkPolyDataToImageStencil::New(); polyDataToImageStencil->SetInput( extrudeFilter->GetOutput() ); // Export from ITK to VTK (to use a VTK filter) typedef itk::VTKImageImport< UCharImageType > ImageImportType; typedef itk::VTKImageExport< UCharImageType > ImageExportType; typename ImageExportType::Pointer itkExporter = ImageExportType::New(); itkExporter->SetInput( newMaskImage ); vtkImageImport *vtkImporter = vtkImageImport::New(); this->ConnectPipelines( itkExporter, vtkImporter ); vtkImporter->Update(); // Apply the generated image stencil to the input image vtkImageStencil *imageStencilFilter = vtkImageStencil::New(); imageStencilFilter->SetInputConnection( vtkImporter->GetOutputPort() ); imageStencilFilter->SetStencil( polyDataToImageStencil->GetOutput() ); imageStencilFilter->ReverseStencilOff(); imageStencilFilter->SetBackgroundValue( 0 ); imageStencilFilter->Update(); // Export from VTK back to ITK vtkImageExport *vtkExporter = vtkImageExport::New(); vtkExporter->SetInputConnection( imageStencilFilter->GetOutputPort() ); vtkExporter->Update(); typename ImageImportType::Pointer itkImporter = ImageImportType::New(); this->ConnectPipelines( vtkExporter, itkImporter ); itkImporter->Update(); // calculate cropping bounding box m_InternalImageMask3D = itkImporter->GetOutput(); m_InternalImageMask3D->SetDirection(image->GetDirection()); itk::ImageRegionConstIterator itmask(m_InternalImageMask3D, m_InternalImageMask3D->GetLargestPossibleRegion()); itk::ImageRegionIterator itimage(image, image->GetLargestPossibleRegion()); itmask = itmask.Begin(); itimage = itimage.Begin(); typename ImageType::SizeType lowersize = {{9999999999,9999999999,9999999999}}; typename ImageType::SizeType uppersize = {{0,0,0}}; while( !itmask.IsAtEnd() ) { if(itmask.Get() == 0) { itimage.Set(0); } else { typename ImageType::IndexType index = itimage.GetIndex(); typename ImageType::SizeType signedindex; signedindex[0] = index[0]; signedindex[1] = index[1]; signedindex[2] = index[2]; lowersize[0] = signedindex[0] < lowersize[0] ? signedindex[0] : lowersize[0]; lowersize[1] = signedindex[1] < lowersize[1] ? signedindex[1] : lowersize[1]; lowersize[2] = signedindex[2] < lowersize[2] ? signedindex[2] : lowersize[2]; uppersize[0] = signedindex[0] > uppersize[0] ? signedindex[0] : uppersize[0]; uppersize[1] = signedindex[1] > uppersize[1] ? signedindex[1] : uppersize[1]; uppersize[2] = signedindex[2] > uppersize[2] ? signedindex[2] : uppersize[2]; } ++itmask; ++itimage; } typename ImageType::IndexType index; index[0] = lowersize[0]; index[1] = lowersize[1]; index[2] = lowersize[2]; typename ImageType::SizeType size; size[0] = uppersize[0] - lowersize[0] + 1; size[1] = uppersize[1] - lowersize[1] + 1; size[2] = uppersize[2] - lowersize[2] + 1; itk::ImageRegion<3> cropRegion = itk::ImageRegion<3>(index, size); // crop internal mask typedef itk::RegionOfInterestImageFilter< UCharImageType, UCharImageType > ROIMaskFilterType; typename ROIMaskFilterType::Pointer roi2 = ROIMaskFilterType::New(); roi2->SetRegionOfInterest(cropRegion); roi2->SetInput(m_InternalImageMask3D); roi2->Update(); m_InternalImageMask3D = roi2->GetOutput(); Image::Pointer tmpImage = Image::New(); tmpImage->InitializeByItk(m_InternalImageMask3D.GetPointer()); tmpImage->SetVolume(m_InternalImageMask3D->GetBufferPointer()); Image::Pointer tmpImage2 = Image::New(); tmpImage2->InitializeByItk(m_PlanarFigureImage.GetPointer()); const Geometry3D *pfImageGeometry3D = tmpImage2->GetGeometry( 0 ); const Geometry3D *intImageGeometry3D = tmpImage->GetGeometry( 0 ); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType imageIterator (m_InternalImageMask3D, m_InternalImageMask3D->GetRequestedRegion()); imageIterator.GoToBegin(); while ( !imageIterator.IsAtEnd() ) { unsigned char val = imageIterator.Value(); if (val>0) { itk::Index<3> index = imageIterator.GetIndex(); Point3D point; point[0] = index[0]; point[1] = index[1]; point[2] = index[2]; intImageGeometry3D->IndexToWorld(point, point); pfImageGeometry3D->WorldToIndex(point, point); point[i0] += 0.5; point[i1] += 0.5; index[0] = point[0]; index[1] = point[1]; index[2] = point[2]; m_PlanarFigureImage->SetPixel(index, 1); } ++imageIterator; } // Clean up VTK objects polyline->Delete(); extrudeFilter->Delete(); polyDataToImageStencil->Delete(); vtkImporter->Delete(); imageStencilFilter->Delete(); //vtkExporter->Delete(); // TODO: crashes when outcommented; memory leak?? delete[] ptIds; } void QmitkFiberProcessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkFiberProcessingView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkFiberProcessingView::UpdateGui() { // are fiber bundles selected? if ( m_SelectedFB.empty() ) { m_Controls->m_JoinBundles->setEnabled(false); m_Controls->m_SubstractBundles->setEnabled(false); m_Controls->m_ProcessFiberBundleButton->setEnabled(false); m_Controls->doExtractFibersButton->setEnabled(false); } else { m_Controls->m_ProcessFiberBundleButton->setEnabled(true); // one bundle and one planar figure needed to extract fibers if (!m_SelectedPF.empty()) m_Controls->doExtractFibersButton->setEnabled(true); - // two bundles needed to subtract - if (m_SelectedFB.size() == 2) - m_Controls->m_SubstractBundles->setEnabled(true); - else - m_Controls->m_SubstractBundles->setEnabled(false); - - // more than two bundles needed to join + // more than two bundles needed to join/subtract if (m_SelectedFB.size() > 1) + { m_Controls->m_JoinBundles->setEnabled(true); + m_Controls->m_SubstractBundles->setEnabled(true); + } else + { m_Controls->m_JoinBundles->setEnabled(false); + m_Controls->m_SubstractBundles->setEnabled(false); + } } // are planar figures selected? if ( m_SelectedPF.empty() ) { m_Controls->doExtractFibersButton->setEnabled(false); m_Controls->PFCompoANDButton->setEnabled(false); m_Controls->PFCompoORButton->setEnabled(false); m_Controls->PFCompoNOTButton->setEnabled(false); m_Controls->m_GenerateRoiImage->setEnabled(false); } else { if ( m_SelectedImage.IsNotNull() ) m_Controls->m_GenerateRoiImage->setEnabled(true); else m_Controls->m_GenerateRoiImage->setEnabled(false); if (m_SelectedPF.size() > 1) { m_Controls->PFCompoANDButton->setEnabled(true); m_Controls->PFCompoORButton->setEnabled(true); m_Controls->PFCompoNOTButton->setEnabled(false); } else { m_Controls->PFCompoANDButton->setEnabled(false); m_Controls->PFCompoORButton->setEnabled(false); m_Controls->PFCompoNOTButton->setEnabled(true); } } } void QmitkFiberProcessingView::OnSelectionChanged( std::vector nodes ) { if ( !this->IsVisible() ) return; //reset existing Vectors containing FiberBundles and PlanarFigures from a previous selection m_SelectedFB.clear(); m_SelectedPF.clear(); m_SelectedImage = NULL; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if ( dynamic_cast(node->GetData()) ) m_SelectedFB.push_back(node); else if (dynamic_cast(node->GetData())) m_SelectedPF.push_back(node); else if (dynamic_cast(node->GetData())) m_SelectedImage = dynamic_cast(node->GetData()); } UpdateGui(); GenerateStats(); } void QmitkFiberProcessingView::ActionDrawPolygonTriggered() { // bool checked = m_Controls->m_PolygonButton->isChecked(); // if(!this->AssertDrawingIsPossible(checked)) // return; mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOn(); this->AddFigureToDataStorage(figure, QString("Polygon%1").arg(++m_PolygonCounter)); MITK_INFO << "PlanarPolygon created ..."; mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDefaultDataStorage()->GetAll(); mitk::DataNode* node = 0; mitk::PlanarFigureInteractor::Pointer figureInteractor = 0; mitk::PlanarFigure* figureP = 0; for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End() ; it++) { node = const_cast(it->Value().GetPointer()); figureP = dynamic_cast(node->GetData()); if(figureP) { figureInteractor = dynamic_cast(node->GetInteractor()); if(figureInteractor.IsNull()) figureInteractor = mitk::PlanarFigureInteractor::New("PlanarFigureInteractor", node); mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); } } } void QmitkFiberProcessingView::ActionDrawEllipseTriggered() { //bool checked = m_Controls->m_CircleButton->isChecked(); //if(!this->AssertDrawingIsPossible(checked)) // return; mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New(); this->AddFigureToDataStorage(figure, QString("Circle%1").arg(++m_EllipseCounter)); this->GetDataStorage()->Modified(); MITK_INFO << "PlanarCircle created ..."; //call mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDefaultDataStorage()->GetAll(); mitk::DataNode* node = 0; mitk::PlanarFigureInteractor::Pointer figureInteractor = 0; mitk::PlanarFigure* figureP = 0; for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End() ; it++) { node = const_cast(it->Value().GetPointer()); figureP = dynamic_cast(node->GetData()); if(figureP) { figureInteractor = dynamic_cast(node->GetInteractor()); if(figureInteractor.IsNull()) figureInteractor = mitk::PlanarFigureInteractor::New("PlanarFigureInteractor", node); mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); } } } void QmitkFiberProcessingView::Activated() { MITK_INFO << "FB OPerations ACTIVATED()"; /* mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDefaultDataStorage()->GetAll(); mitk::DataNode* node = 0; mitk::PlanarFigureInteractor::Pointer figureInteractor = 0; mitk::PlanarFigure* figure = 0; for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End() ; it++) { node = const_cast(it->Value().GetPointer()); figure = dynamic_cast(node->GetData()); if(figure) { figureInteractor = dynamic_cast(node->GetInteractor()); if(figureInteractor.IsNull()) figureInteractor = mitk::PlanarFigureInteractor::New("PlanarFigureInteractor", node); mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); } } */ } void QmitkFiberProcessingView::AddFigureToDataStorage(mitk::PlanarFigure* figure, const QString& name, const char *propertyKey, mitk::BaseProperty *property ) { // initialize figure's geometry with empty geometry mitk::PlaneGeometry::Pointer emptygeometry = mitk::PlaneGeometry::New(); figure->SetGeometry2D( emptygeometry ); //set desired data to DataNode where Planarfigure is stored mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetName(name.toStdString()); newNode->SetData(figure); newNode->AddProperty( "planarfigure.default.line.color", mitk::ColorProperty::New(1.0,0.0,0.0)); newNode->AddProperty( "planarfigure.line.width", mitk::FloatProperty::New(2.0)); newNode->AddProperty( "planarfigure.drawshadow", mitk::BoolProperty::New(true)); newNode->AddProperty( "selected", mitk::BoolProperty::New(true) ); newNode->AddProperty( "planarfigure.ishovering", mitk::BoolProperty::New(true) ); newNode->AddProperty( "planarfigure.drawoutline", mitk::BoolProperty::New(true) ); newNode->AddProperty( "planarfigure.drawquantities", mitk::BoolProperty::New(false) ); newNode->AddProperty( "planarfigure.drawshadow", mitk::BoolProperty::New(true) ); newNode->AddProperty( "planarfigure.line.width", mitk::FloatProperty::New(3.0) ); newNode->AddProperty( "planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.outline.width", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.helperline.width", mitk::FloatProperty::New(2.0) ); // PlanarFigureControlPointStyleProperty::Pointer styleProperty = // dynamic_cast< PlanarFigureControlPointStyleProperty* >( node->GetProperty( "planarfigure.controlpointshape" ) ); // if ( styleProperty.IsNotNull() ) // { // m_ControlPointShape = styleProperty->GetShape(); // } newNode->AddProperty( "planarfigure.default.line.color", mitk::ColorProperty::New(1.0,1.0,1.0) ); newNode->AddProperty( "planarfigure.default.line.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.default.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.default.outline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.default.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.default.helperline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(0.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.default.markerline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(1.0,1.0,1.0) ); newNode->AddProperty( "planarfigure.default.marker.opacity",mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.hover.line.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.hover.outline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.hover.helperline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.hover.markerline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.hover.markerline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.hover.marker.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.hover.marker.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.selected.line.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.selected.line.opacity",mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.selected.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.selected.outline.opacity", mitk::FloatProperty::New(2.0)); newNode->AddProperty( "planarfigure.selected.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.selected.helperline.opacity",mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.selected.markerline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.selected.markerline.opacity", mitk::FloatProperty::New(2.0) ); newNode->AddProperty( "planarfigure.selected.marker.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); newNode->AddProperty( "planarfigure.selected.marker.opacity",mitk::FloatProperty::New(2.0)); // Add custom property, if available //if ( (propertyKey != NULL) && (property != NULL) ) //{ // newNode->AddProperty( propertyKey, property ); //} //get current selected DataNode -which should be a FiberBundle- and set PlanarFigure as child //this->GetDataStorage()->GetNodes() // mitk::FiberBundle::Pointer selectedFBNode = m_SelectedFBNodes.at(0); // figure drawn on the topmost layer / image this->GetDataStorage()->Add(newNode ); std::vector selectedNodes = GetDataManagerSelection(); for(unsigned int i = 0; i < selectedNodes.size(); i++) { selectedNodes[i]->SetSelected(false); } //selectedNodes = m_SelectedPlanarFigureNodes->GetNodes(); /*for(unsigned int i = 0; i < selectedNodes.size(); i++) { selectedNodes[i]->SetSelected(false); } */ newNode->SetSelected(true); //Select(newNode); } void QmitkFiberProcessingView::DoFiberExtraction() { if ( m_SelectedFB.empty() ){ QMessageBox::information( NULL, "Warning", "No fibe bundle selected!"); MITK_WARN("QmitkFiberProcessingView") << "no fibe bundle selected"; return; } for (int i=0; i(m_SelectedFB.at(i)->GetData()); mitk::PlanarFigure::Pointer roi = dynamic_cast (m_SelectedPF.at(0)->GetData()); // std::vector extFBset = fib->extractFibersByPF(roi); // mitk::FiberBundleX::Pointer extFB = fib->extractFibersById(extFBset); mitk::DataNode::Pointer node; node = mitk::DataNode::New(); //fbNode->SetData(extFB); QString name(m_SelectedFB.at(0)->GetName().c_str()); name += "_extracted"; node->SetName(name.toStdString()); GetDataStorage()->Add(node); } } void QmitkFiberProcessingView::GenerateAndComposite() { mitk::PlanarFigureComposite::Pointer PFCAnd = mitk::PlanarFigureComposite::New(); mitk::PlaneGeometry* currentGeometry2D = dynamic_cast( const_cast(GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer()->GetCurrentWorldGeometry2D())); PFCAnd->SetGeometry2D(currentGeometry2D); PFCAnd->setOperationType(mitk::PFCOMPOSITION_AND_OPERATION); for( std::vector::iterator it = m_SelectedPF.begin(); it != m_SelectedPF.end(); ++it ) { mitk::DataNode::Pointer nodePF = *it; mitk::PlanarFigure::Pointer tmpPF = dynamic_cast( nodePF->GetData() ); PFCAnd->addPlanarFigure( tmpPF ); PFCAnd->addDataNode( nodePF ); PFCAnd->setDisplayName("AND_COMPO"); } AddCompositeToDatastorage(PFCAnd, NULL); } void QmitkFiberProcessingView::GenerateOrComposite() { mitk::PlanarFigureComposite::Pointer PFCOr = mitk::PlanarFigureComposite::New(); mitk::PlaneGeometry* currentGeometry2D = dynamic_cast( const_cast(GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer()->GetCurrentWorldGeometry2D())); PFCOr->SetGeometry2D(currentGeometry2D); PFCOr->setOperationType(mitk::PFCOMPOSITION_OR_OPERATION); for( std::vector::iterator it = m_SelectedPF.begin(); it != m_SelectedPF.end(); ++it ) { mitk::DataNode::Pointer nodePF = *it; mitk::PlanarFigure::Pointer tmpPF = dynamic_cast( nodePF->GetData() ); PFCOr->addPlanarFigure( tmpPF ); PFCOr->addDataNode( nodePF ); PFCOr->setDisplayName("OR_COMPO"); } AddCompositeToDatastorage(PFCOr, NULL); } void QmitkFiberProcessingView::GenerateNotComposite() { mitk::PlanarFigureComposite::Pointer PFCNot = mitk::PlanarFigureComposite::New(); mitk::PlaneGeometry* currentGeometry2D = dynamic_cast( const_cast(GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer()->GetCurrentWorldGeometry2D())); PFCNot->SetGeometry2D(currentGeometry2D); PFCNot->setOperationType(mitk::PFCOMPOSITION_NOT_OPERATION); for( std::vector::iterator it = m_SelectedPF.begin(); it != m_SelectedPF.end(); ++it ) { mitk::DataNode::Pointer nodePF = *it; mitk::PlanarFigure::Pointer tmpPF = dynamic_cast( nodePF->GetData() ); PFCNot->addPlanarFigure( tmpPF ); PFCNot->addDataNode( nodePF ); PFCNot->setDisplayName("NOT_COMPO"); } AddCompositeToDatastorage(PFCNot, NULL); } /* CLEANUP NEEDED */ void QmitkFiberProcessingView::AddCompositeToDatastorage(mitk::PlanarFigureComposite::Pointer pfcomp, mitk::DataNode::Pointer parentDataNode ) { mitk::DataNode::Pointer newPFCNode; newPFCNode = mitk::DataNode::New(); newPFCNode->SetName( pfcomp->getDisplayName() ); newPFCNode->SetData(pfcomp); newPFCNode->SetVisibility(true); switch (pfcomp->getOperationType()) { case 0: { if (!parentDataNode.IsNull()) { GetDataStorage()->Add(newPFCNode, parentDataNode); } else { GetDataStorage()->Add(newPFCNode); } //iterate through its childs for(int i=0; igetNumberOfChildren(); ++i) { mitk::PlanarFigure::Pointer tmpPFchild = pfcomp->getChildAt(i); mitk::DataNode::Pointer savedPFchildNode = pfcomp->getDataNodeAt(i); mitk::PlanarFigureComposite::Pointer pfcompcast= dynamic_cast(tmpPFchild.GetPointer()); if ( !pfcompcast.IsNull() ) { // child is of type planar Figure composite // make new node of the child, cuz later the child has to be removed of its old position in datamanager // feed new dataNode with information of the savedDataNode, which is gonna be removed soon mitk::DataNode::Pointer newChildPFCNode; newChildPFCNode = mitk::DataNode::New(); newChildPFCNode->SetData(tmpPFchild); newChildPFCNode->SetName( savedPFchildNode->GetName() ); pfcompcast->setDisplayName( savedPFchildNode->GetName() ); //name might be changed in DataManager by user //update inside vector the dataNodePointer pfcomp->replaceDataNodeAt(i, newChildPFCNode); AddCompositeToDatastorage(pfcompcast, newPFCNode); //the current PFCNode becomes the childs parent // remove savedNode here, cuz otherwise its children will change their position in the dataNodeManager // without having its parent anymore //GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " exists in DS...trying to remove it"; }else{ MITK_INFO << "[ERROR] does NOT exist, but can I read its Name? " << savedPFchildNode->GetName(); } // remove old child position in dataStorage GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " still exists"; } } else { // child is not of type PlanarFigureComposite, so its one of the planarFigures // create new dataNode containing the data of the old dataNode, but position in dataManager will be // modified cuz we re setting a (new) parent. mitk::DataNode::Pointer newPFchildNode = mitk::DataNode::New(); newPFchildNode->SetName(savedPFchildNode->GetName() ); newPFchildNode->SetData(tmpPFchild); newPFchildNode->SetVisibility(true); // replace the dataNode in PFComp DataNodeVector pfcomp->replaceDataNodeAt(i, newPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " exists in DS...trying to remove it"; } else { MITK_INFO << "[ERROR] does NOT exist, but can I read its Name? " << savedPFchildNode->GetName(); } // remove old child position in dataStorage GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " still exists"; } MITK_INFO << "adding " << newPFchildNode->GetName() << " to " << newPFCNode->GetName(); //add new child to datamanager with its new position as child of newPFCNode parent GetDataStorage()->Add(newPFchildNode, newPFCNode); } } GetDataStorage()->Modified(); break; } case 1: { if (!parentDataNode.IsNull()) { MITK_INFO << "adding " << newPFCNode->GetName() << " to " << parentDataNode->GetName() ; GetDataStorage()->Add(newPFCNode, parentDataNode); } else { MITK_INFO << "adding " << newPFCNode->GetName(); GetDataStorage()->Add(newPFCNode); } for(int i=0; igetNumberOfChildren(); ++i) { mitk::PlanarFigure::Pointer tmpPFchild = pfcomp->getChildAt(i); mitk::DataNode::Pointer savedPFchildNode = pfcomp->getDataNodeAt(i); mitk::PlanarFigureComposite::Pointer pfcompcast= dynamic_cast(tmpPFchild.GetPointer()); if ( !pfcompcast.IsNull() ) { // child is of type planar Figure composite // make new node of the child, cuz later the child has to be removed of its old position in datamanager // feed new dataNode with information of the savedDataNode, which is gonna be removed soon mitk::DataNode::Pointer newChildPFCNode; newChildPFCNode = mitk::DataNode::New(); newChildPFCNode->SetData(tmpPFchild); newChildPFCNode->SetName( savedPFchildNode->GetName() ); pfcompcast->setDisplayName( savedPFchildNode->GetName() ); //name might be changed in DataManager by user //update inside vector the dataNodePointer pfcomp->replaceDataNodeAt(i, newChildPFCNode); AddCompositeToDatastorage(pfcompcast, newPFCNode); //the current PFCNode becomes the childs parent // remove savedNode here, cuz otherwise its children will change their position in the dataNodeManager // without having its parent anymore //GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " exists in DS...trying to remove it"; }else{ MITK_INFO << "[ERROR] does NOT exist, but can I read its Name? " << savedPFchildNode->GetName(); } // remove old child position in dataStorage GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " still exists"; } } else { // child is not of type PlanarFigureComposite, so its one of the planarFigures // create new dataNode containing the data of the old dataNode, but position in dataManager will be // modified cuz we re setting a (new) parent. mitk::DataNode::Pointer newPFchildNode = mitk::DataNode::New(); newPFchildNode->SetName(savedPFchildNode->GetName() ); newPFchildNode->SetData(tmpPFchild); newPFchildNode->SetVisibility(true); // replace the dataNode in PFComp DataNodeVector pfcomp->replaceDataNodeAt(i, newPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " exists in DS...trying to remove it"; }else{ MITK_INFO << "[ERROR] does NOT exist, but can I read its Name? " << savedPFchildNode->GetName(); } // remove old child position in dataStorage GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " still exists"; } MITK_INFO << "adding " << newPFchildNode->GetName() << " to " << newPFCNode->GetName(); //add new child to datamanager with its new position as child of newPFCNode parent GetDataStorage()->Add(newPFchildNode, newPFCNode); } } GetDataStorage()->Modified(); break; } case 2: { if (!parentDataNode.IsNull()) { MITK_INFO << "adding " << newPFCNode->GetName() << " to " << parentDataNode->GetName() ; GetDataStorage()->Add(newPFCNode, parentDataNode); } else { MITK_INFO << "adding " << newPFCNode->GetName(); GetDataStorage()->Add(newPFCNode); } //iterate through its childs for(int i=0; igetNumberOfChildren(); ++i) { mitk::PlanarFigure::Pointer tmpPFchild = pfcomp->getChildAt(i); mitk::DataNode::Pointer savedPFchildNode = pfcomp->getDataNodeAt(i); mitk::PlanarFigureComposite::Pointer pfcompcast= dynamic_cast(tmpPFchild.GetPointer()); if ( !pfcompcast.IsNull() ) { // child is of type planar Figure composite // makeRemoveBundle new node of the child, cuz later the child has to be removed of its old position in datamanager // feed new dataNode with information of the savedDataNode, which is gonna be removed soon mitk::DataNode::Pointer newChildPFCNode; newChildPFCNode = mitk::DataNode::New(); newChildPFCNode->SetData(tmpPFchild); newChildPFCNode->SetName( savedPFchildNode->GetName() ); pfcompcast->setDisplayName( savedPFchildNode->GetName() ); //name might be changed in DataManager by user //update inside vector the dataNodePointer pfcomp->replaceDataNodeAt(i, newChildPFCNode); AddCompositeToDatastorage(pfcompcast, newPFCNode); //the current PFCNode becomes the childs parent // remove savedNode here, cuz otherwise its children will change their position in the dataNodeManager // without having its parent anymore //GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " exists in DS...trying to remove it"; }else{ MITK_INFO << "[ERROR] does NOT exist, but can I read its Name? " << savedPFchildNode->GetName(); } // remove old child position in dataStorage GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " still exists"; } } else { // child is not of type PlanarFigureComposite, so its one of the planarFigures // create new dataNode containing the data of the old dataNode, but position in dataManager will be // modified cuz we re setting a (new) parent. mitk::DataNode::Pointer newPFchildNode = mitk::DataNode::New(); newPFchildNode->SetName(savedPFchildNode->GetName() ); newPFchildNode->SetData(tmpPFchild); newPFchildNode->SetVisibility(true); // replace the dataNode in PFComp DataNodeVector pfcomp->replaceDataNodeAt(i, newPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " exists in DS...trying to remove it"; }else{ MITK_INFO << "[ERROR] does NOT exist, but can I read its Name? " << savedPFchildNode->GetName(); } // remove old child position in dataStorage GetDataStorage()->Remove(savedPFchildNode); if ( GetDataStorage()->Exists(savedPFchildNode)) { MITK_INFO << savedPFchildNode->GetName() << " still exists"; } MITK_INFO << "adding " << newPFchildNode->GetName() << " to " << newPFCNode->GetName(); //add new child to datamanager with its new position as child of newPFCNode parent GetDataStorage()->Add(newPFchildNode, newPFCNode); } } GetDataStorage()->Modified(); break; } default: MITK_INFO << "we have an UNDEFINED composition... ERROR" ; break; } } void QmitkFiberProcessingView::JoinBundles() { -// if ( m_SelectedFB.size()<2 ){ -// QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!"); -// MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!"; -// return; -// } -// mitk::FiberBundleX::Pointer newBundle = mitk::FiberBundleX::New(); -// std::vector::const_iterator it; -// for (it = m_SelectedFB.begin(); it!=m_SelectedFB.end(); ++it) -// { -// newBundle = newBundle->JoinBundle(dynamic_cast((*it)->GetData())); -// } + if ( m_SelectedFB.size()<2 ){ + QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!"); + MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!"; + return; + } + + std::vector::const_iterator it = m_SelectedFB.begin(); + mitk::FiberBundleX::Pointer newBundle = dynamic_cast((*it)->GetData()); + QString name(""); + name += QString((*it)->GetName().c_str()); + ++it; + for (it; it!=m_SelectedFB.end(); ++it) + { + newBundle = *newBundle+dynamic_cast((*it)->GetData()); + name += "+"+QString((*it)->GetName().c_str()); + } -// mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); -// fbNode->SetData(newBundle); -// fbNode->SetName("JoinedBundle"); -// fbNode->SetVisibility(true); -// GetDataStorage()->Add(fbNode); + mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); + fbNode->SetData(newBundle); + fbNode->SetName(name.toStdString()); + fbNode->SetVisibility(true); + GetDataStorage()->Add(fbNode); } void QmitkFiberProcessingView::SubstractBundles() { -// if ( m_SelectedFB.size()!=2 ){ -// QMessageBox::information( NULL, "Warning", "Select two fiber bundles!"); -// MITK_WARN("QmitkFiberProcessingView") << "Select two fiber bundles!"; -// return; -// } -// mitk::FiberBundleX::Pointer bundle1 = dynamic_cast(m_SelectedFB.at(0)->GetData()); -// mitk::FiberBundleX::Pointer bundle2 = dynamic_cast(m_SelectedFB.at(1)->GetData()); - -// mitk::FiberBundleX::Pointer newBundle = bundle1->SubstractBundle(bundle2); -// mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); -// fbNode->SetData(newBundle); -// fbNode->SetName(m_SelectedFB.at(0)->GetName()+"-"+m_SelectedFB.at(1)->GetName()); -// fbNode->SetVisibility(true); -// GetDataStorage()->Add(fbNode); + if ( m_SelectedFB.size()<2 ){ + QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!"); + MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!"; + return; + } + + std::vector::const_iterator it = m_SelectedFB.begin(); + mitk::FiberBundleX::Pointer newBundle = dynamic_cast((*it)->GetData()); + QString name(""); + name += QString((*it)->GetName().c_str()); + ++it; + for (it; it!=m_SelectedFB.end(); ++it) + { + newBundle = *newBundle-dynamic_cast((*it)->GetData()); + name += "-"+QString((*it)->GetName().c_str()); + } + + mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); + fbNode->SetData(newBundle); + fbNode->SetName(name.toStdString()); + fbNode->SetVisibility(true); + GetDataStorage()->Add(fbNode); } void QmitkFiberProcessingView::GenerateStats() { if ( m_SelectedFB.empty() ) return; QString stats(""); for( int i=0; i(node->GetData())) { if (i>0) stats += "\n-----------------------------\n"; stats += QString(node->GetName().c_str()) + "\n"; mitk::FiberBundleX::Pointer fib = dynamic_cast(node->GetData()); vtkSmartPointer fiberPolyData = fib->GetFiberPolyData(); vtkSmartPointer vLines = fiberPolyData->GetLines(); vLines->InitTraversal(); int numberOfLines = vLines->GetNumberOfCells(); stats += "Number of fibers: "+ QString::number(numberOfLines) + "\n"; float length = 0; std::vector lengths; for (int i=0; iGetNextCell ( numPoints, points ); float l=0; for (unsigned int j=0; jGetPoint(points[j], p1); double p2[3] = {0,0,0}; fiberPolyData->GetPoint(points[j+1], p2); float a = p1[0]-p2[0]; float b = p1[1]-p2[1]; float c = p1[2]-p2[2]; float dist = std::sqrt(a*a+b*b+c*c); length += dist; l += dist; } lengths.push_back(l); } std::sort(lengths.begin(), lengths.end()); if (numberOfLines>0) length /= numberOfLines; float dev=0; int count = 0; vLines->InitTraversal(); for (int i=0; iGetNextCell ( numPoints, points ); float l=0; for (unsigned int j=0; jGetPoint(points[j], p1); double p2[3] = {0,0,0}; fiberPolyData->GetPoint(points[j+1], p2); float a = p1[0]-p2[0]; float b = p1[1]-p2[1]; float c = p1[2]-p2[2]; float dist = std::sqrt(a*a+b*b+c*c); l += dist; } dev += (length-l)*(length-l); count++; } if (numberOfLines>0) - { dev /= numberOfLines; - dev = std::sqrt(dev); - } stats += "Mean fiber length: "+ QString::number(length/10) + "cm\n"; stats += "Median fiber length: "+ QString::number(lengths.at(lengths.size()/2)/10) + "cm\n"; stats += "Standard deviation: "+ QString::number(dev/10) + "cm\n"; } } this->m_Controls->m_StatsTextEdit->setText(stats); } void QmitkFiberProcessingView::ProcessSelectedBundles() { if ( m_SelectedFB.empty() ){ QMessageBox::information( NULL, "Warning", "No fibe bundle selected!"); MITK_WARN("QmitkFiberProcessingView") << "no fibe bundle selected"; return; } int generationMethod = m_Controls->m_GenerationBox->currentIndex(); for( int i=0; i(node->GetData())) { mitk::FiberBundleX::Pointer fib = dynamic_cast(node->GetData()); + QString name(node->GetName().c_str()); + DataNode::Pointer newNode = NULL; switch(generationMethod){ case 0: - GenerateTractDensityImage(fib, false); + newNode = GenerateTractDensityImage(fib, false); + name += "_TDI"; break; case 1: - GenerateTractDensityImage(fib, true); + newNode = GenerateTractDensityImage(fib, true); + name += "_envelope"; break; case 2: - GenerateColorHeatmap(fib); + newNode = GenerateColorHeatmap(fib); break; case 3: - GenerateFiberEndingsImage(fib); + newNode = GenerateFiberEndingsImage(fib); + name += "_fiber_endings"; break; case 4: - GenerateFiberEndingsPointSet(fib); + newNode = GenerateFiberEndingsPointSet(fib); + name += "_fiber_endings"; break; } + if (newNode.IsNotNull()) + { + newNode->SetName(name.toStdString()); + GetDataStorage()->Add(newNode); + } } } } // generate pointset displaying the fiber endings mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateFiberEndingsPointSet(mitk::FiberBundleX::Pointer fib) { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); + vtkSmartPointer fiberPolyData = fib->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); -// int numTracts = fib->GetNumFibers(); -// int count = 0; -// for( int i=0; iGetNumPoints(i); -// itk::Point start = m_FiberBundle->GetPoint(i,0); -// itk::Point world1; -// geometry->IndexToWorld(start, world1); -// pointSet->InsertPoint(count, world1); -// count++; -// // get fiber end point -// if(numVertices>1) -// { -// itk::Point end = m_FiberBundle->GetPoint(i,numVertices-1); -// itk::Point world; -// geometry->IndexToWorld(end, world); -// pointSet->InsertPoint(count, world); -// count++; -// } -// } + int count = 0; + int numFibers = fib->GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + if (numPoints>0) + { + double* point = fiberPolyData->GetPoint(points[0]); + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + pointSet->InsertPoint(count, itkPoint); + count++; + } + if (numPoints>2) + { + double* point = fiberPolyData->GetPoint(points[numPoints-1]); + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + pointSet->InsertPoint(count, itkPoint); + count++; + } + } mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( pointSet ); return node; - -// QString name(m_FiberBundleNode->GetName().c_str()); -// name += "_fiber_endings"; -// pointSetNode->SetName(name.toStdString()); -// pointSetNode->SetProperty( "opacity", mitk::FloatProperty::New( 1 ) ); -// pointSetNode->SetProperty( "pointsize", mitk::FloatProperty::New( 0.1*m_Controls->m_UpsamplingSpinBox->value()) ); -// pointSetNode->SetColor( 1.0, 1.0, 1.0 ); - -// GetDefaultDataStorage()->Add(pointSetNode); } // generate image displaying the fiber endings mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateFiberEndingsImage(mitk::FiberBundleX::Pointer fib) { typedef unsigned char OutPixType; - typedef itk::TractsToFiberEndingsImageFilter ImageGeneratorType; + typedef itk::Image OutImageType; + + typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); - //generator->SetFiberBundle(fib); + generator->SetFiberBundle(fib); + generator->SetInvertImage(m_Controls->m_InvertCheckbox->isChecked()); generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value()); generator->Update(); // get output image - typedef itk::Image OutType; - OutType::Pointer outImg = generator->GetOutput(); + OutImageType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // init data node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); return node; - -// QString name(m_FiberBundleNode->GetName().c_str()); -// name += "_fiber_endings"; -// node->SetName(name.toStdString()); -// node->SetVisibility(true); - -// GetDataStorage()->Add(node); } // generate rgba heatmap from fiber bundle mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateColorHeatmap(mitk::FiberBundleX::Pointer fib) { typedef itk::RGBAPixel OutPixType; - typedef itk::TractsToProbabilityImageFilter ImageGeneratorType; + typedef itk::Image OutImageType; + typedef itk::TractsToRgbaImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); - //generator->SetFiberBundle(fib); + generator->SetFiberBundle(fib); generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value()); generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // init data node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); return node; - -// QString name(m_FiberBundleNode->GetName().c_str()); -// node->SetName(name.toStdString()); -// node->SetVisibility(true); - -// mitk::LevelWindow opaclevwin; -// opaclevwin.SetRangeMinMax(0,255); -// opaclevwin.SetWindowBounds(0,0); -// mitk::LevelWindowProperty::Pointer prop = -// mitk::LevelWindowProperty::New(opaclevwin); -// node->AddProperty( "opaclevelwindow", prop ); - -// GetDataStorage()->Add(node); } // generate tract density image from fiber bundle mitk::DataNode::Pointer QmitkFiberProcessingView::GenerateTractDensityImage(mitk::FiberBundleX::Pointer fib, bool binary) { - typedef unsigned char OutPixType; - typedef itk::TractsToProbabilityImageFilter ImageGeneratorType; - ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); - //generator->SetFiberBundle(fib); + typedef float OutPixType; + typedef itk::Image OutImageType; + + itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); + generator->SetFiberBundle(fib); + generator->SetBinaryOutput(binary); generator->SetInvertImage(m_Controls->m_InvertCheckbox->isChecked()); generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value()); - if (binary) - generator->SetBinaryEnvelope(true); - else - generator->SetBinaryEnvelope(false); generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // init data node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); return node; - -// QString name(m_FiberBundleNode->GetName().c_str()); -// if(binary) -// name += "_envelope"; -// else -// name += "_TDI"; -// node->SetName(name.toStdString()); -// node->SetVisibility(true); - -// mitk::LevelWindow opaclevwin2; -// opaclevwin2.SetRangeMinMax(0,255); -// opaclevwin2.SetWindowBounds(0,0); -// mitk::LevelWindowProperty::Pointer prop2 = -// mitk::LevelWindowProperty::New(opaclevwin2); -// node->AddProperty( "opaclevelwindow", prop2 ); - -// GetDataStorage()->Add(node); } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingViewControls.ui b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingViewControls.ui index 44969d1cad..f92bacfab3 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingViewControls.ui +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberProcessingViewControls.ui @@ -1,562 +1,562 @@ QmitkFiberProcessingViewControls 0 0 665 587 Form 5 0 5 0 Fiber Bundle Modification 0 0 200 0 16777215 60 QFrame::NoFrame QFrame::Raised 0 30 30 Draw circular ROI :/QmitkDiffusionImaging/circle.png:/QmitkDiffusionImaging/circle.png 32 32 false true 30 30 Draw rectangular ROI :/QmitkDiffusionImaging/rectangle.png:/QmitkDiffusionImaging/rectangle.png 32 32 true true 30 30 Draw polygonal ROI :/QmitkDiffusionImaging/polygon.png:/QmitkDiffusionImaging/polygon.png 32 32 true true Qt::Horizontal 40 20 QFrame::NoFrame QFrame::Raised 0 false 0 0 200 16777215 11 Extract fibers passing through selected ROI or composite ROI Extract false 0 0 200 16777215 11 Returns fiber bundle containing all fibers the two selected bundles dont't have in common Substract false 0 0 16777215 16777215 11 Generate a binary image containing all selected ROIs ROI Image false 0 0 200 16777215 11 Merge selected fiber bundles Join Qt::Horizontal 40 20 0 0 200 0 16777215 60 QFrame::NoFrame QFrame::Raised 0 Qt::Horizontal 40 20 false 60 16777215 Create AND composition with selected ROIs AND false 60 16777215 Create OR composition with selected ROIs OR false 60 16777215 Create NOT composition from selected ROI NOT Fiber Bundle Processing 0 0 Tract Density Image (TDI) Binary Envelope Fiber Bundle Image Fiber Endings Image Fiber Endings Pointset Upsampling Factor 1 10 - 4 + 2 false 0 0 200 16777215 11 Perform selected operation on fiber bundle Generate If selected operation generates an image, the inverse image is returned Invert Fiber Bundle Statistics Qt::Vertical 20 40 diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp index 9873a691d2..ffe3ef3acf 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp @@ -1,670 +1,669 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ 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. =========================================================================*/ // Blueberry #include #include #include "berryIStructuredSelection.h" // Qmitk #include "QmitkStochasticFiberTrackingView.h" #include "QmitkStdMultiWidget.h" // Qt #include //MITK //#include "mitkNodePredicateProperty.h" //#include "mitkNodePredicateAND.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include const std::string QmitkStochasticFiberTrackingView::VIEW_ID = "org.mitk.views.stochasticfibertracking"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; // Strings for Data handling const QString qDiffStr = "DiffusionImage"; const QString qStatusErr = "[Err]"; const QString qStatusOk = "[OK]"; const QString qSeed = "Seed"; //*****PERSONAL REMINDER****** //############################## /* THIS CLASS IS A MESS!! * CLEANUP IN PROGRESS... */ //############################## QmitkStochasticFiberTrackingView::QmitkStochasticFiberTrackingView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) { } // Destructor QmitkStochasticFiberTrackingView::~QmitkStochasticFiberTrackingView() { } void QmitkStochasticFiberTrackingView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkStochasticFiberTrackingViewControls; m_Controls->setupUi( parent ); // set tableWidget column with m_Controls->tableWidget->setColumnWidth(0,38); m_Controls->tableWidget->setColumnWidth(1,250); m_Controls->tableWidget->setEnabled(false); m_Controls->tableWidget->setLineWidth(0); connect( m_Controls->commandLinkButton, SIGNAL(clicked()), this, SLOT(DoFiberTracking()) ); //connect( m_Controls->comboBox_fiberAlgo, SIGNAL(selected()), this, SLOT(handleAlgoSelection() ); } } void QmitkStochasticFiberTrackingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkStochasticFiberTrackingView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } /* This method refreshes the Status-Message and its corresponding filename of tableWidget Input: tmpVec: contains either dwi-image-DataNode or seedImage-DataNodes tmpStatus: flag if dataNode-vector contains correct nodes or not */ void QmitkStochasticFiberTrackingView::refreshTableWidget(std::vector tmpVec , QString tmpStatus) { for(int idw=0; idw<(int)tmpVec.size(); idw++){ mitk::DataNode::Pointer tmpnode; QTableWidgetItem *itemStatus = new QTableWidgetItem; QTableWidgetItem *itemText = new QTableWidgetItem; tmpnode = tmpVec.at(idw); itemText->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); itemText->setText( tmpnode->GetName().c_str() ); itemStatus->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); itemStatus->setText(tmpStatus); if(tmpStatus.compare(qStatusErr) == 0){ itemText->setTextColor(QColor(90, 0, 3, 255)); itemStatus->setTextColor(QColor(90, 0, 3, 255)); }else{ itemText->setTextColor(QColor(92, 198, 10, 255)); itemStatus->setTextColor(QColor(92, 198, 10, 255)); } /* take next available row */ int row = m_Controls->tableWidget->rowCount(); m_Controls->tableWidget->insertRow(row); m_Controls->tableWidget->setItem(row,0,itemStatus); m_Controls->tableWidget->setItem(row,1,itemText); } } /* This method checks if given node is validSeed image*/ bool QmitkStochasticFiberTrackingView::checkSeedROI( mitk::DataNode::Pointer node ) { bool isSeed = false; QString qClassName = node->GetData()->GetNameOfClass(); /* propValue contains the result after calling GetPropertyValue success contains the bool if desired propertyname is available or not */ bool propValue = false; bool success = node->GetPropertyValue("binary",propValue); if(qClassName.compare("Image") == 0 && success == true && propValue == true) isSeed = true; return isSeed; } /* This method checks if given node is dwi image*/ bool QmitkStochasticFiberTrackingView::checkDWIType( mitk::DataNode::Pointer node ) { bool isDwi = false; QString qClassName = node->GetData()->GetNameOfClass(); // ie. TensorImage or DiffusionImage if(qClassName.compare(qDiffStr) == 0) isDwi = true; return isDwi; } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkStochasticFiberTrackingView::OnSelectionChanged( std::vector nodes ) { //++++++++RESET GUI AND POINTER VECTORS+++++++++++++++ /* clear GUI tableWidget */ for( int i=m_Controls->tableWidget->rowCount(); i >= 0; --i) { m_Controls->tableWidget->removeRow(i); } /* reset DWI selection vector */ vPselDWImg.clear(); vSeedROI.clear(); //+++++++++++++++++++++++++++++++++++++++++++++++++++++ //############### HOMELAND SECURITY ################################ /* When selection not empty, extract data of interest, otherwise return */ if(!nodes.empty()){ /* Flag to set commandButton enabled or not keep flag true until selection is not DWIImage */ bool flag_execFTComd = true; /* checkpoint for singe Seedpoint track */ // singleSeedpoint is depricated // m_singleSeedpoint = false; //for debugging singleSeedpoint is init here, otherwise get boolean from GUI for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { //flags needed for algorithm execution logic bool isDWI = false; bool isSeed = false; mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { /* Check and sort image types */ isDWI = checkDWIType(node); if( isDWI ){ vPselDWImg.push_back(*it); } else if(!m_singleSeedpoint){ isSeed = checkSeedROI(node); if( isSeed ) vSeedROI.push_back(*it); } //else single seedPoint } //end if node.IsNotNull && dynamic_cast mitkImage } //end node iterator //############### BORDER CONTROL ################################ /* ++++++++ Logic to en/disable execution of Algorithm +++++++++++ Requirements: 1 dwi Image, >=1 Seedimage(s) or 1 single seedpoint */ if(vPselDWImg.size() > 1){ flag_execFTComd = false; std::cout << "TODO GUI Warning, too much dwi images selected \n"; refreshTableWidget(vPselDWImg, qStatusErr); }else if(vPselDWImg.empty()){ flag_execFTComd = false; std::cout << "TODO GUI Warning, NO dwi image selected \n"; }else{ // exactly 1 node in vector flag_execFTComd = true; refreshTableWidget(vPselDWImg, qStatusOk); } if(!m_singleSeedpoint){ //no manual selection if(vSeedROI.empty()){ flag_execFTComd = false; std::cout << "TODO GUI Warning, NO seed image selected \n"; }else{ //color seedImages green refreshTableWidget(vSeedROI, qSeed); } } /* Logic to Dis-/Enable Execute-FiberTracking-Button */ if (m_Controls->commandLinkButton->isEnabled()) { if(!flag_execFTComd) m_Controls->commandLinkButton->setEnabled(false); } else if(flag_execFTComd){ m_Controls->commandLinkButton->setEnabled(true); } } else { // else statement of " if node.isEmpty() " /* Selection from datamanager is empty therefore set commandButton disable if necessary */ if(m_Controls->commandLinkButton->isEnabled()) { m_Controls->commandLinkButton->setEnabled(false); return; } } } void QmitkStochasticFiberTrackingView::DoFiberTracking() { // for debugging use only first image node mitk::DataNode::Pointer SpDWI = vPselDWImg.at(0); // cast node to compatible type mitk::DiffusionImage::Pointer dwiImg = dynamic_cast< mitk::DiffusionImage* >( SpDWI->GetData() ); /* get Gradients/Direction of dwi */ itk::VectorContainer< unsigned int, vnl_vector_fixed >::Pointer Pdir = dwiImg->GetDirections(); /* bValueContainer, Container includes b-values according to corresponding gradient-direction*/ PTFilterType::bValueContainerType::Pointer vecCont = PTFilterType::bValueContainerType::New(); /* for each gradient set b-Value; for 0-gradient set b-value eq. 0 */ for ( int i=0; i<(int)Pdir->size(); ++i) { vnl_vector_fixed valsGrad = Pdir->at(i); if (valsGrad.get(0) == 0 && valsGrad.get(1) == 0 && valsGrad.get(2) == 0) { //set 0-Gradient to bValue 0 vecCont->InsertElement(i,0); }else{ vecCont->InsertElement(i,dwiImg->GetB_Value()); } } /* former variant without setting 0-Gradient to 0 for(int i=0; iGetDirections()->Size(); i++) vecCont->InsertElement(i,dwiImg->GetB_Value()); */ /* define measurement frame (identity-matrix 3x3) */ PTFilterType::MeasurementFrameType measurement_frame; measurement_frame.set_identity(); /* generate white matterImage */ FloatImageType::Pointer wmImage = FloatImageType::New(); wmImage->SetSpacing( dwiImg->GetVectorImage()->GetSpacing() ); wmImage->SetOrigin( dwiImg->GetVectorImage()->GetOrigin() ); wmImage->SetDirection( dwiImg->GetVectorImage()->GetDirection() ); wmImage->SetLargestPossibleRegion( dwiImg->GetVectorImage()->GetLargestPossibleRegion() ); wmImage->SetBufferedRegion( wmImage->GetLargestPossibleRegion() ); wmImage->SetRequestedRegion( wmImage->GetLargestPossibleRegion() ); wmImage->Allocate(); itk::ImageRegionIterator ot(wmImage, wmImage->GetLargestPossibleRegion() ); while (!ot.IsAtEnd()) { ot.Set(1); ++ot; } /* init TractographyFilter, note: it's a smartpointer */ PTFilterType::Pointer ptfilterPtr = PTFilterType::New(); ptfilterPtr->SetInput(dwiImg->GetVectorImage().GetPointer()); ptfilterPtr->SetbValues(vecCont); ptfilterPtr->SetGradients(Pdir); ptfilterPtr->SetMeasurementFrame(measurement_frame); ptfilterPtr->SetWhiteMatterProbabilityImageInput(wmImage); /*** get parameters from GUI ... TODO check validity during user input ***/ ptfilterPtr->SetTotalTracts(m_Controls->lineEdit_totalTracts->text().toInt()); ptfilterPtr->SetMaxLikelihoodCacheSize(m_Controls->lineEdit_likelihood_cache->text().toInt()); ptfilterPtr->SetMaxTractLength(m_Controls->lineEdit_maxTractLength->text().toInt()); /* define seed Index manual */ //PTFilterType::InputDWIImageType::IndexType seedIdx; //seedIdx[0] = m_Controls->lineEdit_seedIndex1->text().toInt(); //seedIdx[1] = m_Controls->lineEdit_seedIndex2->text().toInt(); //seedIdx[2] = m_Controls->lineEdit_seedIndex3->text().toInt(); /* SEEDPOINT/REGION PREPARATION */ m_tractcontainer = PTFilterType::TractContainerType::New(); //int seedROIcnt = vSeedROI.size(); // ############## SEED OPERATIONS ######## // todo iterate over all seed ROIs /// for(int si=0; si(SpSeedR->GetData()); /* nice structure of fibers in datamanager */ /* mitk::DataNode::Pointer roiParentNode; roiParentNode = mitk::DataNode::New(); roiParentNode->SetName("FiberBundle_ROI_1"); roiParentNode->SetData(mitkSeed); roiParentNode->SetVisibility(true); GetDataStorage()->Add(roiParentNode);*/ //itk::Image< char, 3 > mitk::ImageToItk< itk::Image< unsigned char, 3 > >::Pointer binaryImageToItk1 = mitk::ImageToItk< itk::Image< unsigned char, 3 > >::New(); binaryImageToItk1->SetInput( mitkSeed ); binaryImageToItk1->Update(); itk::ImageRegionConstIterator< BinaryImageType > it(binaryImageToItk1->GetOutput(), binaryImageToItk1->GetOutput()->GetRequestedRegion()); it.Begin(); while(!it.IsAtEnd()) { itk::ImageConstIterator::PixelType tmpPxValue = it.Get(); if(tmpPxValue != 0){ itk::ImageRegionConstIterator< BinaryImageType >::IndexType seedIdx = it.GetIndex(); ptfilterPtr->SetSeedIndex(seedIdx); ptfilterPtr->Update(); /* get results from Filter */ /* write each single tract into member container */ PTFilterType::TractContainerType::Pointer container_tmp = ptfilterPtr->GetOutputTractContainer(); CImageType::Pointer cmap = ptfilterPtr->GetOutput(); PTFilterType::TractContainerType::Iterator elIt = container_tmp->Begin(); PTFilterType::TractContainerType::Iterator end = container_tmp->End(); while( elIt != end ){ PTFilterType::TractContainerType::Element tract_tmp = elIt.Value(); m_tractcontainer->InsertElement(m_tractcontainer->Size(),tract_tmp); ++elIt; } } ++it; } // } /* allocate the VTK Polydata to output the tracts */ vtkSmartPointer pts = vtkSmartPointer::New(); vtkSmartPointer cells = vtkSmartPointer::New(); float bounds[] = {0,0,0}; bounds[0] = dwiImg->GetLargestPossibleRegion().GetSize().GetElement(0); bounds[1] = dwiImg->GetLargestPossibleRegion().GetSize().GetElement(1); bounds[2] = dwiImg->GetLargestPossibleRegion().GetSize().GetElement(2); mitk::FiberBundle::Pointer transformer = mitk::FiberBundle::New(); transformer->additkStochTractContainer(m_tractcontainer); transformer->initFiberGroup(); transformer->SetGeometry(dwiImg->GetGeometry()); transformer->SetBounds(bounds); //transformer->debug_members(); //testing, get dti Fibers out of group mitk::FiberBundle::FiberGroupType::Pointer fiberBundle = transformer->GetGroupFiberBundle(); mitk::FiberBundle::ChildrenListType *fibersList = fiberBundle->GetChildren(); for(mitk::FiberBundle::ChildrenListType::iterator itFibers = fibersList->begin(); itFibers != fibersList->end(); ++itFibers) { //we know we have DTITubeSpatialObjects stored in List DTITubeType::Pointer dtiTract = dynamic_cast (itFibers->GetPointer()); } mitk::DataNode::Pointer fbNode; fbNode = mitk::DataNode::New(); fbNode->SetData(transformer); fbNode->SetName("GroupFinberBundle"); fbNode->SetVisibility(true); GetDataStorage()->Add(fbNode); for( int i=0; i<(int)m_tractcontainer->Size(); i++ ) { /* for each iteration create a new dtiTube containing a list of its points */ DTITubeType::Pointer dtiTube = DTITubeType::New(); DTITubeType::PointListType list; mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); mitk::Point3D point; PTFilterType::TractContainerType::Element tract = m_tractcontainer->GetElement(i); PTFilterType::TractContainerType::Element::ObjectType::VertexListType::ConstPointer vertexlist = tract->GetVertexList(); /* create VTK points and PolyLine */ vtkSmartPointer polyLine = vtkSmartPointer::New(); polyLine->GetPointIds()->SetNumberOfIds((int)vertexlist->Size()); unsigned long pntIdxHelper = pts->GetNumberOfPoints(); for( int j=0; j<(int)vertexlist->Size(); j++){ PTFilterType::TractContainerType::Element::ObjectType::VertexListType::Element vertex = vertexlist->GetElement(j); float vertex_f[3] = {(float)vertex[0],(float)vertex[1],(float)vertex[2]}; mitk::Point3D world(vertex_f); dwiImg->GetGeometry()->IndexToWorld(world, point); /* VTK add Points */ double vertex_d[3] = {(double)vertex[0],(double)vertex[1],(double)vertex[2]}; pts->InsertNextPoint(vertex_d); polyLine->GetPointIds()->SetId(j,j+pntIdxHelper); } /* dtiTubes dtiTube->GetProperty()->SetName("dtiTube"); dtiTube->SetId(i); dtiTube->SetPoints(list); myFiberScene->AddSpatialObject(dtiTube);*/ /* VTK add line */ cells->InsertNextCell(polyLine); /*mitk::DataNode::Pointer curveNode; curveNode = mitk::DataNode::New(); curveNode->SetData(spline); curveNode->SetName("Fiber"); curveNode->SetVisibility(true); GetDataStorage()->Add(curveNode, roiParentNode); */ mitk::Point3D newIdx3D; // std::cout << "cross position world: " << m_MultiWidget->GetCrossPosition() << "\n" ; // std::cout << "cross position index: " << newIdx3D << "\n" ; } /* ////////////// // Klaus' Code ////////////////////// // Generate RGBA Image typedef itk::RGBAPixel OutPixType; // run generator typedef itk::TractsToProbabilityImageFilter ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); generator->SetInput(wmImage); generator->SetTractContainer(m_tractcontainer); generator->SetUpsamplingFactor(20); generator->SetMinTractLength(10); //generator->Update(); // get result typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // write to datastorage mitk::DataNode::Pointer node1 = mitk::DataNode::New(); node1->SetData(img); node1->SetName("RgbImage"); node1->SetVisibility(true); mitk::LevelWindow opaclevwin; opaclevwin.SetRangeMinMax(0,255); opaclevwin.SetWindowBounds(0,0); mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin); node1->AddProperty( "opaclevelwindow", prop ); GetDataStorage()->Add(node1); /////////////////////////////// // Generate unsigned char Image typedef unsigned char OutPixType2; // run generator typedef itk::TractsToProbabilityImageFilter ImageGeneratorType2; ImageGeneratorType2::Pointer generator2 = ImageGeneratorType2::New(); generator2->SetInput(wmImage); generator2->SetTractContainer(m_tractcontainer); generator2->SetUpsamplingFactor(20); generator2->SetMinTractLength(10); generator2->Update(); // get result typedef itk::Image OutType2; OutType2::Pointer outImg2 = generator2->GetOutput(); mitk::Image::Pointer img2 = mitk::Image::New(); img2->InitializeByItk(outImg2.GetPointer()); img2->SetVolume(outImg2->GetBufferPointer()); // to datastorage mitk::DataNode::Pointer node2 = mitk::DataNode::New(); node2->SetData(img2); node2->SetName("ProbImage"); node2->SetVisibility(true); mitk::LevelWindow opaclevwin2; opaclevwin2.SetRangeMinMax(0,255); opaclevwin2.SetWindowBounds(0,0); mitk::LevelWindowProperty::Pointer prop2 = mitk::LevelWindowProperty::New(opaclevwin2); node2->AddProperty( "opaclevelwindow", prop2 ); GetDataStorage()->Add(node2); */ GetDataStorage()->Modified(); m_MultiWidget->RequestUpdate(); /* vtkSmartPointer linesPolyData = vtkSmartPointer::New(); linesPolyData->SetPoints(pts); linesPolyData->SetLines(cells); //setup actor and mapper vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(linesPolyData); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); //setup render window, renderer, and interactor vtkSmartPointer renderer = vtkSmartPointer::New(); vtkSmartPointer renderWindow = vtkSmartPointer::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer renderWindowInteractor = vtkSmartPointer::New(); renderWindowInteractor->SetRenderWindow(renderWindow); renderer->AddActor(actor); renderWindow->Render(); renderWindowInteractor->Start(); */ } diff --git a/Modules/DiffusionImaging/Algorithms/itkTractDensityImageFilter.cpp b/Modules/DiffusionImaging/Algorithms/itkTractDensityImageFilter.cpp new file mode 100644 index 0000000000..d11037064a --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/itkTractDensityImageFilter.cpp @@ -0,0 +1,183 @@ +#include "itkTractDensityImageFilter.h" + +// VTK +#include +#include +#include + +// misc +#include + +namespace itk{ + + template< class OutputImageType > + TractDensityImageFilter< OutputImageType >::TractDensityImageFilter() + : m_BinaryOutput(false) + , m_InvertImage(false) + , m_UpsamplingFactor(1) + { + + } + + template< class OutputImageType > + TractDensityImageFilter< OutputImageType >::~TractDensityImageFilter() + { + } + + template< class OutputImageType > + itk::Point TractDensityImageFilter< OutputImageType >::GetItkPoint(double point[3]) + { + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + return itkPoint; + } + + template< class OutputImageType > + void TractDensityImageFilter< OutputImageType >::GenerateData() + { + // generate upsampled image + mitk::Geometry3D::Pointer geometry = m_FiberBundle->GetGeometry(); + typename OutputImageType::Pointer outImage = this->GetOutput(); + + // calculate new image parameters + mitk::Vector3D newSpacing = geometry->GetSpacing()/m_UpsamplingFactor; + mitk::Point3D newOrigin = geometry->GetOrigin(); + mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds(); + newOrigin[0] += bounds.GetElement(0); + newOrigin[1] += bounds.GetElement(2); + newOrigin[2] += bounds.GetElement(4); + + itk::Matrix newDirection; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + newDirection[j][i] = geometry->GetMatrixColumn(i)[j]; + ImageRegion<3> upsampledRegion; + upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor); + upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor); + upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor); + typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); + + // aply new image parameters + outImage->SetSpacing( newSpacing ); + outImage->SetOrigin( newOrigin ); + outImage->SetDirection( newDirection ); + outImage->SetRegions( upsampledRegion ); + outImage->Allocate(); + + int w = upsampledSize[0]; + int h = upsampledSize[1]; + int d = upsampledSize[2]; + + // set/initialize output + OutPixelType* outImageBufferPointer = (OutPixelType*)outImage->GetBufferPointer(); + for (int i=0; iGetDeepCopy(); + m_FiberBundle->ResampleFibers(minSpacing/10); + + vtkSmartPointer fiberPolyData = m_FiberBundle->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); + + int numFibers = m_FiberBundle->GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + // fill output image + for( int j=0; j vertex = GetItkPoint(fiberPolyData->GetPoint(points[j])); + itk::Index<3> index; + itk::ContinuousIndex contIndex; + outImage->TransformPhysicalPointToIndex(vertex, index); + outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex); + + int ix = Math::Round(contIndex[0]); + int iy = Math::Round(contIndex[1]); + int iz = Math::Round(contIndex[2]); + + float frac_x = contIndex[0] - ix; + float frac_y = contIndex[1] - iy; + float frac_z = contIndex[2] - iz; + + int px = (int)contIndex[0]; + if (frac_x<0) + { + px -= 1; + frac_x *= -1; + } + int py = (int)contIndex[1]; + if (frac_y<0) + { + py -= 1; + frac_y *= -1; + } + int pz = (int)contIndex[2]; + if (frac_z<0) + { + pz -= 1; + frac_z *= -1; + } + + // int coordinates inside image? + if (px < 0 || px >= w-1) + continue; + if (py < 0 || py >= h-1) + continue; + if (pz < 0 || pz >= d-1) + continue; + + if (m_BinaryOutput) + { + outImageBufferPointer[( px + w*(py + h*pz ))] = 1; + outImageBufferPointer[( px + w*(py+1+ h*pz ))] = 1; + outImageBufferPointer[( px + w*(py + h*pz+h))] = 1; + outImageBufferPointer[( px + w*(py+1+ h*pz+h))] = 1; + outImageBufferPointer[( px+1 + w*(py + h*pz ))] = 1; + outImageBufferPointer[( px+1 + w*(py + h*pz+h))] = 1; + outImageBufferPointer[( px+1 + w*(py+1+ h*pz ))] = 1; + outImageBufferPointer[( px+1 + w*(py+1+ h*pz+h))] = 1; + } + else + { + outImageBufferPointer[( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z); + outImageBufferPointer[( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z); + outImageBufferPointer[( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z); + outImageBufferPointer[( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z); + outImageBufferPointer[( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z); + outImageBufferPointer[( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z); + outImageBufferPointer[( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z); + outImageBufferPointer[( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z); + } + } + } + if (!m_BinaryOutput) + { + OutPixelType max = 0; + for (int i=0; i0) + for (int i=0; i +#include +#include +#include +#include + +namespace itk{ + +template< class OutputImageType > +class TractDensityImageFilter : public ImageSource< OutputImageType > +{ + +public: + typedef TractDensityImageFilter Self; + typedef ProcessObject Superclass; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + typedef typename OutputImageType::PixelType OutPixelType; + + itkNewMacro(Self); + itkTypeMacro( TractDensityImageFilter, ImageSource ); + + /** Upsampling factor **/ + itkSetMacro( UpsamplingFactor, unsigned int); + itkGetMacro( UpsamplingFactor, unsigned int); + + /** Invert Image **/ + itkSetMacro( InvertImage, bool); + itkGetMacro( InvertImage, bool); + + /** Binary Output **/ + itkSetMacro( BinaryOutput, bool); + itkGetMacro( BinaryOutput, bool); + + itkSetMacro( FiberBundle, mitk::FiberBundleX::Pointer); + + void GenerateData(); + +protected: + + itk::Point GetItkPoint(double point[3]); + + TractDensityImageFilter(); + virtual ~TractDensityImageFilter(); + + mitk::FiberBundleX::Pointer m_FiberBundle; + unsigned int m_UpsamplingFactor; + bool m_InvertImage; + bool m_BinaryOutput; +}; + +} + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkTractDensityImageFilter.cpp" +#endif + +#endif // __itkTractDensityImageFilter_h__ diff --git a/Modules/DiffusionImaging/Algorithms/itkTractEnvelopeImageFilter.cpp b/Modules/DiffusionImaging/Algorithms/itkTractEnvelopeImageFilter.cpp new file mode 100644 index 0000000000..b608e3b827 --- /dev/null +++ b/Modules/DiffusionImaging/Algorithms/itkTractEnvelopeImageFilter.cpp @@ -0,0 +1,238 @@ +#include "itkTractDensityImageFilter.h" + +#include + +#define __CEIL_UCHAR__(val) (val) = \ +( (val) < 0 ) ? ( 0 ) : ( ( (val)>255 ) ? ( 255 ) : ( (val) ) ); + +namespace itk{ + + template< class TInputImage, class TOutputPixelType > + TractDensityImageFilter< TInputImage, TOutputPixelType > + ::TractDensityImageFilter(): + m_BinaryEnvelope(false) + { + this->SetNumberOfRequiredInputs(0); + } + + template< class TInputImage, class TOutputPixelType > + TractDensityImageFilter< TInputImage, TOutputPixelType > + ::~TractDensityImageFilter() + { + } + + + template< class TInputImage, class TOutputPixelType > + itk::Point TractDensityImageFilter< TInputImage, TOutputPixelType > + ::GetItkPoint(double point[3]) + { + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + return itkPoint; + } + + template< class TInputImage, class TOutputPixelType > + void TractDensityImageFilter< TInputImage, TOutputPixelType > + ::GenerateData() + { + // check for correct pixel type + if(&typeid(TOutputPixelType) != &typeid(unsigned char)) + { + MITK_INFO << "Only 'unsigned char' supported as OutputPixelType"; + return; + } + + // generate upsampled image + mitk::Geometry3D::Pointer geometry = m_FiberBundle->GetGeometry(); + typename OutputImageType::Pointer outImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); + + // calculate new image parameters + mitk::Vector3D newSpacing = geometry->GetSpacing()/m_UpsamplingFactor; + mitk::Point3D newOrigin = geometry->GetOrigin(); + itk::Matrix newDirection; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + newDirection[j][i] = geometry->GetMatrixColumn(i)[j]/newSpacing[i]; + ImageRegion<3> upsampledRegion; + upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor); + upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor); + upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor); + typename InputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); + + // aply new image parameters + outImage->SetSpacing( newSpacing ); + outImage->SetOrigin( newOrigin ); + outImage->SetDirection( newDirection ); + outImage->SetRegions( upsampledRegion ); + outImage->Allocate(); + + int w = upsampledSize[0]; + int h = upsampledSize[1]; + int d = upsampledSize[2]; + + // set/initialize output + float* accu; + unsigned char* outImageBufferPointer = reinterpret_cast(outImage->GetBufferPointer()); + if(isRgba) + { + accu = new float[w*h*d*4]; + for (int i=0; iGetDeepCopy(); + m_FiberBundle->ResampleFibers(minSpacing); + + // for each tract + vtkSmartPointer fiberPolyData = m_FiberBundle->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); + + int numFibers = m_FiberBundle->GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + // fill output image + for( int j=0; j vertex = GetItkPoint(fiberPolyData->GetPoint(points[j])); + itk::Index index; + + if ( outImage->TransformPhysicalPointToIndex(vertex, index) ) + { + // float fraction of coordinates + float frac_x = vertex[0] - px; + float frac_y = vertex[1] - py; + float frac_z = vertex[2] - pz; + + } + + float scale = 100 * pow((float)m_UpsamplingFactor,3); + + if (m_BinaryEnvelope) + { + accu[( px + w*(py + h*pz ))] = 1; + accu[( px + w*(py+1+ h*pz ))] = 1; + accu[( px + w*(py + h*pz+h))] = 1; + accu[( px + w*(py+1+ h*pz+h))] = 1; + accu[( px+1 + w*(py + h*pz ))] = 1; + accu[( px+1 + w*(py + h*pz+h))] = 1; + accu[( px+1 + w*(py+1+ h*pz ))] = 1; + accu[( px+1 + w*(py+1+ h*pz+h))] = 1; + } + else + { + accu[( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; + accu[( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * intweight * scale; + accu[( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * intweight * scale; + accu[( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * intweight * scale; + accu[( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; + accu[( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * intweight * scale; + accu[( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * intweight * scale; + accu[( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * intweight * scale; + } + + } + } + + float maxRgb = 0.000000001; + float maxInt = 0.000000001; + int numPix; + + if(isRgba) + { + numPix = w*h*d*4; + + // calc maxima + for(int i=0; i maxRgb) + { + maxRgb = accu[i]; + } + } + else + { + if(accu[i] > maxInt) + { + maxInt = accu[i]; + } + } + } + + // write output, normalized uchar 0..255 + for(int i=0; i maxInt) + { + maxInt = accu[i]; + } + } + + // write output, normalized uchar 0..255 + for(int i=0; i +#include +#include +#include namespace itk{ template< class TInputImage, class TOutputPixelType > -class TractsToProbabilityImageFilter : +class TractDensityImageFilter : public ImageToImageFilter > -//huhu public ImageToImageFilter > { public: - typedef TractsToProbabilityImageFilter Self; + typedef TractDensityImageFilter Self; typedef ImageToImageFilter > Superclass; -//huhu typedef ImageToImageFilter > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro(Self); - itkTypeMacro( TractsToProbabilityImageFilter, + itkTypeMacro( TractDensityImageFilter, ImageToImageFilter ); /** Types for the Output Image**/ typedef TInputImage InputImageType; /** Types for the Output Image**/ typedef itk::Image OutputImageType; /** Type for the directions **/ typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > TractOrientationsType; /** Type for the directions container **/ typedef VectorContainer< unsigned int, TractOrientationsType > TractOrientationsContainerType; /** Upsampling factor **/ itkSetMacro( UpsamplingFactor, unsigned int); itkGetMacro( UpsamplingFactor, unsigned int); /** Upsampling factor **/ itkSetMacro( InvertImage, bool); itkGetMacro( InvertImage, bool); itkSetMacro(FiberBundle, mitk::FiberBundle::Pointer); itkGetMacro(FiberBundle, mitk::FiberBundle::Pointer); itkSetMacro( BinaryEnvelope, bool); itkGetMacro( BinaryEnvelope, bool); void GenerateData(); protected: - TractsToProbabilityImageFilter(); - virtual ~TractsToProbabilityImageFilter(); + itk::Point GetItkPoint(double point[3]); - unsigned int m_UpsamplingFactor; - mitk::FiberBundle::Pointer m_FiberBundle; + TractDensityImageFilter(); + virtual ~TractDensityImageFilter(); + mitk::FiberBundleX::Pointer m_FiberBundle; + unsigned int m_UpsamplingFactor; bool m_InvertImage; bool m_BinaryEnvelope; }; } #ifndef ITK_MANUAL_INSTANTIATION -#include "itkTractsToProbabilityImageFilter.cpp" +#include "itkTractDensityImageFilter.cpp" #endif -#endif // __itkTractsToProbabilityImageFilter_h__ +#endif // __itkTractDensityImageFilter_h__ diff --git a/Modules/DiffusionImaging/Algorithms/itkTractsToFiberEndingsImageFilter.cpp b/Modules/DiffusionImaging/Algorithms/itkTractsToFiberEndingsImageFilter.cpp index 8a232aad6e..12e6ebc15d 100644 --- a/Modules/DiffusionImaging/Algorithms/itkTractsToFiberEndingsImageFilter.cpp +++ b/Modules/DiffusionImaging/Algorithms/itkTractsToFiberEndingsImageFilter.cpp @@ -1,137 +1,116 @@ #include "itkTractsToFiberEndingsImageFilter.h" -#include "itkBSplineUpsampleImageFilter.h" - -#define __CEIL_UCHAR__(val) (val) = \ -( (val) < 0 ) ? ( 0 ) : ( ( (val)>255 ) ? ( 255 ) : ( (val) ) ); +// VTK +#include +#include +#include namespace itk{ - template< class TInputImage, class TOutputPixelType > - TractsToFiberEndingsImageFilter< TInputImage, TOutputPixelType > - ::TractsToFiberEndingsImageFilter() + template< class OutputImageType > + TractsToFiberEndingsImageFilter< OutputImageType >::TractsToFiberEndingsImageFilter() + : m_InvertImage(false) + , m_UpsamplingFactor(1) { - this->SetNumberOfRequiredInputs(0); + } - template< class TInputImage, class TOutputPixelType > - TractsToFiberEndingsImageFilter< TInputImage, TOutputPixelType > - ::~TractsToFiberEndingsImageFilter() + template< class OutputImageType > + TractsToFiberEndingsImageFilter< OutputImageType >::~TractsToFiberEndingsImageFilter() { } - template< class TInputImage, class TOutputPixelType > - void TractsToFiberEndingsImageFilter< TInputImage, TOutputPixelType > - ::GenerateData() + template< class OutputImageType > + itk::Point TractsToFiberEndingsImageFilter< OutputImageType >::GetItkPoint(double point[3]) { - MITK_INFO << "Generating 2D fiber endings image"; - if(&typeid(TOutputPixelType) != &typeid(unsigned char)) - { - MITK_INFO << "Only 'unsigned char' and 'itk::RGBAPixel supported as OutputPixelType"; - return; - } - mitk::Geometry3D::Pointer geometry = m_FiberBundle->GetGeometry(); - - typename OutputImageType::Pointer outImage = - static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); - - outImage->SetSpacing( geometry->GetSpacing()/m_UpsamplingFactor ); // Set the image spacing + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + return itkPoint; + } - mitk::Point3D origin = geometry->GetOrigin(); - mitk::Point3D indexOrigin; - geometry->WorldToIndex(origin, indexOrigin); - indexOrigin[0] = indexOrigin[0] - .5 * (1.0-1.0/m_UpsamplingFactor); - indexOrigin[1] = indexOrigin[1] - .5 * (1.0-1.0/m_UpsamplingFactor); - indexOrigin[2] = indexOrigin[2] - .5 * (1.0-1.0/m_UpsamplingFactor); - mitk::Point3D newOrigin; - geometry->IndexToWorld(indexOrigin, newOrigin); + template< class OutputImageType > + void TractsToFiberEndingsImageFilter< OutputImageType >::GenerateData() + { + // generate upsampled image + mitk::Geometry3D::Pointer geometry = m_FiberBundle->GetGeometry(); + typename OutputImageType::Pointer outImage = this->GetOutput(); - outImage->SetOrigin( newOrigin ); // Set the image origin + // calculate new image parameters + mitk::Vector3D newSpacing = geometry->GetSpacing()/m_UpsamplingFactor; + mitk::Point3D newOrigin = geometry->GetOrigin(); + mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds(); + newOrigin[0] += bounds.GetElement(0); + newOrigin[1] += bounds.GetElement(2); + newOrigin[2] += bounds.GetElement(4); - itk::Matrix matrix; + itk::Matrix newDirection; for (int i=0; i<3; i++) for (int j=0; j<3; j++) - matrix[j][i] = geometry->GetMatrixColumn(i)[j]/geometry->GetSpacing().GetElement(i); - outImage->SetDirection( matrix ); // Set the image direction - - float* bounds = m_FiberBundle->GetBounds(); + newDirection[j][i] = geometry->GetMatrixColumn(i)[j]; ImageRegion<3> upsampledRegion; - upsampledRegion.SetSize(0, bounds[0]); - upsampledRegion.SetSize(1, bounds[1]); - upsampledRegion.SetSize(2, bounds[2]); - - typename InputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); - for (unsigned int n = 0; n < 3; n++) - { - upsampledSize[n] = upsampledSize[n] * m_UpsamplingFactor; - } - upsampledRegion.SetSize( upsampledSize ); + upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor); + upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor); + upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor); + typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); + + // aply new image parameters + outImage->SetSpacing( newSpacing ); + outImage->SetOrigin( newOrigin ); + outImage->SetDirection( newDirection ); outImage->SetRegions( upsampledRegion ); - outImage->Allocate(); int w = upsampledSize[0]; int h = upsampledSize[1]; int d = upsampledSize[2]; - - unsigned char* accuout; - accuout = reinterpret_cast(outImage->GetBufferPointer()); - for (int i=0; iGetTractContainer(); - - for (int i=0; iSize(); i++) + // set/initialize output + OutPixelType* outImageBufferPointer = (OutPixelType*)outImage->GetBufferPointer(); + for (int i=0; i fiberPolyData = m_FiberBundle->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); + + int numFibers = m_FiberBundle->GetNumFibers(); + for( int i=0; iGetElement(i); - int tractsize = tract->Size(); + vtkIdType numPoints(0); + vtkIdType* points(NULL); + vLines->GetNextCell ( numPoints, points ); - if (tractsize>1) + // fill output image + if (numPoints>0) { - ContainerPointType start = tract->GetElement(0); - ContainerPointType end = tract->GetElement(tractsize-1); - - start[0] = (start[0]+0.5) * m_UpsamplingFactor; - start[1] = (start[1]+0.5) * m_UpsamplingFactor; - start[2] = (start[2]+0.5) * m_UpsamplingFactor; - - // int coordinates inside image? - int px = (int) (start[0]); - if (px < 0 || px >= w) - continue; - int py = (int) (start[1]); - if (py < 0 || py >= h) - continue; - int pz = (int) (start[2]); - if (pz < 0 || pz >= d) - continue; - - accuout[( px + w*(py + h*pz ))] += 1; - - - end[0] = (end[0]+0.5) * m_UpsamplingFactor; - end[1] = (end[1]+0.5) * m_UpsamplingFactor; - end[2] = (end[2]+0.5) * m_UpsamplingFactor; - - // int coordinates inside image? - px = (int) (end[0]); - if (px < 0 || px >= w) - continue; - py = (int) (end[1]); - if (py < 0 || py >= h) - continue; - pz = (int) (end[2]); - if (pz < 0 || pz >= d) - continue; - - accuout[( px + w*(py + h*pz ))] += 1; + itk::Point vertex = GetItkPoint(fiberPolyData->GetPoint(points[0])); + itk::Index<3> index; + outImage->TransformPhysicalPointToIndex(vertex, index); + outImage->SetPixel(index, 1); + } + + if (numPoints>2) + { + itk::Point vertex = GetItkPoint(fiberPolyData->GetPoint(points[numPoints-1])); + itk::Index<3> index; + outImage->TransformPhysicalPointToIndex(vertex, index); + outImage->SetPixel(index, 1); } } - MITK_INFO << "2D fiber endings image generated"; + if (m_InvertImage) + for (int i=0; i +#include +#include +#include +#include namespace itk{ -template< class TInputImage, class TOutputPixelType > -class TractsToFiberEndingsImageFilter : - public ImageToImageFilter > -//huhu public ImageToImageFilter > +template< class OutputImageType > +class TractsToFiberEndingsImageFilter : public ImageSource< OutputImageType > { public: typedef TractsToFiberEndingsImageFilter Self; - typedef ImageToImageFilter > Superclass; -//huhu typedef ImageToImageFilter > Superclass; + typedef ProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; - - itkNewMacro(Self); - itkTypeMacro( TractsToFiberEndingsImageFilter, - ImageToImageFilter ); - - /** Types for the Output Image**/ - typedef TInputImage InputImageType; - - /** Types for the Output Image**/ - typedef itk::Image OutputImageType; - /** Type for the directions **/ - typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > - TractOrientationsType; + typedef typename OutputImageType::PixelType OutPixelType; - /** Type for the directions container **/ - typedef VectorContainer< unsigned int, TractOrientationsType > - TractOrientationsContainerType; + itkNewMacro(Self); + itkTypeMacro( TractsToFiberEndingsImageFilter, ImageSource ); /** Upsampling factor **/ itkSetMacro( UpsamplingFactor, unsigned int); itkGetMacro( UpsamplingFactor, unsigned int); - - itkSetMacro(FiberBundle, mitk::FiberBundle::Pointer); - itkGetMacro(FiberBundle, mitk::FiberBundle::Pointer); + + /** Invert Image **/ + itkSetMacro( InvertImage, bool); + itkGetMacro( InvertImage, bool); + + itkSetMacro( FiberBundle, mitk::FiberBundleX::Pointer); void GenerateData(); - + protected: + itk::Point GetItkPoint(double point[3]); + TractsToFiberEndingsImageFilter(); virtual ~TractsToFiberEndingsImageFilter(); + mitk::FiberBundleX::Pointer m_FiberBundle; unsigned int m_UpsamplingFactor; - mitk::FiberBundle::Pointer m_FiberBundle; - + bool m_InvertImage; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkTractsToFiberEndingsImageFilter.cpp" #endif #endif // __itkTractsToFiberEndingsImageFilter_h__ diff --git a/Modules/DiffusionImaging/Algorithms/itkTractsToProbabilityImageFilter.cpp b/Modules/DiffusionImaging/Algorithms/itkTractsToProbabilityImageFilter.cpp deleted file mode 100644 index 5c8b9ac092..0000000000 --- a/Modules/DiffusionImaging/Algorithms/itkTractsToProbabilityImageFilter.cpp +++ /dev/null @@ -1,359 +0,0 @@ -#include "itkTractsToProbabilityImageFilter.h" - -#include "itkBSplineUpsampleImageFilter.h" - -#define __CEIL_UCHAR__(val) (val) = \ -( (val) < 0 ) ? ( 0 ) : ( ( (val)>255 ) ? ( 255 ) : ( (val) ) ); - -namespace itk{ - - template< class TInputImage, class TOutputPixelType > - TractsToProbabilityImageFilter< TInputImage, TOutputPixelType > - ::TractsToProbabilityImageFilter(): - m_BinaryEnvelope(false) - { - this->SetNumberOfRequiredInputs(0); - } - - template< class TInputImage, class TOutputPixelType > - TractsToProbabilityImageFilter< TInputImage, TOutputPixelType > - ::~TractsToProbabilityImageFilter() - { - } - - template< class TInputImage, class TOutputPixelType > - void TractsToProbabilityImageFilter< TInputImage, TOutputPixelType > - ::GenerateData() - { - bool isRgba = false; - if(&typeid(TOutputPixelType) == &typeid(itk::RGBAPixel)) - { - isRgba = true; - } - else if(&typeid(TOutputPixelType) != &typeid(unsigned char)) - { - MITK_INFO << "Only 'unsigned char' and 'itk::RGBAPixel supported as OutputPixelType"; - return; - } - - mitk::Geometry3D::Pointer geometry = m_FiberBundle->GetGeometry(); - - typename OutputImageType::Pointer outImage = - static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); - - outImage->SetSpacing( geometry->GetSpacing()/m_UpsamplingFactor ); // Set the image spacing - - mitk::Point3D origin = geometry->GetOrigin(); - mitk::Point3D indexOrigin; - geometry->WorldToIndex(origin, indexOrigin); - indexOrigin[0] = indexOrigin[0] - .5 * (1.0-1.0/m_UpsamplingFactor); - indexOrigin[1] = indexOrigin[1] - .5 * (1.0-1.0/m_UpsamplingFactor); - indexOrigin[2] = indexOrigin[2] - .5 * (1.0-1.0/m_UpsamplingFactor); - mitk::Point3D newOrigin; - geometry->IndexToWorld(indexOrigin, newOrigin); - - outImage->SetOrigin( newOrigin ); // Set the image origin - itk::Matrix matrix; - for (int i=0; i<3; i++) - for (int j=0; j<3; j++) - matrix[j][i] = geometry->GetMatrixColumn(i)[j]/geometry->GetSpacing().GetElement(i); - outImage->SetDirection( matrix ); // Set the image direction - - float* bounds = m_FiberBundle->GetBounds(); - ImageRegion<3> upsampledRegion; - upsampledRegion.SetSize(0, bounds[0]); - upsampledRegion.SetSize(1, bounds[1]); - upsampledRegion.SetSize(2, bounds[2]); - - typename InputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); - for (unsigned int n = 0; n < 3; n++) - { - upsampledSize[n] = upsampledSize[n] * m_UpsamplingFactor; - } - upsampledRegion.SetSize( upsampledSize ); - outImage->SetRegions( upsampledRegion ); - - outImage->Allocate(); - // itk::RGBAPixel pix; - // pix.Set(0,0,0,0); - // outImage->FillBuffer(pix); - - int w = upsampledSize[0]; - int h = upsampledSize[1]; - int d = upsampledSize[2]; - - - unsigned char* accuout; - float* accu; - - accuout = reinterpret_cast(outImage->GetBufferPointer()); - - if(isRgba) - { -// accuout = static_cast( outImage->GetBufferPointer()[0].GetDataPointer()); - accu = new float[w*h*d*4]; - for (int i=0; iGetNumTracts(); - for( int i=0; i > vertices; - - // for each vertex - int numVertices = m_FiberBundle->GetNumPoints(i); - for( int j=0; j point = m_FiberBundle->GetPoint(i,j); - itk::Point nextPoint = m_FiberBundle->GetPoint(i,j+1); - point[0] += 0.5 - 0.5/m_UpsamplingFactor; - point[1] += 0.5 - 0.5/m_UpsamplingFactor; - point[2] += 0.5 - 0.5/m_UpsamplingFactor; - nextPoint[0] += 0.5 - 0.5/m_UpsamplingFactor; - nextPoint[1] += 0.5 - 0.5/m_UpsamplingFactor; - nextPoint[2] += 0.5 - 0.5/m_UpsamplingFactor; - - for(int k=1; k<=m_UpsamplingFactor; k++) - { - itk::Point newPoint; - newPoint[0] = point[0] + ((double)k/(double)m_UpsamplingFactor)*(nextPoint[0]-point[0]); - newPoint[1] = point[1] + ((double)k/(double)m_UpsamplingFactor)*(nextPoint[1]-point[1]); - newPoint[2] = point[2] + ((double)k/(double)m_UpsamplingFactor)*(nextPoint[2]-point[2]); - vertices.push_back(newPoint); - } - } - - //////////////////// - // calc directions (which are used as weights) - std::list< itk::Point > rgbweights; - std::list intensities; - - // for each vertex - numVertices = vertices.size(); - for( int j=0; j vertex = vertices.at(j); - itk::Point vertexPost = vertices.at(j+1); - - itk::Point dir; - dir[0] = fabs((vertexPost[0] - vertex[0]) * outImage->GetSpacing()[0]); - dir[1] = fabs((vertexPost[1] - vertex[1]) * outImage->GetSpacing()[1]); - dir[2] = fabs((vertexPost[2] - vertex[2]) * outImage->GetSpacing()[2]); - - if(isRgba) - { - rgbweights.push_back(dir); - } - - float intensity = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]); - intensities.push_back(intensity); - - // last point gets same as previous one - if(j==numVertices-2) - { - if(isRgba) - { - rgbweights.push_back(dir); - } - intensities.push_back(intensity); - } - } - - - //////////////////// - // fill output image - - // for each vertex - for( int j=0; j vertex = vertices.at(j); - itk::Point rgbweight; - if(isRgba) - { - rgbweight = rgbweights.front(); - rgbweights.pop_front(); - } - float intweight = intensities.front(); - intensities.pop_front(); - - // scaling coordinates (index coords scale with upsampling) - vertex[0] = vertex[0] * m_UpsamplingFactor; - vertex[1] = vertex[1] * m_UpsamplingFactor; - vertex[2] = vertex[2] * m_UpsamplingFactor; - - // int coordinates inside image? - int px = (int) (vertex[0]); - if (px < 0 || px >= w-1) - continue; - int py = (int) (vertex[1]); - if (py < 0 || py >= h-1) - continue; - int pz = (int) (vertex[2]); - if (pz < 0 || pz >= d-1) - continue; - - // float fraction of coordinates - float frac_x = vertex[0] - px; - float frac_y = vertex[1] - py; - float frac_z = vertex[2] - pz; - - float scale = 100 * pow((float)m_UpsamplingFactor,3); - - if(isRgba) - { - // add to r-channel in output image - accu[0+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[0] * scale; - accu[0+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[0] * scale; - accu[0+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[0] * scale; - accu[0+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[0] * scale; - accu[0+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[0] * scale; - accu[0+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[0] * scale; - accu[0+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[0] * scale; - accu[0+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[0] * scale; - - // add to g-channel in output image - accu[1+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[1] * scale; - accu[1+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[1] * scale; - accu[1+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[1] * scale; - accu[1+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[1] * scale; - accu[1+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[1] * scale; - accu[1+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[1] * scale; - accu[1+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[1] * scale; - accu[1+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[1] * scale; - - // add to b-channel in output image - accu[2+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[2] * scale; - accu[2+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[2] * scale; - accu[2+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[2] * scale; - accu[2+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[2] * scale; - accu[2+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[2] * scale; - accu[2+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[2] * scale; - accu[2+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[2] * scale; - accu[2+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[2] * scale; - - // add to a-channel in output image - accu[3+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; - accu[3+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * intweight * scale; - accu[3+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * intweight * scale; - accu[3+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * intweight * scale; - accu[3+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; - accu[3+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * intweight * scale; - accu[3+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * intweight * scale; - accu[3+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * intweight * scale; - } - else if (m_BinaryEnvelope) - { - accu[( px + w*(py + h*pz ))] = 1; - accu[( px + w*(py+1+ h*pz ))] = 1; - accu[( px + w*(py + h*pz+h))] = 1; - accu[( px + w*(py+1+ h*pz+h))] = 1; - accu[( px+1 + w*(py + h*pz ))] = 1; - accu[( px+1 + w*(py + h*pz+h))] = 1; - accu[( px+1 + w*(py+1+ h*pz ))] = 1; - accu[( px+1 + w*(py+1+ h*pz+h))] = 1; - } - else - { - accu[( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; - accu[( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * intweight * scale; - accu[( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * intweight * scale; - accu[( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * intweight * scale; - accu[( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; - accu[( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * intweight * scale; - accu[( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * intweight * scale; - accu[( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * intweight * scale; - } - - } - } - - float maxRgb = 0.000000001; - float maxInt = 0.000000001; - int numPix; - - if(isRgba) - { - numPix = w*h*d*4; - - // calc maxima - for(int i=0; i maxRgb) - { - maxRgb = accu[i]; - } - } - else - { - if(accu[i] > maxInt) - { - maxInt = accu[i]; - } - } - } - - // write output, normalized uchar 0..255 - for(int i=0; i maxInt) - { - maxInt = accu[i]; - } - } - - // write output, normalized uchar 0..255 - for(int i=0; i +#include +#include + +// misc +#include + +namespace itk{ + + template< class OutputImageType > + TractsToRgbaImageFilter< OutputImageType >::TractsToRgbaImageFilter() + : m_BinaryOutput(false) + , m_InvertImage(false) + , m_UpsamplingFactor(1) + { + + } + + template< class OutputImageType > + TractsToRgbaImageFilter< OutputImageType >::~TractsToRgbaImageFilter() + { + } + + template< class OutputImageType > + itk::Point TractsToRgbaImageFilter< OutputImageType >::GetItkPoint(double point[3]) + { + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + return itkPoint; + } + + template< class OutputImageType > + void TractsToRgbaImageFilter< OutputImageType >::GenerateData() + { + if(&typeid(OutPixelType) != &typeid(itk::RGBAPixel)) + return; + + // generate upsampled image + mitk::Geometry3D::Pointer geometry = m_FiberBundle->GetGeometry(); + typename OutputImageType::Pointer outImage = this->GetOutput(); + + // calculate new image parameters + mitk::Vector3D newSpacing = geometry->GetSpacing()/m_UpsamplingFactor; + mitk::Point3D newOrigin = geometry->GetOrigin(); + mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds(); + newOrigin[0] += bounds.GetElement(0); + newOrigin[1] += bounds.GetElement(2); + newOrigin[2] += bounds.GetElement(4); + + itk::Matrix newDirection; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + newDirection[j][i] = geometry->GetMatrixColumn(i)[j]; + ImageRegion<3> upsampledRegion; + upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor); + upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor); + upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor); + typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); + + // aply new image parameters + outImage->SetSpacing( newSpacing ); + outImage->SetOrigin( newOrigin ); + outImage->SetDirection( newDirection ); + outImage->SetRegions( upsampledRegion ); + outImage->Allocate(); + + int w = upsampledSize[0]; + int h = upsampledSize[1]; + int d = upsampledSize[2]; + + // set/initialize output + unsigned char* outImageBufferPointer = (unsigned char*)outImage->GetBufferPointer(); + float* buffer = new float[w*h*d*4]; + for (int i=0; iGetDeepCopy(); + m_FiberBundle->ResampleFibers(minSpacing/10); + + vtkSmartPointer fiberPolyData = m_FiberBundle->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); + + int numFibers = m_FiberBundle->GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + // calc directions (which are used as weights) + std::list< itk::Point > rgbweights; + std::list intensities; + + for( int j=0; j vertex = GetItkPoint(fiberPolyData->GetPoint(points[j])); + itk::Point vertexPost = GetItkPoint(fiberPolyData->GetPoint(points[j+1])); + + itk::Point dir; + dir[0] = fabs((vertexPost[0] - vertex[0]) * outImage->GetSpacing()[0]); + dir[1] = fabs((vertexPost[1] - vertex[1]) * outImage->GetSpacing()[1]); + dir[2] = fabs((vertexPost[2] - vertex[2]) * outImage->GetSpacing()[2]); + + rgbweights.push_back(dir); + + float intensity = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]); + intensities.push_back(intensity); + + // last point gets same as previous one + if(j==numPoints-2) + { + rgbweights.push_back(dir); + intensities.push_back(intensity); + } + } + + // fill output image + for( int j=0; j vertex = GetItkPoint(fiberPolyData->GetPoint(points[j])); + itk::Index<3> index; + itk::ContinuousIndex contIndex; + outImage->TransformPhysicalPointToIndex(vertex, index); + outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex); + + int ix = Math::Round(contIndex[0]); + int iy = Math::Round(contIndex[1]); + int iz = Math::Round(contIndex[2]); + + float frac_x = contIndex[0] - ix; + float frac_y = contIndex[1] - iy; + float frac_z = contIndex[2] - iz; + + int px = (int)contIndex[0]; + if (frac_x<0) + { + px -= 1; + frac_x *= -1; + } + int py = (int)contIndex[1]; + if (frac_y<0) + { + py -= 1; + frac_y *= -1; + } + int pz = (int)contIndex[2]; + if (frac_z<0) + { + pz -= 1; + frac_z *= -1; + } + + // int coordinates inside image? + if (px < 0 || px >= w-1) + continue; + if (py < 0 || py >= h-1) + continue; + if (pz < 0 || pz >= d-1) + continue; + + float scale = 100 * pow((float)m_UpsamplingFactor,3); + itk::Point rgbweight = rgbweights.front(); + rgbweights.pop_front(); + float intweight = intensities.front(); + intensities.pop_front(); + + // add to r-channel in output image + buffer[0+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[0] * scale; + buffer[0+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[0] * scale; + buffer[0+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[0] * scale; + buffer[0+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[0] * scale; + buffer[0+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[0] * scale; + buffer[0+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[0] * scale; + buffer[0+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[0] * scale; + buffer[0+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[0] * scale; + + // add to g-channel in output image + buffer[1+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[1] * scale; + buffer[1+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[1] * scale; + buffer[1+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[1] * scale; + buffer[1+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[1] * scale; + buffer[1+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[1] * scale; + buffer[1+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[1] * scale; + buffer[1+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[1] * scale; + buffer[1+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[1] * scale; + + // add to b-channel in output image + buffer[2+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[2] * scale; + buffer[2+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[2] * scale; + buffer[2+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[2] * scale; + buffer[2+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[2] * scale; + buffer[2+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[2] * scale; + buffer[2+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[2] * scale; + buffer[2+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[2] * scale; + buffer[2+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[2] * scale; + + // add to a-channel in output image + buffer[3+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; + buffer[3+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * intweight * scale; + buffer[3+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * intweight * scale; + buffer[3+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * intweight * scale; + buffer[3+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale; + buffer[3+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * intweight * scale; + buffer[3+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * intweight * scale; + buffer[3+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * intweight * scale; + } + } + float maxRgb = 0.000000001; + float maxInt = 0.000000001; + int numPix; + + numPix = w*h*d*4; + // calc maxima + for(int i=0; i maxRgb) + maxRgb = buffer[i]; + } + else + { + if(buffer[i] > maxInt) + maxInt = buffer[i]; + } + } + + // write output, normalized uchar 0..255 + for(int i=0; i +#include +#include +#include +#include + +namespace itk{ + +template< class OutputImageType > +class TractsToRgbaImageFilter : public ImageSource< OutputImageType > +{ + +public: + typedef TractsToRgbaImageFilter Self; + typedef ProcessObject Superclass; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + typedef typename OutputImageType::PixelType OutPixelType; + + itkNewMacro(Self); + itkTypeMacro( TractsToRgbaImageFilter, ImageSource ); + + /** Upsampling factor **/ + itkSetMacro( UpsamplingFactor, unsigned int); + itkGetMacro( UpsamplingFactor, unsigned int); + + /** Invert Image **/ + itkSetMacro( InvertImage, bool); + itkGetMacro( InvertImage, bool); + + /** Binary Output **/ + itkSetMacro( BinaryOutput, bool); + itkGetMacro( BinaryOutput, bool); + + itkSetMacro( FiberBundle, mitk::FiberBundleX::Pointer); + + void GenerateData(); + +protected: + + itk::Point GetItkPoint(double point[3]); + + TractsToRgbaImageFilter(); + virtual ~TractsToRgbaImageFilter(); + + mitk::FiberBundleX::Pointer m_FiberBundle; + unsigned int m_UpsamplingFactor; + bool m_InvertImage; + bool m_BinaryOutput; +}; + +} + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkTractsToRgbaImageFilter.cpp" +#endif + +#endif // __itkTractsToRgbaImageFilter_h__ diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp index 383f8ae030..c2b204e47b 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp @@ -1,686 +1,841 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ 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 "mitkFiberBundleX.h" #include #include #include #include #include #include #include #include #include #include #include #include const char* mitk::FiberBundleX::COLORCODING_ORIENTATION_BASED = "Color_Orient"; const char* mitk::FiberBundleX::COLORCODING_FA_BASED = "Color_FA"; const char* mitk::FiberBundleX::FIBER_ID_ARRAY = "Fiber_IDs"; -mitk::FiberBundleX::FiberBundleX(vtkSmartPointer fiberPolyData ) +mitk::FiberBundleX::FiberBundleX( vtkPolyData* fiberPolyData ) : m_currentColorCoding(NULL) , m_isModified(false) , m_NumFibers(0) { if (fiberPolyData == NULL) m_FiberPolyData = vtkSmartPointer::New(); else m_FiberPolyData = fiberPolyData; m_NumFibers = m_FiberPolyData->GetNumberOfLines(); UpdateFiberGeometry(); } mitk::FiberBundleX::~FiberBundleX() { } +mitk::FiberBundleX::Pointer mitk::FiberBundleX::GetDeepCopy() +{ + mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(); + +// newFib->m_FiberIdDataSet = vtkSmartPointer::New(); +// newFib->m_FiberIdDataSet->DeepCopy(m_FiberIdDataSet); + newFib->m_FiberPolyData = vtkSmartPointer::New(); + newFib->m_FiberPolyData->DeepCopy(m_FiberPolyData); + newFib->SetColorCoding(m_currentColorCoding); + newFib->m_isModified = m_isModified; + newFib->m_NumFibers = m_NumFibers; + newFib->UpdateFiberGeometry(); + + return newFib; +} + +// merge two fiber bundles +mitk::FiberBundleX::Pointer mitk::FiberBundleX::operator+(mitk::FiberBundleX* fib) +{ + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer vLines = m_FiberPolyData->GetLines(); + vLines->InitTraversal(); + + // add current fiber bundle + int numFibers = GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + vtkSmartPointer container = vtkSmartPointer::New(); + for( int j=0; jInsertNextPoint(m_FiberPolyData->GetPoint(points[j])); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + } + + vLines = fib->m_FiberPolyData->GetLines(); + vLines->InitTraversal(); + + // add new fiber bundle + numFibers = fib->GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + vtkSmartPointer container = vtkSmartPointer::New(); + for( int j=0; jInsertNextPoint(fib->m_FiberPolyData->GetPoint(points[j])); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + } + + // initialize polydata + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // initialize fiber bundle + mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(vNewPolyData); + return newFib; +} + +// subtract two fiber bundles +mitk::FiberBundleX::Pointer mitk::FiberBundleX::operator-(mitk::FiberBundleX* fib) +{ + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer vLines = m_FiberPolyData->GetLines(); + vLines->InitTraversal(); + + // iterate over current fibers + int numFibers = GetNumFibers(); + for( int i=0; iGetNextCell ( numPoints, points ); + + vtkSmartPointer vLines2 = fib->m_FiberPolyData->GetLines(); + vLines2->InitTraversal(); + int numFibers2 = fib->GetNumFibers(); + bool contained = false; + for( int i2=0; i2GetNextCell ( numPoints2, points2 ); + + // check endpoints + itk::Point point_start = GetItkPoint(m_FiberPolyData->GetPoint(points[0])); + itk::Point point_end = GetItkPoint(m_FiberPolyData->GetPoint(points[numPoints-1])); + itk::Point point2_start = GetItkPoint(fib->m_FiberPolyData->GetPoint(points2[0])); + itk::Point point2_end = GetItkPoint(fib->m_FiberPolyData->GetPoint(points2[numPoints2-1])); + + if (point_start.SquaredEuclideanDistanceTo(point2_start)<=mitk::eps && point_end.SquaredEuclideanDistanceTo(point2_end)<=mitk::eps || + point_start.SquaredEuclideanDistanceTo(point2_end)<=mitk::eps && point_end.SquaredEuclideanDistanceTo(point2_start)<=mitk::eps) + { + // further checking ??? + contained = true; + } + } + + // add to result because fiber is not subtracted + if (!contained) + { + vtkSmartPointer container = vtkSmartPointer::New(); + for( int j=0; jInsertNextPoint(m_FiberPolyData->GetPoint(points[j])); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + } + } + + // initialize polydata + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // initialize fiber bundle + mitk::FiberBundleX::Pointer newFib = mitk::FiberBundleX::New(vNewPolyData); + return newFib; +} + +itk::Point mitk::FiberBundleX::GetItkPoint(double point[3]) +{ + itk::Point itkPoint; + itkPoint[0] = point[0]; + itkPoint[1] = point[1]; + itkPoint[2] = point[2]; + return itkPoint; +} + /* * set polydata (additional flag to recompute fiber geometry, default = true) */ void mitk::FiberBundleX::SetFiberPolyData(vtkSmartPointer fiberPD, bool updateGeometry) { if (fiberPD == NULL) this->m_FiberPolyData = vtkSmartPointer::New(); else this->m_FiberPolyData = fiberPD; if (updateGeometry) UpdateFiberGeometry(); m_NumFibers = m_FiberPolyData->GetNumberOfLines(); m_isModified = true; } /* * return vtkPolyData */ vtkSmartPointer mitk::FiberBundleX::GetFiberPolyData() { return m_FiberPolyData; } void mitk::FiberBundleX::DoColorCodingOrientationbased() { //===== FOR WRITING A TEST ======================== // colorT size == tupelComponents * tupelElements // compare color results // to cover this code 100% also polydata needed, where colorarray already exists // + one fiber with exactly 1 point // + one fiber with 0 points //================================================= /* make sure that processing colorcoding is only called when necessary */ if ( m_FiberPolyData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) && m_FiberPolyData->GetNumberOfPoints() == m_FiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetNumberOfTuples() ) { // fiberstructure is already colorcoded MITK_INFO << " NO NEED TO REGENERATE COLORCODING! " ; return; } /* Finally, execute color calculation */ vtkPoints* extrPoints = m_FiberPolyData->GetPoints(); int numOfPoints = extrPoints->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; int componentSize = sizeof(rgba); vtkUnsignedCharArray * colorsT = vtkUnsignedCharArray::New(); colorsT->Allocate(numOfPoints * componentSize); colorsT->SetNumberOfComponents(componentSize); colorsT->SetName(COLORCODING_ORIENTATION_BASED); /* checkpoint: does polydata contain any fibers */ int numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) { MITK_INFO << "\n ========= Number of Fibers is 0 and below ========= \n"; return; } /* extract single fibers of fiberBundle */ vtkCellArray* fiberList = m_FiberPolyData->GetLines(); fiberList->InitTraversal(); for (int fi=0; fiGetNextCell(pointsPerFiber, idList); // MITK_INFO << "Fib#: " << fi << " of " << numOfFibers << " pnts in fiber: " << pointsPerFiber ; /* single fiber checkpoints: is number of points valid */ if (pointsPerFiber > 1) { /* operate on points of single fiber */ for (int i=0; i 0) { /* The color value of the current point is influenced by the previous point and next point. */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; vnl_vector_fixed< double, 3 > diff; diff = (diff1 - diff2) / 2.0; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if (i==0) { /* First point has no previous point, therefore only diff1 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; diff1.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff1[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff1[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff1[2])); rgba[3] = (unsigned char) (255.0); } else if (i==pointsPerFiber-1) { /* Last point has no next point, therefore only diff2 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; diff2.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff2[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff2[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff2[2])); rgba[3] = (unsigned char) (255.0); } colorsT->InsertTupleValue(idList[i], rgba); } //end for loop } else if (pointsPerFiber == 1) { /* a single point does not define a fiber (use vertex mechanisms instead */ continue; // colorsT->InsertTupleValue(0, rgba); } else { MITK_INFO << "Fiber with 0 points detected... please check your tractography algorithm!" ; continue; } }//end for loop m_FiberPolyData->GetPointData()->AddArray(colorsT); /*========================= - this is more relevant for renderer than for fiberbundleX datastructure - think about sourcing this to a explicit method which coordinates colorcoding */ this->SetColorCoding(COLORCODING_ORIENTATION_BASED); m_isModified = true; // =========================== //mini test, shall be ported to MITK TESTINGS! if (colorsT->GetSize() != numOfPoints*componentSize) { MITK_INFO << "ALLOCATION ERROR IN INITIATING COLOR ARRAY"; } } void mitk::FiberBundleX::DoGenerateFiberIds() { if (m_FiberPolyData == NULL) return; // for (int i=0; i<10000000; ++i) // { // if(i%500 == 0) // MITK_INFO << i; // } // MITK_INFO << "Generating Fiber Ids"; vtkSmartPointer idFiberFilter = vtkSmartPointer::New(); idFiberFilter->SetInput(m_FiberPolyData); idFiberFilter->CellIdsOn(); // idFiberFilter->PointIdsOn(); // point id's are not needed idFiberFilter->SetIdsArrayName(FIBER_ID_ARRAY); idFiberFilter->FieldDataOn(); idFiberFilter->Update(); m_FiberIdDataSet = idFiberFilter->GetOutput(); MITK_INFO << "Generating Fiber Ids...[done] | " << m_FiberIdDataSet->GetNumberOfCells(); } //temporarely include only #include //========================== std::vector mitk::FiberBundleX::DoExtractFiberIds(mitk::PlanarFigure::Pointer pf) { /* Handle type of planarfigure */ // if incoming pf is a pfc mitk::PlanarFigureComposite::Pointer pfcomp= dynamic_cast(pf.GetPointer()); if (!pfcomp.IsNull()) { // process requested boolean operation of PFC } else { mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); Vector3D planeNormal = planeGeometry->GetNormal(); planeNormal.Normalize(); Point3D planeOrigin = planeGeometry->GetOrigin(); MITK_INFO << "planeOrigin: " << planeOrigin[0] << " | " << planeOrigin[1] << " | " << planeOrigin[2] << endl; MITK_INFO << "planeNormal: " << planeNormal[0] << " | " << planeNormal[1] << " | " << planeNormal[2] << endl; } } /* init necessary vectors hosting pointIds and FiberIds */ // contains all pointIds which are crossing the cutting plane std::vector PointsOnPlane; // based on PointsOnPlane, all ROI relevant point IDs are stored here std::vector PointsInROI; // vector which is returned, contains all extracted FiberIds std::vector FibersInROI; /* Define cutting plane by ROI (PlanarFigure) */ vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetOrigin(10.0,5.0,0.0); plane->SetNormal(0.0,1.0,0.0); //same plane but opposite normal direction. so point cloud will be reduced -> better performance vtkSmartPointer planeR = vtkSmartPointer::New(); planeR->SetOrigin(10.0,5.0,0.0); planeR->SetNormal(0.0,-1.0,0.0); /* get all points/fibers cutting the plane */ vtkSmartPointer clipper = vtkSmartPointer::New(); clipper->SetInput(m_FiberIdDataSet); clipper->SetClipFunction(plane); clipper->GenerateClipScalarsOn(); clipper->GenerateClippedOutputOn(); vtkSmartPointer clipperout1 = clipper->GetClippedOutput(); /* for some reason clipperoutput is not initialized for futher processing * so far only writing out clipped polydata provides requested */ vtkSmartPointer writerC = vtkSmartPointer::New(); writerC->SetInput(clipperout1); writerC->SetFileName("/vtkOutput/Cout1_FbId_clipLineId0+1+2-tests.vtk"); writerC->SetFileTypeToASCII(); writerC->Write(); vtkSmartPointer Rclipper = vtkSmartPointer::New(); Rclipper->SetInput(clipperout1); Rclipper->SetClipFunction(planeR); Rclipper->GenerateClipScalarsOn(); Rclipper->GenerateClippedOutputOn(); vtkSmartPointer clipperout = Rclipper->GetClippedOutput(); vtkSmartPointer writerC1 = vtkSmartPointer::New(); writerC1->SetInput(clipperout); writerC1->SetFileName("/vtkOutput/FbId_clipLineId0+1+2-tests.vtk"); writerC1->SetFileTypeToASCII(); writerC1->Write(); /*======STEP 1====== * extract all points, which are crossing the plane */ // Scalar values describe the distance between each remaining point to the given plane. Values sorted by point index vtkSmartPointer distanceList = clipperout->GetPointData()->GetScalars(); vtkIdType sizeOfList = distanceList->GetNumberOfTuples(); PointsOnPlane.reserve(sizeOfList); /* use reserve for high-performant push_back, no hidden copy procedures are processed then! * size of list can be optimized by reducing allocation, but be aware of iterator and vector size*/ for (int i=0; iGetTuple(i); std::cout << "distance of point " << i << " : " << distance[0] << std::endl; // check if point is on plane. // 0.01 due to some approximation errors when calculating distance if (distance[0] >= -0.01 && distance[0] <= 0.01) { std::cout << "adding " << i << endl; PointsOnPlane.push_back(i); //push back in combination with reserve is fastest way to fill vector with various values } } // DEBUG print out all interesting points, stop where array starts with value -1. after -1 no more interesting idx are set! std::vector::iterator rit = PointsOnPlane.begin(); while (rit != PointsOnPlane.end() ) { std::cout << "interesting point: " << *rit << " coord: " << clipperout->GetPoint(*rit)[0] << " | " << clipperout->GetPoint(*rit)[1] << " | " << clipperout->GetPoint(*rit)[2] << endl; rit++; } /*=======STEP 2===== * extract ROI relevant pointIds */ //ToDo if( true /*point in ROI*/) { PointsInROI = PointsOnPlane; } /*======STEP 3======= * identify fiberIds for points in ROI */ //prepare resulting vector FibersInROI.reserve(PointsInROI.size()); vtkCellArray *clipperlines = clipperout->GetLines(); clipperlines->InitTraversal(); long numOfLineCells = clipperlines->GetNumberOfCells(); // go through resulting "sub"lines which are stored as cells, "i" corresponds to current line id. for (int i=0, ic=0 ; iGetCell(ic, npts, pts); // go through point ids in hosting subline, "j" corresponds to current pointindex in current line i. for (long j=0; jGetCellData()->HasArray("FB_IDs")) { int originalFibId = clipperout->GetCellData()->GetArray("FB_IDs")->GetTuple(i)[0]; std::cout << "found pointid " << PointsInROI[k] << ": " << clipperout->GetPoint(PointsInROI[k])[0] << " | " << clipperout->GetPoint(PointsInROI[k])[1] << " | " << clipperout->GetPoint(PointsInROI[k])[2] << " in subline: " << i << " which belongs to fiber id: " << originalFibId << "\n" << endl; // do something to avoid duplicates int oldFibInRoiSize = FibersInROI.size(); if (oldFibInRoiSize != 0) { for (int f=0; f::iterator finIt = FibersInROI.begin(); while ( finIt != FibersInROI.end() ) { std::cout << *finIt << endl; ++finIt; } std::cout << "=====================\n"; } void mitk::FiberBundleX::UpdateFiberGeometry() { - - + if (m_NumFibers<=0) + { + mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); + geometry->SetImageGeometry(true); + float b[] = {0, 1, 0, 1, 0, 1}; + geometry->SetFloatBounds(b); + SetGeometry(geometry); + return; + } float min = itk::NumericTraits::min(); float max = itk::NumericTraits::max(); float b[] = {max, min, max, min, max, min}; vtkCellArray* cells = m_FiberPolyData->GetLines(); cells->InitTraversal(); for (int i=0; iGetNumberOfCells(); i++) { - vtkCell* cell = m_FiberPolyData->GetCell(i); int p = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, p); if (p[0]b[1]) b[1]=p[0]; if (p[1]b[3]) b[3]=p[1]; if (p[2]b[5]) b[5]=p[2]; - - } - } - // provide some buffer space at borders - - for(int i=0; i<=4; i+=2){ + // provide some border margin + for(int i=0; i<=4; i+=2) b[i] -=10; - } - - for(int i=1; i<=5; i+=2){ + for(int i=1; i<=5; i+=2) b[i] +=10; - } mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetImageGeometry(true); geometry->SetFloatBounds(b); this->SetGeometry(geometry); - - - - } -/*============================== - *++++ FIBER INFORMATION +++++++ - ===============================*/ - QStringList mitk::FiberBundleX::GetAvailableColorCodings() { QStringList availableColorCodings; int numColors = m_FiberPolyData->GetPointData()->GetNumberOfArrays(); for(int i=0; iGetPointData()->GetArrayName(i)); } //this controlstructure shall be implemented by the calling method if (availableColorCodings.isEmpty()) MITK_INFO << "no colorcodings available in fiberbundleX"; // for(int i=0; im_currentColorCoding; + return m_currentColorCoding; } void mitk::FiberBundleX::SetColorCoding(const char* requestedColorCoding) { - // MITK_INFO << "FbX try to set colorCoding: " << requestedColorCoding << " compare with: " << COLORCODING_ORIENTATION_BASED; - if(strcmp (COLORCODING_ORIENTATION_BASED,requestedColorCoding) == 0 ) - { - this->m_currentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; - this->m_isModified = true; - - } else if(strcmp (COLORCODING_FA_BASED,requestedColorCoding) == 0 ) { - this->m_currentColorCoding = (char*) COLORCODING_FA_BASED; - this->m_isModified = true; - } else { - MITK_INFO << "FIBERBUNDLE X: UNKNOWN COLORCODING in FIBERBUNDLEX Datastructure"; - this->m_currentColorCoding = "---"; //will cause blank colorcoding of fibers - this->m_isModified = true; - } + if (requestedColorCoding==NULL) + return; + if(strcmp (COLORCODING_ORIENTATION_BASED,requestedColorCoding) == 0 ) + { + this->m_currentColorCoding = (char*) COLORCODING_ORIENTATION_BASED; + this->m_isModified = true; + + } else if(strcmp (COLORCODING_FA_BASED,requestedColorCoding) == 0 ) { + this->m_currentColorCoding = (char*) COLORCODING_FA_BASED; + this->m_isModified = true; + } else { + MITK_INFO << "FIBERBUNDLE X: UNKNOWN COLORCODING in FIBERBUNDLEX Datastructure"; + this->m_currentColorCoding = "---"; //will cause blank colorcoding of fibers + this->m_isModified = true; + } } bool mitk::FiberBundleX::isFiberBundleXModified() { return m_isModified; } void mitk::FiberBundleX::setFBXModificationDone() { m_isModified = false; } +void mitk::FiberBundleX::ResampleFibers() +{ + mitk::Geometry3D::Pointer geometry = GetGeometry(); + mitk::Vector3D spacing = geometry->GetSpacing(); + + float minSpacing = 1; + if(spacing[0] newPoly = vtkSmartPointer::New(); vtkSmartPointer newCellArray = vtkSmartPointer::New(); vtkSmartPointer newPoints = vtkSmartPointer::New(); vtkSmartPointer vLines = m_FiberPolyData->GetLines(); vLines->InitTraversal(); int numberOfLines = m_NumFibers; for (int i=0; iGetNextCell ( numPoints, points ); vtkSmartPointer container = vtkSmartPointer::New(); double* point = m_FiberPolyData->GetPoint(points[0]); vtkIdType pointId = newPoints->InsertNextPoint(point); container->GetPointIds()->InsertNextId(pointId); float dtau = 0; int cur_p = 1; itk::Vector dR; float normdR = 0; for (;;) { while (dtau <= len && cur_p < numPoints) { itk::Vector v1; point = m_FiberPolyData->GetPoint(points[cur_p-1]); v1[0] = point[0]; v1[1] = point[1]; v1[2] = point[2]; itk::Vector v2; point = m_FiberPolyData->GetPoint(points[cur_p]); v2[0] = point[0]; v2[1] = point[1]; v2[2] = point[2]; dR = v2 - v1; normdR = std::sqrt(dR.GetSquaredNorm()); dtau += normdR; cur_p++; } if (dtau >= len) { itk::Vector v1; point = m_FiberPolyData->GetPoint(points[cur_p-1]); v1[0] = point[0]; v1[1] = point[1]; v1[2] = point[2]; itk::Vector v2 = v1 - dR*( (dtau-len)/normdR ); pointId = newPoints->InsertNextPoint(v2.GetDataPointer()); container->GetPointIds()->InsertNextId(pointId); } else { point = m_FiberPolyData->GetPoint(points[numPoints-1]); pointId = newPoints->InsertNextPoint(point); container->GetPointIds()->InsertNextId(pointId); break; } dtau = dtau-len; } newCellArray->InsertNextCell(container); } newPoly->SetPoints(newPoints); newPoly->SetLines(newCellArray); m_FiberPolyData = newPoly; UpdateFiberGeometry(); } /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundleX::UpdateOutputInformation() { } void mitk::FiberBundleX::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundleX::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundleX::VerifyRequestedRegion() { return true; } void mitk::FiberBundleX::SetRequestedRegion( itk::DataObject *data ) { } diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h index 400c9cbc2d..78e8aa1e63 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h @@ -1,107 +1,107 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision: 11989 $ 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. =========================================================================*/ /* =============== IMPORTANT TODO =================== * ==== USE vtkSmartPointer<> when necessary ONLY!!!! */ #ifndef _MITK_FiberBundleX_H #define _MITK_FiberBundleX_H //includes for MITK datastructure #include #include "MitkDiffusionImagingExports.h" //includes storing fiberdata #include //may be replaced by class precompile argument #include // may be replaced by class #include // my be replaced by class #include #include #include namespace mitk { /** * \brief Base Class for Fiber Bundles; */ class MitkDiffusionImaging_EXPORT FiberBundleX : public BaseData { public: - // names of certain arrays (e.g colorcodings, etc.) static const char* COLORCODING_ORIENTATION_BASED; static const char* COLORCODING_FA_BASED; static const char* FIBER_ID_ARRAY; -// friend class FiberBundleXWriter; -// friend class FiberBundleXReader; - virtual void UpdateOutputInformation(); virtual void SetRequestedRegionToLargestPossibleRegion(); virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); virtual bool VerifyRequestedRegion(); virtual void SetRequestedRegion( itk::DataObject *data ); mitkClassMacro( FiberBundleX, BaseData ) itkNewMacro( Self ) mitkNewMacro1Param(Self, vtkSmartPointer) // custom constructor // set/get vtkPolyData void SetFiberPolyData(vtkSmartPointer, bool updateGeometry = true); vtkSmartPointer GetFiberPolyData(); + mitk::FiberBundleX::Pointer operator+(mitk::FiberBundleX* fib); + mitk::FiberBundleX::Pointer operator-(mitk::FiberBundleX* fib); + char* GetCurrentColorCoding(); void SetColorCoding(const char*); bool isFiberBundleXModified(); void setFBXModificationDone(); QStringList GetAvailableColorCodings(); void DoColorCodingOrientationbased(); void DoGenerateFiberIds(); void ResampleFibers(float len); + void ResampleFibers(); std::vector DoExtractFiberIds(mitk::PlanarFigure::Pointer ); itkGetMacro(NumFibers, int); + mitk::FiberBundleX::Pointer GetDeepCopy(); + protected: - FiberBundleX( vtkSmartPointer fiberPolyData = NULL ); + FiberBundleX( vtkPolyData* fiberPolyData = NULL ); virtual ~FiberBundleX(); void UpdateFiberGeometry(); + itk::Point GetItkPoint(double point[3]); private: // actual fiber container vtkSmartPointer m_FiberPolyData; // contains all additional IDs of Fibers which are needed for efficient fiber manipulation such as extracting etc. vtkSmartPointer m_FiberIdDataSet; char* m_currentColorCoding; - - //this flag concerns only visual representation. bool m_isModified; - - bool m_NumFibers; + int m_NumFibers; }; } // namespace mitk #endif /* _MITK_FiberBundleX_H */ diff --git a/Modules/DiffusionImaging/files.cmake b/Modules/DiffusionImaging/files.cmake index 4b6926c52b..3e2044b204 100644 --- a/Modules/DiffusionImaging/files.cmake +++ b/Modules/DiffusionImaging/files.cmake @@ -1,182 +1,183 @@ SET(CPP_FILES # DicomImport DicomImport/mitkDicomDiffusionImageReader.cpp DicomImport/mitkGroupDiffusionHeadersFilter.cpp DicomImport/mitkDicomDiffusionImageHeaderReader.cpp DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp DicomImport/mitkPhilipsDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp # DataStructures IODataStructures/mitkDiffusionImagingObjectFactory.cpp # DataStructures -> DWI IODataStructures/DiffusionWeightedImages/mitkDiffusionImageHeaderInformation.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriter.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageIOFactory.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriterFactory.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSerializer.cpp # DataStructures -> QBall IODataStructures/QBallImages/mitkQBallImageSource.cpp IODataStructures/QBallImages/mitkNrrdQBallImageReader.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriter.cpp IODataStructures/QBallImages/mitkNrrdQBallImageIOFactory.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriterFactory.cpp IODataStructures/QBallImages/mitkQBallImage.cpp IODataStructures/QBallImages/mitkQBallImageSerializer.cpp # DataStructures -> Tensor IODataStructures/TensorImages/mitkTensorImageSource.cpp IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriter.cpp IODataStructures/TensorImages/mitkNrrdTensorImageIOFactory.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriterFactory.cpp IODataStructures/TensorImages/mitkTensorImage.cpp IODataStructures/TensorImages/mitkTensorImageSerializer.cpp # DataStructures -> FiberBundle IODataStructures/FiberBundle/mitkFiberBundle.cpp IODataStructures/FiberBundle/mitkFiberBundleWriter.cpp IODataStructures/FiberBundle/mitkFiberBundleReader.cpp IODataStructures/FiberBundle/mitkFiberBundleIOFactory.cpp IODataStructures/FiberBundle/mitkFiberBundleWriterFactory.cpp IODataStructures/FiberBundle/mitkFiberBundleSerializer.cpp IODataStructures/FiberBundle/mitkParticle.cpp IODataStructures/FiberBundle/mitkParticleGrid.cpp # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriter.cpp IODataStructures/FiberBundleX/mitkFiberBundleXReader.cpp IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.cpp IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.cpp IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.cpp # DataStructures -> PlanarFigureComposite IODataStructures/PlanarFigureComposite/mitkPlanarFigureComposite.cpp # DataStructures -> Tbss IODataStructures/TbssImages/mitkTbssImageSource.cpp IODataStructures/TbssImages/mitkTbssRoiImageSource.cpp IODataStructures/TbssImages/mitkNrrdTbssImageReader.cpp IODataStructures/TbssImages/mitkNrrdTbssImageIOFactory.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageReader.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageIOFactory.cpp IODataStructures/TbssImages/mitkTbssImage.cpp IODataStructures/TbssImages/mitkTbssRoiImage.cpp IODataStructures/TbssImages/mitkTbssGradientImage.cpp IODataStructures/TbssImages/mitkNrrdTbssImageWriter.cpp IODataStructures/TbssImages/mitkNrrdTbssImageWriterFactory.cpp IODataStructures/TbssImages/mitkNrrdTbssGradientImageWriter.cpp IODataStructures/TbssImages/mitkNrrdTbssGradientImageWriterFactory.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageWriter.cpp IODataStructures/TbssImages/mitkNrrdTbssRoiImageWriterFactory.cpp IODataStructures/TbssImages/mitkTbssImporter.cpp # Rendering Rendering/vtkMaskedProgrammableGlyphFilter.cpp Rendering/mitkCompositeMapper.cpp Rendering/mitkVectorImageVtkGlyphMapper3D.cpp Rendering/vtkOdfSource.cxx Rendering/vtkThickPlane.cxx Rendering/mitkOdfNormalizationMethodProperty.cpp Rendering/mitkOdfScaleByProperty.cpp Rendering/mitkFiberBundleMapper2D.cpp Rendering/mitkFiberBundleMapper3D.cpp Rendering/mitkFiberBundleXMapper2D.cpp Rendering/mitkFiberBundleXMapper3D.cpp Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp Rendering/mitkTbssImageMapper.cpp Rendering/mitkTbssGradientImageMapper.cpp Rendering/mitkPlanarCircleMapper3D.cpp Rendering/mitkPlanarPolygonMapper3D.cpp - + # Interactions Interactions/mitkFiberBundleInteractor.cpp # Algorithms Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.cpp # Tractography Tractography/itkStochasticTractographyFilter.h ) SET(H_FILES # Rendering Rendering/mitkDiffusionImageMapper.h Rendering/mitkTbssImageMapper.h Rendering/mitkTbssGradientImageMapper.h Rendering/mitkOdfVtkMapper2D.h Rendering/mitkFiberBundleMapper2D.h Rendering/mitkFiberBundleMapper3D.h Rendering/mitkFiberBundleXMapper3D.h Rendering/mitkFiberBundleXMapper2D.h Rendering/mitkFiberBundleXThreadMonitorMapper3D.h Rendering/mitkPlanarCircleMapper3D.h Rendering/mitkPlanarPolygonMapper3D.h # Reconstruction Reconstruction/itkDiffusionQballReconstructionImageFilter.h Reconstruction/mitkTeemDiffusionTensor3DReconstructionImageFilter.h Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h Reconstruction/itkPointShell.h Reconstruction/itkOrientationDistributionFunction.h Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h Reconstruction/itkRegularizedIVIMLocalVariationImageFilter.h Reconstruction/itkRegularizedIVIMReconstructionFilter.h Reconstruction/itkRegularizedIVIMReconstructionSingleIteration.h # IO Datastructures IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h - IODataStructures/FiberBundle/itkSlowPolyLineParametricPath.h + IODataStructures/FiberBundle/itkSlowPolyLineParametricPath.h # DataStructures -> FiberBundleX IODataStructures/FiberBundleX/mitkFiberBundleX.h IODataStructures/FiberBundleX/mitkFiberBundleXWriter.h IODataStructures/FiberBundleX/mitkFiberBundleXReader.h IODataStructures/FiberBundleX/mitkFiberBundleXIOFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXWriterFactory.h IODataStructures/FiberBundleX/mitkFiberBundleXSerializer.h IODataStructures/FiberBundleX/mitkFiberBundleXThreadMonitor.h # Tractography Tractography/itkGibbsTrackingFilter.h Tractography/itkStochasticTractographyFilter.h # Algorithms Algorithms/itkDiffusionQballGeneralizedFaImageFilter.h Algorithms/itkDiffusionQballPrepareVisualizationImageFilter.h Algorithms/itkTensorDerivedMeasurementsFilter.h Algorithms/itkBrainMaskExtractionImageFilter.h Algorithms/itkB0ImageExtractionImageFilter.h Algorithms/itkTensorImageToDiffusionImageFilter.h Algorithms/itkTensorToL2NormImageFilter.h - Algorithms/itkTractsToProbabilityImageFilter.h + Algorithms/itkTractDensityImageFilter.h Algorithms/itkTractsToFiberEndingsImageFilter.h + Algorithms/itkTractsToRgbaImageFilter.h Algorithms/itkGaussianInterpolateImageFunction.h Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.h Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.h Algorithms/itkDiffusionTensorPrincipleDirectionImageFilter.h Algorithms/itkCartesianToPolarVectorImageFilter.h Algorithms/itkPolarToCartesianVectorImageFilter.h ) SET( TOOL_FILES ) IF(WIN32) ENDIF(WIN32) #MITK_MULTIPLEX_PICTYPE( Algorithms/mitkImageRegistrationMethod-TYPE.cpp )