PCL教程指南-投影参数模型,索引提取点云,条件滤波,半径滤波
一.Projecting points using a parametric model(投影参数模型)
- 官方文档原文
- 目的是将点云投影到某一个模型上,比如平面,球体等
- 以下对原文代码进行注释解读,并扩展类中其他内容
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>
int
main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (new pcl::PointCloud<pcl::PointXYZ>);
cloud->width = 5;
cloud->height = 1;
cloud->points.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);
}
std::cerr << "Cloud before projection: " << std::endl;
for (const auto& point: *cloud)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
coefficients->values.resize (4);
coefficients->values[0] = coefficients->values[1] = 0;
coefficients->values[2] = 1.0;
coefficients->values[3] = 0;
pcl::ProjectInliers<pcl::PointXYZ> proj;
proj.setModelType (pcl::SACMODEL_PLANE);
proj.setInputCloud (cloud);
proj.setModelCoefficients (coefficients);
proj.filter (*cloud_projected);
std::cerr << "Cloud after projection: " << std::endl;
for (const auto& point: *cloud_projected)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
return (0);
}
- 其中
pcl::ProjectInliers<pcl::PointT>
还有一个常用方法为 void setCopyAllData (bool val)
,用于设置返回所有数据还是只返回执行投影的点数据(区别在于本来就在模型上的点是否输出) - 另外模型除了平面,还有多种内置的采样模型:
namespace pcl
{
enum SacModel
{
SACMODEL_PLANE,
SACMODEL_LINE,
SACMODEL_CIRCLE2D,
SACMODEL_CIRCLE3D,
SACMODEL_SPHERE,
SACMODEL_CYLINDER,
SACMODEL_CONE,
SACMODEL_TORUS,
SACMODEL_PARALLEL_LINE,
SACMODEL_PERPENDICULAR_PLANE,
SACMODEL_PARALLEL_LINES,
SACMODEL_NORMAL_PLANE,
SACMODEL_NORMAL_SPHERE,
SACMODEL_REGISTRATION,
SACMODEL_REGISTRATION_2D,
SACMODEL_PARALLEL_PLANE,
SACMODEL_NORMAL_PARALLEL_PLANE,
SACMODEL_STICK
};
}
二.Extracting indices from a PointCloud(根据索引提取点云数据)
- 官方文档原文
- 由于PCL执行操作时一般输出为索引结构以提高效率,但有时我们需要索引代表的完整点云数据,此类即根据索引来提取点云数据
- 由于原文涉及了分割算法,之后会细讲,对于提取类不会有任何影响所以以下只对关键类进行注释解读,并扩展类中其他内容
pcl::ExtractIndices<pcl::PointXYZ> extract;
pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());
extract.setInputCloud (cloud_filtered);
extract.setIndices (inliers);
extract.setNegative (false);
extract.filter (*cloud_p);
extract.setNegative (true);
extract.filter (*cloud_f);
cloud_filtered.swap (cloud_f);
- 其中
pcl::ExtractIndices<pcl::PointT>
类所用方法主要继承自
pcl::FilterIndices<pcl::PointT> 索引过滤类;
pcl::Filter<pcl::PointT> 过滤类
;pcl::PCLBase ()<pcl::PointT>PCL基础类;
- 索引提取类有一个自身实现的特殊的方法
void pcl::ExtractIndices< PointT >::filterDirectly ( PointCloudPtr & cloud )
- 应用过滤器并将结果直接存储在输入云中,这个方法将节省输出云的时间和内存,但不能改变输入云的原始大小:它的操作方式就像setkeepororganized()为真一样,并将覆盖过滤后的点,而不是删除它们。所有过滤点的字段都将被setUserFilterValue() (default = NaN)设置的值所替换。这个方法还可以通过setInputCloud()自动修改输入云集。它不会改变setkeeorganizized()设置的内部keep organized布尔值。
三.Removing outliers using a Conditional or RadiusOutlier removal(使用条件滤波或半径滤波剔除离群点)
- 官方文档原文
- 条件滤波通过控制过滤条件去除相关点数据; 半径滤波根据点自身半径范围内邻域数量判断是否剔除
- 代码较简单,主要分条件滤波和半径滤波分别注释解读,并扩展说明其他内容
半径滤波
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(0.8);
outrem.setMinNeighborsInRadius (2);
outrem.setKeepOrganized(true);
outrem.filter (*cloud_filtered);
条件滤波
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)));
pcl::ConditionalRemoval<pcl::PointXYZ> condrem;
condrem.setCondition (range_cond);
condrem.setInputCloud (cloud);
condrem.setKeepOrganized(true);
condrem.filter (*cloud_filtered);
- 其中
pcl::ConditionAnd<pcl::PointT>
继承自pcl::ConditionBase< PointT >
类,除了AND(和)运算外还有pcl::ConditionOr<pcl::PointT>
或运算 - 另外,
pcl::FieldComparison<pcl::PointT>
继承自ComparisonBase<PointT>
类,除了字段比较外还有:
类 | 作用 |
---|
PackedRGBComparison< pcl::PointT > | 比较打包后的RGB(即打包成一个浮点数的RGB) |
PackedHSIComparison< pcl::PointT > | 比较打包的HSI |
TfQuadraticXYZComparison< pcl::PointT > | 坐标XYZ中比较公式为(p’Ap + 2v’p + c [OP] 0) 其中 OP为运算符, p = (x,y,z) 是点云中一点; A 是 3x3矩阵; v是3x1向量; c是常数 |
- OP运算符包括 GT, GE, LT, LE or EQ 各意思为 大于,大于等于…(英文缩写对照)