diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/Manual.dox
index a393144a4d..c1a5768584 100644
--- a/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/Manual.dox
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/Manual.dox
@@ -1,18 +1,25 @@
/**
\page org_mitk_gui_qt_classificationsegmentation The Classificationsegmentation Plugin
-\imageMacro{icon.png,"Icon of Classificationsegmentation Plugin",2.00}
+\imageMacro{brain.png,"Icon of Classificationsegmentation Plugin",2.00}
\tableofcontents
\section org_mitk_gui_qt_classificationsegmentationOverview Overview
Segmentation of the classes:
- CSF (value of 1)
- Lesion (value of 2)
- Brain (value of 3)
using a random forest based approach.
+
+Credits (from the Noun Project):
+
+- Brain by Santiago Arias
+
- process by Marek Polakovic
+
- process by Takao Umehara
+
*/
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/brain.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/brain.png
new file mode 100644
index 0000000000..7d4f578611
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/documentation/UserManual/brain.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/files.cmake b/Plugins/org.mitk.gui.qt.classificationsegmentation/files.cmake
index 30bca606c4..bc0dcc0253 100644
--- a/Plugins/org.mitk.gui.qt.classificationsegmentation/files.cmake
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/files.cmake
@@ -1,42 +1,43 @@
set(SRC_CPP_FILES
)
set(INTERNAL_CPP_FILES
org_mitk_gui_qt_classificationsegmentation_Activator.cpp
ClassificationSegmentation.cpp
)
set(UI_FILES
src/internal/ClassificationSegmentationControls.ui
)
set(MOC_H_FILES
src/internal/org_mitk_gui_qt_classificationsegmentation_Activator.h
src/internal/ClassificationSegmentation.h
)
# list of resource files which can be used by the plug-in
# system without loading the plug-ins shared library,
# for example the icon used in the menu and tabs for the
# plug-in views in the workbench
set(CACHED_RESOURCE_FILES
- resources/icon.xpm
+ resources/icon_32.png
+ resources/icon.png
plugin.xml
)
# list of Qt .qrc files which contain additional resources
# specific to this plugin
set(QRC_FILES
-
+ resources/ClassificationSegmentation.qrc
)
set(CPP_FILES )
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/plugin.xml b/Plugins/org.mitk.gui.qt.classificationsegmentation/plugin.xml
index 5b660a172b..1c6fe0f4e2 100644
--- a/Plugins/org.mitk.gui.qt.classificationsegmentation/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/plugin.xml
@@ -1,11 +1,11 @@
+ icon="resources/icon_32.png" />
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/ClassificationSegmentation.qrc b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/ClassificationSegmentation.qrc
new file mode 100644
index 0000000000..0b1bca7399
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/ClassificationSegmentation.qrc
@@ -0,0 +1,8 @@
+
+
+ button_process.png
+ icon_32.png
+ icon.png
+ button_process_2.png
+
+
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/button_process.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/button_process.png
new file mode 100644
index 0000000000..b3f8793fed
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/button_process.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/button_process_2.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/button_process_2.png
new file mode 100644
index 0000000000..299ed61966
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/button_process_2.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/icon.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/icon.png
new file mode 100644
index 0000000000..8f19299ca9
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/icon.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/icon_32.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/icon_32.png
new file mode 100644
index 0000000000..873ca9a67d
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/icon_32.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_brain.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_brain.png
new file mode 100644
index 0000000000..21cb7453dd
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_brain.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_process.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_process.png
new file mode 100644
index 0000000000..5151551999
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_process.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_process_2.png b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_process_2.png
new file mode 100644
index 0000000000..135f32752d
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.classificationsegmentation/resources/orig_process_2.png differ
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.cpp b/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.cpp
index 7890b625d2..9935907978 100644
--- a/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.cpp
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.cpp
@@ -1,963 +1,984 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include
#include
// Qmitk
#include "ClassificationSegmentation.h"
// Qt
#include
//mitk image
#include
#include
#include
#include
#include
#include
#include "mitkVigraRandomForestClassifier.h"
#include "mitkCLUtil.h"
#include "qboxlayout.h"
#include
#include "Eigen/Dense"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
const std::string ClassificationSegmentation::VIEW_ID = "org.mitk.views.classificationsegmentation";
void ClassificationSegmentation::SetFocus()
{
// m_Controls.buttonPerformImageProcessing->setFocus();
}
void ClassificationSegmentation::OnButtonCSFToggle(bool checked)
{
// m_PointListWidget->SetPointSet(dynamic_cast(m_PointSetList[0]->GetData()));
if(checked)
m_PointSetDataInteractor->SetDataNode(m_PointSetList[0]);
else
m_PointSetDataInteractor->SetDataNode(nullptr);
}
void ClassificationSegmentation::OnButtonLESToggle(bool checked)
{
// m_PointListWidget->SetPointSet(dynamic_cast(m_PointSetList[1]->GetData()));
if(checked)
m_PointSetDataInteractor->SetDataNode(m_PointSetList[1]);
else
m_PointSetDataInteractor->SetDataNode(nullptr);
}
void ClassificationSegmentation::OnButtonBRAToggle(bool checked)
{
// m_PointListWidget->SetPointSet(dynamic_cast(m_PointSetList[2]->GetData()));
if(checked)
m_PointSetDataInteractor->SetDataNode(m_PointSetList[2]);
else
m_PointSetDataInteractor->SetDataNode(nullptr);
}
void ClassificationSegmentation::OnButtonNoInteractionToggle(bool checked)
{
if(checked)
m_PointSetDataInteractor->SetDataNode(nullptr);
}
void ClassificationSegmentation::CreateQtPartControl( QWidget *parent )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls.setupUi( parent );
m_CalculateFeatures = true;
m_BlockManualSegmentation = false;
m_BlockPostProcessing = false;
QmitkDataStorageComboBox * cb_inputimage = new QmitkDataStorageComboBox(this->GetDataStorage(), mitk::TNodePredicateDataType::New());
QmitkDataStorageComboBox * cb_maskimage= new QmitkDataStorageComboBox(this->GetDataStorage(),mitk::TNodePredicateDataType::New());
QmitkDataStorageComboBox * cb_classifer= new QmitkDataStorageComboBox(this->GetDataStorage(),mitk::TNodePredicateDataType::New());
m_Controls.m_InputImageLayout->addWidget(cb_inputimage);
m_Controls.m_MaskImageLayout->addWidget(cb_maskimage);
- m_Controls.m_RandomForestLayout->addWidget(cb_classifer);
+ m_Controls.m_ClassifierLayout->addWidget(cb_classifer);
m_Controls.m_ParameterLayout->layout()->addWidget(new QLabel("Gauss Sigma"));
m_GaussSlider = new ctkSliderWidget();
m_GaussSlider->setMinimum(0);
m_GaussSlider->setMaximum(10);
m_GaussSlider->setValue(1);
m_Controls.m_ParameterLayout->layout()->addWidget(m_GaussSlider);
m_Controls.m_ParameterLayout->layout()->addWidget(new QLabel("Hessian Sigma"));
m_HessianSlider = new ctkSliderWidget();
m_HessianSlider->setMinimum(0);
m_HessianSlider->setMaximum(10);
m_HessianSlider->setValue(3);
m_Controls.m_ParameterLayout->layout()->addWidget(m_HessianSlider);
m_Controls.m_ParameterLayout->layout()->addWidget(new QLabel("Structure Tensor Inner and Outer Scale"));
m_STInnerSlider = new ctkSliderWidget();
m_STInnerSlider->setMinimum(0);
m_STInnerSlider->setMaximum(10);
m_STInnerSlider->setValue(1.5);
m_Controls.m_ParameterLayout->layout()->addWidget(m_STInnerSlider);
m_STOuterSlider = new ctkSliderWidget();
m_STOuterSlider->setMinimum(0);
m_STOuterSlider->setMaximum(10);
m_STOuterSlider->setValue(3);
m_Controls.m_ParameterLayout->layout()->addWidget(m_STOuterSlider);
m_Controls.m_PostProcessingLayout->layout()->addWidget(new QLabel("Probability map smoothing"));
m_GaussCSFSlider = new ctkSliderWidget;
m_GaussCSFSlider->setMinimum(0);
m_GaussCSFSlider->setMaximum(10);
m_GaussCSFSlider->setValue(1.5);
m_Controls.m_PostProcessingLayout->layout()->addWidget(m_GaussCSFSlider);
m_GaussLESSlider = new ctkSliderWidget;
m_GaussLESSlider->setMinimum(0);
m_GaussLESSlider->setMaximum(10);
m_GaussLESSlider->setValue(3);
m_Controls.m_PostProcessingLayout->layout()->addWidget(m_GaussLESSlider);
m_GaussBRASlider = new ctkSliderWidget;
m_GaussBRASlider->setMinimum(0);
m_GaussBRASlider->setMaximum(10);
m_GaussBRASlider->setValue(0.5);
m_Controls.m_PostProcessingLayout->layout()->addWidget(m_GaussBRASlider);
m_Controls.m_PostProcessingLayout->layout()->addWidget(new QLabel("Probability map weighting"));
m_WeightCSFSlider = new ctkSliderWidget;
m_WeightCSFSlider->setMinimum(0.0);
m_WeightCSFSlider->setMaximum(2.0);
m_WeightCSFSlider->setValue(1.0);
m_WeightCSFSlider->setSingleStep(0.1);
m_Controls.m_PostProcessingLayout->layout()->addWidget(m_WeightCSFSlider);
m_WeightLESSlider = new ctkSliderWidget;
m_WeightLESSlider->setMinimum(0.0);
m_WeightLESSlider->setMaximum(2.0);
m_WeightLESSlider->setValue(1.0);
m_WeightLESSlider->setSingleStep(0.1);
m_Controls.m_PostProcessingLayout->layout()->addWidget(m_WeightLESSlider);
m_WeightBRASlider = new ctkSliderWidget;
m_WeightBRASlider->setMinimum(0.0);
m_WeightBRASlider->setMaximum(2.0);
m_WeightBRASlider->setValue(1.0);
m_WeightBRASlider->setSingleStep(0.1);
m_Controls.m_PostProcessingLayout->layout()->addWidget(m_WeightBRASlider);
m_PointSetDataInteractor = mitk::PointSetDataInteractor::New();
m_PointSetDataInteractor->LoadStateMachine("PointSet.xml");
m_PointSetDataInteractor->SetEventConfig("PointSetConfig.xml");
connect( cb_inputimage, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnInitializeSession(const mitk::DataNode*)));
connect( cb_maskimage, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnInitializeSession(const mitk::DataNode*)));
- connect( cb_classifer, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnInitializeSession(const mitk::DataNode*)));
- connect( cb_inputimage, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnInitializeSession(const mitk::DataNode*)));
+
connect( m_Controls.m_SavePointsButton, SIGNAL(clicked(bool)), this, SLOT(DoSavePointsAsMask()));
- connect( m_Controls.m_StartProcessingButton_RF, SIGNAL(clicked()), this, SLOT(DoAutomSegmentation()) );
connect( m_Controls.m_ButtonCSFToggle, SIGNAL(toggled(bool)), this, SLOT(OnButtonCSFToggle(bool)));
connect( m_Controls.m_ButtonLESToggle, SIGNAL(toggled(bool)), this, SLOT(OnButtonLESToggle(bool)));
connect( m_Controls.m_ButtonBRAToggle, SIGNAL(toggled(bool)), this, SLOT(OnButtonBRAToggle(bool)));
connect( m_Controls.m_ButtonNoInteraction, SIGNAL(toggled(bool)), this, SLOT(OnButtonNoInteractionToggle(bool)));
connect( &m_ManualSegmentationFutureWatcher, SIGNAL(finished()), this, SLOT(ManualSegmentationFinished()));
connect( &m_PostProcessingFutureWatcher, SIGNAL(finished()), this, SLOT(PostProcessingFinished()));
//connect( m_Controls.m_AddPointSets, SIGNAL(clicked()),this, SLOT(OnAddPointSets()) );
connect( m_GaussSlider, SIGNAL(valueChanged(double)), this, SLOT(OnFeatureSettingsChanged()));
connect( m_HessianSlider, SIGNAL(valueChanged(double)), this, SLOT(OnFeatureSettingsChanged()));
connect( m_STInnerSlider, SIGNAL(valueChanged(double)), this, SLOT(OnFeatureSettingsChanged()));
connect( m_STOuterSlider, SIGNAL(valueChanged(double)), this, SLOT(OnFeatureSettingsChanged()));
connect( m_GaussCSFSlider, SIGNAL(valueChanged(double)), this, SLOT(OnPostProcessingSettingsChanged()));
connect( m_GaussLESSlider, SIGNAL(valueChanged(double)), this, SLOT(OnPostProcessingSettingsChanged()));
connect( m_GaussBRASlider, SIGNAL(valueChanged(double)), this, SLOT(OnPostProcessingSettingsChanged()));
connect( m_WeightCSFSlider, SIGNAL(valueChanged(double)), this, SLOT(OnPostProcessingSettingsChanged()));
connect( m_WeightLESSlider, SIGNAL(valueChanged(double)), this, SLOT(OnPostProcessingSettingsChanged()));
connect( m_WeightBRASlider, SIGNAL(valueChanged(double)), this, SLOT(OnPostProcessingSettingsChanged()));
+ connect(m_Controls.m_DoAutomaticSecmentation, SIGNAL(clicked(bool)), this, SLOT(DoAutomSegmentation()));
+ connect(m_Controls.m_AddForestToDataManager, SIGNAL(clicked(bool)), this, SLOT(OnAddForestToDataManager()));
+
mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New();
pointSetNode->SetName("CSF_Points.");
pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true));
pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024));
pointSetNode->SetColor(0,1.0,0);
pointSetNode->SetDataInteractor(m_PointSetDataInteractor.GetPointer());
m_PointSetList.push_back(pointSetNode);
GetDataStorage()->Add(pointSetNode);
pointSetNode = mitk::DataNode::New();
pointSetNode->SetName("LES_Points.");
pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true));
pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024));
pointSetNode->SetColor(1.0,0,0);
pointSetNode->SetDataInteractor(m_PointSetDataInteractor.GetPointer());
m_PointSetList.push_back(pointSetNode);
GetDataStorage()->Add(pointSetNode);
pointSetNode = mitk::DataNode::New();
pointSetNode->SetName("BRA_Points.");
pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true));
pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024));
pointSetNode->SetColor(0,0,1.0);
pointSetNode->SetDataInteractor(m_PointSetDataInteractor.GetPointer());
m_PointSetList.push_back(pointSetNode);
GetDataStorage()->Add(pointSetNode);
+
+
+ m_Controls.m_PostProcessingLayout->hide();
+ m_Controls.m_ParameterLayout->hide();
}
void ClassificationSegmentation::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/,
- const QList& nodes )
+ const QList& nodes )
{
// iterate all selected objects, adjust warning visibility
foreach( mitk::DataNode::Pointer node, nodes )
{
if( node.IsNotNull() && dynamic_cast(node->GetData()) )
{
// m_Controls.labelWarning->setVisible( false );
// m_Controls.buttonPerformImageProcessing->setEnabled( true );
return;
}
}
// m_Controls.labelWarning->setVisible( true );
// m_Controls.buttonPerformImageProcessing->setEnabled( false );
}
+void ClassificationSegmentation::OnAddForestToDataManager()
+{
+ AddAsDataNode(m_TempClassifier.GetPointer(),"ManualSegmentation_Classifier");
+}
+
void ClassificationSegmentation::OnInitializeSession(const mitk::DataNode *)
{
MITK_WARN << "Data selection changed! New session initialized.";
m_PointSetDataInteractor->SetDataNode(nullptr);
/// CSF POINTSET
mitk::PointSet::Pointer pntset = mitk::PointSet::New();
m_PointSetList[0]->SetData(pntset);
itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &ClassificationSegmentation::ManualSegmentationTrigger);
pntset->AddObserver( mitk::PointSetAddEvent(), command );
pntset->AddObserver( mitk::PointSetRemoveEvent(), command );
pntset->AddObserver( mitk::PointSetMoveEvent(), command );
/// LES POINTSET
pntset = mitk::PointSet::New();
m_PointSetList[1]->SetData(pntset);
command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &ClassificationSegmentation::ManualSegmentationTrigger);
pntset->AddObserver( mitk::PointSetAddEvent(), command );
pntset->AddObserver( mitk::PointSetRemoveEvent(), command );
pntset->AddObserver( mitk::PointSetMoveEvent(), command );
/// BRA POINTSET
pntset = mitk::PointSet::New();
m_PointSetList[2]->SetData(pntset);
command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &ClassificationSegmentation::ManualSegmentationTrigger);
pntset->AddObserver( mitk::PointSetAddEvent(), command );
pntset->AddObserver( mitk::PointSetRemoveEvent(), command );
pntset->AddObserver( mitk::PointSetMoveEvent(), command );
- m_Controls.m_NumCsfPoints->setText(QString::number(dynamic_cast(m_PointSetList[0]->GetData())->GetSize()));
- m_Controls.m_NumLesPoints->setText(QString::number(dynamic_cast(m_PointSetList[1]->GetData())->GetSize()));
- m_Controls.m_NumBraPoints->setText(QString::number(dynamic_cast(m_PointSetList[2]->GetData())->GetSize()));
}
void ClassificationSegmentation::DoSavePointsAsMask()
{
mitk::Image::Pointer sampled_image = nullptr;
QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls.m_InputImageLayout->itemAt(1)->widget());
mitk::Image::Pointer raw_image = dynamic_cast(cb_image->GetSelectedNode()->GetData());
int label = 1;
for( auto datanode : m_PointSetList)
{
mitk::PointSet::Pointer point_set = dynamic_cast(datanode->GetData());
mitk::Image::Pointer temp_img;
SampleClassMaskByPointSet(raw_image, point_set,temp_img);
mitk::CLUtil::InsertLabel(temp_img,sampled_image,label++);
QmitkIOUtil::Save(datanode->GetData(),QString("PointSet.mps"));
}
QmitkIOUtil::Save(sampled_image,QString("PointSetMask.nrrd"));
}
void ClassificationSegmentation::ProcessFeatureImages(const mitk::Image::Pointer & raw_image, const mitk::Image::Pointer & brain_mask)
{
typedef itk::Image DoubleImageType;
typedef itk::Image ShortImageType;
typedef itk::ConstNeighborhoodIterator NeighborhoodType; // Neighborhood iterator to access image
typedef itk::Functor::NeighborhoodFirstOrderStatistics FunctorType;
typedef itk::NeighborhoodFunctorImageFilter FOSFilerType;
typedef FOSFilerType::MaskImageType MaskImageType;
m_FeatureImageVector.clear();
// RAW
m_FeatureImageVector.push_back(raw_image);
// GAUSS
mitk::Image::Pointer smoothed;
mitk::CLUtil::GaussianFilter(raw_image,smoothed,m_GaussSlider->value());
m_FeatureImageVector.push_back(smoothed);
// Calculate Probability maps (parameters used from literatur)
// CSF
mitk::Image::Pointer csf_prob = mitk::Image::New();
mitk::CLUtil::ProbabilityMap(smoothed,13.9, 8.3,csf_prob);
m_FeatureImageVector.push_back(csf_prob);
// Lesion
mitk::Image::Pointer les_prob = mitk::Image::New();
mitk::CLUtil::ProbabilityMap(smoothed,59, 11.6,les_prob);
m_FeatureImageVector.push_back(les_prob);
// Barin (GM/WM)
mitk::Image::Pointer brain_prob = mitk::Image::New();
mitk::CLUtil::ProbabilityMap(smoothed,32, 5.6,brain_prob);
m_FeatureImageVector.push_back(brain_prob);
std::vector FOS_sizes;
FOS_sizes.push_back(1);
DoubleImageType::Pointer input;
ShortImageType::Pointer mask;
mitk::CastToItkImage(smoothed, input);
mitk::CastToItkImage(brain_mask, mask);
for(unsigned int i = 0 ; i < FOS_sizes.size(); i++)
{
FOSFilerType::Pointer filter = FOSFilerType::New();
filter->SetNeighborhoodSize(FOS_sizes[i]);
filter->SetInput(input);
filter->SetMask(mask);
filter->Update();
FOSFilerType::DataObjectPointerArray array = filter->GetOutputs();
for( unsigned int i = 0; i < FunctorType::OutputCount; i++)
{
mitk::Image::Pointer featureimage;
mitk::CastToMitkImage(dynamic_cast(array[i].GetPointer()),featureimage);
m_FeatureImageVector.push_back(featureimage);
// AddImageAsDataNode(featureimage,FunctorType::GetFeatureName(i))->SetVisibility(show_nodes);
}
}
{
itk::HessianMatrixEigenvalueImageFilter< DoubleImageType >::Pointer filter = itk::HessianMatrixEigenvalueImageFilter< DoubleImageType >::New();
filter->SetInput(input);
filter->SetImageMask(mask);
filter->SetSigma(m_HessianSlider->value());
filter->Update();
mitk::Image::Pointer o1,o2,o3;
mitk::CastToMitkImage(filter->GetOutput(0),o1);
mitk::CastToMitkImage(filter->GetOutput(1),o2);
mitk::CastToMitkImage(filter->GetOutput(2),o3);
m_FeatureImageVector.push_back(o1);
m_FeatureImageVector.push_back(o2);
m_FeatureImageVector.push_back(o3);
// AddImageAsDataNode(o1,"HE_1")->SetVisibility(show_nodes);
// AddImageAsDataNode(o2,"HE_2")->SetVisibility(show_nodes);
// AddImageAsDataNode(o3,"HE_3")->SetVisibility(show_nodes);
}
{
itk::StructureTensorEigenvalueImageFilter< DoubleImageType >::Pointer filter = itk::StructureTensorEigenvalueImageFilter< DoubleImageType >::New();
filter->SetInput(input);
filter->SetImageMask(mask);
filter->SetInnerScale(m_STInnerSlider->value());
filter->SetOuterScale(m_STOuterSlider->value());
filter->Update();
mitk::Image::Pointer o1,o2,o3;
mitk::CastToMitkImage(filter->GetOutput(0),o1);
mitk::CastToMitkImage(filter->GetOutput(1),o2);
mitk::CastToMitkImage(filter->GetOutput(2),o3);
m_FeatureImageVector.push_back(o1);
m_FeatureImageVector.push_back(o2);
m_FeatureImageVector.push_back(o3);
// AddImageAsDataNode(o1,"ST_1")->SetVisibility(show_nodes);
// AddImageAsDataNode(o2,"ST_2")->SetVisibility(show_nodes);
// AddImageAsDataNode(o3,"ST_3")->SetVisibility(show_nodes);
}
{
itk::LineHistogramBasedMassImageFilter< DoubleImageType >::Pointer filter = itk::LineHistogramBasedMassImageFilter< DoubleImageType >::New();
filter->SetInput(input);
filter->SetImageMask(mask);
filter->Update();
mitk::Image::Pointer o1;
mitk::CastToMitkImage(filter->GetOutput(0),o1);
m_FeatureImageVector.push_back(o1);
}
}
void ClassificationSegmentation::OnFeatureSettingsChanged()
{
MITK_INFO << "FeatureSettingsChanged";
m_CalculateFeatures = true;
ManualSegmentationTrigger();
}
void ClassificationSegmentation::OnPostProcessingSettingsChanged()
{
MITK_INFO << "PostProcessingSettigsChanged";
PostProcessingTrigger();
}
void ClassificationSegmentation::DoAutomSegmentation()
{
QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls.m_InputImageLayout->itemAt(1)->widget());
mitk::Image::Pointer raw_image = dynamic_cast(cb_image->GetSelectedNode()->GetData());
QmitkDataStorageComboBox * cb_maskimage = dynamic_cast(m_Controls.m_MaskImageLayout->itemAt(1)->widget());
- QmitkDataStorageComboBox * cb_rf = dynamic_cast(m_Controls.m_RandomForestLayout->itemAt(1)->widget());
+ QmitkDataStorageComboBox * cb_rf = dynamic_cast(m_Controls.m_ClassifierLayout->itemAt(1)->widget());
mitk::Image::Pointer mask_image = dynamic_cast(cb_maskimage->GetSelectedNode()->GetData());
mitk::VigraRandomForestClassifier::Pointer classifier = dynamic_cast(cb_rf->GetSelectedNode()->GetData());
if(m_CalculateFeatures)
{
ProcessFeatureImages(raw_image,mask_image);
m_CalculateFeatures = false;
}
Eigen::MatrixXd X_test;
unsigned int count_test = 0;
mitk::CLUtil::CountVoxel(mask_image, count_test);
X_test = Eigen::MatrixXd(count_test, m_FeatureImageVector.size());
unsigned int index = 0;
for( const auto & image : m_FeatureImageVector)
{
X_test.col(index) = mitk::CLUtil::Transform(image,mask_image);
++index;
}
Eigen::MatrixXi Y_test = classifier->Predict(X_test);
mitk::Image::Pointer result_mask = mitk::CLUtil::Transform(Y_test,mask_image);
- AddImageAsDataNode(result_mask,"Autom-ResultMask");
+ auto node = AddAsDataNode(result_mask.GetPointer(),"Autom-ResultMask");
+
+ auto lut = mitk::LookupTable::New();
+ lut->SetType(mitk::LookupTable::PET_20);
+ auto * lut_prop = dynamic_cast(node->GetProperty("LookupTable"));
+ lut_prop->SetLookupTable(lut);
+
+ mitk::LevelWindow lw(1,3);
+ node->SetLevelWindow(lw);
+ node->SetOpacity(0.3);
std::map perlabelvoxelcount;
mitk::CLUtil::CountVoxel(result_mask, perlabelvoxelcount);
double voxel_volume = result_mask->GetGeometry()->GetSpacing().GetVnlVector().inf_norm();
QString newtext;
newtext += "Name\tVolume\tUnit\n";
for(const auto & pair: perlabelvoxelcount)
{
newtext += "Label" + QString::number(pair.first) + "\t" + QString::number(pair.second*voxel_volume* 0.001) + "\tml\n";
}
m_Controls.m_ResultTextEdit->setText(newtext);
}
std::vector ClassificationSegmentation::ManualSegmentationCallback()
{
QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls.m_InputImageLayout->itemAt(1)->widget());
QmitkDataStorageComboBox * cb_maskimage = dynamic_cast(m_Controls.m_MaskImageLayout->itemAt(1)->widget());
mitk::Image::Pointer raw_image = dynamic_cast(cb_image->GetSelectedNode()->GetData());
mitk::Image::Pointer mask_image = dynamic_cast(cb_maskimage->GetSelectedNode()->GetData());
if(raw_image.IsNull() || mask_image.IsNull())
{
MITK_WARN << "Please provide input iamge and mask image";
//return nullptr;
}
if(m_CalculateFeatures)
{
ProcessFeatureImages(raw_image,mask_image);
m_CalculateFeatures = false;
}
mitk::Image::Pointer sampled_image = nullptr;
int label = 1;
for( auto datanode : m_PointSetList)
{
mitk::PointSet::Pointer point_set = dynamic_cast(datanode->GetData());
mitk::Image::Pointer temp_img;
SampleClassMaskByPointSet(raw_image, point_set,temp_img);
mitk::CLUtil::InsertLabel(temp_img,sampled_image,label++);
}
- mitk::VigraRandomForestClassifier::Pointer classifier = mitk::VigraRandomForestClassifier::New();
- classifier->SetTreeCount(50);
- classifier->SetSamplesPerTree(0.66);
+ m_TempClassifier = mitk::VigraRandomForestClassifier::New();
+ m_TempClassifier->SetTreeCount(50);
+ m_TempClassifier->SetSamplesPerTree(0.66);
Eigen::MatrixXd X_train;
Eigen::MatrixXd X_test;
unsigned int count_train = 0;
unsigned int count_test = 0;
mitk::CLUtil::CountVoxel(sampled_image, count_train);
mitk::CLUtil::CountVoxel(mask_image, count_test);
X_train = Eigen::MatrixXd(count_train, m_FeatureImageVector.size() );
X_test = Eigen::MatrixXd(count_test, m_FeatureImageVector.size());
unsigned int index = 0;
for( const auto & image : m_FeatureImageVector)
{
X_train.col(index) = mitk::CLUtil::Transform(image,sampled_image);
X_test.col(index) = mitk::CLUtil::Transform(image,mask_image);
++index;
}
Eigen::MatrixXi Y = mitk::CLUtil::Transform(sampled_image,sampled_image);
- classifier->Train(X_train,Y);
+ m_TempClassifier->Train(X_train,Y);
- Eigen::MatrixXi Y_test = classifier->Predict(X_test);
- Eigen::MatrixXd Yp_test = classifier->GetPointWiseProbabilities();
+ Eigen::MatrixXi Y_test = m_TempClassifier->Predict(X_test);
+ Eigen::MatrixXd Yp_test = m_TempClassifier->GetPointWiseProbabilities();
// mitk::Image::Pointer result_mask = mitk::CLUtil::Transform(Y_test,mask_image);
std::vector resultvector;
resultvector.push_back( mitk::CLUtil::Transform(Y_test,mask_image) );
resultvector.push_back( mitk::CLUtil::Transform(Yp_test.col(0),mask_image) );
resultvector.push_back( mitk::CLUtil::Transform(Yp_test.col(1),mask_image) );
resultvector.push_back( mitk::CLUtil::Transform(Yp_test.col(2),mask_image) );
return resultvector;
}
void ClassificationSegmentation::ManualSegmentationFinished()
{
// Receive Future result
m_ResultImageVector = m_ManualSegmentationFutureWatcher.result();
// Add result to Datastorage
- mitk::DataNode::Pointer node = AddImageAsDataNode(m_ResultImageVector[0],"Manual-ResultMask");
+ mitk::DataNode::Pointer node = AddAsDataNode(m_ResultImageVector[0].GetPointer(),"Manual-ResultMask");
mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
lut->SetType(mitk::LookupTable::PET_20);
mitk::LookupTableProperty * lut_prop = dynamic_cast(node->GetProperty("LookupTable"));
lut_prop->SetLookupTable(lut);
mitk::LevelWindow lw(1,3);
node->SetLevelWindow(lw);
node->SetOpacity(0.3);
m_BlockManualSegmentation = false;
this->PostProcessingTrigger();
// Update Volume data
std::map perlabelvoxelcount;
mitk::CLUtil::CountVoxel(m_ResultImageVector[0], perlabelvoxelcount);
double voxel_volume = m_ResultImageVector[0]->GetGeometry()->GetSpacing().GetVnlVector().inf_norm();
QString newtext;
newtext += "Name\tVolume\tUnit\n";
for(const auto & pair: perlabelvoxelcount)
newtext += "Label" + QString::number(pair.first) + "\t" + QString::number(pair.second*voxel_volume* 0.001) + "\tml\n";
m_Controls.m_ResultTextEdit->setText(newtext);
- // Enable Functionality
- m_Controls.m_StartProcessingButton_RF->setDisabled(false);
+
}
void ClassificationSegmentation::ManualSegmentationTrigger()
{
- m_Controls.m_NumCsfPoints->setText(QString::number(dynamic_cast(m_PointSetList[0]->GetData())->GetSize()));
- m_Controls.m_NumLesPoints->setText(QString::number(dynamic_cast(m_PointSetList[1]->GetData())->GetSize()));
- m_Controls.m_NumBraPoints->setText(QString::number(dynamic_cast(m_PointSetList[2]->GetData())->GetSize()));
-
unsigned int samplecounter = 0;
for( auto datanode : m_PointSetList)
{
mitk::PointSet::Pointer point_set = dynamic_cast(datanode->GetData());
samplecounter += point_set->GetSize();
}
if(samplecounter < 10) return;
if(!m_BlockManualSegmentation){
- // Disable Functionality
- m_Controls.m_StartProcessingButton_RF->setDisabled(true);
// Start GUI Thread
m_ManualSegmentationFutureWatcher.setFuture(
- QtConcurrent::run(this, &ClassificationSegmentation::ManualSegmentationCallback)); // on finish call OnManualSegmentationFinished();
+ QtConcurrent::run(this, &ClassificationSegmentation::ManualSegmentationCallback)); // on finish call OnManualSegmentationFinished();
m_BlockManualSegmentation = true;
}
}
void ClassificationSegmentation::SampleClassMaskByPointSet(const mitk::Image::Pointer & ref_img, mitk::PointSet::Pointer & pointset, mitk::Image::Pointer & outimage)
{
outimage = ref_img->Clone();
itk::Image::Pointer itk_out;
mitk::CastToItkImage(outimage,itk_out);
itk_out->FillBuffer(0);
typedef itk::ImageRegionIteratorWithIndex > IteratorType;
IteratorType oit(itk_out, itk_out->GetLargestPossibleRegion());
for(int i = 0 ; i < pointset->GetSize(); ++i)
{
IteratorType::IndexType index;
ref_img->GetGeometry()->WorldToIndex(pointset->GetPoint(i), index);
oit.SetIndex(index);
oit.Set(1);
}
mitk::CastToMitkImage(itk_out,outimage);
}
// old version
//void ClassificationSegmentation::DoImageProcessing()
//{
// QmitkDataStorageComboBox * cb_image = dynamic_cast(m_Controls.m_InputImageLayout->itemAt(1)->widget());
// QmitkDataStorageComboBox * cb_maskimage = dynamic_cast(m_Controls.m_MaskImageLayout->itemAt(1)->widget());
// QmitkDataStorageComboBox * cb_classifier = dynamic_cast(m_Controls.m_RandomForestLayout->itemAt(1)->widget());
// if (cb_image == nullptr || cb_classifier == nullptr || cb_maskimage == nullptr)
// {
// QMessageBox::information( NULL, "Template", "Please load and select an image before starting image processing.");
// return;
// }
// mitk::VigraRandomForestClassifier::Pointer rf = dynamic_cast(cb_classifier->GetSelectedNode()->GetData());
// mitk::Image::Pointer image = dynamic_cast(cb_image->GetSelectedNode()->GetData());
// mitk::Image::Pointer mask = dynamic_cast(cb_maskimage->GetSelectedNode()->GetData());
// unsigned int n_samples = 0;
// mitk::CLUtil::CountVoxel(mask, n_samples);
// unsigned int n_features = 13; // InputImage, PROBA_CSF, PROBA_LES, PROBA_BRA, FOS_MEAN,FOS_VARIANCE,FOS_SKEWNESS, FOS_KURTOSIS, FOS_MIN, FOS_MAX, HE_1, HE_2, HE_3
// Eigen::MatrixXd feature_matrix = Eigen::MatrixXd(n_samples, n_features);
// MITK_INFO << "Remove voxels outside the mask";
// // mitk::CLUtil::LogicalAndImages(image,brain_mask,image);
// feature_matrix.block(0,0,n_samples,1) = mitk::CLUtil::Transform(image,mask);
// AddImageAsDataNode(image, "UI_InputImage");
// mitk::Image::Pointer csf_prob = mitk::Image::New();
// mitk::CLUtil::ProbabilityMap(image,13.9, 8.3,csf_prob);
// feature_matrix.block(0,1,n_samples,1) = mitk::CLUtil::Transform(csf_prob,mask);
// AddImageAsDataNode(csf_prob, "UI_CSFProb");
// mitk::Image::Pointer les_prob = mitk::Image::New();
// mitk::CLUtil::ProbabilityMap(image,59, 11.6,les_prob);
// feature_matrix.block(0,2,n_samples,1) = mitk::CLUtil::Transform(les_prob,mask);
// AddImageAsDataNode(les_prob, "UI_LESProb");
// mitk::Image::Pointer brain_prob = mitk::Image::New();
// mitk::CLUtil::ProbabilityMap(image,32, 5.6,brain_prob);
// feature_matrix.block(0,3,n_samples,1) = mitk::CLUtil::Transform(brain_prob,mask);
// AddImageAsDataNode(brain_prob, "UI_BRAProb");
// int n = 0;
// std::vector res;
// DoFirstOrderFeatureCalculation(image, mask, 1, res);
// for( const auto & img: res)
// {
// feature_matrix.block(0,3+(++n),n_samples,1) = mitk::CLUtil::Transform(img,mask);
// std::string name;
// img->GetPropertyList()->GetStringProperty("name", name);
// AddImageAsDataNode(img.GetPointer(), name );
// }
// res.clear();
// DoHessianEigenvaluesFeatureCalculation(image, mask, 3.0, res);
// for( const auto & img: res)
// {
// feature_matrix.block(0,3+(++n),n_samples,1) = mitk::CLUtil::Transform(img,mask);
// std::string name;
// img->GetPropertyList()->GetStringProperty("name", name);
// AddImageAsDataNode(img.GetPointer(), name );
// }
// MITK_INFO << "Start Prediction";
// rf->Predict(feature_matrix);
// MITK_INFO << "End Prediction";
// mitk::Image::Pointer result_image = mitk::CLUtil::Transform(rf->GetLabels(),mask);
// mitk::Image::Pointer proba1_image = mitk::CLUtil::Transform(rf->GetPointWiseProbabilities().col(0),mask);
// mitk::Image::Pointer proba2_image = mitk::CLUtil::Transform(rf->GetPointWiseProbabilities().col(1),mask);
// mitk::Image::Pointer proba3_image = mitk::CLUtil::Transform(rf->GetPointWiseProbabilities().col(2),mask);
// AddImageAsDataNode(result_image, "ClassificationResult");
// AddImageAsDataNode(proba1_image, "CSF_Proba_CL");
// AddImageAsDataNode(proba2_image, "LES_Proba_CL");
// AddImageAsDataNode(proba3_image, "BRA_Proba_CL");
// PostProcessing(rf,mask);
//}
-mitk::DataNode::Pointer ClassificationSegmentation::AddImageAsDataNode(const mitk::Image::Pointer & data_image, const std::string & name )
+mitk::DataNode::Pointer ClassificationSegmentation::AddAsDataNode(const mitk::BaseData::Pointer & data_, const std::string & name )
{
mitk::DataNode::Pointer node = nullptr;
node = this->GetDataStorage()->GetNamedNode(name);
if(node.IsNull())
{
node = mitk::DataNode::New();
- node->SetData(data_image);
+ node->SetData(data_);
node->SetName(name);
this->GetDataStorage()->Add(node);
}else{
- mitk::ImageReadAccessor ra(data_image);
- mitk::Image::Pointer image = dynamic_cast(node->GetData());
- image->SetImportVolume(const_cast(ra.GetData()));
- this->RequestRenderWindowUpdate();
+
+ if(dynamic_cast(node->GetData()) && dynamic_cast(data_.GetPointer()))
+ {
+ mitk::Image::Pointer target_image = dynamic_cast(node->GetData());
+ mitk::Image::Pointer source_image = dynamic_cast(data_.GetPointer());
+ mitk::ImageReadAccessor ra(source_image);
+ target_image->SetImportVolume(const_cast(ra.GetData()));
+ this->RequestRenderWindowUpdate();
+ }
+
+ if(dynamic_cast(node->GetData()) && dynamic_cast(data_.GetPointer()))
+ {
+ node->SetData(data_);
+ node->Modified();
+ }
+
}
return node;
}
void ClassificationSegmentation::PostProcessingTrigger()
{
if(m_ResultImageVector.empty() || m_ResultImageVector.size() < 4)
{
MITK_ERROR("PostProcessingCallback") << "Result image vector not initialized!";
return;
}
if(!m_BlockPostProcessing){
m_PostProcessingFutureWatcher.setFuture(
- QtConcurrent::run(this, &ClassificationSegmentation::PostProcessingCallback)); // on finish call OnManualSegmentationFinished();
+ QtConcurrent::run(this, &ClassificationSegmentation::PostProcessingCallback)); // on finish call OnManualSegmentationFinished();
m_BlockPostProcessing = true;
}
}
void ClassificationSegmentation::PostProcessingFinished()
{
// Receive Future result
m_PostProcessingImageVector = m_PostProcessingFutureWatcher.result();
// Add result to Datastorage
- mitk::DataNode::Pointer node = AddImageAsDataNode(m_PostProcessingImageVector[0],"Manual-ResultMask-PostProcessing");
+ mitk::DataNode::Pointer node = AddAsDataNode(m_PostProcessingImageVector[0].GetPointer(),"Manual-ResultMask-PostProcessing");
mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
lut->SetType(mitk::LookupTable::PET_20);
mitk::LookupTableProperty * lut_prop = dynamic_cast(node->GetProperty("LookupTable"));
lut_prop->SetLookupTable(lut);
mitk::LevelWindow lw(1,3);
node->SetLevelWindow(lw);
node->SetOpacity(0.3);
m_BlockPostProcessing = false;
}
std::vector ClassificationSegmentation::PostProcessingCallback()
{
std::vector resultvector;
mitk::Image::Pointer CSF_PMap = m_ResultImageVector[1]->Clone();
mitk::Image::Pointer LES_PMap = m_ResultImageVector[2]->Clone();
mitk::Image::Pointer BRA_PMap = m_ResultImageVector[3]->Clone();
mitk::Image::Pointer mask = m_ResultImageVector[0]->Clone();
typedef itk::Image TImageType;
MITK_INFO("PostProcessingCallback") << "ProbabilityMap merg strat ...";
{
mitk::Image::Pointer resultmask = mask->Clone();
mitk::CLUtil::GaussianFilter(CSF_PMap, CSF_PMap, m_GaussCSFSlider->value());
mitk::CLUtil::GaussianFilter(LES_PMap, LES_PMap, m_GaussLESSlider->value());
mitk::CLUtil::GaussianFilter(BRA_PMap, BRA_PMap, m_GaussBRASlider->value());
itk::Image::Pointer itk_csf, itk_les, itk_bra;
itk::Image::Pointer itk_result;
mitk::CastToItkImage(CSF_PMap, itk_csf);
mitk::CastToItkImage(LES_PMap, itk_les);
mitk::CastToItkImage(BRA_PMap, itk_bra);
mitk::CastToItkImage(resultmask, itk_result);
itk::ImageRegionIterator > it_csf(itk_csf,itk_csf->GetLargestPossibleRegion());
itk::ImageRegionIterator > it_les(itk_les,itk_les->GetLargestPossibleRegion());
itk::ImageRegionIterator > it_bra(itk_bra,itk_bra->GetLargestPossibleRegion());
itk::ImageRegionIterator > it_res(itk_result,itk_result->GetLargestPossibleRegion());
while (!it_csf.IsAtEnd()) {
double csf = it_csf.Value() * m_WeightCSFSlider->value();
double les = it_les.Value() * m_WeightLESSlider->value();
double bra = it_bra.Value() * m_WeightBRASlider->value();
if(csf > les && csf > bra) it_res.Set(1);
if(les > csf && les > bra) it_res.Set(2);
if(bra > les && bra > csf) it_res.Set(3);
++it_csf;
++it_les;
++it_bra;
++it_res;
}
mitk::CastToMitkImage(itk_result, resultmask);
{
std::map mergeinstruction ;
mergeinstruction[1] = 1;
mergeinstruction[2] = 1;
mergeinstruction[3] = 1;
mergeinstruction[4] = 1;
mergeinstruction[5] = 1;
mergeinstruction[6] = 1;
// {{1,1},{2,1},{3,1},{4,1},{5,1},{6,1}};
mitk::Image::Pointer brain_mask = mask->Clone();
mitk::CLUtil::MergeLabels(brain_mask, mergeinstruction);
mitk::CLUtil::ClosingBinary(brain_mask,brain_mask,2,mitk::CLUtil::All);
mitk::CLUtil::LogicalAndImages(resultmask, brain_mask, resultmask);
}
MITK_INFO("PostProcessingCallback") << "ProbabilityMap merg end!";
resultvector.push_back(resultmask);
}
return resultvector;
// {
// MITK_INFO << "Morphological processing strat ...";
// mitk::Image::Pointer resultmask = mask->Clone();
// mitk::Image::Pointer csf_mask;
// mitk::CLUtil::GrabLabel(resultmask, csf_mask, 1);
// mitk::CLUtil::ClosingBinary(csf_mask,csf_mask,1,mitk::CLUtil::Axial);
// mitk::CLUtil::ErodeBinary(csf_mask, csf_mask, 2, mitk::CLUtil::Axial);
// mitk::CLUtil::DilateBinary(csf_mask, csf_mask, 1, mitk::CLUtil::Axial);
// std::map merge_instruction = {{0,0},{1,3},{2,2},{3,3}};
// mitk::CLUtil::MergeLabels(resultmask, merge_instruction);
// mitk::CLUtil::InsertLabel(resultmask, csf_mask, 1/*as csf mask*/); // add morpological manipulated csf_mask
// // ------------
// mitk::Image::Pointer les_mask;
// mitk::CLUtil::GrabLabel(resultmask, les_mask, 2);
// mitk::CLUtil::ClosingBinary(les_mask,les_mask,1,mitk::CLUtil::Axial);
// mitk::Image::Pointer les_cc_mask; unsigned int num = 0;
// mitk::CLUtil::ConnectedComponentsImage(les_mask, mask, les_cc_mask, num);
// std::map map;
// mitk::CLUtil::CountVoxel(les_cc_mask,map);
// unsigned int counter = 0;
// while(map.size() > 2)
// {
// mitk::CLUtil::ErodeBinary(les_mask, les_mask, 1, mitk::CLUtil::Axial);
// mitk::CLUtil::LogicalAndImages(les_cc_mask,les_mask,les_cc_mask);
// map.clear();
// mitk::CLUtil::CountVoxel(les_cc_mask,map);
// MITK_INFO("PostProcessing") << map.size();
// counter++;
// }
// while(counter != 0)
// {
// mitk::CLUtil::DilateBinary(les_mask, les_mask, 1, mitk::CLUtil::Axial);
// counter--;
// }
// merge_instruction = {{0,0},{1,1},{2,3},{3,3}};
// mitk::CLUtil::MergeLabels(resultmask, merge_instruction);
// mitk::CLUtil::InsertLabel(resultmask, les_mask, 2/*as les mask*/);
// MITK_INFO << "Morphological processing end";
// // ------------
// mitk::CLUtil::LogicalAndImages(resultmask,mask,resultmask);
// AddImageAsDataNode(resultmask,"SmoothedMaskMorphed");
// }
}
// mitk::Image::Pointer r= mitk::Image::New(),g= mitk::Image::New(),b = mitk::Image::New();
// unsigned int* m_ImageDimensions;
// m_ImageDimensions = new unsigned int[3];
// m_ImageDimensions[0] = raw_image->GetDimensions()[0];
// m_ImageDimensions[1] = raw_image->GetDimensions()[1];
// m_ImageDimensions[2] = 1;
// r->Initialize( mitk::MakePixelType() ,3,m_ImageDimensions);
// g->Initialize( mitk::MakePixelType() ,3,m_ImageDimensions);
// b->Initialize( mitk::MakePixelType() ,3,m_ImageDimensions);
// mitk::ImageReadAccessor inputAccForRGB(raw_image, raw_image->GetSliceData(0,0,0));
// unsigned char* rbgSlice = (unsigned char*)inputAccForRGB.GetData();
// mitk::ImageReadAccessor inputAcc(r, r->GetSliceData(0,0,0));
// unsigned char* rData = (unsigned char*)inputAcc.GetData();
// mitk::ImageReadAccessor inputAcc2(g, g->GetSliceData(0,0,0));
// unsigned char* gData = (unsigned char*)inputAcc2.GetData();
// mitk::ImageReadAccessor inputAcc3(b, b->GetSliceData(0,0,0));
// unsigned char*
// bData = (unsigned char*)inputAcc3.GetData();
// for(int i = 0; i < m_ImageDimensions[0] * m_ImageDimensions[1]*3; i+=3)
// {
// rData[i/3] = rbgSlice[i];
// gData[i/3] = rbgSlice[i+1];
// bData[i/3] = rbgSlice[i+2];
// }
// m_FeatureImageVector.push_back(r);
// m_FeatureImageVector.push_back(g);
// m_FeatureImageVector.push_back(b);
// AddImageAsDataNode(r,"r");
// AddImageAsDataNode(g,"g");
// AddImageAsDataNode(b,"b");
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.h b/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.h
index 8b2290fa75..c7d23a30ad 100644
--- a/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.h
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentation.h
@@ -1,144 +1,145 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef ClassificationSegmentation_h
#define ClassificationSegmentation_h
#include
#include
#include "ui_ClassificationSegmentationControls.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "QmitkPointListViewWidget.h"
#include
+
+#include
/**
\brief ClassificationSegmentation
\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation.
\sa QmitkAbstractView
\ingroup ${plugin_target}_internal
*/
-namespace mitk{
- class VigraRandomForestClassifier;
-}
//class QmitkPointListWidget;
class ctkSliderWidget;
class ClassificationSegmentation : public QmitkAbstractView
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkPointListViewWidget * m_PointListWidget;
std::vector m_PointSetList;
bool m_CalculateFeatures;
std::vector m_FeatureImageVector;
std::vector m_ResultImageVector;
std::vector m_PostProcessingImageVector;
bool m_BlockManualSegmentation;
QFutureWatcher> m_ManualSegmentationFutureWatcher;
bool m_BlockPostProcessing;
QFutureWatcher> m_PostProcessingFutureWatcher;
protected slots:
/// \brief Called when the user clicks the GUI button
void DoAutomSegmentation();
void DoSavePointsAsMask();
void OnButtonCSFToggle(bool);
void OnButtonLESToggle(bool);
void OnButtonBRAToggle(bool);
void OnButtonNoInteractionToggle(bool);
+ void OnAddForestToDataManager();
void ManualSegmentationTrigger();
std::vector ManualSegmentationCallback();
void ManualSegmentationFinished();
void PostProcessingTrigger();
std::vector PostProcessingCallback();
void PostProcessingFinished();
void OnFeatureSettingsChanged();
void OnPostProcessingSettingsChanged();
void OnInitializeSession(const mitk::DataNode*);
protected:
typedef float MeasurementType;
typedef itk::Statistics::Histogram< MeasurementType,
itk::Statistics::DenseFrequencyContainer2 > HistogramType;
// void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart);
// void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart);
virtual void CreateQtPartControl(QWidget *parent) override;
virtual void SetFocus() override;
- mitk::DataNode::Pointer AddImageAsDataNode(const mitk::Image::Pointer & data_image, const std::string & name );
+ mitk::DataNode::Pointer AddAsDataNode(const mitk::BaseData::Pointer & data_, const std::string & name );
void SampleClassMaskByPointSet(const mitk::Image::Pointer & ref_img, mitk::PointSet::Pointer & pointset, mitk::Image::Pointer & outimage);
void ProcessFeatureImages(const mitk::Image::Pointer & raw_image, const mitk::Image::Pointer & mask_image);
/// \brief called by QmitkFunctionality when DataManager's selection has changed
virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source,
const QList& nodes ) override;
mitk::Image::Pointer CreateClassMaskByPointsetList(std::map a_args);
Ui::ClassificationSegmentationControls m_Controls;
// Feature settings
ctkSliderWidget * m_GaussSlider;
ctkSliderWidget * m_HessianSlider;
ctkSliderWidget * m_STInnerSlider;
ctkSliderWidget * m_STOuterSlider;
ctkSliderWidget * m_GaussCSFSlider;
ctkSliderWidget * m_GaussLESSlider;
ctkSliderWidget * m_GaussBRASlider;
ctkSliderWidget * m_WeightCSFSlider;
ctkSliderWidget * m_WeightLESSlider;
ctkSliderWidget * m_WeightBRASlider;
mitk::PointSetDataInteractor::Pointer m_PointSetDataInteractor;
+ mitk::VigraRandomForestClassifier::Pointer m_TempClassifier;
};
#endif // ClassificationSegmentation_h
diff --git a/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentationControls.ui b/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentationControls.ui
index 0a6b995ac5..e61b432f3a 100644
--- a/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentationControls.ui
+++ b/Plugins/org.mitk.gui.qt.classificationsegmentation/src/internal/ClassificationSegmentationControls.ui
@@ -1,261 +1,588 @@
ClassificationSegmentationControls
0
0
- 353
- 600
+ 352
+ 979
0
0
QmitkTemplate
+ -
+
+
+
+ 17
+ 75
+ true
+ false
+ false
+ PreferAntialias
+ true
+
+
+
+ Data selection
+
+
+
-
-
+
+
+ true
+
+
CT Head Image
-
-
+
+
+ true
+
+
Mask Image
-
-
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 0
+ 32
+
+
+
+
+ 17
+ 75
+ true
+ false
+ false
+ PreferAntialias
+ true
+
+
+
+ Automatic segmentation
+
+
+
+ -
+
+
+
+ 11
+
+
+
+ Show user information
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+ 0
+
-
-
+
+
+
+ true
+
+
- Random Forest
+ Classifier
-
-
-
- Automatic segmentation
+
+
+ 32
-
-
- -
-
-
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 64
+
+
+
+
+ 14
+ 75
+ true
+
+
- Add Class Seedpoints
+ Start classification
+
+
+
+ :/ClassificationSegmentation/button_process.png:/ClassificationSegmentation/button_process.png
+
+
+
+ 32
+ 32
+
+
+
+ Ctrl+A
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 0
+ 32
+
+
+
+
+ 17
+ 75
+ true
+ false
+ false
+ PreferAntialias
+ true
+
+
+
+ Manual segmentation
+
+
+
+ -
+
+
+
+ 11
+
+
+
+ Show user information
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+ 32
+
-
0
0
-
-
-
- #CSF
-
-
-
- -
-
-
- 0
-
-
-
- -
-
-
- #LES
+
+
+
+ 64
+ 64
+
-
-
- -
-
-
- 0
+
+
+ 64
+ 64
+
-
-
- -
-
-
- #BRA
+
+
+ 75
+ true
+
-
-
- -
-
-
- 0
+
+ background-color: #8AFF88
-
-
-
-
- -
-
-
-
-
- CSF (green)
+ CSF
true
true
-
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 75
+ true
+
+
+
+ background-color: #FF7E78
+
- Lesion (red)
+ Lesion
true
true
-
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 75
+ true
+
+
+
+ background-color: #4F9EE5
+
- Brain (blue)
+ Brain
true
true
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
-
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 75
+ true
+
+
- No interaction
+ Clear all
true
true
-
-
-
- Feature settings
-
-
-
-
- -
-
-
- Postprocessing settings
+
+
+ 32
-
-
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 64
+
+
+
+
+ 14
+ 75
+ true
+
+
+
+ Update result
+
+
+
+ :/ClassificationSegmentation/button_process_2.png:/ClassificationSegmentation/button_process_2.png
+
+
+
+ 32
+ 32
+
+
+
+ Ctrl+M
+
+
+ false
+
+
+
+
-
-
-
- Qt::Horizontal
+
+
+ 0
-
+
-
+
+
+ Add classifier to Data Manager
+
+
+
+
-
QLayout::SetMinAndMaxSize
10
10
-
-
+
- Clear points
+ Load pointsets
-
- Save points as mask
+ Save pointsets
-
Qt::Horizontal
-
+
+
+ 0
+ 100
+
+
+
+
+ 16777215
+ 250
+
+
false
true
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'.Helvetica Neue DeskInterface'; font-size:13pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Volumetric data...</p></body></html>
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Postprocessing settings
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+
+
+ -
+
+
+ true
+
+
+ Feature settings
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+
+
-
+
+
+