diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp index 2bc4794ec2..241009d34a 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp +++ b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp @@ -1,210 +1,235 @@ /*=================================================================== 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 #include namespace mitk { - ImageStatisticsContainer::ImageStatisticsContainer() + ImageStatisticsContainer::ImageStatisticsContainer() { this->Reset(); } + + // The order is derived from the old (<2018) image statistics plugin. + const ImageStatisticsContainer::StatisticsObject::StatisticNameVector + ImageStatisticsContainer::StatisticsObject::m_DefaultNames = {ImageStatisticsConstants::MEAN(), + ImageStatisticsConstants::MEDIAN(), + ImageStatisticsConstants::STANDARDDEVIATION(), + ImageStatisticsConstants::RMS(), + ImageStatisticsConstants::MAXIMUM(), + ImageStatisticsConstants::MAXIMUMPOSITION(), + ImageStatisticsConstants::MINIMUM(), + ImageStatisticsConstants::MINIMUMPOSITION(), + ImageStatisticsConstants::NUMBEROFVOXELS(), + ImageStatisticsConstants::VOLUME(), + ImageStatisticsConstants::SKEWNESS(), + ImageStatisticsConstants::KURTOSIS(), + ImageStatisticsConstants::UNIFORMITY(), + ImageStatisticsConstants::ENTROPY(), + ImageStatisticsConstants::MPP(), + ImageStatisticsConstants::UPP()}; + + ImageStatisticsContainer::StatisticsObject::StatisticsObject() { Reset(); } + + void ImageStatisticsContainer::StatisticsObject::AddStatistic(const std::string &key, StatisticsVariantType value) + { + m_Statistics.emplace(key, value); + + if (std::find(std::cbegin(m_DefaultNames), std::cend(m_DefaultNames), key) == std::cend(m_DefaultNames)) { - this->Reset(); - } - - //The order is derived from the old (<2018) image statistics plugin. - const ImageStatisticsContainer::StatisticsObject::StatisticNameVector ImageStatisticsContainer::StatisticsObject::m_DefaultNames = { - ImageStatisticsConstants::MEAN(), - ImageStatisticsConstants::MEDIAN(), - ImageStatisticsConstants::STANDARDDEVIATION(), - ImageStatisticsConstants::RMS(), - ImageStatisticsConstants::MAXIMUM(), - ImageStatisticsConstants::MAXIMUMPOSITION(), - ImageStatisticsConstants::MINIMUM(), - ImageStatisticsConstants::MINIMUMPOSITION(), - ImageStatisticsConstants::NUMBEROFVOXELS(), - ImageStatisticsConstants::VOLUME(), - ImageStatisticsConstants::SKEWNESS(), - ImageStatisticsConstants::KURTOSIS(), - ImageStatisticsConstants::UNIFORMITY(), - ImageStatisticsConstants::ENTROPY(), - ImageStatisticsConstants::MPP(), - ImageStatisticsConstants::UPP() }; - - ImageStatisticsContainer::StatisticsObject::StatisticsObject() { - Reset(); - } - - void ImageStatisticsContainer::StatisticsObject::AddStatistic(const std::string& key, StatisticsVariantType value) - { - m_Statistics.emplace(key, value); - - if (std::find(std::cbegin(m_DefaultNames), std::cend(m_DefaultNames), key)==std::cend(m_DefaultNames)) + if (std::find(std::cbegin(m_CustomNames), std::cend(m_CustomNames), key) == std::cend(m_CustomNames)) { - if (std::find(std::cbegin(m_CustomNames), std::cend(m_CustomNames), key) == std::cend(m_CustomNames)) - { - m_CustomNames.emplace_back(key); - } + m_CustomNames.emplace_back(key); } } + } - const ImageStatisticsContainer::StatisticsObject::StatisticNameVector& ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames() - { - return m_DefaultNames; - }; + const ImageStatisticsContainer::StatisticsObject::StatisticNameVector & + ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames() + { + return m_DefaultNames; + }; - const ImageStatisticsContainer::StatisticsObject::StatisticNameVector& ImageStatisticsContainer::StatisticsObject::GetCustomStatisticNames() const - { - return m_CustomNames; - } + const ImageStatisticsContainer::StatisticsObject::StatisticNameVector & + ImageStatisticsContainer::StatisticsObject::GetCustomStatisticNames() const + { + return m_CustomNames; + } - ImageStatisticsContainer::StatisticsObject::StatisticNameVector ImageStatisticsContainer::StatisticsObject::GetAllStatisticNames() const - { - StatisticNameVector names = GetDefaultStatisticNames(); - names.insert(std::end(names),std::cbegin(m_CustomNames), std::cend(m_CustomNames)); + ImageStatisticsContainer::StatisticsObject::StatisticNameVector + ImageStatisticsContainer::StatisticsObject::GetAllStatisticNames() const + { + StatisticNameVector names = GetDefaultStatisticNames(); - return names; - } + names.insert(std::end(names), std::cbegin(m_CustomNames), std::cend(m_CustomNames)); + + return names; + } - bool ImageStatisticsContainer::StatisticsObject::HasStatistic(const std::string& name) const + ImageStatisticsContainer::StatisticsObject::StatisticNameVector + ImageStatisticsContainer::StatisticsObject::GetExistingStatisticNames() const + { + StatisticNameVector names; + + std::transform(m_Statistics.begin(), m_Statistics.end(), std::back_inserter(names), [](const auto &pair) { + return pair.first; + }); + + return names; + } + + bool ImageStatisticsContainer::StatisticsObject::HasStatistic(const std::string &name) const + { + return m_Statistics.find(name) != std::cend(m_Statistics); + } + + ImageStatisticsContainer::StatisticsVariantType ImageStatisticsContainer::StatisticsObject::GetValueNonConverted( + const std::string &name) const + { + if (HasStatistic(name)) { - return m_Statistics.find(name)!=std::cend(m_Statistics); + return m_Statistics.find(name)->second; } - - ImageStatisticsContainer::StatisticsVariantType ImageStatisticsContainer::StatisticsObject::GetValueNonConverted(const std::string& name) const + else { - if (HasStatistic(name)) { - return m_Statistics.find(name)->second; - } - else { - mitkThrow() << "invalid statistic key, could not find"; - } + mitkThrow() << "invalid statistic key, could not find"; + } + } + + void ImageStatisticsContainer::StatisticsObject::Reset() + { + m_Statistics.clear(); + m_CustomNames.clear(); + } + + bool ImageStatisticsContainer::TimeStepExists(TimeStepType timeStep) const + { + return m_TimeStepMap.find(timeStep) != m_TimeStepMap.end(); + } + + const ImageStatisticsContainer::StatisticsObject &ImageStatisticsContainer::GetStatisticsForTimeStep( + TimeStepType timeStep) const + { + auto it = m_TimeStepMap.find(timeStep); + if (it != m_TimeStepMap.end()) + { + return it->second; } + mitkThrow() << "StatisticsObject for timeStep " << timeStep << " not found!"; + } - void ImageStatisticsContainer::StatisticsObject::Reset() + void ImageStatisticsContainer::SetStatisticsForTimeStep(TimeStepType timeStep, StatisticsObject statistics) + { + if (timeStep < this->GetTimeSteps()) { - m_Statistics.clear(); - m_CustomNames.clear(); + m_TimeStepMap.emplace(timeStep, statistics); + this->Modified(); } - - bool ImageStatisticsContainer::TimeStepExists(TimeStepType timeStep) const { - return m_TimeStepMap.find(timeStep) != m_TimeStepMap.end(); + else + { + mitkThrow() << "Given timeStep " << timeStep + << " out of timeStep geometry bounds. TimeSteps in geometry: " << this->GetTimeSteps(); } + } - const ImageStatisticsContainer::StatisticsObject& ImageStatisticsContainer::GetStatisticsForTimeStep(TimeStepType timeStep) const { - auto it = m_TimeStepMap.find(timeStep); - if (it != m_TimeStepMap.end()) { - return it->second; + void ImageStatisticsContainer::PrintSelf(std::ostream &os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + for (unsigned int i = 0; i < this->GetTimeSteps(); i++) + { + auto statisticsValues = GetStatisticsForTimeStep(i); + os << std::endl << indent << "Statistics instance for timeStep " << i << ":"; + auto statisticKeys = statisticsValues.GetExistingStatisticNames(); + os << std::endl << indent << "Number of entries: " << statisticKeys.size(); + for (const auto &aKey : statisticKeys) + { + os << std::endl << indent.GetNextIndent() << aKey << ": " << statisticsValues.GetValueNonConverted(aKey); } - mitkThrow() << "StatisticsObject for timeStep " << timeStep << " not found!"; } + } - void ImageStatisticsContainer::SetStatisticsForTimeStep(TimeStepType timeStep, StatisticsObject statistics) { - if (timeStep < this->GetTimeSteps()) { - m_TimeStepMap.emplace(timeStep, statistics); - this->Modified(); - } - else { - mitkThrow() << "Given timeStep " << timeStep << " out of timeStep geometry bounds. TimeSteps in geometry: " << this->GetTimeSteps(); - } - } + unsigned int ImageStatisticsContainer::GetNumberOfTimeSteps() const { return this->GetTimeSteps(); } - void ImageStatisticsContainer::PrintSelf(std::ostream &os, itk::Indent indent) const + void ImageStatisticsContainer::Reset() + { + for (auto iter = m_TimeStepMap.begin(); iter != m_TimeStepMap.end(); iter++) { - Superclass::PrintSelf(os, indent); - for (unsigned int i = 0; i < this->GetTimeSteps(); i++) { - auto statisticsValues = GetStatisticsForTimeStep(i); - os << std::endl << indent << "Statistics instance for timeStep " << i << ":"; - auto statisticKeys = statisticsValues.GetAllStatisticNames(); - os << std::endl << indent << "Number of entries: " << statisticKeys.size(); - for (const auto& aKey : statisticKeys) { - os << std::endl << indent.GetNextIndent() << aKey << ": " << statisticsValues.GetValueNonConverted(aKey); - } - } - } - - unsigned int ImageStatisticsContainer::GetNumberOfTimeSteps()const { - return this->GetTimeSteps(); + iter->second.Reset(); } + } - void ImageStatisticsContainer::Reset() + itk::LightObject::Pointer ImageStatisticsContainer::InternalClone() const + { + itk::LightObject::Pointer ioPtr = Superclass::InternalClone(); + Self::Pointer rval = dynamic_cast(ioPtr.GetPointer()); + if (rval.IsNull()) { - for (auto iter = m_TimeStepMap.begin(); iter != m_TimeStepMap.end(); iter++) { - iter->second.Reset(); - } + itkExceptionMacro(<< "downcast to type " + << "StatisticsContainer" + << " failed."); } - itk::LightObject::Pointer ImageStatisticsContainer::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->SetTimeStepMap(m_TimeStepMap); + rval->SetTimeGeometry(this->GetTimeGeometry()->Clone()); - rval->SetTimeStepMap(m_TimeStepMap); - rval->SetTimeGeometry(this->GetTimeGeometry()->Clone()); + return ioPtr; + } - return ioPtr; - } + void ImageStatisticsContainer::SetTimeStepMap(TimeStepMapType map) { m_TimeStepMap = map; } - void ImageStatisticsContainer::SetTimeStepMap(TimeStepMapType map) { - m_TimeStepMap = map; - } + ImageStatisticsContainer::StatisticsObject::StatisticNameVector GetAllStatisticNames( + const ImageStatisticsContainer *container) + { + ImageStatisticsContainer::StatisticsObject::StatisticNameVector names = + ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames(); - ImageStatisticsContainer::StatisticsObject::StatisticNameVector - GetAllStatisticNames(const ImageStatisticsContainer* container) + if (container) { - ImageStatisticsContainer::StatisticsObject::StatisticNameVector names = ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames(); + std::set customKeys; - if (container) + for (unsigned int i = 0; i < container->GetTimeSteps(); i++) { - std::set customKeys; - - for (unsigned int i = 0; i < container->GetTimeSteps(); i++) { - auto statisticKeys = container->GetStatisticsForTimeStep(i).GetCustomStatisticNames(); - customKeys.insert(std::cbegin(statisticKeys), std::cend(statisticKeys)); - } - - names.insert(std::end(names), std::begin(customKeys), std::end(customKeys)); + auto statisticKeys = container->GetStatisticsForTimeStep(i).GetCustomStatisticNames(); + customKeys.insert(std::cbegin(statisticKeys), std::cend(statisticKeys)); } - return names; - }; + names.insert(std::end(names), std::begin(customKeys), std::end(customKeys)); + } - ImageStatisticsContainer::StatisticsObject::StatisticNameVector - GetAllStatisticNames(std::vector containers) - { - ImageStatisticsContainer::StatisticsObject::StatisticNameVector names = ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames(); + return names; + }; - std::set customKeys; + ImageStatisticsContainer::StatisticsObject::StatisticNameVector GetAllStatisticNames( + std::vector containers) + { + ImageStatisticsContainer::StatisticsObject::StatisticNameVector names = + ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames(); + + std::set customKeys; - for (auto container : containers) + for (auto container : containers) + { + for (unsigned int i = 0; i < container->GetTimeSteps(); i++) { - for (unsigned int i = 0; i < container->GetTimeSteps(); i++) { - auto statisticKeys = container->GetStatisticsForTimeStep(i).GetCustomStatisticNames(); - customKeys.insert(std::cbegin(statisticKeys), std::cend(statisticKeys)); - } + auto statisticKeys = container->GetStatisticsForTimeStep(i).GetCustomStatisticNames(); + customKeys.insert(std::cbegin(statisticKeys), std::cend(statisticKeys)); } + } - names.insert(std::end(names), std::begin(customKeys), std::end(customKeys)); + names.insert(std::end(names), std::begin(customKeys), std::end(customKeys)); - return names; - }; + return names; + }; -} +} // namespace mitk diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainer.h b/Modules/ImageStatistics/mitkImageStatisticsContainer.h index 591928490b..9ce8a34797 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainer.h +++ b/Modules/ImageStatistics/mitkImageStatisticsContainer.h @@ -1,163 +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. ===================================================================*/ #ifndef MITKIMAGESTATISTICSCONTAINER #define MITKIMAGESTATISTICSCONTAINER #include #include #include #include #include namespace mitk { /** @brief Container class for storing a StatisticsObject for each timestep. Stored statistics are: - for the defined statistics, see GetAllStatisticNames - Histogram of Pixel Values*/ class MITKIMAGESTATISTICS_EXPORT ImageStatisticsContainer : public mitk::BaseData { public: mitkClassMacro(ImageStatisticsContainer, mitk::BaseData) itkFactorylessNewMacro(Self) itkCloneMacro(Self) using HistogramType = itk::Statistics::Histogram; using RealType = double; using LabelIndex = unsigned int; using IndexType = vnl_vector; using VoxelCountType = unsigned long; using StatisticsVariantType = boost::variant; using StatisticsMapType = std::map < std::string, StatisticsVariantType>; using StatisticsKeyType = std::string; virtual void SetRequestedRegionToLargestPossibleRegion() override {}; virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override { return false; }; virtual bool VerifyRequestedRegion() override { return true; }; virtual void SetRequestedRegion(const itk::DataObject*) override {}; /** @brief Container class for storing the computed image statistics. @details The statistics are stored in a map with value as boost::variant. The type used to create the boost::variant is important as only this type can be recovered lateron. */ class MITKIMAGESTATISTICS_EXPORT StatisticsObject { public: StatisticsObject(); /** @brief Adds a statistic to the statistics object @details if already a statistic with that name is included, it is overwritten */ void AddStatistic(const std::string& key, StatisticsVariantType value); using StatisticNameVector = std::vector; /** @brief Returns the names of the default statistics @details The order is derived from the image statistics plugin. */ static const StatisticNameVector& GetDefaultStatisticNames(); /** @brief Returns the names of all custom statistics (defined at runtime and no default names). */ const StatisticNameVector& GetCustomStatisticNames() const; /** @brief Returns the names of all statistics (default and custom defined) Additional custom keys are added at the end in a sorted order. */ StatisticNameVector GetAllStatisticNames() const; + StatisticNameVector GetExistingStatisticNames() const; + bool HasStatistic(const std::string& name) const; /** @brief Converts the requested value to the defined type @param name defined string on creation (AddStatistic) @exception if no statistics with key name was found. */ template TType GetValueConverted(const std::string& name) const { auto value = GetValueNonConverted(name); return boost::get(value); }; /** @brief Returns the requested value @exception if no statistics with key name was found. */ StatisticsVariantType GetValueNonConverted(const std::string& name) const; void Reset(); HistogramType::ConstPointer m_Histogram=nullptr; private: StatisticsMapType m_Statistics; StatisticNameVector m_CustomNames; static const StatisticNameVector m_DefaultNames; }; using TimeStepMapType = std::map; unsigned int GetNumberOfTimeSteps() const; /** @brief Deletes all stored values*/ void Reset(); /** @brief Returns the statisticObject for the given Timestep @pre timeStep must be valid */ const StatisticsObject& GetStatisticsForTimeStep(TimeStepType timeStep) const; /** @brief Sets the statisticObject for the given Timestep @pre timeStep must be valid */ void SetStatisticsForTimeStep(TimeStepType timeStep, StatisticsObject statistics); /** @brief Checks if the Time step exists @pre timeStep must be valid */ bool TimeStepExists(TimeStepType timeStep) const; protected: ImageStatisticsContainer(); virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override; private: itk::LightObject::Pointer InternalClone() const override; void SetTimeStepMap(TimeStepMapType map); TimeStepMapType m_TimeStepMap; }; MITKIMAGESTATISTICS_EXPORT ImageStatisticsContainer::StatisticsObject::StatisticNameVector GetAllStatisticNames(const ImageStatisticsContainer* container); MITKIMAGESTATISTICS_EXPORT ImageStatisticsContainer::StatisticsObject::StatisticNameVector GetAllStatisticNames(std::vector containers); } #endif // MITKIMAGESTATISTICSCONTAINER