diff --git a/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp new file mode 100644 index 0000000000..0e18d63be6 --- /dev/null +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp @@ -0,0 +1,126 @@ +/*=================================================================== + +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 + +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); +} + +mitk::FeatureBasedEdgeDetectionFilter::~FeatureBasedEdgeDetectionFilter(){} + +void mitk::FeatureBasedEdgeDetectionFilter::GenerateData() +{ + mitk::Image::ConstPointer image = ImageToUnstructuredGridFilter::GetInput(); + mitk::Image::Pointer ncImage = image->Clone(); + + //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); + + //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 = pclFilter->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())->Clone(); +} + +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 new file mode 100644 index 0000000000..edc5de39e0 --- /dev/null +++ b/Modules/Segmentation/Algorithms/mitkFeatureBasedEdgeDetectionFilter.h @@ -0,0 +1,65 @@ +/*=================================================================== + +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 + +#include +#include + +namespace mitk +{ + +class MitkSegmentation_EXPORT FeatureBasedEdgeDetectionFilter: + public ImageToUnstructuredGridFilter +{ + +public: + + mitkClassMacro( FeatureBasedEdgeDetectionFilter, ImageToUnstructuredGridFilter) + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + void SetSegmentationMask(mitk::Image::Pointer); + +protected: + + virtual void GenerateData(); + + virtual void GenerateOutputInformation(); + + FeatureBasedEdgeDetectionFilter(); + + virtual ~FeatureBasedEdgeDetectionFilter(); + + template + void ITKThresholding( itk::Image* originalImage, double lower, double upper); + +private: + + mitk::UnstructuredGrid::Pointer m_PointGrid; + mitk::Image::Pointer m_SegmentationMask; + mitk::Image::Pointer m_thresholdImage; + +}; + +} +#endif diff --git a/Modules/Segmentation/files.cmake b/Modules/Segmentation/files.cmake index 981f749ddf..7d69d6df21 100644 --- a/Modules/Segmentation/files.cmake +++ b/Modules/Segmentation/files.cmake @@ -1,118 +1,119 @@ set(CPP_FILES Algorithms/mitkCalculateSegmentationVolume.cpp Algorithms/mitkContourModelSetToImageFilter.cpp Algorithms/mitkContourSetToPointSetFilter.cpp Algorithms/mitkContourUtils.cpp Algorithms/mitkCorrectorAlgorithm.cpp Algorithms/mitkDiffImageApplier.cpp Algorithms/mitkDiffSliceOperation.cpp Algorithms/mitkDiffSliceOperationApplier.cpp + Algorithms/mitkFeatureBasedEdgeDetectionFilter.cpp Algorithms/mitkImageLiveWireContourModelFilter.cpp Algorithms/mitkImageToContourFilter.cpp #Algorithms/mitkImageToContourModelFilter.cpp Algorithms/mitkImageToLiveWireContourFilter.cpp Algorithms/mitkManualSegmentationToSurfaceFilter.cpp Algorithms/mitkOtsuSegmentationFilter.cpp Algorithms/mitkOverwriteDirectedPlaneImageFilter.cpp Algorithms/mitkOverwriteSliceImageFilter.cpp Algorithms/mitkSegmentationObjectFactory.cpp Algorithms/mitkShapeBasedInterpolationAlgorithm.cpp Algorithms/mitkShowSegmentationAsSmoothedSurface.cpp Algorithms/mitkShowSegmentationAsSurface.cpp Algorithms/mitkVtkImageOverwrite.cpp Controllers/mitkSegmentationInterpolationController.cpp Controllers/mitkToolManager.cpp Controllers/mitkSegmentationModuleActivator.cpp Controllers/mitkToolManagerProvider.cpp DataManagement/mitkContour.cpp #DataManagement/mitkContourElement.cpp #DataManagement/mitkContourModel.cpp DataManagement/mitkContourSet.cpp DataManagement/mitkExtrudedContour.cpp Interactions/mitkAdaptiveRegionGrowingTool.cpp Interactions/mitkAddContourTool.cpp Interactions/mitkAutoCropTool.cpp Interactions/mitkAutoSegmentationTool.cpp Interactions/mitkBinaryThresholdTool.cpp Interactions/mitkBinaryThresholdULTool.cpp Interactions/mitkCalculateGrayValueStatisticsTool.cpp Interactions/mitkCalculateVolumetryTool.cpp Interactions/mitkContourInteractor.cpp Interactions/mitkContourModelInteractor.cpp Interactions/mitkContourModelLiveWireInteractor.cpp Interactions/mitkContourTool.cpp Interactions/mitkCorrectorTool2D.cpp Interactions/mitkCreateSurfaceTool.cpp Interactions/mitkDrawPaintbrushTool.cpp Interactions/mitkErasePaintbrushTool.cpp Interactions/mitkEraseRegionTool.cpp Interactions/mitkExtrudedContourInteractor.cpp Interactions/mitkFastMarchingTool.cpp Interactions/mitkFastMarchingTool3D.cpp Interactions/mitkFeedbackContourTool.cpp Interactions/mitkFillRegionTool.cpp Interactions/mitkLiveWireTool2D.cpp Interactions/mitkOtsuTool3D.cpp Interactions/mitkPaintbrushTool.cpp Interactions/mitkPixelManipulationTool.cpp Interactions/mitkRegionGrow3DTool.cpp Interactions/mitkRegionGrowingTool.cpp Interactions/mitkSegmentationsProcessingTool.cpp Interactions/mitkSetRegionTool.cpp Interactions/mitkSegTool2D.cpp Interactions/mitkSubtractContourTool.cpp Interactions/mitkTool.cpp Interactions/mitkToolCommand.cpp Interactions/mitkWatershedTool.cpp Interactions/mitkPickingTool.cpp #IO/mitkContourModelIOFactory.cpp #IO/mitkContourModelReader.cpp #IO/mitkContourModelWriter.cpp #IO/mitkContourModelWriterFactory.cpp Rendering/mitkContourMapper2D.cpp #Rendering/mitkContourModelGLMapper2D.cpp #Rendering/mitkContourModelMapper2D.cpp #Rendering/mitkContourModelMapper3D.cpp Rendering/mitkContourSetMapper2D.cpp Rendering/mitkContourSetVtkMapper3D.cpp Rendering/mitkContourVtkMapper3D.cpp SegmentationUtilities/BooleanOperations/mitkBooleanOperation.cpp SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp ) set(RESOURCE_FILES Add_48x48.png Add_Cursor_32x32.png Correction_48x48.png Correction_Cursor_32x32.png Erase_48x48.png Erase_Cursor_32x32.png FastMarching_48x48.png FastMarching_Cursor_32x32.png Fill_48x48.png Fill_Cursor_32x32.png LiveWire_48x48.png LiveWire_Cursor_32x32.png Otsu_48x48.png Paint_48x48.png Paint_Cursor_32x32.png Pick_48x48.png RegionGrowing_48x48.png RegionGrowing_Cursor_32x32.png Subtract_48x48.png Subtract_Cursor_32x32.png Threshold_48x48.png TwoThresholds_48x48.png Watershed_48x48.png Watershed_Cursor_32x32.png Wipe_48x48.png Wipe_Cursor_32x32.png Interactions/dummy.xml Interactions/LiveWireTool.xml Interactions/PressMoveRelease.xml Interactions/PressMoveReleaseAndPointSetting.xml Interactions/PressMoveReleaseWithCTRLInversion.xml Interactions/PressMoveReleaseWithCTRLInversionAllMouseMoves.xml Interactions/SegmentationToolsConfig.xml ) diff --git a/Modules/SurfaceInterpolation/CMakeLists.txt b/Modules/SurfaceInterpolation/CMakeLists.txt index 33cd8a94ec..cab2c46a95 100644 --- a/Modules/SurfaceInterpolation/CMakeLists.txt +++ b/Modules/SurfaceInterpolation/CMakeLists.txt @@ -1,7 +1,7 @@ MITK_CREATE_MODULE( - DEPENDS MitkAlgorithmsExt + DEPENDS MitkImageExtraction MitkImageStatistics PACKAGE_DEPENDS PUBLIC Eigen WARNINGS_AS_ERRORS ) add_subdirectory(Testing) diff --git a/Modules/SurfaceInterpolation/files.cmake b/Modules/SurfaceInterpolation/files.cmake index f3339c5be6..c162e1a981 100644 --- a/Modules/SurfaceInterpolation/files.cmake +++ b/Modules/SurfaceInterpolation/files.cmake @@ -1,7 +1,8 @@ set(CPP_FILES mitkComputeContourSetNormalsFilter.cpp mitkCreateDistanceImageFromSurfaceFilter.cpp mitkPointCloudScoringFilter.cpp + mitkImageToPointCloudFilter.cpp mitkReduceContourSetFilter.cpp mitkSurfaceInterpolationController.cpp ) diff --git a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp new file mode 100644 index 0000000000..d18bfff820 --- /dev/null +++ b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.cpp @@ -0,0 +1,176 @@ +/*=================================================================== + +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 +#include + +mitk::ImageToPointCloudFilter::ImageToPointCloudFilter(): + m_NumberOfExtractedPoints(0) +{ + m_PointGrid = mitk::UnstructuredGrid::New(); + m_Method = DetectConstant(0); + m_EdgeImage = mitk::Image::New(); + m_EdgePoints = mitk::Image::New(); + + this->SetNumberOfRequiredInputs(1); + this->SetNumberOfRequiredOutputs(1); + + this->SetNthOutput(0, m_PointGrid); +} + +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; + } + + switch(m_Method) + { + case 0: + this->LaplacianStdDev(image, 2); + break; + + case 1: + this->LaplacianStdDev(image, 3); + break; + + default: + this->LaplacianStdDev(image, 2); + break; + } +} + +void mitk::ImageToPointCloudFilter:: + LaplacianStdDev(mitk::Image::ConstPointer image, int amount) +{ + mitk::Image::Pointer notConstImage = image->Clone(); + AccessByItk_1(notConstImage.GetPointer(), StdDeviations, amount) +} + +template +void mitk::ImageToPointCloudFilter:: + StdDeviations(itk::Image* image, int amount) +{ + typedef itk::Image InputImageType; + typedef itk::CastImageFilter< InputImageType, FloatImageType > + ImagePTypeToFloatPTypeCasterType; + 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(); + m_EdgeImage = mitk::ImportItkImage(lapFilter->GetOutput())->Clone(); + + mitk::ImageStatisticsCalculator::Pointer statCalc = + mitk::ImageStatisticsCalculator::New(); + statCalc->SetImage(m_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; + } + + m_EdgePoints = mitk::ImportItkImage(lapFilter->GetOutput())->Clone(); + + 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); +} + + +void mitk::ImageToPointCloudFilter::GenerateOutputInformation() +{ + Superclass::GenerateOutputInformation(); +} diff --git a/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h new file mode 100644 index 0000000000..01f33b8d66 --- /dev/null +++ b/Modules/SurfaceInterpolation/mitkImageToPointCloudFilter.h @@ -0,0 +1,94 @@ +/*=================================================================== + +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 + +#include +#include + +namespace mitk +{ + +enum MitkSurfaceInterpolation_EXPORT DetectConstant +{ + LAPLACIAN_STD_DEV2, + LAPLACIAN_STD_DEV3, + CANNY_EDGE, + THRESHOLD +}; + +class MitkSurfaceInterpolation_EXPORT ImageToPointCloudFilter: + public ImageToUnstructuredGridFilter +{ + +public: + + mitkClassMacro( ImageToPointCloudFilter, ImageToUnstructuredGridFilter) + + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + typedef itk::Image ImageType; + typedef itk::Image DoubleImageType; + typedef itk::Image FloatImageType; + typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > + LaplacianFilterType; + typedef DetectConstant DetectionMethod; + + itkGetMacro(Method,DetectionMethod) + itkGetMacro(EdgeImage,mitk::Image::Pointer) + itkGetMacro(EdgePoints,mitk::Image::Pointer) + itkGetMacro(NumberOfExtractedPoints,int) + + itkSetMacro(Method,DetectionMethod) + +protected: + + virtual void GenerateData(); + + virtual void GenerateOutputInformation(); + + ImageToPointCloudFilter(); + + virtual ~ImageToPointCloudFilter(); + +private: + + template + void StdDeviations(itk::Image* image, int amount); + + void LaplacianStdDev(Image::ConstPointer image, int amount); + + mitk::UnstructuredGrid::Pointer m_PointGrid; + + mitk::BaseGeometry* m_Geometry; + + mitk::Image::Pointer m_EdgeImage; + mitk::Image::Pointer m_EdgePoints; + + int m_NumberOfExtractedPoints; + + DetectionMethod m_Method; + +}; + +} +#endif