diff --git a/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h b/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h index 743dae16d6..504db804c1 100644 --- a/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h +++ b/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h @@ -1,112 +1,140 @@ /*=================================================================== 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 _MITKUNSTRUCTUREDGRIDCLUSTERINGFILTER_h__ #define _MITKUNSTRUCTUREDGRIDCLUSTERINGFILTER_h__ #include #include #include #include #include #include #include namespace mitk { /** - * @brief The UnstructuredGridClusteringFilter class + * @brief This filter uses the DBSCAN algorithm for clustering an + * mitk::UnstructuredGrid. "MinPts" defines the number of neighbours which are + * required to be a kernel point if a point is in range of a kernel point + * but hasnt enough neighbours this point is added to the cluster but is a + * density reachable point and the cluster ends at this point. "eps" is the + * range in which the neighbours are searched. If "Meshing" is set the + * clusteres UnstructuredGrid is meshed and visible in 2D renderwindows. * * DBSCAN algorithm: * * DBSCAN(D, eps, MinPts) * C = 0 * for each unvisited point P in dataset D * mark P as visited * N = D.regionQuery(P, eps) * if sizeof(N) < MinPts * mark P as NOISE * else * C = next cluster * expandCluster(P, N, C, eps, MinPts) * * expandCluster(P, N, C, eps, MinPts) * add P to cluster C * for each point P' in N * if P' is not visited * mark P' as visited * N' = D.regionQuery(P', eps) * if sizeof(N') >= MinPts * N = N joined with N' * if P' is not yet member of any cluster * add P' to cluster C */ class MITKALGORITHMSEXT_EXPORT UnstructuredGridClusteringFilter : public UnstructuredGridToUnstructuredGridFilter { public: mitkClassMacro(UnstructuredGridClusteringFilter, UnstructuredGridToUnstructuredGridFilter) itkFactorylessNewMacro(Self) itkCloneMacro(Self) + /** Sets the distance for the neighbour search */ itkSetMacro(eps, double) itkGetMacro(eps, double) + /** Sets the number of required neighbours */ itkSetMacro(MinPts, int) itkGetMacro(MinPts, int) + /** If activated the clusteres UnstructuredGrid is meshed */ itkSetMacro(Meshing, bool) + /** Returns all clusters as UnstructuredGrids which were found */ virtual std::vector< mitk::UnstructuredGrid::Pointer> GetAllClusters(); + /** Returns the number of the clusters which were found */ virtual int GetNumberOfFoundClusters(); - virtual void GenerateOutputInformation(); - - virtual void GenerateData(); - protected: + /** Constructor */ UnstructuredGridClusteringFilter(); + /** Destructor */ virtual ~UnstructuredGridClusteringFilter(); + /** Defines the output of the filter */ + virtual void GenerateOutputInformation(); + + /** Is called by the Update() method */ + virtual void GenerateData(); + private: + /** Used for the DBSCAN algorithm to expand a cluster and add more points to it */ void ExpandCluster(int id, vtkIdList* pointIDs, vtkPoints* cluster, vtkPoints *inpPoints); + /** The result main Cluster */ mitk::UnstructuredGrid::Pointer m_UnstructGrid; + /** All clusters which were found */ std::vector< vtkSmartPointer > m_Clusters; + /** The distances of the points from the input UnstructuredGrid*/ + std::vector< vtkSmartPointer > m_DistanceArrays; + + /** The range for the neighbout search */ double m_eps; + /** The number of the required neighbours */ int m_MinPts; + /** Activates the meshing for the UnstructuredGrid clusters*/ bool m_Meshing; + /** If its activated the distance of the clusters is used instead of the + * size */ + bool m_DistCalc; + }; } // namespace mitk #endif //_MITKUNSTRUCTUREDGRIDCLUSTERINGFILTER_h__ diff --git a/Modules/AlgorithmsExt/src/mitkUnstructuredGridClusteringFilter.cpp b/Modules/AlgorithmsExt/src/mitkUnstructuredGridClusteringFilter.cpp index 9b1f089927..2a3ad2844d 100644 --- a/Modules/AlgorithmsExt/src/mitkUnstructuredGridClusteringFilter.cpp +++ b/Modules/AlgorithmsExt/src/mitkUnstructuredGridClusteringFilter.cpp @@ -1,218 +1,271 @@ /*=================================================================== 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 -mitk::UnstructuredGridClusteringFilter::UnstructuredGridClusteringFilter() : m_eps(0.0), m_MinPts(0), m_Meshing(true) +mitk::UnstructuredGridClusteringFilter::UnstructuredGridClusteringFilter() : m_eps(5.0), m_MinPts(4), m_Meshing(false), m_DistCalc(false) { this->m_UnstructGrid = mitk::UnstructuredGrid::New(); } mitk::UnstructuredGridClusteringFilter::~UnstructuredGridClusteringFilter(){} std::map visited; std::map isNoise; std::map clusterMember; vtkSmartPointer pLocator; +std::vector< vtkSmartPointer > clusterVector; + +std::vector< std::vector > clustersPointsIDs; void mitk::UnstructuredGridClusteringFilter::GenerateOutputInformation() { m_UnstructGrid = this->GetOutput(); } void mitk::UnstructuredGridClusteringFilter::GenerateData() { mitk::UnstructuredGrid::Pointer inputGrid = const_cast(this->GetInput()); if(inputGrid.IsNull()) return; vtkSmartPointer vtkInpGrid = inputGrid->GetVtkUnstructuredGrid(); vtkSmartPointer inpPoints = vtkInpGrid->GetPoints(); pLocator =vtkSmartPointer::New(); - std::vector< vtkSmartPointer > clusterVector; + + vtkSmartPointer distances = vtkSmartPointer::New(); + if(inputGrid->GetVtkUnstructuredGrid()->GetPointData()->GetNumberOfArrays() > 0) + { + m_DistCalc = true; + distances = dynamic_cast(vtkInpGrid->GetPointData()->GetArray(0)); + } pLocator->SetDataSet(vtkInpGrid); pLocator->AutomaticOn(); pLocator->SetNumberOfPointsPerBucket(2); pLocator->BuildLocator(); //fill the visited map with false for checking for(int i=0; iGetNumberOfPoints();i++) { visited[i] = false; isNoise[i] = false; clusterMember[i] = false; } for(int i=0; iGetNumberOfPoints();i++) { if(!visited[i]) { visited[i] = true; //mark P as visited vtkSmartPointer idList = vtkSmartPointer::New(); //represent N pLocator->FindPointsWithinRadius(m_eps, inpPoints->GetPoint(i), idList); //N = D.regionQuery(P, eps) if(idList->GetNumberOfIds() < m_MinPts) //if sizeof(N) < MinPts { isNoise[i] = true; //mark P as NOISE } else { vtkSmartPointer cluster = vtkSmartPointer::New(); //represent a cluster clusterVector.push_back(cluster); //C = next cluster this->ExpandCluster(i,idList,cluster,inpPoints); //expandCluster(P, N, C, eps, MinPts) mod. the parameter list } } } //OUTPUT LOGIC m_Clusters = clusterVector; int numberOfClusterPoints = 0; int IdOfBiggestCluster = 0; for(unsigned int i=0; i array = vtkSmartPointer::New(); vtkSmartPointer points = m_Clusters.at(i); - for(int j=0; jGetNumberOfPoints();j++) + if(m_DistCalc) { - double point[3]; - points->GetPoint(j,point); + array->SetNumberOfComponents(1); + array->SetNumberOfTuples(points->GetNumberOfPoints()); + for(int j=0; jGetNumberOfPoints();j++) + { + double point[3]; + points->GetPoint(j,point); + if(clustersPointsIDs.at(i).at(j)GetNumberOfPoints()) + { + if(distances->GetValue(clustersPointsIDs.at(i).at(j)) > 0.001) + { + double dist[1] = {distances->GetValue(clustersPointsIDs.at(i).at(j))}; + array->SetTuple(j, dist); + } + else + { + double dist[1] = {0.0}; + array->SetTuple(j, dist); + } + } + } + m_DistanceArrays.push_back(array); } if(points->GetNumberOfPoints() > numberOfClusterPoints) { numberOfClusterPoints = points->GetNumberOfPoints(); IdOfBiggestCluster = i; } } vtkSmartPointer biggestCluster = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); points = m_Clusters.at(IdOfBiggestCluster); vtkSmartPointer verts = vtkSmartPointer::New(); verts->GetPointIds()->SetNumberOfIds(m_Clusters.at(IdOfBiggestCluster)->GetNumberOfPoints()); for(int i=0; iGetNumberOfPoints(); i++) { verts->GetPointIds()->SetId(i,i); } biggestCluster->Allocate(1); biggestCluster->InsertNextCell(verts->GetCellType(), verts->GetPointIds()); biggestCluster->SetPoints(m_Clusters.at(IdOfBiggestCluster)); if(m_Meshing) { vtkSmartPointer mesher = vtkSmartPointer::New(); mesher->SetInputData(biggestCluster); mesher->SetAlpha(0.9); mesher->Update(); vtkSmartPointer output = mesher->GetOutput(); m_UnstructGrid->SetVtkUnstructuredGrid(output); } else { m_UnstructGrid->SetVtkUnstructuredGrid(biggestCluster); } + + clusterVector.clear(); + clustersPointsIDs.clear(); } void mitk::UnstructuredGridClusteringFilter::ExpandCluster(int id, vtkIdList *pointIDs, vtkPoints* cluster, vtkPoints* inpPoints) { + std::vector x; + x.push_back(id); cluster->InsertNextPoint(inpPoints->GetPoint(id)); //add P to cluster C - clusterMember[id] = true; //right? + clusterMember[id] = true; vtkSmartPointer neighbours = vtkSmartPointer::New(); //same N as in other function inpPoints->GetPoints(pointIDs,neighbours); for(int i=0; iGetNumberOfIds();i++) //for each point P' in N { if(!visited[pointIDs->GetId(i)]) //if P' is not visited { visited[pointIDs->GetId(i)] = true; //mark P' as visited vtkSmartPointer idList = vtkSmartPointer::New(); //represent N' pLocator->FindPointsWithinRadius(m_eps, inpPoints->GetPoint(pointIDs->GetId(i)), idList); //N' = D.regionQuery(P', eps) + if(idList->GetNumberOfIds() >= m_MinPts) //if sizeof(N') >= MinPts { for(int j=0; jGetNumberOfIds();j++) //N = N joined with N' { - pointIDs->InsertNextId(idList->GetId(j)); + if(idList->GetId(j)GetNumberOfPoints())//a litte bit hacked ?! + { + pointIDs->InsertNextId(idList->GetId(j)); + } } } } if(!clusterMember[pointIDs->GetId(i)]) //if P' is not yet member of any cluster { - clusterMember[pointIDs->GetId(i)] = true; - cluster->InsertNextPoint(inpPoints->GetPoint(pointIDs->GetId(i))); //add P' to cluster C + if(pointIDs->GetId(i)GetNumberOfPoints()){ + clusterMember[pointIDs->GetId(i)] = true; + x.push_back(pointIDs->GetId(i)); + cluster->InsertNextPoint(inpPoints->GetPoint(pointIDs->GetId(i))); //add P' to cluster C + } } } + + clustersPointsIDs.push_back(x); } std::vector mitk::UnstructuredGridClusteringFilter::GetAllClusters() { std::vector< mitk::UnstructuredGrid::Pointer > mitkUGridVector; for(unsigned int i=0; i cluster = vtkSmartPointer::New(); vtkSmartPointer points = m_Clusters.at(i); vtkSmartPointer verts = vtkSmartPointer::New(); verts->GetPointIds()->SetNumberOfIds(points->GetNumberOfPoints()); - for(int i=0; iGetNumberOfPoints(); i++) + for(int j=0; jGetNumberOfPoints(); j++) { - verts->GetPointIds()->SetId(i,i); + verts->GetPointIds()->SetId(j,j); } cluster->Allocate(1); cluster->InsertNextCell(verts->GetCellType(), verts->GetPointIds()); cluster->SetPoints(points); + if(m_DistCalc) + { + cluster->GetPointData()->AddArray(m_DistanceArrays.at(i)); + } mitk::UnstructuredGrid::Pointer mitkGrid = mitk::UnstructuredGrid::New(); if(m_Meshing) { vtkSmartPointer mesher = vtkSmartPointer::New(); mesher->SetInputData(cluster); mesher->SetAlpha(0.9); mesher->Update(); vtkSmartPointer output = mesher->GetOutput(); mitkGrid->SetVtkUnstructuredGrid(output); } else { mitkGrid->SetVtkUnstructuredGrid(cluster); } mitkUGridVector.push_back(mitkGrid); } return mitkUGridVector; } int mitk::UnstructuredGridClusteringFilter::GetNumberOfFoundClusters() { return m_Clusters.size(); } diff --git a/Modules/AlgorithmsExt/test/mitkUnstructuredGridClusteringFilterTest.cpp b/Modules/AlgorithmsExt/test/mitkUnstructuredGridClusteringFilterTest.cpp index 8f2409f9e7..8adfc77384 100644 --- a/Modules/AlgorithmsExt/test/mitkUnstructuredGridClusteringFilterTest.cpp +++ b/Modules/AlgorithmsExt/test/mitkUnstructuredGridClusteringFilterTest.cpp @@ -1,129 +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 "mitkTestingMacros.h" #include #include #include #include #include #include #include #include -#include class mitkUnstructuredGridClusteringFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkUnstructuredGridClusteringFilterTestSuite); - vtkDebugLeaks::SetExitError(0); - MITK_TEST(testUnstructuredGridClusteringFilterInitialization); MITK_TEST(testInput); MITK_TEST(testUnstructuredGridGeneration); MITK_TEST(testReturnedCluster); MITK_TEST(testClusterVector); MITK_TEST(testGetNumberOfFoundClusters); CPPUNIT_TEST_SUITE_END(); private: mitk::UnstructuredGrid::Pointer m_UnstructuredGrid; public: void setUp() { m_UnstructuredGrid = mitk::UnstructuredGrid::New(); //Loading the test data std::vector< mitk::BaseData::Pointer > vector = mitk::IOUtil::Load(GetTestDataFilePath("UnstructuredGrid/scoredGrid.vtu")); mitk::BaseData::Pointer base = vector.at(0); m_UnstructuredGrid = dynamic_cast(base.GetPointer()); } void testUnstructuredGridClusteringFilterInitialization() { mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); CPPUNIT_ASSERT_MESSAGE("Testing instantiation of filter object", clusterFilter.IsNotNull()); } void testInput() { mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); clusterFilter->SetInput(m_UnstructuredGrid); CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", clusterFilter->GetInput() == m_UnstructuredGrid); } void testUnstructuredGridGeneration() { mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); clusterFilter->SetInput(m_UnstructuredGrid); clusterFilter->SetMeshing(false); clusterFilter->SetMinPts(4); clusterFilter->Seteps(1.2); clusterFilter->Update(); CPPUNIT_ASSERT_MESSAGE("Testing output generation!", clusterFilter->GetOutput() != NULL); } void testReturnedCluster() { mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); clusterFilter->SetInput(m_UnstructuredGrid); clusterFilter->SetMeshing(false); clusterFilter->SetMinPts(4); clusterFilter->Seteps(1.2); clusterFilter->Update(); mitk::UnstructuredGrid::Pointer cluster = clusterFilter->GetOutput(); CPPUNIT_ASSERT_MESSAGE("Testing the output cluster!", cluster->GetVtkUnstructuredGrid()->GetPoints()->GetNumberOfPoints() == 620); } void testClusterVector() { mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); clusterFilter->SetInput(m_UnstructuredGrid); clusterFilter->SetMeshing(false); clusterFilter->SetMinPts(4); clusterFilter->Seteps(1.2); clusterFilter->Update(); std::vector< mitk::UnstructuredGrid::Pointer > clustervector = clusterFilter->GetAllClusters(); //test that all clusters have points: bool havePoints = true; for(unsigned int i=0; iGetVtkUnstructuredGrid()->GetPoints()->GetNumberOfPoints()<1) havePoints = false; } CPPUNIT_ASSERT_MESSAGE("Testing number of found clusters!", havePoints && clustervector.size() == 17); } void testGetNumberOfFoundClusters() { mitk::UnstructuredGridClusteringFilter::Pointer clusterFilter = mitk::UnstructuredGridClusteringFilter::New(); clusterFilter->SetInput(m_UnstructuredGrid); clusterFilter->SetMeshing(false); clusterFilter->SetMinPts(4); clusterFilter->Seteps(1.2); clusterFilter->Update(); CPPUNIT_ASSERT_MESSAGE("Testing number of found clusters!", clusterFilter->GetNumberOfFoundClusters() == 17); } }; MITK_TEST_SUITE_REGISTRATION(mitkUnstructuredGridClusteringFilter) diff --git a/Modules/SurfaceInterpolation/files.cmake b/Modules/SurfaceInterpolation/files.cmake index c162e1a981..40b96eee8e 100644 --- a/Modules/SurfaceInterpolation/files.cmake +++ b/Modules/SurfaceInterpolation/files.cmake @@ -1,8 +1,9 @@ set(CPP_FILES + mitkClusteredPlaneSuggestionFilter.cpp mitkComputeContourSetNormalsFilter.cpp mitkCreateDistanceImageFromSurfaceFilter.cpp mitkPointCloudScoringFilter.cpp mitkImageToPointCloudFilter.cpp mitkReduceContourSetFilter.cpp mitkSurfaceInterpolationController.cpp ) diff --git a/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp new file mode 100644 index 0000000000..4239061337 --- /dev/null +++ b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp @@ -0,0 +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) +{ + 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; +} diff --git a/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.h b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.h new file mode 100644 index 0000000000..83c9b00440 --- /dev/null +++ b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.h @@ -0,0 +1,127 @@ +/*=================================================================== + +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 _MITKCLUSTEREDPLANESUGGESTIONFILTER_h__ +#define _MITKCLUSTEREDPLANESUGGESTIONFILTER_h__ + +#include + +#include +#include + + +namespace mitk { + + /** + * @brief Clustering an UnstructuredGrid and calculating a Plane through it. + * + * The output is the biggest found cluster but you can get all clusters in a + * std::vector represented by vtkPoints. Use GetClusters() the get the vector. + * With GetGeoData() you get the calculated geometry as a mitk::GeometryData. + * Internally the mitk::UnstructuredGridClusteringFilter is used for + * clustering and after the mitk::PlaneFit for calculating the plane. + * The parameters m_Meshing (Set/GetMeshing()), m_MinPts (Set/GetMinPts()) and + * m_Eps (Set/GetEps()) are used for the UnstructuredGridClusteringFilter. + */ + class MITKSURFACEINTERPOLATION_EXPORT ClusteredPlaneSuggestionFilter + : public UnstructuredGridToUnstructuredGridFilter + { + public: + + mitkClassMacro(ClusteredPlaneSuggestionFilter, + UnstructuredGridToUnstructuredGridFilter) + + itkFactorylessNewMacro(Self) + + itkCloneMacro(Self) + + /** Returns the geometry of the calculated plane from mitk::PlaneFit */ + itkGetMacro(GeoData, mitk::GeometryData::Pointer) + + /** Returns all clusters which were found by the clustering filter */ + itkGetMacro(Clusters, std::vector< mitk::UnstructuredGrid::Pointer >) + + /** Activate the meshing function for the returned clusters. The meshing + * is needed to see the result in the 2D-renderwindows */ + itkGetMacro(Meshing, bool) + itkSetMacro(Meshing, bool) + + /** Minimal points which have to be located in the neighbourhood to define + * the point as a core point. For more information see DBSCAN algorithm */ + itkGetMacro(MinPts, int) + itkSetMacro(MinPts, int) + + /** The range/neighbourhood for clustering the points. For more + * information see DBSCAN algorithm */ + itkGetMacro(Eps, double) + itkSetMacro(Eps, double) + + /** Setting to true, uses the distances of the clusters otherwise the + * the size of the clusters is used */ + itkSetMacro(UseDistances, bool) + + /** Sets the number of clusters which are used for the plane suggestion + * if the number of found clusters is lower than the "NumberOfUsedClusters" + * all found clusters are used */ + itkSetMacro(NumberOfUsedClusters, int) + + + protected: + + /** Constructor */ + ClusteredPlaneSuggestionFilter(); + + /** Destructor */ + virtual ~ClusteredPlaneSuggestionFilter(); + + /** Is called by the Update() method of the filter */ + virtual void GenerateData(); + + /** Defines the output of the filter */ + virtual void GenerateOutputInformation(); + + + private: + + /** The geometry of the calculated plane */ + mitk::GeometryData::Pointer m_GeoData; + + /** The vector which holds all found clusters */ + std::vector< mitk::UnstructuredGrid::Pointer > m_Clusters; + + /** The biggest found cluster - the output */ + mitk::UnstructuredGrid::Pointer m_MainCluster; + + /** Connect the points to meshes. Required for 2D rendering */ + bool m_Meshing; + + /** Number of points required to define a core point */ + int m_MinPts; + + /** The distance/neighbourhood for clustering */ + double m_Eps; + + /** Decides to use the distances or the size */ + bool m_UseDistances; + + /** The number of clusters which are used for the plane suggestion */ + unsigned int m_NumberOfUsedClusters; + + }; + +} // namespace mitk + +#endif //_MITKCLUSTEREDPLANESUGGESTIONFILTER_h__