PCL-03-点云滤波、降采样、离群点移除、深度图和关键点提取

1. 点云滤波
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
// 创建滤波器对象
pcl::PassThrough<pcl::PointXYZ> pass;
//只保留z轴范围在0-1之间的点
pass.setInputCloud(cloud);          // 1. 设置输入源
pass.setFilterFieldName("z");       // 2. 设置过滤域名
pass.setFilterLimits(0.0, 1.0);     // 3. 设置过滤范围
//    pass.setFilterLimitsNegative(true); // 设置获取Limits之外的内容,即结果取反
pass.filter(*cloud_filtered);       // 4. 执行过滤,并将结果输出到cloud_filtered
2. 降采样,使用VoxelGrid
pcl::getFieldsList()  //用于获得*cloud点云的包含的点云信息种类 (x,y,z,intensity)
// 创建一个长宽高分别是1cm的体素过滤器,cloud作为输入数据,cloud_filtered作为输出数据
float leftSize = 0.01f;    //值越小,结果点越多
// Create the filtering object
pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
sor.setInputCloud (cloud);
sor.setLeafSize (leftSize, leftSize, leftSize);
sor.filter (*cloud_filtered);
3. 离群点的移除
  • 统计学移除法
    在这里插入图片描述
    在这里插入图片描述
// 创建过滤器,每个点分析计算时考虑的最近邻居个数为50个;
// 设置标准差阈值为1,这意味着所有距离查询点的平均距离的标准偏差均大于1个标准偏差的所有点都将被标记为离群值并删除。
// 计算输出并将其存储在cloud_filtered中

// 创建滤波对象
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud (cloud);
// 设置平均距离估计的最近邻居的数量K
sor.setMeanK (50);
// 设置标准差阈值系数,值越小,滤波效果越强
sor.setStddevMulThresh (1.0);
// sor.setNegative(True); 滤波器取反
// 执行过滤
sor.filter (*cloud_filtered);
  • 条件移除法
    半径移除法:指定半径内续有n个邻点才保留,否则移除
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
// build the filter
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(0.4);
outrem.setMinNeighborsInRadius(2);
// apply filter
outrem.filter(*cloud_filtered);

    条件移除法:

// build the condition 或的写法:pcl::ConditionOr<pcl::PointXYZ>::Ptr
pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>());
// GT大于0 小于0.8 的范围内的点 保留
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)));
// build the filter
pcl::ConditionalRemoval<pcl::PointXYZ> condrem;
condrem.setCondition(range_cond);
condrem.setInputCloud(cloud);
condrem.setKeepOrganized(true);
// apply filter
condrem.filter(*cloud_filtered);
4. 深度图(RangeImage)的创建

选定一个视角,根据视角计算点云的深度。注意,这个深度和视角密切相关。

// We now want to create a range image from the above point cloud, with a 1deg angular resolution
// 根据之前得到的点云图,通过1deg的分辨率生成深度图。
float angularResolution = (float) (1.0f * (M_PI / 180.0f));//   弧度1°
float maxAngleWidth = (float) (360.0f * (M_PI / 180.0f));  //  弧度360°
float maxAngleHeight = (float) (180.0f * (M_PI / 180.0f)); // 弧度180°
Eigen::Affine3f sensorPose = (Eigen::Affine3f) Eigen::Translation3f(0.0f, 0.0f, 0.0f);  // 采集位置,平移变换
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;      // 相机坐标系
float noiseLevel = 0.00;
float minRange = 0.0f;
int borderSize = 1;

boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);
pcl::RangeImage& rangeImage = *range_image_ptr;

rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
                                sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);

5. 从深度图获得边界
pcl::RangeImageBorderExtractor border_extractor(&range_image);
pcl::PointCloud<pcl::BorderDescription> border_descriptions;
border_extractor.compute(border_descriptions);
6. 关键点提取,NARF,Normal Aligned Radial Feature
//获得相机位姿
scene_sensor_pose = Eigen::Affine3f(Eigen::Translation3f(point_cloud.sensor_origin_[0],
                                                                 point_cloud.sensor_origin_[1],
                                                                 point_cloud.sensor_origin_[2])) *
                            Eigen::Affine3f(point_cloud.sensor_orientation_);
//NARF提取
pcl::RangeImageBorderExtractor range_image_border_extractor;
pcl::NarfKeypoint narf_keypoint_detector(&range_image_border_extractor);
narf_keypoint_detector.setRangeImage(&range_image);
narf_keypoint_detector.getParameters().support_size = support_size;
//narf_keypoint_detector.getParameters ().add_points_on_straight_edges = true;
//narf_keypoint_detector.getParameters ().distance_for_additional_points = 0.5;

pcl::PointCloud<int> keypoint_indices;
narf_keypoint_detector.compute(keypoint_indices);
std::cout << "Found " << keypoint_indices.points.size() << " key points.\n";
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值