diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp index 8771895c49..ac71afffb9 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp @@ -1,379 +1,435 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkImageStatisticsView.h" #include // berry includes #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include "mitkPlanarFigureMaskGenerator.h" #include "QmitkImageStatisticsDataGenerator.h" #include "mitkImageStatisticsContainerManager.h" #include const std::string QmitkImageStatisticsView::VIEW_ID = "org.mitk.views.imagestatistics"; QmitkImageStatisticsView::~QmitkImageStatisticsView() { - if (nullptr != m_selectedPlanarFigure) - { - m_selectedPlanarFigure->RemoveObserver(m_PlanarFigureObserverTag); - } } void QmitkImageStatisticsView::CreateQtPartControl(QWidget *parent) { m_Controls.setupUi(parent); m_Controls.widget_histogram->SetTheme(GetColorTheme()); m_Controls.widget_intensityProfile->SetTheme(GetColorTheme()); m_Controls.groupBox_histogram->setVisible(true); m_Controls.groupBox_intensityProfile->setVisible(false); m_Controls.label_currentlyComputingStatistics->setVisible(false); m_Controls.sliderWidget_histogram->setPrefix("Time: "); m_Controls.sliderWidget_histogram->setDecimals(0); m_Controls.sliderWidget_histogram->setVisible(false); m_Controls.sliderWidget_intensityProfile->setPrefix("Time: "); m_Controls.sliderWidget_intensityProfile->setDecimals(0); m_Controls.sliderWidget_intensityProfile->setVisible(false); ResetGUI(); m_DataGenerator = new QmitkImageStatisticsDataGenerator(parent); m_DataGenerator->SetDataStorage(this->GetDataStorage()); m_DataGenerator->SetAutoUpdate(true); m_Controls.widget_statistics->SetDataStorage(this->GetDataStorage()); m_Controls.widget_histogram->SetTheme(GetColorTheme()); + + m_Controls.imageNodesSelector->SetDataStorage(this->GetDataStorage()); + m_Controls.imageNodesSelector->SetNodePredicate(mitk::GetImageStatisticsImagePredicate()); + m_Controls.imageNodesSelector->SetSelectionCheckFunction(this->CheckForSameGeometry()); + m_Controls.imageNodesSelector->SetSelectionIsOptional(false); + m_Controls.imageNodesSelector->SetInvalidInfo(QStringLiteral("Please select images for statistics")); + m_Controls.imageNodesSelector->SetPopUpTitel(QStringLiteral("Select input images")); + m_Controls.roiNodesSelector->SetPopUpHint(QStringLiteral("You may select multiple images for the statistics computation. But all selected images must have the same geometry.")); + + m_Controls.roiNodesSelector->SetDataStorage(this->GetDataStorage()); + m_Controls.roiNodesSelector->SetNodePredicate(this->GenerateROIPredicate()); + m_Controls.roiNodesSelector->SetSelectionIsOptional(true); + m_Controls.roiNodesSelector->SetEmptyInfo(QStringLiteral("Please select ROIs")); + m_Controls.roiNodesSelector->SetPopUpTitel(QStringLiteral("Select ROIs for statistics computation")); + m_Controls.roiNodesSelector->SetPopUpHint(QStringLiteral("You may select ROIs (e.g. planar figures, segmentations) that should be used for the statistics computation. The statistics will only computed for the image parts defined by the ROIs.")); + + CreateConnections(); } void QmitkImageStatisticsView::CreateConnections() { connect(m_Controls.checkBox_ignoreZero, &QCheckBox::stateChanged, this, &QmitkImageStatisticsView::OnCheckBoxIgnoreZeroStateChanged); connect(m_Controls.buttonSelection, &QAbstractButton::clicked, this, &QmitkImageStatisticsView::OnButtonSelectionPressed); connect(m_Controls.widget_histogram, &QmitkHistogramVisualizationWidget::RequestHistogramUpdate, this, &QmitkImageStatisticsView::OnRequestHistogramUpdate); connect(m_DataGenerator, &QmitkImageStatisticsDataGenerator::DataGenerationStarted, this, &QmitkImageStatisticsView::OnGenerationStarted); connect(m_DataGenerator, &QmitkImageStatisticsDataGenerator::GenerationFinished, this, &QmitkImageStatisticsView::OnGenerationFinished); connect(m_DataGenerator, &QmitkImageStatisticsDataGenerator::JobError, this, &QmitkImageStatisticsView::OnJobError); + connect(m_Controls.imageNodesSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, + this, &QmitkImageStatisticsView::OnImageSelectionChanged); + connect(m_Controls.roiNodesSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, + this, &QmitkImageStatisticsView::OnROISelectionChanged); } void QmitkImageStatisticsView::UpdateIntensityProfile() { m_Controls.groupBox_intensityProfile->setVisible(false); - if (m_selectedImageNodes.size()==1) + const auto selectedImageNodes = m_Controls.imageNodesSelector->GetSelectedNodes(); + const auto selectedROINodes = m_Controls.roiNodesSelector->GetSelectedNodes(); + + if (selectedImageNodes.size()==1 && selectedROINodes.size()==1) { //only supported for one image and roi currently - auto image = dynamic_cast(m_selectedImageNodes.front()->GetData()); + auto image = dynamic_cast(selectedImageNodes.front()->GetData()); + + mitk::PlanarFigure* maskPlanarFigure = dynamic_cast(selectedROINodes.front()->GetData()); - if (m_selectedPlanarFigure.IsNotNull()) + if (maskPlanarFigure != nullptr) { - if (!m_selectedPlanarFigure->IsClosed()) + if (!maskPlanarFigure->IsClosed()) { mitk::Image::Pointer inputImage; if (image->GetDimension() == 4) { m_Controls.sliderWidget_intensityProfile->setVisible(true); unsigned int maxTimestep = image->GetTimeSteps(); m_Controls.sliderWidget_intensityProfile->setMaximum(maxTimestep - 1); // Intensity profile can only be calculated on 3D, so extract if 4D mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); int currentTimestep = static_cast(m_Controls.sliderWidget_intensityProfile->value()); timeSelector->SetInput(image); timeSelector->SetTimeNr(currentTimestep); timeSelector->Update(); inputImage = timeSelector->GetOutput(); } else { m_Controls.sliderWidget_intensityProfile->setVisible(false); inputImage = image; } - auto intensityProfile = mitk::ComputeIntensityProfile(inputImage, m_selectedPlanarFigure); + auto intensityProfile = mitk::ComputeIntensityProfile(inputImage, maskPlanarFigure); m_Controls.groupBox_intensityProfile->setVisible(true); m_Controls.widget_intensityProfile->Reset(); m_Controls.widget_intensityProfile->SetIntensityProfile(intensityProfile.GetPointer(), - "Intensity Profile of " + m_selectedImageNodes.front()->GetName()); + "Intensity Profile of " + selectedImageNodes.front()->GetName()); } } } } void QmitkImageStatisticsView::UpdateHistogramWidget() { - m_Controls.groupBox_histogram->setVisible(true); + m_Controls.groupBox_histogram->setVisible(false); - if (m_selectedImageNodes.size() == 1 && m_selectedMaskNodes.size()<=1) + const auto selectedImageNodes = m_Controls.imageNodesSelector->GetSelectedNodes(); + const auto selectedMaskNodes = m_Controls.roiNodesSelector->GetSelectedNodes(); + + if (selectedImageNodes.size() == 1 && selectedMaskNodes.size()<=1) { //currently only supported for one image and roi due to histogram widget limitations. - auto imageNode = m_selectedImageNodes.front(); + auto imageNode = selectedImageNodes.front(); const mitk::DataNode* roiNode = nullptr; - if (!m_selectedMaskNodes.empty()) + const mitk::PlanarFigure* planarFigure = nullptr; + if (!selectedMaskNodes.empty()) { - roiNode = m_selectedMaskNodes.front(); + roiNode = selectedMaskNodes.front(); + planarFigure = dynamic_cast(roiNode->GetData()); } - auto statisticsNode = m_DataGenerator->GetLatestResult(imageNode, roiNode, true); - if (statisticsNode.IsNotNull()) - { - auto statistics = dynamic_cast(statisticsNode->GetData()); + if (planarFigure == nullptr || planarFigure->IsClosed()) + { //if a planar figure is not closed, we show the intensity profile instead of the histogram. + auto statisticsNode = m_DataGenerator->GetLatestResult(imageNode, roiNode, true); - if (statistics) + if (statisticsNode.IsNotNull()) { - std::stringstream label; - label << "Histogram " << imageNode->GetName(); - if (imageNode->GetData()->GetTimeSteps() > 1) - { - label << "[0]"; - } + auto statistics = dynamic_cast(statisticsNode->GetData()); - if (roiNode) + if (statistics) { - label << " with " << roiNode->GetName(); - } + std::stringstream label; + label << "Histogram " << imageNode->GetName(); + if (imageNode->GetData()->GetTimeSteps() > 1) + { + label << "[0]"; + } - m_Controls.widget_histogram->SetHistogram(statistics->GetHistogramForTimeStep(0), label.str()); + if (roiNode) + { + label << " with " << roiNode->GetName(); + } + + m_Controls.widget_histogram->SetHistogram(statistics->GetHistogramForTimeStep(0), label.str()); + } + m_Controls.groupBox_histogram->setVisible(statisticsNode.IsNotNull()); } - m_Controls.groupBox_histogram->setVisible(statisticsNode.IsNotNull()); } } } QmitkChartWidget::ColorTheme QmitkImageStatisticsView::GetColorTheme() const { ctkPluginContext *context = berry::WorkbenchPlugin::GetDefault()->GetPluginContext(); ctkServiceReference styleManagerRef = context->getServiceReference(); if (styleManagerRef) { auto styleManager = context->getService(styleManagerRef); if (styleManager->GetStyle().name == "Dark") { return QmitkChartWidget::ColorTheme::darkstyle; } else { return QmitkChartWidget::ColorTheme::lightstyle; } } return QmitkChartWidget::ColorTheme::darkstyle; } void QmitkImageStatisticsView::ResetGUI() { m_Controls.widget_statistics->Reset(); m_Controls.widget_statistics->setEnabled(false); m_Controls.widget_histogram->Reset(); m_Controls.widget_histogram->setEnabled(false); m_Controls.widget_histogram->SetTheme(GetColorTheme()); } void QmitkImageStatisticsView::OnGenerationStarted(const mitk::DataNode* /*imageNode*/, const mitk::DataNode* /*roiNode*/, const QmitkDataGenerationJobBase* /*job*/) { m_Controls.label_currentlyComputingStatistics->setVisible(true); } void QmitkImageStatisticsView::OnGenerationFinished() { m_Controls.label_currentlyComputingStatistics->setVisible(false); mitk::StatusBar::GetInstance()->Clear(); this->UpdateIntensityProfile(); this->UpdateHistogramWidget(); } void QmitkImageStatisticsView::OnJobError(QString error, const QmitkDataGenerationJobBase* /*failedJob*/) { mitk::StatusBar::GetInstance()->DisplayErrorText(error.toStdString().c_str()); MITK_WARN << "Error when calculating statistics: " << error; } void QmitkImageStatisticsView::OnRequestHistogramUpdate(unsigned int nbins) { m_Controls.widget_statistics->SetHistogramNBins(nbins); m_DataGenerator->SetHistogramNBins(nbins); this->UpdateIntensityProfile(); this->UpdateHistogramWidget(); } void QmitkImageStatisticsView::OnCheckBoxIgnoreZeroStateChanged(int state) { auto ignoreZeroValueVoxel = (state == Qt::Unchecked) ? false : true; m_Controls.widget_statistics->SetIgnoreZeroValueVoxel(ignoreZeroValueVoxel); m_DataGenerator->SetIgnoreZeroValueVoxel(ignoreZeroValueVoxel); this->UpdateIntensityProfile(); this->UpdateHistogramWidget(); } +void QmitkImageStatisticsView::OnImageSelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList /*nodes*/) +{ + auto images = m_Controls.imageNodesSelector->GetSelectedNodesStdVector(); + m_Controls.widget_statistics->SetImageNodes(images); + + m_DataGenerator->SetAutoUpdate(false); + m_DataGenerator->SetImageNodes(images); + m_DataGenerator->Generate(); + m_DataGenerator->SetAutoUpdate(true); + + m_Controls.widget_statistics->setEnabled(!images.empty()); + + m_Controls.roiNodesSelector->SetNodePredicate(this->GenerateROIPredicate()); + + this->UpdateHistogramWidget(); + this->UpdateIntensityProfile(); +} + +void QmitkImageStatisticsView::OnROISelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList /*nodes*/) +{ + auto rois = m_Controls.roiNodesSelector->GetSelectedNodesStdVector(); + + m_Controls.widget_statistics->SetMaskNodes(rois); + + m_DataGenerator->SetAutoUpdate(false); + m_DataGenerator->SetROINodes(rois); + m_DataGenerator->Generate(); + m_DataGenerator->SetAutoUpdate(true); + + this->UpdateHistogramWidget(); + this->UpdateIntensityProfile(); +} + + void QmitkImageStatisticsView::OnButtonSelectionPressed() { QmitkNodeSelectionDialog* dialog = new QmitkNodeSelectionDialog(nullptr, "Select input for the statistic","You may select images and ROIs to compute their statistic. ROIs may be segmentations or planar figures."); dialog->SetDataStorage(GetDataStorage()); dialog->SetSelectionCheckFunction(CheckForSameGeometry()); // set predicates auto isPlanarFigurePredicate = mitk::GetImageStatisticsPlanarFigurePredicate(); auto isMaskPredicate = mitk::GetImageStatisticsMaskPredicate(); auto isImagePredicate = mitk::GetImageStatisticsImagePredicate(); auto isMaskOrPlanarFigurePredicate = mitk::NodePredicateOr::New(isPlanarFigurePredicate, isMaskPredicate); auto isImageOrMaskOrPlanarFigurePredicate = mitk::NodePredicateOr::New(isMaskOrPlanarFigurePredicate, isImagePredicate); dialog->SetNodePredicate(isImageOrMaskOrPlanarFigurePredicate); dialog->SetSelectionMode(QAbstractItemView::MultiSelection); - dialog->SetCurrentSelection(m_SelectedNodeList); + dialog->SetCurrentSelection(m_Controls.imageNodesSelector->GetSelectedNodes()+m_Controls.roiNodesSelector->GetSelectedNodes()); if (dialog->exec()) { - std::vector imageNodes; - std::vector maskNodes; + auto selectedNodeList = dialog->GetSelectedNodes(); - m_SelectedNodeList = dialog->GetSelectedNodes(); - auto isImagePredicate = mitk::GetImageStatisticsImagePredicate(); - for (const auto& node : m_SelectedNodeList) - { - if (isImagePredicate->CheckNode(node)) - { - imageNodes.push_back(node.GetPointer()); - } - else - { - maskNodes.push_back(node.GetPointer()); - } - } - - m_selectedImageNodes = imageNodes; - m_selectedMaskNodes = maskNodes; - - if (nullptr != m_selectedPlanarFigure) - { - m_selectedPlanarFigure->RemoveObserver(m_PlanarFigureObserverTag); - m_selectedPlanarFigure = nullptr; - } - - mitk::PlanarFigure* maskPlanarFigure = nullptr; - - if (m_selectedMaskNodes.size() == 1) - { //currently we support this only with one ROI selected - maskPlanarFigure = dynamic_cast(m_selectedMaskNodes.front()->GetData()); - } - - if (nullptr != maskPlanarFigure) - { - m_selectedPlanarFigure = maskPlanarFigure; - ITKCommandType::Pointer changeListener = ITKCommandType::New(); - changeListener->SetCallbackFunction(this, &QmitkImageStatisticsView::UpdateIntensityProfile); - m_PlanarFigureObserverTag = - m_selectedPlanarFigure->AddObserver(mitk::EndInteractionPlanarFigureEvent(), changeListener); - - this->UpdateIntensityProfile(); - } - - m_Controls.widget_statistics->SetImageNodes(m_selectedImageNodes); - m_Controls.widget_statistics->SetMaskNodes(m_selectedMaskNodes); - - m_DataGenerator->SetAutoUpdate(false); - m_DataGenerator->SetImageNodes(m_selectedImageNodes); - m_DataGenerator->SetROINodes(m_selectedMaskNodes); - m_DataGenerator->Generate(); - m_DataGenerator->SetAutoUpdate(true); - - m_Controls.widget_statistics->setEnabled(!m_selectedImageNodes.empty()); + m_Controls.imageNodesSelector->SetCurrentSelection(selectedNodeList); + m_Controls.roiNodesSelector->SetCurrentSelection(selectedNodeList); } delete dialog; } QmitkNodeSelectionDialog::SelectionCheckFunctionType QmitkImageStatisticsView::CheckForSameGeometry() const { auto lambda = [](const QmitkNodeSelectionDialog::NodeList& nodes) { if (nodes.empty()) { return std::string(); } const mitk::Image* imageNodeData = nullptr; for (auto& node : nodes) { imageNodeData = dynamic_cast(node->GetData()); if (imageNodeData) { break; } } if (imageNodeData == nullptr) { std::stringstream ss; ss << "

Select at least one image.

"; return ss.str(); } auto imageGeoPredicate = mitk::NodePredicateGeometry::New(imageNodeData->GetGeometry()); for (auto& rightNode : nodes) { if (imageNodeData != rightNode->GetData()) { bool sameGeometry = true; if (dynamic_cast(rightNode->GetData())) { sameGeometry = imageGeoPredicate->CheckNode(rightNode); } else { const mitk::PlanarFigure* planar2 = dynamic_cast(rightNode->GetData()); if (planar2) { sameGeometry = mitk::PlanarFigureMaskGenerator::CheckPlanarFigureIsNotTilted(planar2->GetPlaneGeometry(), imageNodeData->GetGeometry()); } } if (!sameGeometry) { std::stringstream ss; ss << "

Invalid selection: All selected nodes must have the same geometry.

Differing node i.a.: \""; ss << rightNode->GetName() <<"\"

"; return ss.str(); } } } return std::string(); }; return lambda; } + +mitk::NodePredicateBase::Pointer QmitkImageStatisticsView::GenerateROIPredicate() const +{ + auto isPlanarFigurePredicate = mitk::GetImageStatisticsPlanarFigurePredicate(); + auto isMaskPredicate = mitk::GetImageStatisticsMaskPredicate(); + auto isMaskOrPlanarFigurePredicate = mitk::NodePredicateOr::New(isPlanarFigurePredicate, isMaskPredicate); + + mitk::NodePredicateBase::Pointer result = isMaskOrPlanarFigurePredicate; + + if(!m_Controls.imageNodesSelector->GetSelectedNodes().empty()) + { + auto image = m_Controls.imageNodesSelector->GetSelectedNodes().front()->GetData(); + + auto lambda = [image](const mitk::DataNode* node) + { + auto imageGeoPredicate = mitk::NodePredicateGeometry::New(image->GetGeometry()); + + bool sameGeometry = true; + + if (dynamic_cast(node->GetData())) + { + sameGeometry = imageGeoPredicate->CheckNode(node); + } + else + { + const mitk::PlanarFigure* planar2 = dynamic_cast(node->GetData()); + if (planar2) + { + sameGeometry = mitk::PlanarFigureMaskGenerator::CheckPlanarFigureIsNotTilted(planar2->GetPlaneGeometry(), image->GetGeometry()); + } + } + + return sameGeometry; + }; + + result = mitk::NodePredicateAnd::New(isMaskOrPlanarFigurePredicate, mitk::NodePredicateFunction::New(lambda)).GetPointer(); + } + + return result; +} diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h index 1d8c754f5c..e72053298f 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h @@ -1,89 +1,85 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QMITKIMAGESTATISTICSVIEW_H #define QMITKIMAGESTATISTICSVIEW_H #include "ui_QmitkImageStatisticsViewControls.h" #include #include #include #include class QmitkImageStatisticsDataGenerator; class QmitkDataGenerationJobBase; /*! \brief QmitkImageStatisticsView is a bundle that allows statistics calculation from images. Three modes are supported: 1. Statistics of one image, 2. Statistics of an image and a segmentation, 3. Statistics of an image and a Planar Figure. The statistics calculation is realized in a separate thread to keep the gui accessible during calculation. \ingroup Plugins/org.mitk.gui.qt.measurementtoolbox */ class QmitkImageStatisticsView : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; /*! \brief default destructor */ ~QmitkImageStatisticsView() override; /*! \brief Creates the widget containing the application controls, like sliders, buttons etc.*/ void CreateQtPartControl(QWidget *parent) override; protected: using HistogramType = mitk::ImageStatisticsContainer::HistogramType; void SetFocus() override { }; virtual void CreateConnections(); void UpdateIntensityProfile(); void UpdateHistogramWidget(); QmitkChartWidget::ColorTheme GetColorTheme() const; void ResetGUI(); void OnGenerationStarted(const mitk::DataNode* imageNode, const mitk::DataNode* roiNode, const QmitkDataGenerationJobBase* job); void OnGenerationFinished(); void OnJobError(QString error, const QmitkDataGenerationJobBase* failedJob); void OnRequestHistogramUpdate(unsigned int); void OnCheckBoxIgnoreZeroStateChanged(int state); void OnButtonSelectionPressed(); + void OnImageSelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList nodes); + void OnROISelectionChanged(QmitkAbstractNodeSelectionWidget::NodeList nodes); // member variable Ui::QmitkImageStatisticsViewControls m_Controls; private: QmitkNodeSelectionDialog::SelectionCheckFunctionType CheckForSameGeometry() const; + mitk::NodePredicateBase::Pointer QmitkImageStatisticsView::GenerateROIPredicate() const; - typedef itk::SimpleMemberCommand ITKCommandType; - mitk::PlanarFigure::Pointer m_selectedPlanarFigure = nullptr; - - long m_PlanarFigureObserverTag; - std::vector m_selectedMaskNodes; - std::vector m_selectedImageNodes; - QmitkNodeSelectionDialog::NodeList m_SelectedNodeList; std::vector m_StatisticsForSelection; QmitkImageStatisticsDataGenerator* m_DataGenerator = nullptr; }; #endif // QMITKIMAGESTATISTICSVIEW_H diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui index 85e13fdea2..1a34302c5b 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui @@ -1,184 +1,295 @@ QmitkImageStatisticsViewControls true 0 0 419 1016 Form + + 3 + + + 3 + + + 3 + + + 3 + - - - - 0 - 200 - + + + 0 - - Statistics - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - 0 - 0 - - - - - - - - - - - 0 - 0 - - - - Calculating statistics... + + + Statistics + + + + 5 + + + 5 + + + 5 + + + 5 + + + + + Quick selector button for input data. + + + + + + + true + + + + + + + + 0 + 200 + + + + Statistics + + + + 3 - - - - - - + + + 3 - - true + + 3 - - - - - - Ignore zero-valued voxels + + 3 - - - - - - - - - - - - 0 - 200 - - - - Histogram - - - - - - - - - - + + + + 0 + 0 + + + - - - Qt::Vertical - - - - 20 - 40 - - - + + + + + + 0 + 0 + + + + Calculating statistics... + + + + + + + Ignore zero-valued voxels + + + + - - - - - - - - - - - 0 - 200 - - - - Intensity Profile - - - - - - - - - + + + + + + + 0 + 200 + + + + Histogram + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 0 + 200 + + + + Intensity Profile + + + + + + + + + + + + + + + + Input data + + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + Images + + + + + + + + + + + 0 + 0 + + + + ROIs (segmentations, planarfigures...) + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + QmitkImageStatisticsWidget QWidget
QmitkImageStatisticsWidget.h
1
QmitkHistogramVisualizationWidget QWidget
QmitkHistogramVisualizationWidget.h
1
QmitkIntensityProfileVisualizationWidget QWidget
QmitkIntensityProfileVisualizationWidget.h
1
ctkSliderWidget QWidget
ctkSliderWidget.h
1
+ + QmitkMultiNodeSelectionWidget + QWidget +
QmitkMultiNodeSelectionWidget.h
+ 1 +