diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/files.cmake b/Plugins/org.mitk.gui.qt.measurementtoolbox/files.cmake index c6751d8b7a..7273bd39d3 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/files.cmake +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/files.cmake @@ -1,56 +1,53 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES QmitkMeasurementView.cpp - QmitkImageStatisticsView.cpp QmitkImageStatisticsReloadedView.cpp mitkPluginActivator.cpp ) set(UI_FILES src/internal/QmitkImageStatisticsReloadedViewControls.ui - src/internal/QmitkImageStatisticsViewControls.ui ) set(MOC_H_FILES src/internal/QmitkMeasurementView.h - src/internal/QmitkImageStatisticsView.h src/internal/QmitkImageStatisticsReloadedView.h src/internal/mitkPluginActivator.h ) set(CACHED_RESOURCE_FILES resources/angle.png resources/arrow.png resources/circle.png resources/four-point-angle.png resources/lena.xpm resources/line.png resources/measurement.svg resources/path.png resources/polygon.png resources/rectangle.png resources/stats.png resources/text.png resources/bar-chart.svg resources/bar-chart2.svg plugin.xml ) set(QRC_FILES resources/measurement.qrc resources/QmitkImageStatisticsView.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.measurementtoolbox/plugin.xml b/Plugins/org.mitk.gui.qt.measurementtoolbox/plugin.xml index 2e69a3ef29..fb21078931 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/plugin.xml +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/plugin.xml @@ -1,53 +1,42 @@ Measure distance and areas in the image - - - - DEPRECATED: Calculate the statistic of image regions - - - Calculate the statistic of image regions diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp deleted file mode 100644 index 31aabd3b2c..0000000000 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp +++ /dev/null @@ -1,1298 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#include "QmitkImageStatisticsView.h" - -// Qt includes -#include -#include -#include - -// berry includes -#include - -// mitk includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// itk includes -#include "itksys/SystemTools.hxx" -#include "itkImageRegionConstIteratorWithIndex.h" - -#include - -//blueberry includes -#include -#include - -const std::string QmitkImageStatisticsView::VIEW_ID = "org.mitk.views.imagestatistics"; -const int QmitkImageStatisticsView::STAT_TABLE_BASE_HEIGHT = 180; - -QmitkImageStatisticsView::QmitkImageStatisticsView(QObject* /*parent*/, const char* /*name*/) - : m_Controls(nullptr), - m_SelectedImage(nullptr), - m_SelectedImageMask(nullptr), - m_SelectedPlanarFigure(nullptr), - m_ImageObserverTag(-1), - m_ImageMaskObserverTag(-1), - m_PlanarFigureObserverTag(-1), - m_TimeObserverTag(-1), - m_CurrentStatisticsValid(false), - m_StatisticsUpdatePending(false), - m_DataNodeSelectionChanged(false), - m_Visible(false) -{ - this->m_CalculationThread = new QmitkImageStatisticsCalculationJob; -} - -QmitkImageStatisticsView::~QmitkImageStatisticsView() -{ - if (m_SelectedImage != nullptr) - m_SelectedImage->RemoveObserver(m_ImageObserverTag); - if (m_SelectedImageMask != nullptr) - m_SelectedImageMask->RemoveObserver(m_ImageMaskObserverTag); - if (m_SelectedPlanarFigure != nullptr) - m_SelectedPlanarFigure->RemoveObserver(m_PlanarFigureObserverTag); - - while (this->m_CalculationThread->isRunning()) // wait until thread has finished - { - itksys::SystemTools::Delay(100); - } - delete this->m_CalculationThread; -} - - -void QmitkImageStatisticsView::CreateQtPartControl(QWidget *parent) -{ - if (m_Controls == nullptr) - { - m_Controls = new Ui::QmitkImageStatisticsViewControls; - m_Controls->setupUi(parent); - CreateConnections(); - - m_Controls->m_ErrorMessageLabel->hide(); - m_Controls->m_StatisticsWidgetStack->setCurrentIndex(0); - m_Controls->m_BinSizeFrame->setEnabled(false); - } -} - -void QmitkImageStatisticsView::OnPageSuccessfullyLoaded() -{ - berry::IPreferencesService* prefService = berry::WorkbenchPlugin::GetDefault()->GetPreferencesService(); - m_StylePref = prefService->GetSystemPreferences()->Node(berry::QtPreferences::QT_STYLES_NODE); - - QString styleName = m_StylePref->Get(berry::QtPreferences::QT_STYLE_NAME, ""); - - if (styleName == ":/org.blueberry.ui.qt/darkstyle.qss") - { - this->m_Controls->m_JSHistogram->SetTheme(QmitkChartWidget::ColorTheme::darkstyle); - } - else - { - this->m_Controls->m_JSHistogram->SetTheme(QmitkChartWidget::ColorTheme::lightstyle); - } -} - -void QmitkImageStatisticsView::CreateConnections() -{ - if (m_Controls) - { - connect((QObject*)(this->m_Controls->m_ButtonCopyHistogramToClipboard), SIGNAL(clicked()), (QObject*)this, SLOT(OnClipboardHistogramButtonClicked())); - connect((QObject*)(this->m_Controls->m_ButtonCopyStatisticsToClipboard), SIGNAL(clicked()), (QObject*)this, SLOT(OnClipboardStatisticsButtonClicked())); - connect((QObject*)(this->m_Controls->m_IgnoreZerosCheckbox), SIGNAL(clicked()), (QObject*)this, SLOT(OnIgnoreZerosCheckboxClicked())); - connect((QObject*)this->m_CalculationThread, SIGNAL(finished()), this, SLOT(OnThreadedStatisticsCalculationEnds()), Qt::QueuedConnection); - connect((QObject*)this, SIGNAL(StatisticsUpdate()), this, SLOT(RequestStatisticsUpdate()), Qt::QueuedConnection); - connect((QObject*)this->m_Controls->m_StatisticsTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(JumpToCoordinates(int, int))); - connect((QObject*)(this->m_Controls->m_barRadioButton), SIGNAL(clicked()), (QObject*)(this), SLOT(OnBarRadioButtonSelected())); - connect((QObject*)(this->m_Controls->m_lineRadioButton), SIGNAL(clicked()), (QObject*)(this), SLOT(OnLineRadioButtonSelected())); - connect((QObject*)(this->m_Controls->m_HistogramNBinsSpinbox), SIGNAL(editingFinished()), this, SLOT(OnHistogramNBinsCheckBoxValueChanged())); - connect((QObject*)(this->m_Controls->m_UseDefaultNBinsCheckBox), SIGNAL(clicked()), (QObject*)this, SLOT(OnDefaultNBinsSpinBoxChanged())); - connect((QObject*)(this->m_Controls->m_ShowSubchartCheckBox), SIGNAL(clicked()), (QObject*)this, SLOT(OnShowSubchartBoxChanged())); - connect((QObject*)(this->m_Controls->m_JSHistogram), SIGNAL(PageSuccessfullyLoaded()), (QObject*)this, SLOT(OnPageSuccessfullyLoaded())); - } -} - -void QmitkImageStatisticsView::OnDefaultNBinsSpinBoxChanged() -{ - if (this->m_Controls->m_UseDefaultNBinsCheckBox->isChecked()) { - m_Controls->m_HistogramNBinsSpinbox->setValue(100); - this->m_CalculationThread->SetHistogramNBins(m_Controls->m_HistogramNBinsSpinbox->value()); - m_HistogramNBins = m_Controls->m_HistogramNBinsSpinbox->value(); - } - m_Controls->m_BinSizeFrame->setEnabled(!m_Controls->m_UseDefaultNBinsCheckBox->isChecked()); - - this->UpdateStatistics(); - -} - -void QmitkImageStatisticsView::OnShowSubchartBoxChanged() -{ - bool showSubchart = this->m_Controls->m_ShowSubchartCheckBox->isChecked(); - this->m_Controls->m_JSHistogram->SetShowSubchart(showSubchart); - this->m_Controls->m_JSHistogram->Reload(); -} - - -void QmitkImageStatisticsView::OnBarRadioButtonSelected() -{ - this->m_Controls->m_JSHistogram->SetChartTypeForAllDataAndReload(QmitkChartWidget::ChartType::bar); -} - -void QmitkImageStatisticsView::OnLineRadioButtonSelected() -{ - this->m_Controls->m_JSHistogram->SetChartTypeForAllDataAndReload(QmitkChartWidget::ChartType::line); -} - -void QmitkImageStatisticsView::PartClosed(const berry::IWorkbenchPartReference::Pointer&) -{ -} - -void QmitkImageStatisticsView::OnTimeChanged(const itk::EventObject& e) -{ - if (this->m_SelectedDataNodes.isEmpty() || this->m_SelectedImage == nullptr) - return; - - const mitk::SliceNavigationController::GeometryTimeEvent* timeEvent = - dynamic_cast(&e); - assert(timeEvent != nullptr); - int timestep = timeEvent->GetPos(); - - if (this->m_SelectedImage->GetTimeSteps() > 1) - { - for (int x = 0; x < this->m_Controls->m_StatisticsTable->columnCount(); x++) - { - for (int y = 0; y < this->m_Controls->m_StatisticsTable->rowCount(); y++) - { - QTableWidgetItem* item = this->m_Controls->m_StatisticsTable->item(y, x); - if (item == nullptr) - break; - - if (x == timestep) - { - item->setBackgroundColor(Qt::yellow); - } - else - { - if (y % 2 == 0) - item->setBackground(this->m_Controls->m_StatisticsTable->palette().base()); - else - item->setBackground(this->m_Controls->m_StatisticsTable->palette().alternateBase()); - } - } - } - - this->m_Controls->m_StatisticsTable->viewport()->update(); - } - - if ((this->m_SelectedImage->GetTimeSteps() == 1 && timestep == 0) || - this->m_SelectedImage->GetTimeSteps() > 1) - { - m_Controls->m_JSHistogram->Clear(); - QmitkImageStatisticsCalculationJob::HistogramType::ConstPointer histogram = - (QmitkImageStatisticsCalculationJob::HistogramType::ConstPointer)this->m_CalculationThread->GetTimeStepHistogram(timestep); - - if (histogram.IsNotNull()) - { - bool statisticsUpdateSuccessful = this->m_CalculationThread->GetStatisticsUpdateSuccessFlag(); - - if (statisticsUpdateSuccessful) - { - - auto imageNameLabel = m_Controls->m_SelectedFeatureImageLabel->text().toStdString(); - this->m_Controls->m_JSHistogram->AddData2D(ConvertHistogramToMap(histogram), imageNameLabel); - if (this->m_Controls->m_lineRadioButton->isChecked()) - { - this->m_Controls->m_JSHistogram->SetChartType(imageNameLabel, QmitkChartWidget::ChartType::line); - } - else - { - this->m_Controls->m_JSHistogram->SetChartType(imageNameLabel, QmitkChartWidget::ChartType::bar); - } - this->m_Controls->m_JSHistogram->SetXAxisLabel("Grey value"); - this->m_Controls->m_JSHistogram->SetYAxisLabel("Frequency"); - this->m_Controls->m_JSHistogram->Show(this->m_Controls->m_ShowSubchartCheckBox->isChecked()); - } - } - } -} - -void QmitkImageStatisticsView::JumpToCoordinates(int row, int col) -{ - if (m_SelectedDataNodes.isEmpty()) - { - MITK_WARN("QmitkImageStatisticsView") << "No data node selected for statistics calculation."; - return; - } - - mitk::Point3D world; - if (row == 5 && !m_WorldMinList.empty()) - world = m_WorldMinList[col]; - else if (row == 4 && !m_WorldMaxList.empty()) - world = m_WorldMaxList[col]; - else - return; - - mitk::IRenderWindowPart* part = this->GetRenderWindowPart(); - if (part) - { - part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SelectSliceByPoint(world); - part->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SelectSliceByPoint(world); - part->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SelectSliceByPoint(world); - - mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), col); - part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetGeometryTime(timeEvent); - } -} - -void QmitkImageStatisticsView::OnIgnoreZerosCheckboxClicked() -{ - emit StatisticsUpdate(); -} - -void QmitkImageStatisticsView::OnClipboardHistogramButtonClicked() -{ - if (!m_CurrentStatisticsValid) - { - QApplication::clipboard()->clear(); - } - - if (m_SelectedPlanarFigure == nullptr) - { - const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); - - typedef mitk::ImageStatisticsCalculator::HistogramType HistogramType; - const HistogramType *histogram = this->m_CalculationThread->GetTimeStepHistogram(t).GetPointer(); - - QString clipboard("Measurement \t Frequency\n"); - for (HistogramType::ConstIterator it = histogram->Begin(); - it != histogram->End(); - ++it) - { - clipboard = clipboard.append("%L1 \t %L2\n") - .arg(it.GetMeasurementVector()[0], 0, 'f', 2) - .arg(it.GetFrequency()); - } - - QApplication::clipboard()->setText( - clipboard, QClipboard::Clipboard); - } - //If a (non-closed) PlanarFigure is selected, display a line profile widget - else if (m_SelectedPlanarFigure != nullptr) - { - QString clipboard("Pixel \t Intensity\n"); - for (unsigned int i = 0; i < m_IntensityProfileList.size(); i++) - { - clipboard = - clipboard.append("%L1 \t %L2\n").arg(QString::number(i)).arg(QString::number(m_IntensityProfileList.at(i))); - } - QApplication::clipboard()->setText(clipboard, QClipboard::Clipboard); - } -} - -void QmitkImageStatisticsView::OnClipboardStatisticsButtonClicked() -{ - QLocale tempLocal; - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - if (m_CurrentStatisticsValid && !(m_SelectedPlanarFigure != nullptr)) - { - const auto &statistics = - this->m_CalculationThread->GetStatisticsData(); - - // Set time borders for for loop ;) - unsigned int startT, endT; - if (this->m_Controls->m_CheckBox4dCompleteTable->checkState() == Qt::CheckState::Unchecked) - { - startT = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()-> - GetPos(); - endT = startT + 1; - } - else - { - startT = 0; - endT = statistics->GetNumberOfTimeSteps(); - } - QVector< QVector > statisticsTable; - QStringList headline{ "Timestep", "Mean", "Median", "StdDev", "RMS", "Max", "Min", "NumberOfVoxels", "Skewness", "Kurtosis", "Uniformity", "Entropy", "MPP", "UPP", "V [mm³]" }; - - for (int i = 0; i < headline.size(); i++) - { - QVector row; - row.append(headline.at(i)); - statisticsTable.append(row); - } - - // Fill Table - for (unsigned int t = startT; t < endT; t++) - { - // Copy statistics to clipboard ("%Ln" will use the default locale for - // number formatting) - QStringList value; - value << QString::number(t) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::MEAN())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::MEDIAN())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::STANDARDDEVIATION())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::RMS())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::MAXIMUM())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::MINIMUM())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::NUMBEROFVOXELS())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::SKEWNESS())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::KURTOSIS())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::UNIFORMITY())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::ENTROPY())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::MPP())) - << QString::number(statistics->GetStatisticsForTimeStep(t).GetValueConverted(mitk::ImageStatisticsConstants::UPP())) - << QString::number(m_Controls->m_StatisticsTable->item(7, 0)->data(Qt::DisplayRole).toDouble()); - - for (int z = 0; z < value.size(); z++) - { - statisticsTable[z].append(value.at(z)); - } - } - - // Create output string - QString clipboard; - for (int i = 0; i < statisticsTable.size(); i++) - { - for (int t = 0; t < statisticsTable.at(i).size(); t++) - { - clipboard.append(statisticsTable.at(i).at(t)); - clipboard.append("\t"); - } - clipboard.append("\n"); - } - QApplication::clipboard()->setText(clipboard, QClipboard::Clipboard); - } - else - { - QApplication::clipboard()->clear(); - } - QLocale::setDefault(tempLocal); -} - -void QmitkImageStatisticsView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, - const QList &nodes) -{ - if (this->m_Visible) - { - this->SelectionChanged(nodes); - } - else - { - this->m_DataNodeSelectionChanged = true; - } -} - -void QmitkImageStatisticsView::SelectionChanged(const QList &selectedNodes) -{ - m_Controls->m_JSHistogram->Clear(); - - if (this->m_StatisticsUpdatePending) - { - this->m_DataNodeSelectionChanged = true; - return; // not ready for new data now! - } - - if (selectedNodes.size() == this->m_SelectedDataNodes.size()) - { - int i = 0; - for (; i < selectedNodes.size(); ++i) - { - if (selectedNodes.at(i) != this->m_SelectedDataNodes.at(i)) - { - break; - } - } - // node selection did not change - if (i == selectedNodes.size()) return; - } - - //reset the feature image and image mask field - m_Controls->m_SelectedFeatureImageLabel->setText("None"); - m_Controls->m_SelectedMaskLabel->setText("None"); - - this->ReinitData(); - if (selectedNodes.isEmpty()) - { - DisableHistogramGUIElements(); - } - else - { - EnableHistogramGUIElements(); - ResetHistogramGUIElementsToDefault(); - } - if (selectedNodes.size() == 1 || selectedNodes.size() == 2) - { - bool isBinary = false; - selectedNodes.value(0)->GetBoolProperty("binary", isBinary); - mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); - isBinary |= isLabelSet->CheckNode(selectedNodes.value(0)); - if (isBinary) - { - EnableHistogramGUIElements(); - m_Controls->m_InfoLabel->setText(""); - } - for (int i = 0; i < selectedNodes.size(); ++i) - { - this->m_SelectedDataNodes.push_back(selectedNodes.at(i)); - } - this->m_DataNodeSelectionChanged = false; - this->m_Controls->m_ErrorMessageLabel->setText(""); - this->m_Controls->m_ErrorMessageLabel->hide(); - emit StatisticsUpdate(); - } - else - { - this->m_DataNodeSelectionChanged = false; - } -} - -void QmitkImageStatisticsView::DisableHistogramGUIElements() -{ - m_Controls->m_InfoLabel->setText(""); - m_Controls->groupBox_histogram->setEnabled(false); - m_Controls->groupBox_statistics->setEnabled(false); -} - -void QmitkImageStatisticsView::ResetHistogramGUIElementsToDefault() -{ - m_Controls->m_barRadioButton->setChecked(true); - m_Controls->m_HistogramNBinsSpinbox->setValue(100); - m_HistogramNBins = m_Controls->m_HistogramNBinsSpinbox->value(); - m_Controls->m_UseDefaultNBinsCheckBox->setChecked(true); - m_Controls->m_ShowSubchartCheckBox->setChecked(true); - m_Controls->m_BinSizeFrame->setEnabled(false); - m_Controls->m_barRadioButton->setEnabled(true); - m_Controls->m_lineRadioButton->setEnabled(true); - m_Controls->m_HistogramNBinsSpinbox->setEnabled(true); - this->m_CalculationThread->SetHistogramNBins(m_Controls->m_HistogramNBinsSpinbox->value()); -} - -void QmitkImageStatisticsView::EnableHistogramGUIElements() -{ - m_Controls->groupBox_histogram->setEnabled(true); - m_Controls->groupBox_plot->setEnabled(true); - m_Controls->groupBox_statistics->setEnabled(true); -} - -void QmitkImageStatisticsView::ReinitData() -{ - while (this->m_CalculationThread->isRunning()) // wait until thread has finished - { - itksys::SystemTools::Delay(100); - } - - if (this->m_SelectedImage != nullptr) - { - this->m_SelectedImage->RemoveObserver(this->m_ImageObserverTag); - this->m_SelectedImage = nullptr; - } - if (this->m_SelectedImageMask != nullptr) - { - this->m_SelectedImageMask->RemoveObserver(this->m_ImageMaskObserverTag); - this->m_SelectedImageMask = nullptr; - } - if (this->m_SelectedPlanarFigure != nullptr) - { - this->m_SelectedPlanarFigure->RemoveObserver(this->m_PlanarFigureObserverTag); - this->m_SelectedPlanarFigure = nullptr; - } - this->m_SelectedDataNodes.clear(); - this->m_StatisticsUpdatePending = false; - - m_Controls->m_ErrorMessageLabel->setText(""); - m_Controls->m_ErrorMessageLabel->hide(); - this->InvalidateStatisticsTableView(); - m_Controls->m_StatisticsWidgetStack->setCurrentIndex(0); -} - -void QmitkImageStatisticsView::OnThreadedStatisticsCalculationEnds() -{ - m_Controls->m_ErrorMessageLabel->setText(""); - m_Controls->m_ErrorMessageLabel->hide(); - this->WriteStatisticsToGUI(); -} - -void QmitkImageStatisticsView::UpdateStatistics() -{ - mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart(); - if (renderPart == nullptr) - { - this->m_StatisticsUpdatePending = false; - return; - } - m_WorldMinList.clear(); - m_WorldMaxList.clear(); - - // classify selected nodes - mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); - mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); - mitk::NodePredicateOr::Pointer imagePredicate = mitk::NodePredicateOr::New(isImage, isLabelSet); - - std::string maskName; - std::string maskType; - std::string featureImageName; - unsigned int maskDimension = 0; - - // reset data from last run - ITKCommandType::Pointer changeListener = ITKCommandType::New(); - changeListener->SetCallbackFunction(this, &QmitkImageStatisticsView::SelectedDataModified); - - mitk::DataNode::Pointer planarFigureNode; - for (int i = 0; i < this->m_SelectedDataNodes.size(); ++i) - { - mitk::PlanarFigure::Pointer planarFig = dynamic_cast(this->m_SelectedDataNodes.at(i)->GetData()); - if (imagePredicate->CheckNode(this->m_SelectedDataNodes.at(i))) - { - bool isMask = false; - this->m_SelectedDataNodes.at(i)->GetPropertyValue("binary", isMask); - isMask |= isLabelSet->CheckNode(this->m_SelectedDataNodes.at(i)); - - if (this->m_SelectedImageMask == nullptr && isMask) - { - this->m_SelectedImageMask = dynamic_cast(this->m_SelectedDataNodes.at(i)->GetData()); - this->m_ImageMaskObserverTag = this->m_SelectedImageMask->AddObserver(itk::ModifiedEvent(), changeListener); - - maskName = this->m_SelectedDataNodes.at(i)->GetName(); - maskType = m_SelectedImageMask->GetNameOfClass(); - maskDimension = 3; - } - else if (!isMask) - { - if (this->m_SelectedImage == nullptr) - { - this->m_SelectedImage = static_cast(this->m_SelectedDataNodes.at(i)->GetData()); - this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener); - } - featureImageName = this->m_SelectedDataNodes.at(i)->GetName(); - } - } - else if (planarFig.IsNotNull()) - { - if (this->m_SelectedPlanarFigure == nullptr) - { - this->m_SelectedPlanarFigure = planarFig; - this->m_PlanarFigureObserverTag = - this->m_SelectedPlanarFigure->AddObserver(mitk::EndInteractionPlanarFigureEvent(), changeListener); - maskName = this->m_SelectedDataNodes.at(i)->GetName(); - maskType = this->m_SelectedPlanarFigure->GetNameOfClass(); - maskDimension = 2; - planarFigureNode = m_SelectedDataNodes.at(i); - } - } - else - { - m_Controls->m_ErrorMessageLabel->setText("Invalid data node type!"); - m_Controls->m_ErrorMessageLabel->show(); - } - } - - if (maskName == "") - { - maskName = "None"; - maskType = ""; - maskDimension = 0; - } - - if (featureImageName == "") - { - featureImageName = "None"; - } - - if (m_SelectedPlanarFigure != nullptr && m_SelectedImage == nullptr) - { - mitk::DataStorage::SetOfObjects::ConstPointer parentSet = this->GetDataStorage()->GetSources(planarFigureNode); - for (unsigned int i = 0; i < parentSet->Size(); i++) - { - mitk::DataNode::Pointer node = parentSet->ElementAt(i); - if (imagePredicate->CheckNode(node)) - { - bool isMask = false; - node->GetPropertyValue("binary", isMask); - isMask |= isLabelSet->CheckNode(node); - - if (!isMask) - { - if (this->m_SelectedImage == nullptr) - { - this->m_SelectedImage = static_cast(node->GetData()); - this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener); - } - } - } - } - } - - unsigned int timeStep = renderPart->GetTimeNavigationController()->GetTime()->GetPos(); - - if (m_SelectedImage != nullptr && m_SelectedImage->IsInitialized()) - { - // Check if a the selected image is a multi-channel image. If yes, statistics - // cannot be calculated currently. - if (m_SelectedImage->GetPixelType().GetNumberOfComponents() > 1) - { - m_Controls->m_ErrorMessageLabel->setText("Multi-component images not supported."); - m_Controls->m_ErrorMessageLabel->show(); - - this->InvalidateStatisticsTableView(); - m_Controls->m_StatisticsWidgetStack->setCurrentIndex(0); - m_CurrentStatisticsValid = false; - this->m_StatisticsUpdatePending = false; - this->DisableHistogramGUIElements(); - m_Controls->m_InfoLabel->setText(""); - return; - } - - std::stringstream maskLabel; - maskLabel << maskName; - if (maskDimension > 0) - { - maskLabel << " [" << maskDimension << "D " << maskType << "]"; - } - m_Controls->m_SelectedMaskLabel->setText(maskLabel.str().c_str()); - m_Controls->m_SelectedFeatureImageLabel->setText(featureImageName.c_str()); - - // check time step validity - if (m_SelectedImage->GetDimension() <= 3 && timeStep > m_SelectedImage->GetDimension(3) - 1) - { - timeStep = m_SelectedImage->GetDimension(3) - 1; - } - - // Add the used mask time step to the mask label so the user knows which mask time step was used - // if the image time step is bigger than the total number of mask time steps (see - // ImageStatisticsCalculator::ExtractImageAndMask) - if (m_SelectedImageMask != nullptr) - { - unsigned int maskTimeStep = timeStep; - - if (maskTimeStep >= m_SelectedImageMask->GetTimeSteps()) - { - maskTimeStep = m_SelectedImageMask->GetTimeSteps() - 1; - } - - m_Controls->m_SelectedMaskLabel->setText(m_Controls->m_SelectedMaskLabel->text() + - QString(" (t=") + - QString::number(maskTimeStep) + - QString(")")); - } - - // check if the segmentation mask is empty - if (m_SelectedImageMask != nullptr) - { - auto maskStatistics = m_SelectedImageMask->GetStatistics(); - mitk::ScalarType maskMaxValue = maskStatistics->GetScalarValueMax(0); - if (m_SelectedImageMask->GetDimension() == 4) { - for (unsigned int curTimestep = 1; curTimestep < m_SelectedImageMask->GetTimeSteps(); curTimestep++) { - maskMaxValue = std::max(maskStatistics->GetScalarValueMax(curTimestep), maskMaxValue); - } - } - - bool segmentationIsEmpty = maskMaxValue == 0; - - if (segmentationIsEmpty) - { - m_Controls->m_ErrorMessageLabel->setText("Empty segmentation mask selected..."); - m_Controls->m_ErrorMessageLabel->show(); - this->m_StatisticsUpdatePending = false; - return; - } - } - - //// initialize thread and trigger it - this->m_CalculationThread->SetIgnoreZeroValueVoxel(m_Controls->m_IgnoreZerosCheckbox->isChecked()); - this->m_CalculationThread->Initialize(m_SelectedImage, m_SelectedImageMask, m_SelectedPlanarFigure); - this->m_CalculationThread->SetTimeStep(timeStep); - - m_Controls->m_ErrorMessageLabel->setText("Calculating statistics..."); - m_Controls->m_ErrorMessageLabel->show(); - - try - { - // Compute statistics - this->m_CalculationThread->start(); - } - catch (const mitk::Exception& e) - { - m_Controls->m_ErrorMessageLabel->setText("" + QString(e.GetDescription()) + ""); - m_Controls->m_ErrorMessageLabel->show(); - this->m_StatisticsUpdatePending = false; - } - catch (const std::runtime_error &e) - { - // In case of exception, print error message on GUI - m_Controls->m_ErrorMessageLabel->setText("" + QString(e.what()) + ""); - m_Controls->m_ErrorMessageLabel->show(); - this->m_StatisticsUpdatePending = false; - } - catch (const std::exception &e) - { - MITK_ERROR << "Caught exception: " << e.what(); - - // In case of exception, print error message on GUI - m_Controls->m_ErrorMessageLabel->setText("" + QString(e.what()) + ""); - m_Controls->m_ErrorMessageLabel->show(); - this->m_StatisticsUpdatePending = false; - } - } - else - { - this->m_StatisticsUpdatePending = false; - } -} - -void QmitkImageStatisticsView::SelectedDataModified() -{ - if (!m_StatisticsUpdatePending) - { - emit StatisticsUpdate(); - } -} - -void QmitkImageStatisticsView::NodeRemoved(const mitk::DataNode *node) -{ - while (this->m_CalculationThread->isRunning()) // wait until thread has finished - { - itksys::SystemTools::Delay(100); - } - - if (node->GetData() == m_SelectedImage) - { - m_SelectedImage = nullptr; - } -} - -void QmitkImageStatisticsView::RequestStatisticsUpdate() -{ - if (!m_StatisticsUpdatePending) - { - if (this->m_DataNodeSelectionChanged) - { - this->SelectionChanged(this->GetCurrentSelection()); - } - else - { - this->m_StatisticsUpdatePending = true; - this->UpdateStatistics(); - } - } - if (this->GetRenderWindowPart()) - this->GetRenderWindowPart()->RequestUpdate(); -} - -void QmitkImageStatisticsView::OnHistogramNBinsCheckBoxValueChanged() -{ - if (static_cast(m_Controls->m_HistogramNBinsSpinbox->value()) != m_HistogramNBins) - { - m_HistogramNBins = m_Controls->m_HistogramNBinsSpinbox->value(); - this->m_CalculationThread->SetHistogramNBins(m_Controls->m_HistogramNBinsSpinbox->value()); - this->UpdateStatistics(); - } -} - -void QmitkImageStatisticsView::WriteStatisticsToGUI() -{ - m_Controls->m_JSHistogram->Clear(); - m_IntensityProfileList.clear(); - - //Disconnect OnLineRadioButtonSelected() to prevent reloading chart when radiobutton is checked programmatically - disconnect((QObject*)(this->m_Controls->m_JSHistogram), SIGNAL(PageSuccessfullyLoaded()), 0, 0); - connect((QObject*)(this->m_Controls->m_JSHistogram), SIGNAL(PageSuccessfullyLoaded()), (QObject*)this, SLOT(OnPageSuccessfullyLoaded())); - m_Controls->m_InfoLabel->setText(""); - - if (m_DataNodeSelectionChanged) - { - this->m_StatisticsUpdatePending = false; - this->RequestStatisticsUpdate(); - return; // stop visualization of results and calculate statistics of new selection - } - - if (this->m_CalculationThread->GetStatisticsUpdateSuccessFlag()) - { - if (this->m_CalculationThread->GetStatisticsChangedFlag()) - { - // Do not show any error messages - m_Controls->m_ErrorMessageLabel->hide(); - m_CurrentStatisticsValid = true; - } - - if (m_SelectedImage != nullptr) { - //all statistics are now computed also on planar figures (lines, paths...)! - // If a (non-closed) PlanarFigure is selected, display a line profile widget - if (m_SelectedPlanarFigure != nullptr && !m_SelectedPlanarFigure->IsClosed()) { - - // check whether PlanarFigure is initialized - const mitk::PlaneGeometry *planarFigurePlaneGeometry = m_SelectedPlanarFigure->GetPlaneGeometry(); - - if (planarFigurePlaneGeometry != nullptr) - { - unsigned int timeStep = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); - - mitk::Image::Pointer image; - - if (this->m_CalculationThread->GetStatisticsImage()->GetDimension() == 4) - { - mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); - timeSelector->SetInput(this->m_CalculationThread->GetStatisticsImage()); - timeSelector->SetTimeNr(timeStep); - timeSelector->Update(); - - image = timeSelector->GetOutput(); - } - else - { - image = this->m_CalculationThread->GetStatisticsImage()->Clone(); - } - - mitk::IntensityProfile::ConstPointer intensityProfile = (mitk::IntensityProfile::ConstPointer)mitk::ComputeIntensityProfile(image, m_SelectedPlanarFigure); - - m_IntensityProfileList = ConvertIntensityProfileToVector(intensityProfile); - auto lineDataLabel = "Intensity profile " + m_Controls->m_SelectedMaskLabel->text().toStdString(); - m_Controls->m_JSHistogram->SetChartType(lineDataLabel, QmitkChartWidget::ChartType::line); - m_Controls->m_JSHistogram->AddData1D(m_IntensityProfileList, lineDataLabel); - m_Controls->m_JSHistogram->SetXAxisLabel("Distance"); - m_Controls->m_JSHistogram->SetYAxisLabel("Intensity"); - m_Controls->m_JSHistogram->Show(m_Controls->m_ShowSubchartCheckBox->isChecked()); - - m_Controls->m_lineRadioButton->setChecked(true); - m_Controls->m_lineRadioButton->setEnabled(false); - m_Controls->m_barRadioButton->setEnabled(false); - m_Controls->m_HistogramNBinsSpinbox->setEnabled(false); - m_Controls->m_BinSizeFrame->setEnabled(false); - m_Controls->m_UseDefaultNBinsCheckBox->setEnabled(false); - - //Reconnect OnLineRadioButtonSelected() - connect((QObject*)(this->m_Controls->m_JSHistogram), SIGNAL(PageSuccessfullyLoaded()), (QObject*)this, SLOT(OnLineRadioButtonSelected())); - auto statisticsContainer = this->m_CalculationThread->GetStatisticsData(); - //only one entry (current timestep) - this->FillLinearProfileStatisticsTableView(statisticsContainer, this->m_CalculationThread->GetStatisticsImage()); - - QString message("Only linegraph available for an intensity profile!"); - if (this->m_CalculationThread->GetStatisticsImage()->GetDimension() == 4) { - message += "Only current timestep displayed!"; - } - message += ""; - m_Controls->m_InfoLabel->setText(message); - m_CurrentStatisticsValid = true; - } - else - { - // Clear statistics, histogram, and GUI - this->InvalidateStatisticsTableView(); - m_Controls->m_StatisticsWidgetStack->setCurrentIndex(0); - m_CurrentStatisticsValid = false; - m_Controls->m_ErrorMessageLabel->hide(); - m_Controls->m_SelectedMaskLabel->setText("None"); - this->m_StatisticsUpdatePending = false; - m_Controls->m_InfoLabel->setText(""); - return; - } - } - else - { - m_Controls->m_StatisticsWidgetStack->setCurrentIndex(0); - - auto histogram = this->m_CalculationThread->GetTimeStepHistogram(this->m_CalculationThread->GetTimeStep()).GetPointer(); - - auto imageLabelName = m_Controls->m_SelectedFeatureImageLabel->text().toStdString(); - m_Controls->m_JSHistogram->AddData2D(ConvertHistogramToMap(histogram), imageLabelName); - m_Controls->m_JSHistogram->SetChartType(imageLabelName, QmitkChartWidget::ChartType::bar); - this->m_Controls->m_JSHistogram->SetXAxisLabel("Gray value"); - this->m_Controls->m_JSHistogram->SetYAxisLabel("Frequency"); - m_Controls->m_UseDefaultNBinsCheckBox->setEnabled(true); - m_Controls->m_JSHistogram->Show(this->m_Controls->m_ShowSubchartCheckBox->isChecked()); - this->FillStatisticsTableView(this->m_CalculationThread->GetStatisticsData(), this->m_CalculationThread->GetStatisticsImage()); - - auto aStatistic = this->m_CalculationThread->GetStatisticsData(); - auto statisticsNode = mitk::DataNode::New(); - statisticsNode->SetName(m_Controls->m_SelectedFeatureImageLabel->text().toStdString()); - statisticsNode->SetData(aStatistic->Clone()); - statisticsNode->SetProperty("helper object", mitk::BoolProperty::New(true)); - this->GetDataStorage()->Add(statisticsNode); - - } - m_CurrentStatisticsValid = true; - } - } - else - { - m_Controls->m_SelectedMaskLabel->setText("None"); - m_Controls->m_ErrorMessageLabel->setText(m_CalculationThread->GetLastErrorMessage().c_str()); - m_Controls->m_ErrorMessageLabel->show(); - - // Clear statistics and histogram - this->InvalidateStatisticsTableView(); - m_Controls->m_StatisticsWidgetStack->setCurrentIndex(0); - m_CurrentStatisticsValid = false; - - } - berry::IPreferencesService* prefService = berry::WorkbenchPlugin::GetDefault()->GetPreferencesService(); - m_StylePref = prefService->GetSystemPreferences()->Node(berry::QtPreferences::QT_STYLES_NODE); - - this->m_StatisticsUpdatePending = false; -} - -void QmitkImageStatisticsView::FillStatisticsTableView( - mitk::ImageStatisticsContainer::ConstPointer statistics, - const mitk::Image *image) -{ - this->m_Controls->m_StatisticsTable->setColumnCount(image->GetTimeSteps()); - this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(image->GetTimeSteps() > 1); - - // Set Checkbox for complete copy of statistic table - if (image->GetTimeSteps() > 1) - { - this->m_Controls->m_CheckBox4dCompleteTable->setEnabled(true); - } - else - { - this->m_Controls->m_CheckBox4dCompleteTable->setEnabled(false); - this->m_Controls->m_CheckBox4dCompleteTable->setChecked(false); - } - - - for (unsigned int t = 0; t < image->GetTimeSteps(); t++) - { - this->m_Controls->m_StatisticsTable->setHorizontalHeaderItem(t, - new QTableWidgetItem(QString::number(t))); - - auto minIndex = statistics->GetStatisticsForTimeStep(t).GetValueConverted( - mitk::ImageStatisticsConstants::MINIMUMPOSITION()); - auto maxIndex = statistics->GetStatisticsForTimeStep(t).GetValueConverted( - mitk::ImageStatisticsConstants::MAXIMUMPOSITION()); - - if (maxIndex.size() == 3) - { - - mitk::Point3D index, max, min; - index[0] = maxIndex[0]; - index[1] = maxIndex[1]; - index[2] = maxIndex[2]; - m_SelectedImage->GetGeometry()->IndexToWorld(index, max); - this->m_WorldMaxList.push_back(max); - index[0] = minIndex[0]; - index[1] = minIndex[1]; - index[2] = minIndex[2]; - m_SelectedImage->GetGeometry()->IndexToWorld(index, min); - this->m_WorldMinList.push_back(min); - } - - auto statisticsVector = AssembleStatisticsIntoVector(statistics, image); - - unsigned int count = 0; - for (const auto& entry : statisticsVector) { - auto item = new QTableWidgetItem(entry); - this->m_Controls->m_StatisticsTable->setItem(count, t, item); - count++; - } - - } - - - this->m_Controls->m_StatisticsTable->resizeColumnsToContents(); - int height = STAT_TABLE_BASE_HEIGHT; - - if (this->m_Controls->m_StatisticsTable->horizontalHeader()->isVisible()) - height += this->m_Controls->m_StatisticsTable->horizontalHeader()->height(); - - if (this->m_Controls->m_StatisticsTable->horizontalScrollBar()->isVisible()) - height += this->m_Controls->m_StatisticsTable->horizontalScrollBar()->height(); - - this->m_Controls->m_StatisticsTable->setMinimumHeight(height); - - // make sure the current timestep's column is highlighted (and the correct histogram is displayed) - unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()-> - GetPos(); - mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), - t); - this->OnTimeChanged(timeEvent); - - t = std::min(image->GetTimeSteps() - 1, t); - - // See bug 18340 - /*QString hotspotMean; hotspotMean.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMean(), 0, 'f', decimals)); - hotspotMean += " ("; - for (int i=0; im_Controls->m_StatisticsTable->setItem( 7, t, new QTableWidgetItem( hotspotMean ) ); - - QString hotspotMax; hotspotMax.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMax(), 0, 'f', decimals)); - hotspotMax += " ("; - for (int i=0; im_Controls->m_StatisticsTable->setItem( 8, t, new QTableWidgetItem( hotspotMax ) ); - - QString hotspotMin; hotspotMin.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMin(), 0, 'f', decimals)); - hotspotMin += " ("; - for (int i=0; im_Controls->m_StatisticsTable->setItem( 9, t, new QTableWidgetItem( hotspotMin ) );*/ -} - -std::vector QmitkImageStatisticsView::AssembleStatisticsIntoVector(mitk::ImageStatisticsContainer::ConstPointer statistics, mitk::Image::ConstPointer image, bool noVolumeDefined) const -{ - std::vector result; - - unsigned int decimals = 2; - - //statistics of higher order should have 5 decimal places because they used to be very small - unsigned int decimalsHigherOrderStatistics = 5; - - if (image->GetPixelType().GetComponentType() == itk::ImageIOBase::DOUBLE || image->GetPixelType().GetComponentType() == itk::ImageIOBase::FLOAT) - { - decimals = 5; - } - auto statistic = statistics->GetStatisticsForTimeStep(0); - result.push_back(GetFormattedString( - statistic.GetValueConverted(mitk::ImageStatisticsConstants::MEAN()), decimals)); - result.push_back(GetFormattedString( - statistic.GetValueConverted(mitk::ImageStatisticsConstants::MEDIAN()), decimals)); - result.push_back(GetFormattedString( - statistic.GetValueConverted(mitk::ImageStatisticsConstants::STANDARDDEVIATION()), decimals)); - result.push_back(GetFormattedString( - statistic.GetValueConverted(mitk::ImageStatisticsConstants::RMS()), decimals)); - result.push_back(GetFormattedString( - statistic.GetValueConverted(mitk::ImageStatisticsConstants::MAXIMUM()), decimals) + - " " + GetFormattedIndex(statistic.GetValueConverted(mitk::ImageStatisticsConstants::MAXIMUMPOSITION()))); - result.push_back(GetFormattedString( - statistic.GetValueConverted(mitk::ImageStatisticsConstants::MINIMUM()), decimals) + - " " + GetFormattedIndex(statistic.GetValueConverted(mitk::ImageStatisticsConstants::MINIMUMPOSITION()))); - - auto numberVoxels = statistic.GetValueConverted(mitk::ImageStatisticsConstants::NUMBEROFVOXELS()); - //to prevent large negative values of empty image statistics - if (numberVoxels != std::numeric_limits::min()) { - result.push_back(GetFormattedString(numberVoxels, 0)); - - const mitk::BaseGeometry *geometry = image->GetGeometry(); - if (geometry != NULL && !noVolumeDefined) - { - const mitk::Vector3D &spacing = image->GetGeometry()->GetSpacing(); - double volume = spacing[0] * spacing[1] * spacing[2] * static_cast(numberVoxels); - result.push_back(GetFormattedString(volume, decimals)); - } - else { - result.push_back("NA"); - } - } - else { - result.push_back("NA"); - result.push_back("NA"); - } - - result.push_back( - GetFormattedString(statistic.GetValueConverted(mitk::ImageStatisticsConstants::SKEWNESS()), decimalsHigherOrderStatistics)); - result.push_back( - GetFormattedString(statistic.GetValueConverted(mitk::ImageStatisticsConstants::KURTOSIS()), decimalsHigherOrderStatistics)); - result.push_back( - GetFormattedString(statistic.GetValueConverted(mitk::ImageStatisticsConstants::UNIFORMITY()), decimalsHigherOrderStatistics)); - result.push_back( - GetFormattedString(statistic.GetValueConverted(mitk::ImageStatisticsConstants::ENTROPY()), decimalsHigherOrderStatistics)); - result.push_back( - GetFormattedString(statistic.GetValueConverted(mitk::ImageStatisticsConstants::MPP()), decimals)); - result.push_back( - GetFormattedString(statistic.GetValueConverted(mitk::ImageStatisticsConstants::UPP()), decimalsHigherOrderStatistics)); - - return result; -} - -void QmitkImageStatisticsView::FillLinearProfileStatisticsTableView(mitk::ImageStatisticsContainer::ConstPointer statistics, - const mitk::Image *image) -{ - this->m_Controls->m_StatisticsTable->setColumnCount(1); - this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(false); - - m_PlanarFigureStatistics = this->AssembleStatisticsIntoVector(statistics, image, true); - - for (unsigned int i = 0; i < m_PlanarFigureStatistics.size(); i++) - { - this->m_Controls->m_StatisticsTable->setItem(i, 0, new QTableWidgetItem(m_PlanarFigureStatistics[i])); - } - - this->m_Controls->m_StatisticsTable->resizeColumnsToContents(); - int height = STAT_TABLE_BASE_HEIGHT; - - if (this->m_Controls->m_StatisticsTable->horizontalHeader()->isVisible()) - height += this->m_Controls->m_StatisticsTable->horizontalHeader()->height(); - - if (this->m_Controls->m_StatisticsTable->horizontalScrollBar()->isVisible()) - height += this->m_Controls->m_StatisticsTable->horizontalScrollBar()->height(); - - this->m_Controls->m_StatisticsTable->setMinimumHeight(height); -} - -void QmitkImageStatisticsView::InvalidateStatisticsTableView() -{ - this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(false); - this->m_Controls->m_StatisticsTable->setColumnCount(1); - - for (int i = 0; i < this->m_Controls->m_StatisticsTable->rowCount(); ++i) - { - { - this->m_Controls->m_StatisticsTable->setItem(i, 0, new QTableWidgetItem("NA")); - } - } - - this->m_Controls->m_StatisticsTable->setMinimumHeight(STAT_TABLE_BASE_HEIGHT); -} - -void QmitkImageStatisticsView::Activated() -{ -} - -void QmitkImageStatisticsView::Deactivated() -{ -} - -void QmitkImageStatisticsView::Visible() -{ - m_Visible = true; - - mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart(); - - if (renderWindow) - { - itk::ReceptorMemberCommand::Pointer cmdTimeEvent = - itk::ReceptorMemberCommand::New(); - cmdTimeEvent->SetCallbackFunction(this, &QmitkImageStatisticsView::OnTimeChanged); - - // It is sufficient to add the observer to the axial render window since the GeometryTimeEvent - // is always triggered by all views. - m_TimeObserverTag = renderWindow->GetQmitkRenderWindow("axial")-> - GetSliceNavigationController()-> - AddObserver(mitk::SliceNavigationController::GeometryTimeEvent(nullptr, 0), cmdTimeEvent); - } - - if (m_DataNodeSelectionChanged) - { - if (this->IsCurrentSelectionValid()) - { - this->SelectionChanged(this->GetCurrentSelection()); - } - else - { - this->SelectionChanged(this->GetDataManagerSelection()); - } - m_DataNodeSelectionChanged = false; - } -} - -void QmitkImageStatisticsView::Hidden() -{ - m_Visible = false; - - // The slice navigation controller observer is removed here instead of in the destructor. - // If it was called in the destructor, the application would freeze because the view's - // destructor gets called after the render windows have been destructed. - if (m_TimeObserverTag != 0) - { - mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart(); - - if (renderWindow) - { - renderWindow->GetQmitkRenderWindow("axial")->GetSliceNavigationController()-> - RemoveObserver(m_TimeObserverTag); - } - m_TimeObserverTag = 0; - } -} - -void QmitkImageStatisticsView::SetFocus() -{ -} - -std::map QmitkImageStatisticsView::ConvertHistogramToMap(itk::Statistics::Histogram::ConstPointer histogram) const -{ - std::map histogramMap; - - auto endIt = histogram->End(); - auto it = histogram->Begin(); - - // generating Lists of measurement and frequencies - for (; it != endIt; ++it) - { - double frequency = it.GetFrequency(); - double measurement = it.GetMeasurementVector()[0]; - histogramMap.emplace(measurement, frequency); - } - - return histogramMap; -} - -std::vector QmitkImageStatisticsView::ConvertIntensityProfileToVector(mitk::IntensityProfile::ConstPointer intensityProfile) const -{ - std::vector intensityProfileList; - auto end = intensityProfile->End(); - - for (auto it = intensityProfile->Begin(); it != end; ++it) - { - intensityProfileList.push_back(it.GetMeasurementVector()[0]); - } - return intensityProfileList; -} - -QString QmitkImageStatisticsView::GetFormattedString(double value, unsigned int decimals) const -{ - typedef mitk::ImageStatisticsContainer::RealType RealType; - RealType maxVal = std::numeric_limits::max(); - - if (value == maxVal) - { - return QString("NA"); - } - else - { - return QString("%1").arg(value, 0, 'f', decimals); - } -} - -QString QmitkImageStatisticsView::GetFormattedIndex(const vnl_vector& vector) const -{ - if (vector.empty()) { - return QString(); - } - QString formattedIndex("("); - for (const auto& entry : vector) - { - formattedIndex += QString::number(entry); - formattedIndex += ","; - } - formattedIndex.chop(1); - formattedIndex += ")"; - return formattedIndex; -} diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h deleted file mode 100644 index e49ee842d2..0000000000 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.h +++ /dev/null @@ -1,191 +0,0 @@ -/*=================================================================== - -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 QmitkImageStatisticsView_H__INCLUDED -#define QmitkImageStatisticsView_H__INCLUDED - -#include "ui_QmitkImageStatisticsViewControls.h" - -// Qmitk includes -#include -#include -#include -#include - -// mitk includes -#include -#include -#include - -#include - -/*! -\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, public mitk::ILifecycleAwarePart, public berry::IPartListener -{ - Q_OBJECT - -private: - /*! - \ Convenient typedefs */ - typedef QList SelectedDataNodeVectorType; - typedef itk::SimpleMemberCommand< QmitkImageStatisticsView > ITKCommandType; - - std::map ConvertHistogramToMap(itk::Statistics::Histogram::ConstPointer histogram) const; - std::vector ConvertIntensityProfileToVector(mitk::IntensityProfile::ConstPointer intensityProfile) const; - std::vector AssembleStatisticsIntoVector(mitk::ImageStatisticsContainer::ConstPointer statistics, mitk::Image::ConstPointer image, bool noVolumeDefined=false) const; - - QString GetFormattedIndex(const vnl_vector& vector) const; - QString GetFormattedString(double value, unsigned int decimals) const; -public: - - /*! - \brief default constructor */ - QmitkImageStatisticsView(QObject *parent = nullptr, const char *name = nullptr); - /*! - \brief default destructor */ - virtual ~QmitkImageStatisticsView(); - /*! - \brief method for creating the widget containing the application controls, like sliders, buttons etc. */ - virtual void CreateQtPartControl(QWidget *parent) override; - /*! - \brief method for creating the connections of main and control widget */ - virtual void CreateConnections(); - /*! - \brief Is called from the selection mechanism once the data manager selection has changed*/ - void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &selectedNodes) override; - - static const std::string VIEW_ID; - static const int STAT_TABLE_BASE_HEIGHT; - - public slots: - /** \brief Called when the statistics update is finished, sets the results to GUI.*/ - void OnThreadedStatisticsCalculationEnds(); - - /** \brief Update bin size for histogram resolution. */ - void OnHistogramNBinsCheckBoxValueChanged(); - - protected slots: - /** \brief Saves the histogram to the clipboard */ - void OnClipboardHistogramButtonClicked(); - /** \brief Saves the statistics to the clipboard */ - void OnClipboardStatisticsButtonClicked(); - /** \brief Indicates if zeros should be excluded from statistics calculation */ - void OnIgnoreZerosCheckboxClicked(); - /** \brief Checks if update is possible and calls StatisticsUpdate() possible */ - void RequestStatisticsUpdate(); - /** \brief Jump to coordinates stored in the double clicked cell */ - void JumpToCoordinates(int row, int col); - /** \brief Toogle GUI elements if histogram default bin size checkbox value changed. */ - void OnDefaultNBinsSpinBoxChanged(); - - void OnShowSubchartBoxChanged(); - - void OnBarRadioButtonSelected(); - - void OnLineRadioButtonSelected(); - - void OnPageSuccessfullyLoaded(); - -signals: - /** \brief Method to set the data to the member and start the threaded statistics update */ - void StatisticsUpdate(); - -protected: - /** \brief Writes the calculated statistics to the GUI */ - void FillStatisticsTableView(mitk::ImageStatisticsContainer::ConstPointer statistics, - const mitk::Image *image); - - void FillLinearProfileStatisticsTableView(mitk::ImageStatisticsContainer::ConstPointer statistics, const mitk::Image *image); - - /** \brief Removes statistics from the GUI */ - void InvalidateStatisticsTableView(); - - /** \brief Recalculate statistics for currently selected image and mask and - * update the GUI. */ - void UpdateStatistics(); - - virtual void Activated() override; - virtual void Deactivated() override; - virtual void Visible() override; - virtual void Hidden() override; - - virtual void SetFocus() override; - - /** \brief Method called when itkModifiedEvent is called by selected data. */ - void SelectedDataModified(); - /** \brief Method called when the data manager selection changes */ - void SelectionChanged(const QList &selectedNodes); - - void DisableHistogramGUIElements(); - - void ResetHistogramGUIElementsToDefault(); - - void EnableHistogramGUIElements(); - - /** \brief Method called to remove old selection when a new selection is present */ - void ReinitData(); - /** \brief writes the statistics to the gui*/ - void WriteStatisticsToGUI(); - - void NodeRemoved(const mitk::DataNode *node) override; - - /** \brief Is called right before the view closes (before the destructor) */ - virtual void PartClosed(const berry::IWorkbenchPartReference::Pointer&) override; - /** \brief Is called from the image navigator once the time step has changed */ - void OnTimeChanged(const itk::EventObject&); - /** \brief Required for berry::IPartListener */ - virtual Events::Types GetPartEventTypes() const override { return Events::CLOSED; } - - // member variables - Ui::QmitkImageStatisticsViewControls *m_Controls; - // if you have a planar figure selected, the statistics values will be saved in this one. - std::vector m_PlanarFigureStatistics; - QmitkImageStatisticsCalculationJob* m_CalculationThread; - - // Image and mask data - mitk::Image* m_SelectedImage; - mitk::Image* m_SelectedImageMask; - mitk::PlanarFigure* m_SelectedPlanarFigure; - - // observer tags - long m_ImageObserverTag; - long m_ImageMaskObserverTag; - long m_PlanarFigureObserverTag; - long m_TimeObserverTag; - - SelectedDataNodeVectorType m_SelectedDataNodes; - - bool m_CurrentStatisticsValid; - bool m_StatisticsUpdatePending; - bool m_DataNodeSelectionChanged; - bool m_Visible; - - unsigned int m_HistogramNBins; - - std::vector m_WorldMinList; - std::vector m_WorldMaxList; - - std::vector m_IntensityProfileList; - berry::IPreferences::Pointer m_StylePref; -}; -#endif // QmitkImageStatisticsView_H__INCLUDED diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui deleted file mode 100644 index d0171ca775..0000000000 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui +++ /dev/null @@ -1,747 +0,0 @@ - - - QmitkImageStatisticsViewControls - - - true - - - - 0 - 0 - 548 - 812 - - - - Form - - - - - - - - - - - 255 - 0 - 4 - - - - - - - 255 - 0 - 4 - - - - - - - 255 - 0 - 4 - - - - - - - - - 255 - 0 - 4 - - - - - - - 255 - 0 - 4 - - - - - - - 255 - 0 - 4 - - - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - 120 - 120 - 120 - - - - - - - - This plugin is deprecated. Consider using the new image statistics plugin (icon with star). - - - - - - - - - - 0 - 0 - - - - Qt::LeftToRight - - - Feature Image: - - - - - - - - 0 - 0 - - - - None - - - - - - - - 0 - 0 - - - - Mask: - - - - - - - - 0 - 0 - - - - None - - - -1 - - - - - - - - 0 - 0 - - - - color: rgb(255, 0, 0); - - - Error Message - - - Qt::AutoText - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - Ignore zero-valued voxels - - - - - - - false - - - Statistics - - - - 9 - - - 9 - - - 9 - - - - - - 100 - 180 - - - - - 16777215 - 16777215 - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - true - - - QAbstractItemView::NoEditTriggers - - - true - - - true - - - Qt::DotLine - - - false - - - 14 - - - 1 - - - false - - - false - - - 80 - - - true - - - 80 - - - false - - - true - - - true - - - false - - - 25 - - - 25 - - - false - - - false - - - - Mean - - - - - Median - - - - - StdDev - - - - - RMS - - - - - Max - - - - - Min - - - - - N - - - - - V (mm³) - - - - - Skewness - - - - - Kurtosis - - - - - Uniformity - - - - - Entropy - - - - - MPP - - - - - UPP - - - - - 0 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Copy to Clipboard - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - false - - - copy complete table - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - false - - - - 400 - 450 - - - - Histogram - - - false - - - - - - false - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Plot - - - - - - - - - 0 - 0 - - - - - - - Barchart - - - true - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Linegraph - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Show Subchart - - - true - - - - - - - Use default #bins - - - true - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 60 - 0 - - - - - 100 - 16777215 - - - - # bins: - - - - - - - false - - - Press enter to recalculate statistics with new bin size. - - - 1 - - - 10000 - - - 100 - - - - - - - - - - - - - - 0 - 0 - - - - 0 - - - - - 0 - 0 - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Copy to Clipboard - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - QmitkChartWidget - QWidget -
QmitkChartWidget.h
-
-
- - -
diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp index 259a13aeeb..ad305f2275 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp @@ -1,41 +1,39 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPluginActivator.h" #include "QmitkMeasurementView.h" -#include "QmitkImageStatisticsView.h" #include "QmitkImageStatisticsReloadedView.h" ctkPluginContext* mitk::PluginActivator::m_Context = nullptr; ctkPluginContext* mitk::PluginActivator::GetContext() { return m_Context; } void mitk::PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkMeasurementView, context) - BERRY_REGISTER_EXTENSION_CLASS(QmitkImageStatisticsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkImageStatisticsReloadedView, context) m_Context = context; } void mitk::PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = nullptr; }