You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
8.3 KiB
C++

/*=========================================================================
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) override;
/**
* 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 candidate
* 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() override;
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
int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
int FillInputPortInformation(int port, vtkInformation* info) override;
// Internal method for propagating connected waves.
void InsertIntoWave(vtkIdList* wave, vtkIdType ptId);
void TraverseAndMark(vtkPoints* pts);
private:
vtkEuclideanClusterExtraction(const vtkEuclideanClusterExtraction&) = delete;
void operator=(const vtkEuclideanClusterExtraction&) = delete;
// 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