Attention

You are viewing an older version of the documentation. The latest version is 2.2.

Removing Outliers Using a StatisticalOutlierRemoval Filter

In this tutorial we will learn how to remove noisy measurements, e.g. outliers, from a point cloud data set using statistical analysis techniques. This is the oneAPI™ optimization version of pcl::StatisticalOutlierRemoval.

For more info of pcl::StatusticalOutlierRemoval filter, refer to this page.

Note

This tutorial can be run both inside and outside a Docker* image. We assume that the pcl-oneapi-tutorial Deb package has been installed, and the user has copied the tutorial directory from /opt/intel/pcl/oneapi/tutorials/ to a user-writable directory.

  1. Prepare the environment:

    cd <path-to-oneapi-tutorials>/statistical_outlier_removal
    
    Copy to clipboard
  2. oneapi_statistical_outlier_removal.cpp should be in the directory with following content:

     1#include <pcl/oneapi/filters/statistical_outlier_removal.h>
     2#include <pcl/point_types.h>
     3#include <pcl/point_cloud.h>
     4#include <pcl/io/pcd_io.h>
     5
     6
     7using namespace pcl::oneapi;
     8
     9int main (int argc, char** argv)
    10{
    11  std::cout << "Running on device: " << dpct::get_default_queue().get_device().get_info<sycl::info::device::name>() << "\n";
    12
    13  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud( new pcl::PointCloud<pcl::PointXYZ>() );
    14  // Fill in the cloud data
    15  pcl::io::loadPCDFile ("table_scene_lms400.pcd", *cloud);
    16
    17  std::cerr << "Cloud before filtering: " << std::endl;
    18  std::cerr << *cloud << std::endl;
    19
    20  pcl::PointCloud<pcl::PointXYZ>::Ptr oneapi_cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
    21
    22  // Create the filtering object
    23  pcl::oneapi::StatisticalOutlierRemoval<pcl::PointXYZ> oneapi_sor;
    24  oneapi_sor.setInputCloud(cloud);
    25  oneapi_sor.setMeanK(50);
    26  oneapi_sor.setStddevMulThresh(1.0);
    27  oneapi_sor.filter(*oneapi_cloud_filtered);
    28
    29  std::cerr << "Cloud after filtering: " << std::endl;
    30  std::cerr << *oneapi_cloud_filtered << std::endl;
    31
    32  pcl::PCDWriter writer;
    33  writer.write<pcl::PointXYZ> ("table_scene_lms400_inliers.pcd", *oneapi_cloud_filtered, false);
    34
    35  oneapi_sor.setNegative (true);
    36  oneapi_sor.filter (*oneapi_cloud_filtered);
    37  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *oneapi_cloud_filtered, false);
    38
    39  return (0);
    40}
    
    Copy to clipboard
  3. Source the Intel® oneAPI Base Toolkit environment:

    source /opt/intel/oneapi/setvars.sh
    
    Copy to clipboard
  4. (Optional) Setup proxy setting to download test data:

    export http_proxy="http://<http_proxy>:port"
    export https_proxy="http://<https_proxy>:port"
    
    Copy to clipboard
  5. Build the code:

    mkdir build && cd build
    cmake ../
    make -j
    
    Copy to clipboard
  6. Run the binary:

    ./oneapi_statistical_outlier_removal
    
    Copy to clipboard
  7. Expected results example:

    Cloud before filtering:
    header: seq: 0 stamp: 0 frame_id:
    
    points[]: 460400
    width: 460400
    height: 1
    is_dense: 1
    sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]
    
    Cloud after filtering:
    header: seq: 0 stamp: 0 frame_id:
    
    points[]: 451410
    width: 451410
    height: 1
    is_dense: 1
    sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]
    
    Copy to clipboard

Code Explanation

Now, let’s break down the code piece by piece.

The following lines of code will read the point cloud data from disk.

  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud( new pcl::PointCloud<pcl::PointXYZ>() );
  // Fill in the cloud data
  pcl::io::loadPCDFile ("table_scene_lms400.pcd", *cloud);
Copy to clipboard

Then, a pcl::StatisticalOutlierRemoval filter is created. The number of neighbors to analyze for each point is set to 50, and the standard deviation multiplier threshold to 1. What this means is that all points that have distance larger than 1 standard deviation of the mean distance to the query point will be marked as outliers and removed. The output is computed and stored in oneapi_cloud_filtered.

  // Create the filtering object
  pcl::oneapi::StatisticalOutlierRemoval<pcl::PointXYZ> oneapi_sor;
  oneapi_sor.setInputCloud(cloud);
  oneapi_sor.setMeanK(50);
  oneapi_sor.setStddevMulThresh(1.0);
  oneapi_sor.filter(*oneapi_cloud_filtered);
Copy to clipboard

The remaining data (inliers) is written to disk for later inspection.

  pcl::PCDWriter writer;
Copy to clipboard

Then, the filter is called with the same parameters, but with the output negated, to obtain the outliers (e.g., the points that were filtered).

  oneapi_sor.setNegative (true);
  oneapi_sor.filter (*oneapi_cloud_filtered);
Copy to clipboard

And the data is written back to disk.

  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *oneapi_cloud_filtered, false);
Copy to clipboard