diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp index ab7bae8bb4..f636fc1f64 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp +++ b/Modules/ImageStatistics/mitkImageStatisticsContainer.cpp @@ -1,209 +1,210 @@ /*=================================================================== 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() { 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)) { m_CustomNames.emplace_back(key); } } } const ImageStatisticsContainer::StatisticsObject::StatisticNameVector& ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames() { return m_DefaultNames; }; 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)); return std::move(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)->second; } else { 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::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(); } } 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.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(); } void ImageStatisticsContainer::Reset() { for (auto iter = m_TimeStepMap.begin(); iter != m_TimeStepMap.end(); iter++) { iter->second.Reset(); } } 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()); return ioPtr; } void ImageStatisticsContainer::SetTimeStepMap(TimeStepMapType map) { m_TimeStepMap = map; } ImageStatisticsContainer::StatisticsObject::StatisticNameVector GetAllStatisticNames(const ImageStatisticsContainer* container) { ImageStatisticsContainer::StatisticsObject::StatisticNameVector names = ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames(); if (container) { 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)); } return std::move(names); }; ImageStatisticsContainer::StatisticsObject::StatisticNameVector GetAllStatisticNames(std::vector containers) { ImageStatisticsContainer::StatisticsObject::StatisticNameVector names = ImageStatisticsContainer::StatisticsObject::GetDefaultStatisticNames(); std::set customKeys; for (auto container : containers) { 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)); return std::move(names); }; } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsCalculationJob.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsCalculationJob.cpp index 52d62643a9..ec242732b9 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsCalculationJob.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkImageStatisticsCalculationJob.cpp @@ -1,253 +1,246 @@ /*=================================================================== 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 "QmitkImageStatisticsCalculationJob.h" #include "mitkImageStatisticsCalculator.h" #include #include #include QmitkImageStatisticsCalculationJob::QmitkImageStatisticsCalculationJob() : QThread() , m_StatisticsImage(nullptr) , m_BinaryMask(nullptr) , m_PlanarFigureMask(nullptr) , m_TimeStep(0) , m_IgnoreZeros(false) , m_HistogramNBins(100) , m_StatisticChanged(false) , m_CalculationSuccessful(false) { } QmitkImageStatisticsCalculationJob::~QmitkImageStatisticsCalculationJob() { } void QmitkImageStatisticsCalculationJob::Initialize( mitk::Image::ConstPointer image, mitk::Image::ConstPointer binaryImage, mitk::PlanarFigure::ConstPointer planarFig ) { // reset old values if( this->m_StatisticsImage.IsNotNull() ) this->m_StatisticsImage = nullptr; if( this->m_BinaryMask.IsNotNull() ) this->m_BinaryMask = nullptr; if( this->m_PlanarFigureMask.IsNotNull()) this->m_PlanarFigureMask = nullptr; // set new values if passed in if(image.IsNotNull()) this->m_StatisticsImage = image; if(binaryImage.IsNotNull()) this->m_BinaryMask = binaryImage; if(planarFig.IsNotNull()) this->m_PlanarFigureMask = planarFig; } void QmitkImageStatisticsCalculationJob::SetTimeStep( int times ) { this->m_TimeStep = times; } int QmitkImageStatisticsCalculationJob::GetTimeStep() const { return this->m_TimeStep; } mitk::ImageStatisticsContainer::ConstPointer QmitkImageStatisticsCalculationJob::GetStatisticsData() const { mitk::ImageStatisticsContainer::ConstPointer constContainer = this->m_StatisticsContainer.GetPointer(); return constContainer; } mitk::Image::ConstPointer QmitkImageStatisticsCalculationJob::GetStatisticsImage() const { return this->m_StatisticsImage; } mitk::Image::ConstPointer QmitkImageStatisticsCalculationJob::GetMaskImage() const { return this->m_BinaryMask; } mitk::PlanarFigure::ConstPointer QmitkImageStatisticsCalculationJob::GetPlanarFigure() const { return this->m_PlanarFigureMask; } void QmitkImageStatisticsCalculationJob::SetIgnoreZeroValueVoxel(bool _arg) { this->m_IgnoreZeros = _arg; } bool QmitkImageStatisticsCalculationJob::GetIgnoreZeroValueVoxel() const { return this->m_IgnoreZeros; } void QmitkImageStatisticsCalculationJob::SetHistogramNBins(unsigned int nbins) { this->m_HistogramNBins = nbins; } unsigned int QmitkImageStatisticsCalculationJob::GetHistogramNBins() const { return this->m_HistogramNBins; } std::string QmitkImageStatisticsCalculationJob::GetLastErrorMessage() const { return m_message; } QmitkImageStatisticsCalculationJob::HistogramType::ConstPointer QmitkImageStatisticsCalculationJob::GetTimeStepHistogram(unsigned int t) const { if (t >= this->m_HistogramVector.size()) return nullptr; return this->m_HistogramVector[t]; } bool QmitkImageStatisticsCalculationJob::GetStatisticsChangedFlag() const { return m_StatisticChanged; } bool QmitkImageStatisticsCalculationJob::GetStatisticsUpdateSuccessFlag() const { return m_CalculationSuccessful; } void QmitkImageStatisticsCalculationJob::run() { bool statisticCalculationSuccessful = true; mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New(); if(this->m_StatisticsImage.IsNotNull()) { calculator->SetInputImage(m_StatisticsImage->Clone()); } else { statisticCalculationSuccessful = false; } // Bug 13416 : The ImageStatistics::SetImageMask() method can throw exceptions, i.e. when the dimensionality // of the masked and input image differ, we need to catch them and mark the calculation as failed // the same holds for the ::SetPlanarFigure() try { if(this->m_BinaryMask.IsNotNull()) { mitk::ImageMaskGenerator::Pointer imgMask = mitk::ImageMaskGenerator::New(); imgMask->SetImageMask(m_BinaryMask->Clone()); calculator->SetMask(imgMask.GetPointer()); } if(this->m_PlanarFigureMask.IsNotNull()) { mitk::PlanarFigureMaskGenerator::Pointer pfMaskGen = mitk::PlanarFigureMaskGenerator::New(); pfMaskGen->SetInputImage(m_StatisticsImage->Clone()); pfMaskGen->SetPlanarFigure(m_PlanarFigureMask->Clone()); calculator->SetMask(pfMaskGen.GetPointer()); } } catch (const mitk::Exception& e) { MITK_ERROR << "MITK Exception: " << e.what(); m_message = e.what(); statisticCalculationSuccessful = false; } catch( const itk::ExceptionObject& e) { MITK_ERROR << "ITK Exception:" << e.what(); m_message = e.what(); statisticCalculationSuccessful = false; } catch ( const std::runtime_error &e ) { MITK_ERROR<< "Runtime Exception: " << e.what(); m_message = e.what(); statisticCalculationSuccessful = false; } catch ( const std::exception &e ) { MITK_ERROR<< "Standard Exception: " << e.what(); m_message = e.what(); statisticCalculationSuccessful = false; } bool statisticChanged = false; if (this->m_IgnoreZeros) { mitk::IgnorePixelMaskGenerator::Pointer ignorePixelValueMaskGen = mitk::IgnorePixelMaskGenerator::New(); ignorePixelValueMaskGen->SetIgnoredPixelValue(0); ignorePixelValueMaskGen->SetInputImage(m_StatisticsImage->Clone()); calculator->SetSecondaryMask(ignorePixelValueMaskGen.GetPointer()); } else { calculator->SetSecondaryMask(nullptr); } calculator->SetNBinsForHistogramStatistics(m_HistogramNBins); - for (unsigned int i = 0; i < m_StatisticsImage->GetTimeSteps(); i++) - { try { - calculator->GetStatistics(i); + calculator->GetStatistics(); } catch ( mitk::Exception& e) { m_message = e.GetDescription(); MITK_ERROR<< "MITK Exception: " << e.what(); statisticCalculationSuccessful = false; } catch ( const std::runtime_error &e ) { m_message = "Failure: " + std::string(e.what()); MITK_ERROR<< "Runtime Exception: " << e.what(); statisticCalculationSuccessful = false; } catch ( const std::exception &e ) { m_message = "Failure: " + std::string(e.what()); MITK_ERROR<< "Standard Exception: " << e.what(); statisticCalculationSuccessful = false; } - } this->m_StatisticChanged = statisticChanged; this->m_CalculationSuccessful = statisticCalculationSuccessful; if(statisticCalculationSuccessful) { - // maybe use reset if this line does not work - m_StatisticsContainer = mitk::ImageStatisticsContainer::New(); + m_StatisticsContainer = calculator->GetStatistics(); this->m_HistogramVector.clear(); - mitk::TimeGeometry::Pointer tg = m_StatisticsImage->GetTimeGeometry()->Clone(); - m_StatisticsContainer->SetTimeGeometry(tg); for (unsigned int i = 0; i < m_StatisticsImage->GetTimeSteps(); i++) { - this->m_StatisticsContainer->SetStatisticsForTimeStep(i, calculator->GetStatistics(i)); - this->m_HistogramVector.push_back(calculator->GetStatistics(i).m_Histogram); + this->m_HistogramVector.push_back(calculator->GetStatistics()->GetStatisticsForTimeStep(i).m_Histogram); } } } diff --git a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp index bef734bbdb..34dfe97c86 100644 --- a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp @@ -1,199 +1,199 @@ /*=================================================================== 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 "mitkFeatureBasedEdgeDetectionFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::FeatureBasedEdgeDetectionFilter::FeatureBasedEdgeDetectionFilter() { this->SetNumberOfRequiredInputs(1); this->SetNumberOfIndexedOutputs(1); } mitk::FeatureBasedEdgeDetectionFilter::~FeatureBasedEdgeDetectionFilter() { } void mitk::FeatureBasedEdgeDetectionFilter::GenerateData() { mitk::Image::Pointer image = ImageToUnstructuredGridFilter::GetInput(); if (m_SegmentationMask.IsNull()) { MITK_WARN << "Please set a segmentation mask first" << std::endl; return; } // First create a threshold segmentation of the image. The threshold is determined // by the mean +/- stddev of the pixel values that are covered by the segmentation mask // Compute mean and stdDev based on the current segmentation mitk::ImageStatisticsCalculator::Pointer statCalc = mitk::ImageStatisticsCalculator::New(); statCalc->SetInputImage(image); mitk::ImageMaskGenerator::Pointer imgMask = mitk::ImageMaskGenerator::New(); imgMask->SetImageMask(m_SegmentationMask); - auto stats = statCalc->GetStatistics(); + auto stats = statCalc->GetStatistics()->GetStatisticsForTimeStep(0); double mean = stats.GetValueConverted(mitk::ImageStatisticsConstants::MEAN()); double stdDev = stats.GetValueConverted(mitk::ImageStatisticsConstants::STANDARDDEVIATION()); double upperThreshold = mean + stdDev; double lowerThreshold = mean - stdDev; // Perform thresholding mitk::Image::Pointer thresholdImage = mitk::Image::New(); AccessByItk_3(image.GetPointer(), ITKThresholding, lowerThreshold, upperThreshold, thresholdImage) mitk::ProgressBar::GetInstance() ->Progress(2); // Postprocess threshold segmentation // First a closing will be executed mitk::Image::Pointer closedImage = mitk::Image::New(); AccessByItk_1(thresholdImage, ThreadedClosing, closedImage); // Then we will holes that might exist mitk::MorphologicalOperations::FillHoles(closedImage); mitk::ProgressBar::GetInstance()->Progress(); // Extract the binary edges of the resulting segmentation mitk::Image::Pointer edgeImage = mitk::Image::New(); AccessByItk_1(closedImage, ContourSearch, edgeImage); // Convert the edge image into an unstructured grid mitk::ImageToUnstructuredGridFilter::Pointer i2UFilter = mitk::ImageToUnstructuredGridFilter::New(); i2UFilter->SetInput(edgeImage); i2UFilter->SetThreshold(1.0); i2UFilter->Update(); m_PointGrid = this->GetOutput(); if (m_PointGrid.IsNull()) m_PointGrid = mitk::UnstructuredGrid::New(); m_PointGrid->SetVtkUnstructuredGrid(i2UFilter->GetOutput()->GetVtkUnstructuredGrid()); mitk::ProgressBar::GetInstance()->Progress(); } template void mitk::FeatureBasedEdgeDetectionFilter::ThreadedClosing(itk::Image *originalImage, mitk::Image::Pointer &result) { typedef itk::BinaryBallStructuringElement myKernelType; myKernelType ball; ball.SetRadius(1); ball.CreateStructuringElement(); typedef typename itk::Image ImageType; typename itk::DilateObjectMorphologyImageFilter::Pointer dilationFilter = itk::DilateObjectMorphologyImageFilter::New(); dilationFilter->SetInput(originalImage); dilationFilter->SetKernel(ball); dilationFilter->Update(); typename itk::Image::Pointer dilatedImage = dilationFilter->GetOutput(); typename itk::ErodeObjectMorphologyImageFilter::Pointer erodeFilter = itk::ErodeObjectMorphologyImageFilter::New(); erodeFilter->SetInput(dilatedImage); erodeFilter->SetKernel(ball); erodeFilter->Update(); mitk::GrabItkImageMemory(erodeFilter->GetOutput(), result); } template void mitk::FeatureBasedEdgeDetectionFilter::ContourSearch(itk::Image *originalImage, mitk::Image::Pointer &result) { typedef itk::Image ImageType; typedef itk::BinaryContourImageFilter binaryContourImageFilterType; typename binaryContourImageFilterType::Pointer binaryContourFilter = binaryContourImageFilterType::New(); binaryContourFilter->SetInput(originalImage); binaryContourFilter->SetForegroundValue(1); binaryContourFilter->SetBackgroundValue(0); binaryContourFilter->Update(); typename itk::Image::Pointer itkImage = itk::Image::New(); itkImage->Graft(binaryContourFilter->GetOutput()); mitk::GrabItkImageMemory(itkImage, result); } template void mitk::FeatureBasedEdgeDetectionFilter::ITKThresholding(itk::Image *originalImage, double lower, double upper, mitk::Image::Pointer &result) { typedef itk::Image ImageType; typedef itk::Image SegmentationType; typedef itk::BinaryThresholdImageFilter ThresholdFilterType; if (typeid(TPixel) != typeid(float) && typeid(TPixel) != typeid(double)) { // round the thresholds if we have nor a float or double image lower = std::floor(lower + 0.5); upper = std::floor(upper - 0.5); } if (lower >= upper) { upper = lower; } typename ThresholdFilterType::Pointer filter = ThresholdFilterType::New(); filter->SetInput(originalImage); filter->SetLowerThreshold(lower); filter->SetUpperThreshold(upper); filter->SetInsideValue(1); filter->SetOutsideValue(0); filter->Update(); mitk::GrabItkImageMemory(filter->GetOutput(), result); } void mitk::FeatureBasedEdgeDetectionFilter::SetSegmentationMask(mitk::Image::Pointer segmentation) { this->m_SegmentationMask = segmentation; } void mitk::FeatureBasedEdgeDetectionFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); } diff --git a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp index 9878911009..6b001b3410 100644 --- a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp +++ b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp @@ -1,167 +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. ===================================================================*/ #include "mitkImageToPointCloudFilter.h" #include #include #include #include #include #include #include #include #include #include mitk::ImageToPointCloudFilter::ImageToPointCloudFilter() { m_Method = DetectionMethod(0); this->SetNumberOfRequiredInputs(1); this->SetNumberOfIndexedOutputs(1); } mitk::ImageToPointCloudFilter::~ImageToPointCloudFilter() { } void mitk::ImageToPointCloudFilter::GenerateData() { mitk::Image::ConstPointer image = ImageToUnstructuredGridFilter::GetInput(); m_Geometry = image->GetGeometry(); if (image.IsNull()) { MITK_ERROR << "mitk::ImageToContourFilter: No input available. " "Please set the input!" << std::endl; return; } mitk::Image::Pointer notConstImage = const_cast(image.GetPointer()); switch (m_Method) { case 0: AccessByItk_1(notConstImage.GetPointer(), StdDeviations, 2) break; case 1: AccessByItk_1(notConstImage.GetPointer(), StdDeviations, 3) break; case 2: AccessByItk_1(notConstImage.GetPointer(), StdDeviations, 4) break; default: AccessByItk_1(notConstImage.GetPointer(), StdDeviations, 2) break; } } template void mitk::ImageToPointCloudFilter::StdDeviations(itk::Image *image, int amount) { typedef itk::Image InputImageType; typedef itk::CastImageFilter ImagePTypeToFloatPTypeCasterType; typedef itk::LaplacianImageFilter LaplacianFilterType; typename LaplacianFilterType::Pointer lapFilter = LaplacianFilterType::New(); typename ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput(image); caster->Update(); FloatImageType::Pointer fImage = caster->GetOutput(); lapFilter->SetInput(fImage); lapFilter->UpdateLargestPossibleRegion(); mitk::Image::Pointer edgeImage = mitk::ImportItkImage(lapFilter->GetOutput()); mitk::ImageStatisticsCalculator::Pointer statCalc = mitk::ImageStatisticsCalculator::New(); statCalc->SetInputImage(edgeImage); - auto stats = statCalc->GetStatistics(); + auto stats = statCalc->GetStatistics()->GetStatisticsForTimeStep(0); auto mean = stats.GetValueConverted(mitk::ImageStatisticsConstants::MEAN()); auto stdDev = stats.GetValueConverted(mitk::ImageStatisticsConstants::STANDARDDEVIATION()); double upperThreshold = mean + stdDev * amount; double lowerThreshold = mean - stdDev * amount; typename itk::ImageRegionIterator it(lapFilter->GetOutput(), lapFilter->GetOutput()->GetRequestedRegion()); vtkSmartPointer points = vtkSmartPointer::New(); double greatX = 0, greatY = 0, greatZ = 0; it.GoToBegin(); while (!it.IsAtEnd()) { if (it.Get() > lowerThreshold && it.Get() < upperThreshold) { it.Set(0); } else { it.Set(1); mitk::Point3D imagePoint; mitk::Point3D worldPoint; imagePoint[0] = it.GetIndex()[0]; imagePoint[1] = it.GetIndex()[1]; imagePoint[2] = it.GetIndex()[2]; m_Geometry->IndexToWorld(imagePoint, worldPoint); if (worldPoint[0] > greatX) greatX = worldPoint[0]; if (worldPoint[1] > greatY) greatY = worldPoint[1]; if (worldPoint[2] > greatZ) greatZ = worldPoint[2]; points->InsertNextPoint(worldPoint[0], worldPoint[1], worldPoint[2]); m_NumberOfExtractedPoints++; } ++it; } /*need to build the UnstructuredGrid with at least one vertex otherwise its not visible*/ vtkSmartPointer verts = vtkSmartPointer::New(); verts->GetPointIds()->SetNumberOfIds(m_NumberOfExtractedPoints); for (int i = 0; i < m_NumberOfExtractedPoints; i++) { verts->GetPointIds()->SetId(i, i); } vtkSmartPointer uGrid = vtkSmartPointer::New(); uGrid->Allocate(1); uGrid->InsertNextCell(verts->GetCellType(), verts->GetPointIds()); uGrid->SetPoints(points); mitk::UnstructuredGrid::Pointer outputGrid = mitk::UnstructuredGrid::New(); outputGrid->SetVtkUnstructuredGrid(uGrid); this->SetNthOutput(0, outputGrid); } void mitk::ImageToPointCloudFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); }