【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
基于半径的滤波,主要是指某个半径的范围内,必须要有一定数量的邻居。而基于条件的滤波,这一点和PassThrough有点像,但是它可以把很多条件组合在一起,比如说同时满足x轴、y轴、z轴等条件,然后开始滤波。原来的代码在这,https://pcl.readthedocs.io/projects/tutorials/en/latest/remove_outliers.html#remove-outliers。之前的代码效果不太好,不太看得出效果,在数量和约束条件稍做修改后,效果明显。
1、准备remove_outliers.cpp文件
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>
int
main (int argc, char** argv)
{
if (argc != 2)
{
std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
exit(0);
}
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 the cloud data
cloud->width = 100;
cloud->height = 1;
cloud->resize (cloud->width * cloud->height);
for (auto& point: *cloud)
{
point.x = 1024 * rand () / (RAND_MAX + 1.0f);
point.y = 1024 * rand () / (RAND_MAX + 1.0f);
point.z = 1024 * rand () / (RAND_MAX + 1.0f);
}
if (strcmp(argv[1], "-r") == 0){
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
// build the filter
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(100);
outrem.setMinNeighborsInRadius (1);
outrem.setKeepOrganized(true);
// apply filter
outrem.filter (*cloud_filtered);
}
else if (strcmp(argv[1], "-c") == 0){
// build the condition
pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond (new
pcl::ConditionAnd<pcl::PointXYZ> ());
range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new
pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::GT, 0.0)));
range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new
pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::LT, 100.0)));
// build the filter
pcl::ConditionalRemoval<pcl::PointXYZ> condrem;
condrem.setCondition (range_cond);
condrem.setInputCloud (cloud);
condrem.setKeepOrganized(true);
// apply filter
condrem.filter (*cloud_filtered);
}
else{
std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
exit(0);
}
std::cerr << "Cloud before filtering: " << std::endl;
for (const auto& point: *cloud)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
// display pointcloud after filtering
std::cerr << "Cloud after filtering: " << std::endl;
for (const auto& point: *cloud_filtered)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
return (0);
}
2、准备CMakeLists.txt文件
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(remove_outliers)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (remove_outliers remove_outliers.cpp)
target_link_libraries (remove_outliers ${PCL_LIBRARIES})
3、生成sln文件,开始编译
4、执行remove_outliers.exe文件
-r效果显示,
-c效果显示,
实际效果其实是一个效果对比。一个是滤波之前,一个是滤波之后,两者还是有差别的。因为随机生成的数据比较多,一个页面没有办法完全表达完整,这里只是截取了一小段。大家可以自己编译生成可执行文件,实际运行一下就知道效果了。