diff --git a/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h b/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h index d24695cf7c..504db804c1 100644 --- a/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h +++ b/Modules/AlgorithmsExt/include/mitkUnstructuredGridClusteringFilter.h @@ -1,115 +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 ed283ec590..2a3ad2844d 100644 --- a/Modules/AlgorithmsExt/src/mitkUnstructuredGridClusteringFilter.cpp +++ b/Modules/AlgorithmsExt/src/mitkUnstructuredGridClusteringFilter.cpp @@ -1,271 +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), m_DistCalc(false) +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(); 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; - if(m_DistCalc) + for(unsigned int i=0; i array = vtkSmartPointer::New(); + vtkSmartPointer points = m_Clusters.at(i); + if(m_DistCalc) { - vtkSmartPointer array = vtkSmartPointer::New(); - vtkSmartPointer points = m_Clusters.at(i); 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; - } + } + 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' { 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 { 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 j=0; jGetNumberOfPoints(); j++) { 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/mitkClusteredPlaneSuggestionFilter.cpp b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp index 0f977fb5a9..4239061337 100644 --- a/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp +++ b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.cpp @@ -1,262 +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) +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; } -// std::cout << "NUMBER OF INPUT GRID: " << inpGrid->GetVtkUnstructuredGrid()->GetNumberOfPoints() << std::endl; - -// std::cout << "POINTDATA-SIZE OF INPUT GRID: " << inpGrid->GetVtkUnstructuredGrid()->GetPointData()->GetArray(0)->GetSize() << std::endl; - -// std::fstream ds; -// ds.open("/home/riecker/test.txt"); - -// vtkSmartPointer array = dynamic_cast(inpGrid->GetVtkUnstructuredGrid()->GetPointData()->GetArray(0)); -// for(int i=0; iGetSize();i++) -// { -// ds << "point: " << i << " distance " << array->GetValue(i) << std::endl; -// } -// ds.close(); - 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(); - std::fstream fs; - fs.open("/home/riecker/clusters.txt"); - - //test if the scalar transfer works - for(unsigned int i=0; i data = dynamic_cast(cluster->GetVtkUnstructuredGrid()->GetPointData()->GetArray(0)); - for(int j=0; jGetSize();j++) - { - fs << "Point " << j << " - Distance: " << data->GetValue(j) << std::endl; - } - } - fs.close(); - //end - //find the avg distances of every cluster maybe a square mean for better looking at high values? std::vector< std::pair > avgDistances; -// std::vector< double > 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 - //get the number of points and the id of every cluster - std::vector< std::pair > sizeIDs; - for(unsigned int i=0; iGetVtkUnstructuredGrid()->GetNumberOfPoints(), i)); -// std::cout << "CLUSTER ID: " << i << " NUMBER OF POINTS: " << m_Clusters.at(i)->GetVtkUnstructuredGrid()->GetNumberOfPoints() << std::endl; } - //sort the number of points for finding the three biggest + //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); - for(unsigned int i=0; i(avgDistances.size()); - //end calc the overall mean distance - int number = 0; //max number of biggest clusters which are used for the plane - //if less than 3 clusters are found -// if(m_Clusters.size()<3) + //if less than m_NumberOfUsedClusters clusters are found + if(m_Clusters.size() < m_NumberOfUsedClusters) number = m_Clusters.size(); -// else -// number = 3; - -// double mean = 0.0; -// for(unsigned int i=0; i(m_Clusters.size()); - -// for(unsigned int i=0; i=2) -// number = 2; - - //calc the number of clusters which distances are higher than the average -// for(unsigned int i=0; i= " << overallDistance << std::endl; -// if(avgDistances.at(i).first >= overallDistance) -// number++; -// } -// std::cout << "Number of clusters which distance is higher than the average: " << number << std::endl; - - //filter small clusters out! -// int pointsOverAll = 0; -// for(unsigned int i=0; iGetVtkUnstructuredGrid()->GetNumberOfPoints(); -// } -// int avg = pointsOverAll / m_Clusters.size(); - -// for(unsigned int i=0; i= avg) -// number++; -// else -// break; -// } - -// std::cout << "NUMBER OF CLUSTERS: " << number << std::endl; - + 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 = m_Clusters.at(avgDistances.at(j).second)->GetVtkUnstructuredGrid(); //highest distance - vtkSmartPointer tmpGrid = m_Clusters.at(sizeIDs.at(j).second)->GetVtkUnstructuredGrid(); //biggest cluster -// std::cout << "CLUSTER ID: " << avgDistances.at(j).second << " NUMBER OF POINTS: " << avgDistances.at(j).first << std::endl; + vtkSmartPointer 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++; } } -// std::cout << "POINTSET POINTS: " << pointset->GetSize() << std::endl; - 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; } - m_Clusters.clear(); avgDistances.clear(); -// mitk::PlaneGeometry* planeGeometry = dynamic_cast( planeFilter->GetOutput()->GetGeometry()); } 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 index 843046ba10..83c9b00440 100644 --- a/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.h +++ b/Modules/SurfaceInterpolation/mitkClusteredPlaneSuggestionFilter.h @@ -1,112 +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__