(十二)使用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 (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, 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.566198
0.59688 0.823295 -0.604897
-0.329554 0.536459 -0.444451
0.10794 -0.0452059 0.257742
-0.270431 0.0268018 0.904459
Cloud after filtering:
nan nan nan
nan nan nan
nan nan nan
0.10794 -0.0452059 0.257742
nan nan nan
./radius_outlier_removal -c
Cloud before filtering:
0.680375 -0.211234 0.566198
0.59688 0.823295 -0.604897
-0.329554 0.536459 -0.444451
0.10794 -0.0452059 0.257742
-0.270431 0.0268018 0.904459
Cloud after filtering:
0.680375 -0.211234 0.566198
nan nan nan
nan nan nan
0.10794 -0.0452059 0.257742
nan nan nan