# Filtering#

## Principle#

## Passthrough filter#

The passthrough filter create boundaries outside which the points are removed :

The corresponding method is the following :

```
1/**
2 * @brief Filter points outside given box along said axis
3 * @tparam PointT Should be a pcl::PointXYZxxx
4 * @param cloud Input cloud
5 * @param filt_cloud Output cloud
6 * @param axis Axis on which it has to be filtered given ba Axis_t::Axis_e::x/y/z
7 * @param lowlimit Axis min value
8 * @param uplimit Axis max value
9 * @param verbose If has to output debug on console
10*/
11template <typename PointT>
12void passthroughFilterCloud(typename pcl::PointCloud<PointT>::Ptr& cloud, typename pcl::PointCloud<PointT>::Ptr& filt_cloud, Axis_t axis, float lowlimit, float uplimit, bool verbose = 0);
```

**axis**through Axis_t struct.

**lowlimit**and

**uplimit**.

To use it, do as follow :

```
1passthroughFilterCloud<pcl::PointXYZ>(baseCloud, compCloud, Axis_t::Axis_e::z, 2, 4);
```

## Radius outlier removal#

The radius outlier removal check the number of neighbors each point has in a sphere of given radius. If the point has not enough points close to it, it is considered as an outlier.

The corresponding method is the following :

```
1/**
2 * @brief Remove outliers that do not have k neighbors in given sphere radius
3 * @tparam PointT Should be a pcl::PointXYZxxx
4 * @param cloud Input cloud
5 * @param filt_cloud Output cloud
6 * @param radius Sphere radius to check neighbor in
7 * @param minPointsInRadius K neighbors required not to be an outlier
8 * @param verbose If has to output debug on console
9*/
10template <typename PointT>
11void radiusOutlierRemoval(typename pcl::PointCloud<PointT>::Ptr& cloud, typename pcl::PointCloud<PointT>::Ptr& filt_cloud, float radius, unsigned int minPointsInRadius, bool verbose = 0);
```

**radius**giving the radius of the sphere in which to check for neighbors presence.

**minPointsInRadius**gives minimal number of neighbors the point must have to be kept.

To use it, do as follow :

```
1radiusOutlierRemoval<pcl::PointXYZ>(mynewcloud, mynewcloud_filtered, 3, 10);
```

## Statistical outlier removal#

For each point, compute mean distance from their k neigbors

Do global mean

Each point having their mean distance outside the interval [mean-stdDev:mean+stdDev] will be removed

The passthrough filter create boundaries outside which the points are removed.

The corresponding method is the following :

```
1/**
2 * @brief Removes outliers based on statistics of whole cloud
3 * @tparam PointT Should be a pcl::PointXYZxxx
4 * @param cloud Input cloud
5 * @param filt_cloud Output cloud
6 * @param meanK Number of near neighbors to analyze
7 * @param stdDevMultThresh All points who have a distance larger than stdDevMultThresh standard deviation of the mean distance to the query point will be removed
8 * @param verbose If has to output debug on console
9*/
10template <typename PointT>
11void statisticalOutlierRemoval(typename pcl::PointCloud<PointT>::Ptr& cloud, typename pcl::PointCloud<PointT>::Ptr& filt_cloud, unsigned int meanK, float stdDevMultThresh, bool verbose = 0);
```

**meanK**, telling us on how many neighbors each point distance must be computed.

**stdDevMultThresh**gives the interval criterion to keep a point or not. It strongly depends on the resolution of the cloud.

To use it, do as follow :

```
1statisticalOutlierRemoval<pcl::PointXYZ>(mynewcloud, mynewcloud_filtered, 40, 1);
```

## Conditional remover#

## Euclidean clustering#

*If you have a ground, you may need to remove it first to avoid that the clustering process detects it as part of the different pieces you try to isolate*.

*For this, see*PCL - Progressive Morphological Filtering.

The corresponding method is the following :

```
1/**
2 * @brief Extract clusters from given cloud based on density
3 * @tparam PointT Should be a pcl::PointXYZxxx
4 * @param cloud Cloud to extract clusters from
5 * @param indices New vector to store indices of clusters
6 * @param tolerance Tolerance in [m] to look points around
7 * @param minpointsinclust Minimal points for a cluster to be considered
8 * @param maxpointsinclust Maximal points for a cluster to be considered (if 0 -> no limit)
9 * @param verbose If has to output debug on console
10*/
11template <typename PointT>
12void euclideanClustering(typename pcl::PointCloud<PointT>::Ptr& cloud, std::vector<pcl::PointIndices>& indices, float tolerance, unsigned int minpointsinclust = 50, unsigned int maxpointsinclust = 0, bool verbose = false);
```

**tolerance**gives the distance from point to each other to group them. A too low value may create multiple clusters for the same part, while a too big value may merge the different parts together.

**minpointsinclust**and

**maxpointsinclust**give the boundaries to validate a cluster. If a certain cluster contains too few/many points, it is not considered as valid and will points are clustered with other invalid points.

To use it, do as follow :

```
1std::vector<pcl::PointIndices> cluster_indices;
2euclideanClustering<pcl::PointXYZ>(mycloud, cluster_indices, 6, 50, 0);
3// Different clusters are accessed with cluster_indices[n]
4
5// To recreate clouds from them :
6std::vector<pcl::PointIndices> cluster_indices;
7std::vector<pcl::PointCloud<pcl::PointXYZ>> clustered_clouds;
8// Find clusters
9euclideanClustering<pcl::PointXYZ>(mycloud, cluster_indices, 6, 50, 0);
10// Iterate throug clusters and create point clouds
11for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); ++it)
12{
13 pcl::PointCloud<pcl::PointXYZ> cl;
14 for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
15 {
16 cl.push_back((*mycloud)[*pit]);
17 }
18 cl.width = cl.size();
19 cl.height = 1;
20 cl.is_dense = true;
21 clustered_clouds.push_back(cl);
22}
```

## Plane model removing#

The passthrough filter removes planes from a cloud.

The corresponding method is the following :

```
/**
* @brief Remove planes from given cloud based on density
* @tparam PointT Should be a pcl::PointXYZxxx
* @param cloud Cloud to segment
* @param seg_cloud Output segmented cloud
* @param thresh Distance threshold to segment inliers
* @param verbose If has to output debug on console
*/
template <typename PointT>
void segmentPlanes(typename pcl::PointCloud<PointT>::Ptr &cloud, typename pcl::PointCloud<PointT>::Ptr &seg_cloud, float thresh, bool verbose = false);
```

*distance threshold*, which determines how close a point must be to the model in order to be considered an inlier.

```
1segmentPlanes<pcl::PointXYZ>(in_cloud, out_cloud, 0.01, false);
```