diff --git a/Modules/Classification/CLActiveLearning/include/mitkActiveLearningSuggestRegionFilter.h b/Modules/Classification/CLActiveLearning/include/mitkActiveLearningSuggestRegionFilter.h index e8fef52cc6..00282a18be 100644 --- a/Modules/Classification/CLActiveLearning/include/mitkActiveLearningSuggestRegionFilter.h +++ b/Modules/Classification/CLActiveLearning/include/mitkActiveLearningSuggestRegionFilter.h @@ -1,155 +1,167 @@ /*=================================================================== 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 mitkActiveLearningSuggestRegionFilter_h #define mitkActiveLearningSuggestRegionFilter_h #include // ITK #include #include #include #include #include #include #include #include #include +#include +#include // MITK #include #include namespace mitk { /** \class ActiveLearningSuggestRegionFilter * \brief Filter that takes an image of prediction uncertainties and outputs an image (mask) containing only the most uncertain region * * This is just a composite filter using itkThresholdImageFilter and mitkSelectHighestUncertaintyRegionFilter */ template class MITKCLACTIVELEARNING_EXPORT ActiveLearningSuggestRegionFilter : public itk::ImageToImageFilter { public: typedef itk::ImageToImageFilter SuperClassName; mitkClassMacroItkParent(ActiveLearningSuggestRegionFilter, SuperClassName) itkNewMacro(Self) typedef typename InputImageType::PixelType InputImagePixelType; typedef typename OutputImageType::PixelType OutputImagePixelType; // We're not holding threshold as a member, so no set and get macro void SetThreshold(InputImagePixelType threshold) { if (m_ThresholdFilter->GetLowerThreshold() != threshold) { m_ThresholdFilter->SetLowerThreshold(threshold); this->Modified(); } } InputImagePixelType GetThreshold() const { return m_ThresholdFilter->GetLowerThreshold(); } protected: ActiveLearningSuggestRegionFilter() { m_GaussianFilter = itk::DiscreteGaussianImageFilter::New(); m_ThresholdFilter = itk::BinaryThresholdImageFilter::New(); m_CCFilter = itk::ConnectedComponentImageFilter::New(); m_ThresholdOutputFilter = itk::BinaryThresholdImageFilter::New(); + m_OpeningFilter = itk::BinaryMorphologicalOpeningImageFilter::New(); m_ThresholdFilter->SetLowerThreshold(0.5); m_ThresholdFilter->SetOutsideValue(0); m_ThresholdFilter->SetInsideValue(1); m_ThresholdOutputFilter->SetOutsideValue(0); m_ThresholdOutputFilter->SetInsideValue(1); } ~ActiveLearningSuggestRegionFilter(){} virtual void GenerateData() override { // Let this filter's input be threshold filter's input auto input = InputImageType::New(); input->Graft(const_cast(this->GetInput())); m_GaussianFilter->SetInput(input); m_GaussianFilter->Modified(); m_ThresholdFilter->SetInput(m_GaussianFilter->GetOutput()); m_ThresholdFilter->Modified(); + StructuringElementType structuringElement; + structuringElement.SetRadius(5); + structuringElement.CreateStructuringElement(); + m_OpeningFilter->SetKernel(structuringElement); + m_OpeningFilter->SetInput(m_ThresholdFilter->GetOutput()); + m_OPeningFilter->Modified(); + // Run pipeline to get image with connected components - m_CCFilter->SetInput(m_ThresholdFilter->GetOutput()); + m_CCFilter->SetInput(m_OpeningFilter->GetOutput()); m_CCFilter->Update(); // Find sum of uncertainties for all connected components int ccCount = static_cast(m_CCFilter->GetObjectCount()); std::map ccSize; for (int a=1; a<=ccCount; ++a) {ccSize[a] = 0.0;} auto inputIt = itk::ImageRegionConstIterator(input, input->GetLargestPossibleRegion()); auto outputIt = itk::ImageRegionConstIterator(m_CCFilter->GetOutput(), m_CCFilter->GetOutput()->GetLargestPossibleRegion()); while (!outputIt.IsAtEnd()) { OutputImagePixelType ccVal = outputIt.Get(); InputImagePixelType pixelVal = inputIt.Get(); if (ccVal != 0) {ccSize[ccVal] += pixelVal;} ++outputIt; ++inputIt; } // Find component with largest sum typedef typename std::map::value_type PairType; auto maxComponent = std::max_element(ccSize.begin(), ccSize.end(), [](const PairType& lhs, const PairType& rhs){return lhs.second < rhs.second;}); // Create mask m_ThresholdOutputFilter->SetLowerThreshold(maxComponent->first); m_ThresholdOutputFilter->SetUpperThreshold(maxComponent->first); m_ThresholdOutputFilter->SetInput(m_CCFilter->GetOutput()); m_ThresholdOutputFilter->GraftOutput(this->GetOutput()); m_ThresholdOutputFilter->Update(); this->GraftOutput(m_ThresholdOutputFilter->GetOutput()); } // virtual void PrintSelf(std::ostream & os, itk::Indent indent) const // { // Superclass::PrintSelf(os, indent); // m_ThresholdFilter->PrintSelf(os, indent); // m_RegionFilter->PrintSelf(os, indent); // } private: // ITK examples do this... ActiveLearningSuggestRegionFilter(const Self&); void operator=(const Self&); typename itk::DiscreteGaussianImageFilter::Pointer m_GaussianFilter; typename itk::BinaryThresholdImageFilter::Pointer m_ThresholdFilter; typename itk::ConnectedComponentImageFilter::Pointer m_CCFilter; typename itk::BinaryThresholdImageFilter::Pointer m_ThresholdOutputFilter; + typedef itk::BinaryBallStructuringElement StructuringElementType; + typename itk::BinaryMorphologicalOpeningImageFilter::Pointer m_OpeningFilter; }; } #endif