diff --git a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp index 66843c4d29..9d6141cee3 100644 --- a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp @@ -1,131 +1,135 @@ /*=================================================================== 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 mitk::FeatureBasedEdgeDetectionFilter::FeatureBasedEdgeDetectionFilter() { m_PointGrid = mitk::UnstructuredGrid::New(); m_SegmentationMask = mitk::Image::New(); m_thresholdImage = mitk::Image::New(); this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(1); - this->SetNthOutput(0, m_PointGrid); + this->SetNumberOfIndexedOutputs(1); } mitk::FeatureBasedEdgeDetectionFilter::~FeatureBasedEdgeDetectionFilter(){} 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; //thresholding AccessByItk_2(ncImage.GetPointer(), ITKThresholding, lowerThreshold, upperThreshold) //fill holes mitk::MorphologicalOperations::FillHoles(m_thresholdImage); // mitk::MorphologicalOperations::Closing(m_morphThreshold,1,mitk::MorphologicalOperations::Ball); // mitk::MorphologicalOperations::Opening(m_morphThreshold,1,mitk::MorphologicalOperations::Ball); //masking mitk::MaskImageFilter::Pointer maskFilter = mitk::MaskImageFilter::New(); maskFilter->SetInput(image); maskFilter->SetMask(m_thresholdImage); maskFilter->OverrideOutsideValueOn(); maskFilter->SetOutsideValue(0); try { maskFilter->Update(); } catch(itk::ExceptionObject& excpt) { MITK_ERROR << excpt.GetDescription(); return; } mitk::Image::Pointer resultImage = maskFilter->GetOutput(); //imagetopointcloudfilter mitk::ImageToPointCloudFilter::Pointer pclFilter = mitk::ImageToPointCloudFilter::New(); pclFilter->SetInput(resultImage); pclFilter->Update(); - m_PointGrid->SetVtkUnstructuredGrid( pclFilter->GetOutput()->GetVtkUnstructuredGrid() ); + mitk::UnstructuredGrid::Pointer outp = mitk::UnstructuredGrid::New(); + outp->SetVtkUnstructuredGrid( pclFilter->GetOutput()->GetVtkUnstructuredGrid() ); + this->SetNthOutput(0, outp); + +// m_PointGrid->SetVtkUnstructuredGrid( pclFilter->GetOutput()->GetVtkUnstructuredGrid() ); +// m_PointGrid = this->GetOutput(); } template void mitk::FeatureBasedEdgeDetectionFilter::ITKThresholding( itk::Image* originalImage, double lower, double upper) { typedef itk::Image ImageType; typedef itk::Image SegmentationType; typedef itk::BinaryThresholdImageFilter ThresholdFilterType; typename ThresholdFilterType::Pointer filter = ThresholdFilterType::New(); filter->SetInput(originalImage); filter->SetLowerThreshold(lower); filter->SetUpperThreshold(upper); filter->SetInsideValue(1); filter->SetOutsideValue(0); filter->Update(); m_thresholdImage = mitk::ImportItkImage(filter->GetOutput()); } 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 56f4f386af..24162698b7 100644 --- a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h @@ -1,83 +1,80 @@ /*=================================================================== 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 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(SegmentationMask, mitk::Image::Pointer) - itkGetMacro(thresholdImage, 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); 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; }; } #endif diff --git a/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp b/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp index fe138f3316..25a1580ffe 100644 --- a/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkFeatureBasedEdgeDetectionFilterTest.cpp @@ -1,79 +1,73 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include #include class mitkFeatureBasedEdgeDetectionFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkFeatureBasedEdgeDetectionFilterTestSuite); MITK_TEST(testFeatureBasedEdgeDetectionFilterInitialization); MITK_TEST(testInput); MITK_TEST(testUnstructuredGridGeneration); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ mitk::Image::Pointer m_Pic3D; mitk::Image::Pointer m_Segmentation; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() { m_Pic3D = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd")); m_Segmentation = mitk::IOUtil::LoadImage(GetTestDataFilePath("PlaneSuggestion/pic3D_segmentation.nrrd")); } void testFeatureBasedEdgeDetectionFilterInitialization() { mitk::FeatureBasedEdgeDetectionFilter::Pointer testFilter = mitk::FeatureBasedEdgeDetectionFilter::New(); CPPUNIT_ASSERT_MESSAGE("Testing instantiation of test object", testFilter.IsNotNull()); } void testInput() { mitk::FeatureBasedEdgeDetectionFilter::Pointer testFilter = mitk::FeatureBasedEdgeDetectionFilter::New(); testFilter->SetInput(m_Pic3D); CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", testFilter->GetInput() == m_Pic3D); } void testUnstructuredGridGeneration() { mitk::FeatureBasedEdgeDetectionFilter::Pointer testFilter = mitk::FeatureBasedEdgeDetectionFilter::New(); testFilter->SetInput(m_Pic3D); testFilter->SetSegmentationMask(m_Segmentation); testFilter->Update(); - mitk::Image::Pointer thresholdImage = testFilter->GetthresholdImage(); - - mitk::Image::Pointer ref_thresholdImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("PlaneSuggestion/Threshold_Image.nrrd")); - - MITK_ASSERT_EQUAL(thresholdImage, ref_thresholdImage, "Testing thresholded image!"); - - CPPUNIT_ASSERT_MESSAGE("Testing surface generation!", testFilter->GetOutput() != NULL); + CPPUNIT_ASSERT_MESSAGE("Testing surface generation!", testFilter->GetOutput()->GetVtkUnstructuredGrid() != NULL); } }; MITK_TEST_SUITE_REGISTRATION(mitkFeatureBasedEdgeDetectionFilter) diff --git a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp index f53736f844..12981a7dba 100644 --- a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp +++ b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp @@ -1,173 +1,173 @@ /*=================================================================== 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 mitk::ImageToPointCloudFilter::ImageToPointCloudFilter(): m_NumberOfExtractedPoints(0) { - m_PointGrid = mitk::UnstructuredGrid::New(); - m_Method = DetectConstant(0); + m_Method = DetectionMethod(0); this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(1); - this->SetNthOutput(0, m_PointGrid); + 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< InputImageType, FloatImageType > ImagePTypeToFloatPTypeCasterType; typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > 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->SetImage(edgeImage); statCalc->ComputeStatistics(); mitk::ImageStatisticsCalculator::Statistics stats = statCalc->GetStatistics(); double mean = stats.GetMean(); double stdDev = stats.GetSigma(); 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; iGetPointIds()->SetId(i,i); } vtkSmartPointer uGrid = vtkSmartPointer::New(); uGrid->Allocate(1); uGrid->InsertNextCell(verts->GetCellType(), verts->GetPointIds()); uGrid->SetPoints(points); - m_PointGrid->SetVtkUnstructuredGrid(uGrid); + mitk::UnstructuredGrid::Pointer outputGrid = mitk::UnstructuredGrid::New(); + outputGrid->SetVtkUnstructuredGrid(uGrid); + this->SetNthOutput(0, outputGrid); } void mitk::ImageToPointCloudFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); } diff --git a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h index 34edb83624..e2e74638f4 100644 --- a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h +++ b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h @@ -1,93 +1,102 @@ /*=================================================================== 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 mitkImageToPointCloudFilter_h_Included #define mitkImageToPointCloudFilter_h_Included #include #include #include namespace mitk { /** * @brief The filter extracts the edge pixels of an image as points and stores * them in an UnstructuredGrid. Every pixel which grey value is between the * mean +- standard deviation * (2 or 3), will be extracted as point. The * DetectionMethod can be set to choose if the doubled or tripled standard * deviation is used. */ class MITKSURFACEINTERPOLATION_EXPORT ImageToPointCloudFilter: public ImageToUnstructuredGridFilter { public: - enum DetectConstant + /** + * @brief The method which calculates and extracts the edge pixels/points. + * For the edge detection the laplacian filter is used and for extraction + * the standard deviation multiplied with 2, 3 or 4 (depending on selected + * method) is used. + */ + enum DetectionMethod { LAPLACIAN_STD_DEV2 = 0, LAPLACIAN_STD_DEV3 = 1, LAPLACIAN_STD_DEV4 = 2 }; mitkClassMacro( ImageToPointCloudFilter, ImageToUnstructuredGridFilter) - itkFactorylessNewMacro(Self) typedef itk::Image FloatImageType; - typedef DetectConstant DetectionMethod; + /** Returns the selected DetectionMethod */ itkGetMacro(Method,DetectionMethod) + + /** Returns the number of extracted points after edge detection */ itkGetMacro(NumberOfExtractedPoints,int) + /** Sets the DetectionMethod for edge detection and extraction */ itkSetMacro(Method,DetectionMethod) protected: /** This method is called by Update(). */ virtual void GenerateData(); /** Initializes the output information */ virtual void GenerateOutputInformation(); /** Constructor */ ImageToPointCloudFilter(); /** Destructor */ virtual ~ImageToPointCloudFilter(); private: /** Uses the laplace filter to create an image and extracts a pixel as point * if the grey value is between the mean +- standard deviation * (2 or 3) */ template void StdDeviations(itk::Image* image, int amount); - mitk::UnstructuredGrid::Pointer m_PointGrid; + /** The geometry of the input image for transforming the pixel coordinates to + * world coordinates */ mitk::BaseGeometry* m_Geometry; /** The number of extracted points */ int m_NumberOfExtractedPoints; /** The selected detection method */ DetectionMethod m_Method; }; } #endif