(十二)使用ConditionalRemoval 或 RadiusOutlierRemoval滤波器对点云进行滤波
RadiusOutlierRemove滤波器删除PointCloud中在指定半径的邻域范内,邻点没能达到指定数量的点。下图中,如果指定了邻点数为1,则黄色点将从PointCloud中删除。如果指定了邻点数为2,则黄色和绿色点都将从PointCloud中删除。
ConditionalRemove滤波器从PointCloud中删除所有不满足用户指定的一个或多个条件的点。
以下代码实现用RadiusOutlierRemoval或 ConditionalRemoval滤波器对点云进行滤波
radius_outlier_removal.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::cout << "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>);cloud->width = 5;cloud->height = 1;cloud->resize (cloud->width * cloud->height);for (auto& point: *cloud){point.x = (float)rand() / RAND_MAX * 2 - 1; point.y = (float)rand() / RAND_MAX * 2 - 1;point.z = (float)rand() / RAND_MAX * 2 - 1;}// 创建RadiusOutlierRemoval滤波器对象if (strcmp(argv[1], "-r") == 0){pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;outrem.setInputCloud(cloud);outrem.setRadiusSearch(0.8); // 邻域半径设置为0.8 outrem.setMinNeighborsInRadius (2); // 一个点在指定 邻域至少要有2个邻居outrem.setKeepOrganized(true);outrem.filter (*cloud_filtered);}else if (strcmp(argv[1], "-c") == 0){// 条件设置为z大于0.0和z小于0.8。pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond (newpcl::ConditionAnd<pcl::PointXYZ> ());range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (newpcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::GT, 0.0)));range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (newpcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::LT, 0.8)));// 创建ConditionalRemoval对象 pcl::ConditionalRemoval<pcl::PointXYZ> condrem;condrem.setCondition (range_cond);condrem.setInputCloud (cloud);condrem.setKeepOrganized(true);condrem.filter (*cloud_filtered);}else{std::cout << "please specify command line arg '-r' or '-c'" << std::endl;exit(0);}std::cout << "Cloud before filtering: " << std::endl;for (const auto& point: *cloud)std::cout << " " << point.x << " "<< point.y << " "<< point.z << std::endl;std::cout << "Cloud after filtering: " << std::endl;for (const auto& point: *cloud_filtered)std::cout << " " << point.x << " "<< point.y << " "<< point.z << std::endl;return (0);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)project(radius_outlier_removal)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})add_executable (radius_outlier_removal radius_outlier_removal.cpp)
target_link_libraries (radius_outlier_removal ${PCL_LIBRARIES})
编译并运行:
./radius_outlier_removal -r
Cloud before filtering: 0.680375 -0.211234 0.5661980.59688 0.823295 -0.604897-0.329554 0.536459 -0.4444510.10794 -0.0452059 0.257742-0.270431 0.0268018 0.904459
Cloud after filtering: nan nan nannan nan nannan nan nan0.10794 -0.0452059 0.257742nan nan nan
./radius_outlier_removal -c
Cloud before filtering: 0.680375 -0.211234 0.5661980.59688 0.823295 -0.604897-0.329554 0.536459 -0.4444510.10794 -0.0452059 0.257742-0.270431 0.0268018 0.904459
Cloud after filtering: 0.680375 -0.211234 0.566198nan nan nannan nan nan0.10794 -0.0452059 0.257742nan nan nan