/*========================================================================= Program: Visualization Toolkit Module: vtkEuclideanClusterExtraction.h Copyright (c) Kitware, Inc. All rights reserved. See LICENSE file for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkEuclideanClusterExtraction * @brief perform segmentation based on geometric * proximity and optional scalar threshold * * vtkEuclideanClusterExtraction is a filter that extracts points that are in * close geometric proximity, and optionally satisfies a scalar threshold * criterion. (Points extracted in this way are referred to as clusters.) * The filter works in one of five ways: 1) extract the largest cluster in the * dataset; 2) extract specified cluster number(s); 3) extract all clusters * containing specified point ids; 4) extract the cluster closest to a specified * point; or 5) extract all clusters (which can be used for coloring the clusters). * * Note that geometric proximity is defined by setting the Radius instance * variable. This variable defines a local sphere around each point; other * points contained in this sphere are considered "connected" to the * point. Setting this number too large will connect clusters that should not * be; setting it too small will fragment the point cloud into myriad * clusters. To accelerate the geometric proximity operations, a point * locator may be specified. By default, a vtkStaticPointLocator is used, but * any vtkAbstractPointLocator may be specified. * * The behavior of vtkEuclideanClusterExtraction can be modified by turning * on the boolean ivar ScalarConnectivity. If this flag is on, the clustering * algorithm is modified so that points are considered part of a cluster if * they satisfy both the geometric proximity measure, and the points scalar * values falls into the scalar range specified. This use of * ScalarConnectivity is particularly useful for data with intensity or color * information, serving as a simple "connected segmentation" algorithm. For * example, by using a seed point in a known cluster, clustering will pull * out all points "representing" the local structure. * * @sa * vtkConnectivityFilter vtkPolyDataConnectivityFilter */ #ifndef vtkEuclideanClusterExtraction_h #define vtkEuclideanClusterExtraction_h #include "vtkFiltersPointsModule.h" // For export macro #include "vtkPolyDataAlgorithm.h" #define VTK_EXTRACT_POINT_SEEDED_CLUSTERS 1 #define VTK_EXTRACT_SPECIFIED_CLUSTERS 2 #define VTK_EXTRACT_LARGEST_CLUSTER 3 #define VTK_EXTRACT_ALL_CLUSTERS 4 #define VTK_EXTRACT_CLOSEST_POINT_CLUSTER 5 class vtkDataArray; class vtkFloatArray; class vtkIdList; class vtkIdTypeArray; class vtkAbstractPointLocator; class VTKFILTERSPOINTS_EXPORT vtkEuclideanClusterExtraction : public vtkPolyDataAlgorithm { public: vtkTypeMacro(vtkEuclideanClusterExtraction,vtkPolyDataAlgorithm); void PrintSelf(ostream& os, vtkIndent indent); /** * Construct with default extraction mode to extract largest clusters. */ static vtkEuclideanClusterExtraction *New(); //@{ /** * Specify the local search radius. */ vtkSetClampMacro(Radius,double,0.0,VTK_FLOAT_MAX); vtkGetMacro(Radius,double); //@} //@{ /** * Turn on/off connectivity based on scalar value. If on, points are * connected only if the are proximal AND the scalar value of a candiate * point falls in the scalar range specified. Of course input point scalar * data must be provided. */ vtkSetMacro(ScalarConnectivity,bool); vtkGetMacro(ScalarConnectivity,bool); vtkBooleanMacro(ScalarConnectivity,bool); //@} //@{ /** * Set the scalar range used to extract points based on scalar connectivity. */ vtkSetVector2Macro(ScalarRange,double); vtkGetVector2Macro(ScalarRange,double); //@} //@{ /** * Control the extraction of connected surfaces. */ vtkSetClampMacro(ExtractionMode,int, VTK_EXTRACT_POINT_SEEDED_CLUSTERS,VTK_EXTRACT_CLOSEST_POINT_CLUSTER); vtkGetMacro(ExtractionMode,int); void SetExtractionModeToPointSeededClusters() {this->SetExtractionMode(VTK_EXTRACT_POINT_SEEDED_CLUSTERS);}; void SetExtractionModeToLargestCluster() {this->SetExtractionMode(VTK_EXTRACT_LARGEST_CLUSTER);}; void SetExtractionModeToSpecifiedClusters() {this->SetExtractionMode(VTK_EXTRACT_SPECIFIED_CLUSTERS);}; void SetExtractionModeToClosestPointCluster() {this->SetExtractionMode(VTK_EXTRACT_CLOSEST_POINT_CLUSTER);}; void SetExtractionModeToAllClusters() {this->SetExtractionMode(VTK_EXTRACT_ALL_CLUSTERS);}; const char *GetExtractionModeAsString(); //@} /** * Initialize the list of point ids used to seed clusters. */ void InitializeSeedList(); /** * Add a seed id (point id). Note: ids are 0-offset. */ void AddSeed(vtkIdType id); /** * Delete a seed id.a */ void DeleteSeed(vtkIdType id); /** * Initialize the list of cluster ids to extract. */ void InitializeSpecifiedClusterList(); /** * Add a cluster id to extract. Note: ids are 0-offset. */ void AddSpecifiedCluster(int id); /** * Delete a cluster id to extract. */ void DeleteSpecifiedCluster(int id); //@{ /** * Used to specify the x-y-z point coordinates when extracting the cluster * closest to a specified point. */ vtkSetVector3Macro(ClosestPoint,double); vtkGetVectorMacro(ClosestPoint,double,3); //@} /** * Obtain the number of connected clusters. This value is valid only after filter execution. */ int GetNumberOfExtractedClusters(); //@{ /** * Turn on/off the coloring of connected clusters. */ vtkSetMacro(ColorClusters,bool); vtkGetMacro(ColorClusters,bool); vtkBooleanMacro(ColorClusters,bool); //@} //@{ /** * Specify a point locator. By default a vtkStaticPointLocator is * used. The locator performs efficient proximity searches near a * specified interpolation position. */ void SetLocator(vtkAbstractPointLocator *locator); vtkGetObjectMacro(Locator,vtkAbstractPointLocator); //@} protected: vtkEuclideanClusterExtraction(); ~vtkEuclideanClusterExtraction(); double Radius; //connection radius bool ColorClusters; //boolean turns on/off scalar gen for separate clusters int ExtractionMode; //how to extract clusters vtkIdList *Seeds; //id's of points or cells used to seed clusters vtkIdList *SpecifiedClusterIds; //clusters specified for extraction vtkIdTypeArray *ClusterSizes; //size (in cells) of each cluster extracted double ClosestPoint[3]; bool ScalarConnectivity; double ScalarRange[2]; vtkAbstractPointLocator *Locator; // Configure the pipeline virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); virtual int FillInputPortInformation(int port, vtkInformation *info); // Internal method for propagating connected waves. void InsertIntoWave(vtkIdList *wave, vtkIdType ptId); void TraverseAndMark(vtkPoints *pts); private: vtkEuclideanClusterExtraction(const vtkEuclideanClusterExtraction&) VTK_DELETE_FUNCTION; void operator=(const vtkEuclideanClusterExtraction&) VTK_DELETE_FUNCTION; // used to support algorithm execution vtkFloatArray *NeighborScalars; vtkIdList *NeighborPointIds; char *Visited; vtkIdType *PointMap; vtkIdTypeArray *NewScalars; vtkIdType ClusterNumber; vtkIdType PointNumber; vtkIdType NumPointsInCluster; vtkDataArray *InScalars; vtkIdList *Wave; vtkIdList *Wave2; vtkIdList *PointIds; }; //@{ /** * Return the method of extraction as a string. */ inline const char *vtkEuclideanClusterExtraction::GetExtractionModeAsString(void) { if ( this->ExtractionMode == VTK_EXTRACT_POINT_SEEDED_CLUSTERS ) { return "ExtractPointSeededClusters"; } else if ( this->ExtractionMode == VTK_EXTRACT_SPECIFIED_CLUSTERS ) { return "ExtractSpecifiedClusters"; } else if ( this->ExtractionMode == VTK_EXTRACT_ALL_CLUSTERS ) { return "ExtractAllClusters"; } else if ( this->ExtractionMode == VTK_EXTRACT_CLOSEST_POINT_CLUSTER ) { return "ExtractClosestPointCluster"; } else { return "ExtractLargestCluster"; } } //@} #endif