diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp index 0ba410b53a..3441c6c5cb 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp +++ b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp @@ -1,190 +1,181 @@ /*=================================================================== 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 namespace mitk { StatisticsContainer::StatisticsContainer(): m_N(0), m_Volume(nan("")), m_Mean(nan("")), m_Min(nan("")), m_Max(nan("")), m_Std(nan("")), m_Skewness(nan("")), m_Kurtosis(nan("")), m_RMS(nan("")), m_MPP(nan("")), m_Median(nan("")), m_Uniformity(nan("")), m_UPP(nan("")), m_Entropy(nan("")), m_Label(0) { m_MinIndex.set_size(0); m_MaxIndex.set_size(0); } StatisticsContainer::RealType StatisticsContainer::GetVariance() const { return m_Std * m_Std; } void StatisticsContainer::SetHistogram(HistogramType::Pointer hist) { if (m_Histogram != hist) { m_Histogram = hist; } } void StatisticsContainer::PrintSelf(std::ostream &os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); - auto statisticsMap = GetStatisticsAsMap(); + auto statistics = GetStatisticsAsOrderedVector(); os << std::endl << indent << "Statistics instance:"; - for (const auto& aStatisticValue : statisticsMap) { + for (const auto& aStatisticValue : statistics) { os << std::endl << indent.GetNextIndent() << aStatisticValue.first << ": " << aStatisticValue.second; } } - StatisticsContainer::statisticsMapType StatisticsContainer::GetStatisticsAsMap() const - { - statisticsMapType statisticsAsMap; - - statisticsAsMap["#Voxel"] = m_N; - statisticsAsMap["Volume [mm^3]"] = m_Volume; - statisticsAsMap["Mean"] = m_Mean; - statisticsAsMap["Min"] = m_Min; - statisticsAsMap["Max"] = m_Max; - statisticsAsMap["StandardDeviation"] = m_Std; - statisticsAsMap["Skewness"] = m_Skewness; - statisticsAsMap["Kurtosis"] = m_Kurtosis; - statisticsAsMap["RMS"] = m_RMS; - statisticsAsMap["MPP"] = m_MPP; - statisticsAsMap["Median"] = m_Median; - statisticsAsMap["Uniformity"] = m_Uniformity; - statisticsAsMap["UPP"] = m_UPP; - statisticsAsMap["Entropy"] = m_Entropy; - statisticsAsMap["Label"] = m_Label; - - return statisticsAsMap; - } - StatisticsContainer::statisticsOrderedVectorType StatisticsContainer::GetStatisticsAsOrderedVector() const { statisticsOrderedVectorType statisticsAsVector; - statisticsAsVector.emplace_back(std::make_pair("Mean", m_Mean)); - statisticsAsVector.emplace_back(std::make_pair("Median", m_Median)); - statisticsAsVector.emplace_back(std::make_pair("StandardDeviation", m_Std)); - statisticsAsVector.emplace_back(std::make_pair("RMS", m_RMS)); - statisticsAsVector.emplace_back(std::make_pair("Max", m_Max)); - statisticsAsVector.emplace_back(std::make_pair("Min", m_Min)); - statisticsAsVector.emplace_back(std::make_pair("#Voxel", m_N)); - statisticsAsVector.emplace_back(std::make_pair("Volume [mm^3]", m_Volume)); - statisticsAsVector.emplace_back(std::make_pair("Skewness", m_Skewness)); - statisticsAsVector.emplace_back(std::make_pair("Kurtosis", m_Kurtosis)); - statisticsAsVector.emplace_back(std::make_pair("Uniformity", m_Uniformity)); - statisticsAsVector.emplace_back(std::make_pair("Entropy", m_Entropy)); - statisticsAsVector.emplace_back(std::make_pair("MPP", m_MPP)); - statisticsAsVector.emplace_back(std::make_pair("UPP", m_UPP)); + statisticsAsVector.emplace_back(std::make_pair("Mean", std::to_string(m_Mean))); + statisticsAsVector.emplace_back(std::make_pair("Median", std::to_string(m_Median))); + statisticsAsVector.emplace_back(std::make_pair("StandardDeviation", std::to_string(m_Std))); + statisticsAsVector.emplace_back(std::make_pair("RMS", std::to_string(m_RMS))); + statisticsAsVector.emplace_back(std::make_pair("Max", std::to_string( m_Max))); + statisticsAsVector.emplace_back(std::make_pair("MaxPosition", convertToString(m_MaxIndex))); + statisticsAsVector.emplace_back(std::make_pair("Min", std::to_string(m_Min))); + statisticsAsVector.emplace_back(std::make_pair("MinPosition", convertToString(m_MinIndex))); + statisticsAsVector.emplace_back(std::make_pair("#Voxel", std::to_string(m_N))); + statisticsAsVector.emplace_back(std::make_pair("Volume [mm^3]", std::to_string(m_Volume))); + statisticsAsVector.emplace_back(std::make_pair("Skewness", std::to_string(m_Skewness))); + statisticsAsVector.emplace_back(std::make_pair("Kurtosis", std::to_string(m_Kurtosis))); + statisticsAsVector.emplace_back(std::make_pair("Uniformity", std::to_string(m_Uniformity))); + statisticsAsVector.emplace_back(std::make_pair("Entropy", std::to_string(m_Entropy))); + statisticsAsVector.emplace_back(std::make_pair("MPP", std::to_string(m_MPP))); + statisticsAsVector.emplace_back(std::make_pair("UPP", std::to_string(m_UPP))); return statisticsAsVector; } void StatisticsContainer::Reset() { m_N = 0; m_Volume = nan(""); m_Mean = nan(""); m_Min = nan(""); m_Max = nan(""); m_Std = nan(""); m_Skewness = nan(""); m_Kurtosis = nan(""); m_RMS = nan(""); m_MPP = nan(""); m_Median = nan(""); m_Uniformity = nan(""); m_UPP = nan(""); m_Entropy = nan(""); m_Histogram = HistogramType::New(); m_MinIndex.set_size(0); m_MaxIndex.set_size(0); m_Label = 0; } itk::LightObject::Pointer StatisticsContainer::InternalClone() const { itk::LightObject::Pointer ioPtr = Superclass::InternalClone(); Self::Pointer rval = dynamic_cast(ioPtr.GetPointer()); if (rval.IsNull()) { itkExceptionMacro(<< "downcast to type " << "StatisticsContainer" << " failed."); } rval->SetEntropy(this->GetEntropy()); rval->SetKurtosis(this->GetKurtosis()); rval->SetLabel(this->GetLabel()); rval->SetMax(this->GetMax()); rval->SetMin(this->GetMin()); rval->SetMean(this->GetMean()); rval->SetMedian(this->GetMedian()); rval->SetMPP(this->GetMPP()); rval->SetN(this->GetN()); rval->SetVolume(this->GetVolume()); rval->SetRMS(this->GetRMS()); rval->SetSkewness(this->GetSkewness()); rval->SetStd(this->GetStd()); rval->SetUniformity(this->GetUniformity()); rval->SetUPP(this->GetUPP()); rval->SetHistogram(this->GetHistogram()); rval->SetMinIndex(this->GetMinIndex()); rval->SetMaxIndex(this->GetMaxIndex()); return ioPtr; } + std::string StatisticsContainer::convertToString(const vnl_vector& index) const + { + std::string result; + for (const auto& aValue : index) { + if (!result.empty()) { + result += "/"; + } + result += std::to_string(aValue); + } + return result; + } + void StatisticsContainer::Print() { - statisticsMapType statMap = this->GetStatisticsAsMap(); + auto statistics = this->GetStatisticsAsOrderedVector(); // print all map key value pairs // const auto& val:statMap - for (auto it = statMap.begin(); it != statMap.end(); ++it) + for (auto it = statistics.begin(); it != statistics.end(); ++it) { std::cout << it->first << ": " << it->second << std::endl; } // print the min and max index std::cout << "Min Index:" << std::endl; for (auto it = this->GetMinIndex().begin(); it != this->GetMinIndex().end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; // print the min and max index std::cout << "Max Index:" << std::endl; for (auto it = this->GetMaxIndex().begin(); it != this->GetMaxIndex().end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; } } diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainer.h b/Modules/ImageStatistics/mitkImageStatisticsContainer.h index 7ae4f4670c..19fa778f6f 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainer.h +++ b/Modules/ImageStatistics/mitkImageStatisticsContainer.h @@ -1,164 +1,161 @@ /*=================================================================== 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 MITKIMAGESTATISTICSCONTAINER #define MITKIMAGESTATISTICSCONTAINER #include #include #include namespace mitk { /**Documentation @brief Container class for storing the computed image statistics. - Container class for storing the computed image statistics. Stored statistics are: + Stored statistics are: - N: number of voxels - Mean - MPP (Mean of positive pixels) - Median - Skewness - Kurtosis - Uniformity - UPP (Uniformity of positive pixels) - Std (Standard Deviation) - Min - Max - RMS (Root Mean Square) - Label (if applicable, the label (unsigned short) of the mask the statistics belong to) - Entropy - - It furthermore stores the following: - MinIndex (Index of Image where the Minimum is located) - MaxIndex (Index of Image where the Maximum is located) - Histogram of Pixel Values*/ class MITKIMAGESTATISTICS_EXPORT StatisticsContainer : public mitk::BaseData { public: mitkClassMacro(StatisticsContainer, mitk::BaseData) /** Method for creation through the object factory. */ itkNewMacro(Self) typedef itk::Statistics::Histogram HistogramType; typedef double RealType; - typedef std::map statisticsMapType; - typedef std::vector < std::pair > statisticsOrderedVectorType; + typedef std::vector < std::pair > statisticsOrderedVectorType; virtual void SetRequestedRegionToLargestPossibleRegion() override {}; virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override { return false; }; virtual bool VerifyRequestedRegion() override { return true; }; virtual void SetRequestedRegion(const itk::DataObject*) override {}; /**Documentation - @brief Returns a std::map containing all real valued statistics stored in this class (= all statistics except minIndex, maxIndex and the histogram)*/ - statisticsMapType GetStatisticsAsMap() const; + @brief Returns a std::vector); itkGetConstMacro(MinIndex, vnl_vector); itkSetMacro(MaxIndex, vnl_vector); itkGetConstMacro(MaxIndex, vnl_vector); void SetHistogram(HistogramType::Pointer hist); itkGetConstMacro(Histogram, HistogramType::Pointer); itkSetMacro(Entropy, RealType); itkGetConstMacro(Entropy, RealType); itkSetMacro(Median, RealType); itkGetConstMacro(Median, RealType); itkSetMacro(Uniformity, RealType); itkGetConstMacro(Uniformity, RealType); itkSetMacro(UPP, RealType); itkGetConstMacro(UPP, RealType); /**Documentation @brief Creates a StatisticsMapType containing all real valued statistics stored in this class (= all statistics except minIndex, maxIndex and the histogram) and prints its contents to std::cout*/ void Print(); protected: StatisticsContainer(); virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override; private: itk::LightObject::Pointer InternalClone() const override; + std::string convertToString(const vnl_vector& index) const; long m_N; RealType m_Volume; RealType m_Mean, m_Min, m_Max, m_Std; RealType m_Skewness; RealType m_Kurtosis; RealType m_RMS; RealType m_MPP; vnl_vector m_MinIndex, m_MaxIndex; RealType m_Median; RealType m_Uniformity; RealType m_UPP; RealType m_Entropy; unsigned int m_Label; HistogramType::Pointer m_Histogram; }; } #endif // MITKIMAGESTATISTICSCONTAINER diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTableModel.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTableModel.cpp index b3c46fd741..959e3b5688 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTableModel.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsTableModel.cpp @@ -1,154 +1,165 @@ /*=================================================================== 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 "QmitkImageStatisticsTableModel.h" QmitkImageStatisticsTableModel::QmitkImageStatisticsTableModel(QObject *parent) : QAbstractTableModel(parent) {} int QmitkImageStatisticsTableModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } if (!m_statistics.empty()){ return static_cast(m_statistics.front()->GetStatisticsAsOrderedVector().size()); } else { return 0; } } int QmitkImageStatisticsTableModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; return static_cast(m_statistics.size()); } QVariant QmitkImageStatisticsTableModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); QVariant result; if (m_viewMode == viewMode::imageXStatistic) { - if (!m_statistics.empty() && index.row() < static_cast(m_statistics.front()->GetStatisticsAsMap().size()) && index.column() < static_cast(m_statistics.size())) + if (!m_statistics.empty() && index.row() < m_statistics.front()->GetStatisticsAsOrderedVector().size() && index.column() < m_statistics.size()) { if (Qt::DisplayRole == role) { - result = QVariant(m_statistics.at(index.column())->GetStatisticsAsOrderedVector().at(index.row()).second); + auto statistics = m_statistics.at(index.column()); + auto statisticsVector = statistics->GetStatisticsAsOrderedVector(); + auto statisticsValueString = statisticsVector.at(index.row()).second; + result = QVariant(QString::fromStdString(statisticsValueString)); } else if (Qt::UserRole == role) { result = QVariant(index.row()); } } } return result; } Qt::ItemFlags QmitkImageStatisticsTableModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); return flags; } QVariant QmitkImageStatisticsTableModel::headerData(int section, Qt::Orientation orientation, int role) const { - if ((Qt::DisplayRole == role) && (Qt::Horizontal == orientation)) { if (!m_imageNodes.empty()) { if (m_viewMode == viewMode::imageXStatistic) { std::string maskName; if (!m_maskNodes.empty() && m_maskNodes.size() == m_imageNodes.size()) { maskName = " / " + m_maskNodes.at(section)->GetName(); } - return QVariant((m_imageNodes.at(section)->GetName() + maskName).c_str()); + return QVariant((m_imageNodes.at(section)->GetName() + maskName + std::to_string(section)).c_str()); } } } else if ((Qt::DisplayRole == role) && (Qt::Vertical == orientation)){ if (!m_statistics.empty()) { if (m_viewMode == viewMode::imageXStatistic) { return QVariant(m_statisticNames.at(section).c_str()); } } } return QVariant(); } void QmitkImageStatisticsTableModel::SetStatistics(const std::vector& statistics) { emit beginResetModel(); m_statistics = statistics; if (m_statisticNames.empty() && !statistics.empty()) { auto firstStatisticAsMap = statistics.front()->GetStatisticsAsOrderedVector(); for (const auto& keyValue : firstStatisticAsMap) { m_statisticNames.push_back(keyValue.first); } } emit endResetModel(); emit dataChanged(QModelIndex(), QModelIndex()); } void QmitkImageStatisticsTableModel::SetImageNodes(const std::vector& nodes) { - m_imageNodes = nodes; + std::vector tempNodes; + for (int i = 0; i < nodes.size(); i++) + { + int timeSteps = nodes.at(i)->GetData()->GetTimeSteps(); + for (int j = 0; j < timeSteps; j++) + { + tempNodes.push_back(nodes.at(i)); + } + } + m_imageNodes = tempNodes; } void QmitkImageStatisticsTableModel::SetMaskNodes(const std::vector& nodes) { m_maskNodes = nodes; } void QmitkImageStatisticsTableModel::SetViewMode(viewMode m) { m_viewMode = m; } void QmitkImageStatisticsTableModel::SetStatisticsToShow(const std::vector& statisticNames) { m_statisticNamesToShow = statisticNames; } void QmitkImageStatisticsTableModel::SetStatisticsToIgnore(const std::vector& statisticNames) { m_statisticNamesToIgnore = statisticNames; } void QmitkImageStatisticsTableModel::Clear() { emit beginResetModel(); m_statistics.clear(); m_imageNodes.clear(); m_maskNodes.clear(); m_statisticNamesToIgnore.clear(); m_statisticNamesToShow.clear(); m_statisticNames.clear(); emit endResetModel(); emit dataChanged(QModelIndex(), QModelIndex()); }