Laser scanning usually produces a point cloud dataset with uneven density. In addition, the error in the measurement produces sparse outliers, making the effect worse. Estimating local point cloud characteristics, such as the normal vector at the sample point or the rate of curvature change, can result in incorrect values, which in turn may result in post-processing failures such as the registration of point clouds.
The following methods solve some of these problems: a statistical analysis of the neighborhood of each point, and trimming out points that do not meet certain criteria. Our sparse outlier removal method is based on the calculation of the distance distribution from the point to the neighboring point in the input data. For each point, we calculate its average distance to all of its adjacent points. The resulting result is a Gaussian distribution whose shape is determined by the mean and standard deviation, and the average distance is defined as an outlier and can be removed from the dataset, at points outside the standard range (defined by the global distance mean and variance).
Using the Statisticaloutlierremoval filter to remove outlier points
Figure 1 shows the effects of sparse outlier analysis and removal: The left image is the original dataset, and the image on the right is the processing result. The graph shows the average distance of K nearest neighbors in the neighborhood of a point, before and after processing.
Fig. 1 Comparison of sparse outlier analysis and removal effect
Code
First, in the PCL (Point Cloud Learning) China-assisted release book [1], the 8th chapter of the CD-ROM is provided in the example 3 folder, open a code file named Statistical_removal.cpp.
The relevant test point cloud file can be found under the same folder TABLE_SCENE_LMS400.PCD
The following is the key statement that opens the open source code above. The following code reads the point cloud data from the disk.
PCL :: Pcdreaderreader ; // defining Read Objects
Reader . Read < PCL :: pointxyz > ("TABLE_SCENE_LMS400.PCD",*Cloud);// read point cloud Files
A pcl::statisticaloutlierremoval filter is then created that sets the number of proximity points for each point analysis to 50 and sets the standard deviation multiplier to 1, which means that if the distance of a point exceeds the average distance of one standard deviation, the point is marked as an outlier. and will be removed. The computed output is stored in the cloud_filtered .
PCL :: Statisticaloutlierremoval < PCL :: pointxyz > sor ; // Create filter object
Sor . Setinputcloud (Cloud); Set the point cloud for the stay filter
Sor . Setmeank (a); set to consider query point proximity points when making statistics
sor setstddevmulthresh ( 1.0 Set the threshold to determine if the outlier is outliers
Sor . Filter (*cloud_filtered); perform filter processing to save the inner point to cloud_filtered
The remaining data (internal points) will be stored on the disk for other uses, such as visualization.
PCL :: Pcdwriterwriter ;
writer . Write < PCL :: pointxyz > ("TABLE_SCENE_LMS400_INLIERS.PCD",*cloud_filtered, false);
The filter is then called again using the same parameters, but the function setnegative sets the output to take the outside point to obtain outliers (that is, the point that was originally filtered out).
Sor . setnegative (true);
Sor . Filter (*cloud_filtered);
and write the data back to disk .
writer write < PCL :: pointxyz > ( "TABLE_SCENE_LMS400_OUTLIERS.PCD" Span style= "COLOR: #32b432", * cloud_ Filtered false );
#include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/ Filters/statistical_outlier_removal.h>intmain (int argc, char** argv) {PCL::P OINTCLOUD<PCL::P ointxyz>::P TR Cloud (New PCL::P OINTCLOUD<PCL::P ointxyz>); PCL::P OINTCLOUD<PCL::P ointxyz>::P tr cloud_filtered (new PCL::P OINTCLOUD<PCL::P ointxyz>); Fill in point cloud data PCL::P Cdreader Reader; Change the path to the path where you stored the file Reader.read<pcl::P ointxyz> ("TABLE_SCENE_LMS400.PCD", *cloud); Std::cerr << "Cloud before filtering:" << Std::endl; Std::cerr << *cloud << Std::endl; Create Filter Object PCL::STATISTICALOUTLIERREMOVAL<PCL::P ointxyz> sor; Sor.setinputcloud (Cloud); Sor.setmeank (50); Sor.setstddevmulthresh (1.0); Sor.filter (*cloud_filtered); Std::cerr << "Cloud after filtering:" << Std::endl; Std::cerr << *cloud_filtered << Std::endl; PCL::P cdwriter writer; WRITER.WRITE<PCL::P ointxyz> ("Table_scene_lms400_inlIers.pcd ", *cloud_filtered, false); Sor.setnegative (TRUE); Sor.filter (*cloud_filtered); WRITER.WRITE<PCL::P ointxyz> ("TABLE_SCENE_LMS400_OUTLIERS.PCD", *cloud_filtered, false); return (0);}
You can execute the console directly in VS to output the information of the point cloud Filter and get two PCB to store the inner and outer points respectively:
Table_scene_lms400_inliers.pcd
Table_scene_lms400_outliers.pcd
Origin Cloud Visualization Results:
After filtering processing:
Reference: http://www.pclcn.org/study/shownews.php?lang=cn&id=68
Filtering of point clouds