diff --git a/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.h b/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.h index 99ec49358c..b2053c718b 100644 --- a/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.h +++ b/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.h @@ -1,96 +1,101 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITK_MINMAXIMAGEFILTERWITHINDEX_H #define MITK_MINMAXIMAGEFILTERWITHINDEX_H #include #include #include #include namespace itk { template class MinMaxImageFilterWithIndex: public itk::ImageToImageFilter { public: /** Standard Self typedef */ typedef MinMaxImageFilterWithIndex Self; typedef ImageToImageFilter< TInputImage, TInputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(MinMaxImageFilterWithIndex, ImageToImageFilter); typedef typename TInputImage::RegionType RegionType; typedef typename TInputImage::SizeType SizeType; typedef typename TInputImage::IndexType IndexType; typedef typename TInputImage::PixelType PixelType; typedef typename NumericTraits< PixelType >::RealType RealType; RealType GetMin() const { return m_Min; } RealType GetMax() const { return m_Max; } IndexType GetMinIndex() const { return m_MinIndex; } IndexType GetMaxIndex() const { return m_MaxIndex; } protected: + MinMaxImageFilterWithIndex() + { + this->DynamicMultiThreadingOff(); + } + void AllocateOutputs() override; void ThreadedGenerateData(const RegionType & outputRegionForThread, ThreadIdType threadId) override; void BeforeThreadedGenerateData() override; void AfterThreadedGenerateData() override; private: std::vector m_ThreadMin; std::vector m_ThreadMax; std::vector m_ThreadMinIndex; std::vector m_ThreadMaxIndex; PixelType m_Min; PixelType m_Max; IndexType m_MinIndex; IndexType m_MaxIndex; }; } #include "mitkMinMaxImageFilterWithIndex.hxx" #endif diff --git a/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.hxx b/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.hxx index 77b4510f4f..7d50c1224b 100644 --- a/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.hxx +++ b/Modules/ImageStatistics/mitkMinMaxImageFilterWithIndex.hxx @@ -1,109 +1,109 @@ #ifndef MITK_MinMaxImageFilterWithIndex_HXX #define MITK_MinMaxImageFilterWithIndex_HXX #include #include namespace itk { template< typename TInputImage > void MinMaxImageFilterWithIndex< TInputImage >::AllocateOutputs() { // Pass the input through as the output typename TInputImage::Pointer image = const_cast< TInputImage * >( this->GetInput() ); this->GraftOutput(image); // Nothing that needs to be allocated for the remaining outputs } template< typename TInputImage > void MinMaxImageFilterWithIndex< TInputImage >::ThreadedGenerateData(const RegionType & outputRegionForThread, ThreadIdType threadId) { const SizeValueType size0 = outputRegionForThread.GetSize(0); if( size0 == 0) { return; } PixelType value; PixelType threadMin, threadMax; IndexType threadMinIndex; IndexType threadMaxIndex; threadMinIndex.Fill(0); threadMaxIndex.Fill(0); threadMin = std::numeric_limits::max(); threadMax = std::numeric_limits::min(); ImageRegionConstIteratorWithIndex< TInputImage > it (this->GetInput(), outputRegionForThread); // do the work while ( !it.IsAtEnd() ) { value = it.Get(); if (value < threadMin) { threadMin = value; threadMinIndex = it.GetIndex(); } if (value > threadMax) { threadMax = value; threadMaxIndex = it.GetIndex(); } ++it; } m_ThreadMax[threadId] = threadMax; m_ThreadMin[threadId] = threadMin; m_ThreadMaxIndex[threadId] = threadMaxIndex; m_ThreadMinIndex[threadId] = threadMinIndex; } template< typename TInputImage > void MinMaxImageFilterWithIndex< TInputImage >::BeforeThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); m_ThreadMin.resize(numberOfThreads); m_ThreadMax.resize(numberOfThreads); m_ThreadMinIndex.resize(numberOfThreads); m_ThreadMaxIndex.resize(numberOfThreads); for (unsigned int i =0; i < numberOfThreads; i++) { m_ThreadMin[i] = std::numeric_limits::max(); m_ThreadMax[i] = std::numeric_limits::min(); } m_Min = std::numeric_limits::max(); m_Max = std::numeric_limits::min(); } template< typename TInputImage > void MinMaxImageFilterWithIndex< TInputImage >::AfterThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); for (ThreadIdType i = 0; i < numberOfThreads; i++) { if (m_ThreadMin[i] < m_Min) { m_Min = m_ThreadMin[i]; m_MinIndex = m_ThreadMinIndex[i]; } if (m_ThreadMax[i] > m_Max) { m_Max = m_ThreadMax[i]; m_MaxIndex = m_ThreadMaxIndex[i]; } } } } #endif diff --git a/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.h b/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.h index 54f728ec51..ff38ff3d71 100644 --- a/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.h +++ b/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.h @@ -1,189 +1,194 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITK_MINMAXLABELIMAGEFILTERWITHINDEX_H #define MITK_MINMAXLABELIMAGEFILTERWITHINDEX_H #include #include #include #include #include namespace itk { template class MinMaxLabelImageFilterWithIndex: public itk::ImageToImageFilter { public: /** Standard Self typedef */ typedef MinMaxLabelImageFilterWithIndex Self; typedef ImageToImageFilter< TInputImage, TInputImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(MinMaxLabelImageFilterWithIndex, ImageToImageFilter); typedef typename TInputImage::RegionType RegionType; typedef typename TInputImage::SizeType SizeType; typedef typename TInputImage::IndexType IndexType; typedef typename TInputImage::PixelType PixelType; typedef typename NumericTraits< PixelType >::RealType RealType; typedef typename TLabelImage::RegionType LabelRegionType; typedef typename TLabelImage::SizeType LabelSizeType; typedef typename TLabelImage::IndexType LabelIndexType; typedef typename TLabelImage::PixelType LabelPixelType; /** * @brief The LabelExtrema class is just a container for global min/max values and their indices as well as all min and max values (+indices) of the mask labels */ class LabelExtrema { public: PixelType m_Min, m_Max; IndexType m_MinIndex, m_MaxIndex; LabelExtrema(): m_Min(std::numeric_limits::max()), m_Max(std::numeric_limits::min()) {} }; typedef typename std::unordered_map ExtremaMapType; typedef typename ExtremaMapType::iterator ExtremaMapTypeIterator; typedef typename ExtremaMapType::const_iterator ExtremaMapTypeConstIterator; typedef typename ExtremaMapType::value_type MapValueType; PixelType GetMin(LabelPixelType label) const { ExtremaMapTypeConstIterator it = m_LabelExtrema.find(label); if (it == m_LabelExtrema.end()) { MITK_ERROR << "invalid label"; } return (*it).second.m_Min; } PixelType GetMax(LabelPixelType label) const { ExtremaMapTypeConstIterator it = m_LabelExtrema.find(label); if (it == m_LabelExtrema.end()) { MITK_ERROR << "invalid label"; } return (*it).second.m_Max; } /** * @brief Returns a std::vector containing all labels for which min and max values (and indices) have been computed */ std::vector GetRelevantLabels() const { std::vector labels; for (auto&& it:m_LabelExtrema) { labels.push_back(it.first); } return labels; } IndexType GetMinIndex(LabelPixelType label) const { ExtremaMapTypeConstIterator it = m_LabelExtrema.find(label); if (it == m_LabelExtrema.end()) { MITK_ERROR << "invalid label"; } return (*it).second.m_MinIndex; } IndexType GetMaxIndex(LabelPixelType label) const { ExtremaMapTypeConstIterator it = m_LabelExtrema.find(label); if (it == m_LabelExtrema.end()) { MITK_ERROR << "invalid label"; } return (*it).second.m_MaxIndex; } PixelType GetGlobalMin() const { return m_GlobalMin; } PixelType GetGlobalMax() const { return m_GlobalMax; } IndexType GetGlobalMinIndex() const { return m_GlobalMinIndex; } IndexType GetGlobalMaxIndex() const { return m_GlobalMaxIndex; } /** Set the label image */ void SetLabelInput(const TLabelImage *input) { // Process object is not const-correct so the const casting is required. this->SetNthInput( 1, const_cast< TLabelImage * >( input ) ); } /** Get the label image */ const TLabelImage * GetLabelInput() const { return itkDynamicCastInDebugMode< TLabelImage * >( const_cast< DataObject * >( this->ProcessObject::GetInput(1) ) ); } protected: + MinMaxLabelImageFilterWithIndex() + { + this->DynamicMultiThreadingOff(); + } + void AllocateOutputs() override; void ThreadedGenerateData(const RegionType & outputRegionForThread, ThreadIdType threadId) override; void BeforeThreadedGenerateData() override; void AfterThreadedGenerateData() override; private: std::vector m_ThreadExtrema; ExtremaMapType m_LabelExtrema; PixelType m_GlobalMin; PixelType m_GlobalMax; IndexType m_GlobalMinIndex, m_GlobalMaxIndex; }; } #include "mitkMinMaxLabelmageFilterWithIndex.hxx" #endif diff --git a/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.hxx b/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.hxx index c1a0af7ae2..89dc9d1300 100644 --- a/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.hxx +++ b/Modules/ImageStatistics/mitkMinMaxLabelmageFilterWithIndex.hxx @@ -1,130 +1,130 @@ #ifndef MITK_MinMaxLabelImageFilterWithIndex_HXX #define MITK_MinMaxLabelImageFilterWithIndex_HXX #include #include namespace itk { template< typename TInputImage, typename TLabelImage > void MinMaxLabelImageFilterWithIndex< TInputImage, TLabelImage >::AllocateOutputs() { // Pass the input through as the output typename TInputImage::Pointer image = const_cast< TInputImage * >( this->GetInput() ); this->GraftOutput(image); // Nothing that needs to be allocated for the remaining outputs } template< typename TInputImage, typename TLabelImage > void MinMaxLabelImageFilterWithIndex< TInputImage, TLabelImage >::ThreadedGenerateData(const RegionType & outputRegionForThread, ThreadIdType threadId) { const SizeValueType size0 = outputRegionForThread.GetSize(0); if( size0 == 0) { return; } PixelType value; LabelPixelType label; ExtremaMapType threadExtrema; ExtremaMapTypeIterator threadExtremaIt; ImageRegionConstIteratorWithIndex< TInputImage > it (this->GetInput(), outputRegionForThread); ImageRegionConstIteratorWithIndex< TLabelImage > labelit (this->GetLabelInput(), outputRegionForThread); // do the work while ( !it.IsAtEnd() ) { value = it.Get(); label = labelit.Get(); threadExtremaIt = threadExtrema.find(label); // if label does not exist yet, create a new entry in the map. if (threadExtremaIt == threadExtrema.end()) { threadExtremaIt = threadExtrema.insert( MapValueType(label, LabelExtrema()) ).first; } if (value < (*threadExtremaIt).second.m_Min) { (*threadExtremaIt).second.m_Min = value; (*threadExtremaIt).second.m_MinIndex = it.GetIndex(); } if (value > (*threadExtremaIt).second.m_Max) { (*threadExtremaIt).second.m_Max = value; (*threadExtremaIt).second.m_MaxIndex = it.GetIndex(); } ++it; ++labelit; } m_ThreadExtrema[threadId] = threadExtrema; } template< typename TInputImage, typename TLabelImage > void MinMaxLabelImageFilterWithIndex< TInputImage, TLabelImage >::BeforeThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); m_ThreadExtrema.resize(numberOfThreads); for (unsigned int i =0; i < numberOfThreads; i++) { m_ThreadExtrema[i] = ExtremaMapType(); } } template< typename TInputImage, typename TLabelImage > void MinMaxLabelImageFilterWithIndex< TInputImage, TLabelImage >::AfterThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); m_GlobalMin = std::numeric_limits::max(); m_GlobalMax = std::numeric_limits::min(); ExtremaMapTypeIterator it; for (ThreadIdType i = 0; i < numberOfThreads; i++) { for (auto&& it2 : m_ThreadExtrema[i]) { it = m_LabelExtrema.find(it2.first); if (it == m_LabelExtrema.end()) { it = m_LabelExtrema.insert( MapValueType(it2.first, LabelExtrema()) ).first; } if (it2.second.m_Min < (*it).second.m_Min) { (*it).second.m_Min = it2.second.m_Min; (*it).second.m_MinIndex = it2.second.m_MinIndex; if (it2.second.m_Min < m_GlobalMin) { m_GlobalMin = it2.second.m_Min; m_GlobalMinIndex = it2.second.m_MinIndex; } } if (it2.second.m_Max > (*it).second.m_Max) { (*it).second.m_Max = it2.second.m_Max; (*it).second.m_MaxIndex = it2.second.m_MaxIndex; if (it2.second.m_Max > m_GlobalMax) { m_GlobalMax = it2.second.m_Max; m_GlobalMaxIndex = it2.second.m_MaxIndex; } } } } } } #endif