PCL tutorial - Statistical outlierremoval filter for Point Cloud Filtering

Original link: Removing outliers using a StatisticalOutlierRemoval filter

Point cloud data: table_scene_lms400.pcd

This section will learn how to use statistical analysis techniques to remove measurement noise points (i.e. outliers) from a point cloud dataset.

background knowledge

Laser scanning usually produces point cloud data sets with uneven density. In addition, the error in measurement will produce sparse outliers, making the effect worse. The operation of estimating local point cloud features (such as normal vector or curvature change rate at sampling points) is very complex, which will lead to wrong values, which in turn may lead to post-processing failure such as point cloud registration.

Some of these problems can be solved by the following methods:

Make a statistical analysis of the neighborhood of each point, and trim those points that do not meet certain standards. Our sparse outlier removal method is based on the calculation of the distance distribution from the point to the adjacent point in the input data. For each point, we calculate the average distance from it to all its adjacent points. It is assumed that the result is a Gaussian distribution whose shape is determined by the mean and standard deviation. Points with an average distance outside the standard range (defined by the global distance mean and variance) can be defined as outliers and removed from the data set.


The following figure shows the effect of sparse outlier analysis and removal: the original data set is displayed on the left and the result data set is displayed on the right. The figure shows the average k nearest neighbor distance of the point neighborhood before and after filtering.
 

    Program code

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include<pcl/visualization/pcl_visualizer.h>
int
main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
	// Fill in point cloud data
	pcl::PCDReader reader;
	// Change the path to the path where you store your files
	reader.read<pcl::PointXYZ>("table_scene_lms400.pcd", *cloud);
	std::cerr << "Cloud before filtering: " << std::endl;
	std::cerr << *cloud << std::endl;
	// Create filter object
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
	sor.setInputCloud(cloud);//Set the point cloud to be filtered
	sor.setMeanK(50);//Set the number of neighbors of query points to be considered in statistics
	sor.setStddevMulThresh(1.0);//Set the threshold to judge whether it is an outlier
	sor.filter(*cloud_filtered);//Save the filtering results in cloud_ In filtered
	std::cerr << "Cloud after filtering: " << std::endl;
	std::cerr << *cloud_filtered << std::endl;
	pcl::PCDWriter writer;
	writer.write<pcl::PointXYZ>("table_scene_lms400_inliers.pcd", *cloud_filtered, false);
	sor.setNegative(true);


	pcl::visualization::PCLVisualizer viewer("statistic removal");
	int v1(1);
	int v2(2);
	//Create window
	viewer.createViewPort(0, 0, 0.5, 1, v1);
	viewer.createViewPort(0.5, 0, 1, 1, v2);

	viewer.addPointCloud(cloud, "cloud", v1);
	viewer.addPointCloud(cloud_filtered, "cloud_filtered", v2);

	sor.filter(*cloud_filtered);
	writer.write<pcl::PointXYZ>("table_scene_lms400_outliers.pcd", *cloud_filtered, false);
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}

	return (0);
}

Firstly, a PCL:: statisticaltoutlierremoval filter is created. The number of adjacent points analyzed for each point is set to 50 and the standard deviation multiple is set to 1, which means that if the distance of a point exceeds the average distance by more than one standard deviation, the point is marked as an outlier and will be removed. The calculated output results are stored in cloud_ filtered.

	// Create filter object
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
	sor.setInputCloud(cloud);//Set the point cloud to be filtered
	sor.setMeanK(50);//Set the number of neighbors of query points to be considered in statistics
	sor.setStddevMulThresh(1.0);//Set the threshold to judge whether it is an outlier
	sor.filter(*cloud_filtered);//Save the filtering results in cloud_ In filtered

experimental result

The left figure shows the original point cloud, and the right figure shows the point cloud after removing outliers. You can see that some noise has been removed:


Print results:  

Cloud before filtering:
points[]: 460400
width: 460400
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

Cloud after filtering:
points[]: 451410
width: 451410
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

Tags: PCL

Posted on Sat, 20 Nov 2021 09:57:58 -0500 by DfyAnt