diff --git a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp index 0a0ba3838c..15f5761abe 100644 --- a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp @@ -1,164 +1,234 @@ /*=================================================================== 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 +#include +#include + mitk::FeatureBasedEdgeDetectionFilter::FeatureBasedEdgeDetectionFilter() { m_PointGrid = mitk::UnstructuredGrid::New(); m_SegmentationMask = mitk::Image::New(); m_thresholdImage = mitk::Image::New(); m_TestImage = mitk::Image::New(); this->SetNumberOfRequiredInputs(1); this->SetNumberOfIndexedOutputs(1); } mitk::FeatureBasedEdgeDetectionFilter::~FeatureBasedEdgeDetectionFilter(){} - +#include +#include void mitk::FeatureBasedEdgeDetectionFilter::GenerateData() { mitk::Image::ConstPointer image = ImageToUnstructuredGridFilter::GetInput(); mitk::Image::Pointer ncImage = const_cast(image.GetPointer()); //statistics mitk::ImageStatisticsCalculator::Pointer statCalc = mitk::ImageStatisticsCalculator::New(); statCalc->SetImage(image); statCalc->SetMaskingModeToImage(); if(m_SegmentationMask->IsEmpty()) { MITK_WARN << "Please set a segmentation mask first" << std::endl; return; } statCalc->SetImageMask(m_SegmentationMask); statCalc->ComputeStatistics(); mitk::ImageStatisticsCalculator::Statistics stats = statCalc->GetStatistics(); double mean = stats.GetMean(); double stdDev = stats.GetSigma(); double upperThreshold = mean + stdDev; double lowerThreshold = mean - stdDev; - std::cout << "Lower: " << lowerThreshold << " - Upper: " << upperThreshold << std::endl; - //thresholding AccessByItk_2(ncImage.GetPointer(), ITKThresholding, lowerThreshold, upperThreshold) mitk::ProgressBar::GetInstance()->Progress(); //fill holes // mitk::MorphologicalOperations::FillHoles(m_thresholdImage); mitk::ProgressBar::GetInstance()->Progress(); - mitk::MorphologicalOperations::Closing(m_thresholdImage, 1, mitk::MorphologicalOperations::Ball); - mitk::MorphologicalOperations::FillHoles(m_thresholdImage); -// mitk::MorphologicalOperations::Opening(m_thresholdImage,1,mitk::MorphologicalOperations::Ball); +// mitk::MorphologicalOperations::Closing(m_thresholdImage, 1, mitk::MorphologicalOperations::Ball); +// mitk::MorphologicalOperations::FillHoles(m_thresholdImage); +//// mitk::MorphologicalOperations::Opening(m_thresholdImage,1,mitk::MorphologicalOperations::Ball); +/// + + itk::TimeProbe clock; + clock.Start(); + + AccessByItk(m_thresholdImage, ThreadedClosing); +// AccessByItk(m_TestImage, ThreadedOpening); + mitk::MorphologicalOperations::FillHoles(m_TestImage); + + clock.Stop(); + std::cout << "Time needed: " << clock.GetTotal() << std::endl; mitk::ProgressBar::GetInstance()->Progress(); - AccessByItk(m_thresholdImage,ContourSearch) +// AccessByItk(m_thresholdImage,ContourSearch) + AccessByItk(m_TestImage,ContourSearch) //m_TestImage mitk::ImageToUnstructuredGridFilter::Pointer i2UFilter = mitk::ImageToUnstructuredGridFilter::New(); i2UFilter->SetInput(m_TestImage); i2UFilter->SetThreshold(1.0); i2UFilter->Update(); m_PointGrid->SetVtkUnstructuredGrid( i2UFilter->GetOutput()->GetVtkUnstructuredGrid() ); m_PointGrid = this->GetOutput(); mitk::ProgressBar::GetInstance()->Progress(); } -#include -#include +#include + +template +void mitk::FeatureBasedEdgeDetectionFilter::ThreadedClosing( itk::Image* originalImage) +{ + 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::CastToMitkImage(erodeFilter->GetOutput(), m_TestImage); +} + +template +void mitk::FeatureBasedEdgeDetectionFilter::ThreadedOpening( itk::Image* originalImage) +{ + typedef itk::BinaryBallStructuringElement myKernelType; + + myKernelType ball; + ball.SetRadius(1); + ball.CreateStructuringElement(); + + typedef typename itk::Image ImageType; + + typename itk::ErodeObjectMorphologyImageFilter::Pointer erodeFilter = itk::ErodeObjectMorphologyImageFilter::New(); + erodeFilter->SetInput(originalImage); + erodeFilter->SetKernel(ball); + erodeFilter->Update(); + + typename itk::Image::Pointer erodedImage = erodeFilter->GetOutput(); + + typename itk::DilateObjectMorphologyImageFilter::Pointer dilationFilter = itk::DilateObjectMorphologyImageFilter::New(); + dilationFilter->SetInput(erodedImage); + dilationFilter->SetKernel(ball); + dilationFilter->Update(); + + mitk::CastToMitkImage(erodeFilter->GetOutput(), m_TestImage); +} template void mitk::FeatureBasedEdgeDetectionFilter::ContourSearch( itk::Image* originalImage) { typedef itk::Image ImageType; typedef itk::BinaryContourImageFilter binaryContourImageFilterType; typedef unsigned char OutputPixelType; typedef itk::Image< OutputPixelType, VImageDimension > OutputImageType; 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::CastToMitkImage(itkImage, m_TestImage); } template void mitk::FeatureBasedEdgeDetectionFilter::ITKThresholding( itk::Image* originalImage, double lower, double upper) { 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::CastToMitkImage(filter->GetOutput(),m_thresholdImage); } void mitk::FeatureBasedEdgeDetectionFilter::SetSegmentationMask(mitk::Image::Pointer segmentation) { this->m_SegmentationMask = segmentation; } void mitk::FeatureBasedEdgeDetectionFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); } diff --git a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h index e63b0928cf..8b54bbc7e7 100644 --- a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h @@ -1,90 +1,96 @@ /*=================================================================== 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 mitkFeatureBasedEdgeDetectionFilter_h_Included #define mitkFeatureBasedEdgeDetectionFilter_h_Included #include #include #include namespace mitk { /** * @brief Calculates edges and extracts them as an UnstructuredGrid with respect * to the given segmentation. * * At first the statistic of the grey values within the segmentation is * calculated. Based on this statistic a thresholding is executed. The * thresholded image will be processed by morphological filters. The resulting * image will be used for masking the input image. The masked image is used as * input for the ImageToPointCloudFilter, which output is an UnstructuredGrid. */ class MITKSEGMENTATION_EXPORT FeatureBasedEdgeDetectionFilter: public ImageToUnstructuredGridFilter { public: mitkClassMacro( FeatureBasedEdgeDetectionFilter, ImageToUnstructuredGridFilter) itkFactorylessNewMacro(Self) itkGetMacro(thresholdImage,mitk::Image::Pointer) itkGetMacro(TestImage, mitk::Image::Pointer) /** Sets the segmentation for calculating the statistics within that */ void SetSegmentationMask(mitk::Image::Pointer); protected: /** This method is called by Update(). */ virtual void GenerateData(); /** Initializes the output information */ virtual void GenerateOutputInformation(); /** Constructor */ FeatureBasedEdgeDetectionFilter(); /** Destructor */ virtual ~FeatureBasedEdgeDetectionFilter(); /** Execute a thresholding filter with the given lower and upper bound */ template void ITKThresholding( itk::Image* originalImage, double lower, double upper); template void ContourSearch( itk::Image* originalImage); + template + void ThreadedOpening( itk::Image* originalImage); + + template + void ThreadedClosing( itk::Image* originalImage); + private: mitk::UnstructuredGrid::Pointer m_PointGrid; /** The used mask given by the segmentation*/ mitk::Image::Pointer m_SegmentationMask; /** The thesholded image */ mitk::Image::Pointer m_thresholdImage; mitk::Image::Pointer m_TestImage; }; } #endif diff --git a/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp index 4239061337..d42f74553c 100644 --- a/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp +++ b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp @@ -1,164 +1,164 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include -mitk::ClusteredPlaneSuggestionFilter::ClusteredPlaneSuggestionFilter(): m_Meshing(false), m_MinPts(4), m_Eps(1.2), m_UseDistances(false), m_NumberOfUsedClusters(3) +mitk::ClusteredPlaneSuggestionFilter::ClusteredPlaneSuggestionFilter(): m_Meshing(false), m_MinPts(4), m_Eps(1.2), m_UseDistances(true), m_NumberOfUsedClusters(3) { this->m_MainCluster = mitk::UnstructuredGrid::New(); this->m_GeoData = mitk::GeometryData::New(); } mitk::ClusteredPlaneSuggestionFilter::~ClusteredPlaneSuggestionFilter(){} bool myComparison(std::pair i, std::pair j){ return (i.first>j.first); } void mitk::ClusteredPlaneSuggestionFilter::GenerateData() { mitk::UnstructuredGrid::Pointer inpGrid = const_cast(this->GetInput()); if(inpGrid.IsNull()) { MITK_ERROR << "Input or cast to UnstructuredGrid is null"; return; } mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); clusterFilter->SetInput(inpGrid); clusterFilter->SetMeshing(false); clusterFilter->SetMinPts(m_MinPts); clusterFilter->Seteps(m_Eps); clusterFilter->Update(); vtkSmartPointer< vtkUnstructuredGrid > vtkGrid = clusterFilter->GetOutput()->GetVtkUnstructuredGrid(); if(!vtkGrid) { MITK_ERROR << "vtkUnstructuredGrid output from clustering is null"; return; } m_MainCluster->SetVtkUnstructuredGrid(vtkGrid); m_Clusters = clusterFilter->GetAllClusters(); //find the avg distances of every cluster maybe a square mean for better looking at high values? std::vector< std::pair > avgDistances; //get the number of points and the id of every cluster std::vector< std::pair > sizeIDs; for(unsigned int i=0; i data = dynamic_cast(cluster->GetVtkUnstructuredGrid()->GetPointData()->GetArray(0)); double avg = 0.0; for(int j=0; jGetSize();j++) { avg += data->GetValue(j); } avgDistances.push_back(std::make_pair(avg/static_cast(data->GetSize()),i)); } //now sort the clusters with their distances for(unsigned int i=0; iGetVtkUnstructuredGrid()->GetNumberOfPoints(), i)); } //sort the point IDs for finding the biggest clusters and clusters with the //highest distance //sizeIDs is sorted by number of points in each cluster //avgDistances is sorted by avg distance to next edge std::sort(sizeIDs.begin(), sizeIDs.end(), myComparison); std::sort(avgDistances.begin(), avgDistances.end(), myComparison); int number = 0; //max number of biggest clusters which are used for the plane //if less than m_NumberOfUsedClusters clusters are found if(m_Clusters.size() < m_NumberOfUsedClusters) number = m_Clusters.size(); else number = m_NumberOfUsedClusters; //Generate a pointset from UnstructuredGrid for the PlaneFitFilter: mitk::PointSet::Pointer pointset = mitk::PointSet::New(); int pointId = 0; for(int j=0; j tmpGrid; if(m_UseDistances) tmpGrid = m_Clusters.at(avgDistances.at(j).second)->GetVtkUnstructuredGrid(); //highest distance else tmpGrid = m_Clusters.at(sizeIDs.at(j).second)->GetVtkUnstructuredGrid(); //biggest cluster for(int i=0; iGetNumberOfPoints();i++) { mitk::Point3D point; point[0] = tmpGrid->GetPoint(i)[0]; point[1] = tmpGrid->GetPoint(i)[1]; point[2] = tmpGrid->GetPoint(i)[2]; pointset->InsertPoint(pointId,point); pointId++; } } mitk::PlaneFit::Pointer planeFilter = mitk::PlaneFit::New(); planeFilter->SetInput(pointset); planeFilter->Update(); m_GeoData = planeFilter->GetOutput(); if(m_GeoData.IsNull()) { MITK_ERROR << "GeometryData output from PlaneFit filter is null"; return; } avgDistances.clear(); } void mitk::ClusteredPlaneSuggestionFilter::GenerateOutputInformation() { mitk::UnstructuredGrid::ConstPointer inputImage = this->GetInput(); m_MainCluster = this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); if(inputImage.IsNull()) return; }