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.
Prepare the environment:
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}
Source the Intel® oneAPI Base Toolkit environment:
(Optional) Setup proxy setting to download test data:
Build the code:
Run the binary:
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]
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.
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.
The remaining data (inliers) is written to disk for later inspection.
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).
And the data is written back to disk.