文章目录
PCL中常用数据结构
pcl::PointCloud
PointCloud类包含以下成员变量:
注意PointCloud模板类是点云类,其是由很多个点组成的。
width——点云宽度
height——点云高度
用点云数据集中的点数初始化width,width其实有两个含义:
(1)对于无组织或者说无结构的点云来说,width就是指点云中点的个数。
(2) 对于有结构的点云来说,width是指点云数据集一行上点的个数。有结构的点云可以理解成这个点云像image(或者说是一个矩阵)一样进行组织,数据被分为行和列,如立体相机或者TOF相机获得的点云数据就属于这一类。对于有结构点云的一大好处就是能知道点云中点的相邻关系,最近邻操作效率就非常高,可以大大提高PCL中相应算法的效率。
用点云数据集中点的高度(就是行数)初始化height,height同样有两个函数:
(1)对于有结构点云来说,height代表点云的总行数
(2)对于无结构的点云来说,height值为1,因此这也经常用来判断点云是或者不是一个有结构的点云。
pcl::PointCloud<pcl::PointXYZ> cloud;
std::vector<pcl::PointXYZ> data = cloud.points;
存储了数据类型为PointT的一个动态数组,例如,对于一个包含了XYZ数据的点云,points是包含了元素为pcl::PointXYZ一个vector。
is_dense (bool)
判断points中的数据是否是有限的(有限为true)或者说是判断点云中的点是否包含 Inf/NaN这种值(包含为false)。
sensor_origin_ (Eigen::Vector4f)
代表了相应传感器的位置座标(可能是经过平移的),这个数据成员是可选,在大多数的PCL算法中不会使用。
sensor_orientation_ (Eigen::Quaternionf)
代表了相应传感器的朝向,这个数据成员是可选,在大多数的PCL算法中不会使用。
pcl::PointXYZ
pcl::PointXYZ::PointXYZ ( float_x,
float_y,
float_z
)
pcl::PointXYZI
union {
struct {
float intensity
}
float data_c [4]
};
pcl::PointXYZRGB
Eigen::Vector3i getRGBVector3i ()
const Eigen::Vector3i getRGBVector3i () const
Eigen::Vector4i getRGBVector4i ()
const Eigen::Vector4i getRGBVector4i () const
PointXYZRGB (const _PointXYZRGB &p)
PointXYZRGB ()
PointXYZRGB (uint8_t _r, uint8_t _g, uint8_t _b)
//其中PointXYZRGB 为
pcl::PointXYZRGB::PointXYZRGB ( uint8_t _r,
uint8_t _g,
uint8_t _b
) [inline]
pcl::PCLPointCloud2
struct PCLPointCloud2
{
PCLPointCloud2 () : header (), height (0), width (0), fields (),
is_bigendian (false), point_step (0), row_step (0),
data (), is_dense (false)
{
#if defined(BOOST_BIG_ENDIAN)
is_bigendian = true;
#elif defined(BOOST_LITTLE_ENDIAN)
is_bigendian = false;
#else
#error "unable to determine system endianness"
#endif
}
::pcl::PCLHeader header;
pcl::uint32_t height;
pcl::uint32_t width;
std::vector< ::pcl::PCLPointField> fields;
pcl::uint8_t is_bigendian;
pcl::uint32_t point_step;
pcl::uint32_t row_step;
std::vector<pcl::uint8_t> data;
pcl::uint8_t is_dense;
public:
typedef boost::shared_ptr< ::pcl::PCLPointCloud2> Ptr;
typedef boost::shared_ptr< ::pcl::PCLPointCloud2 const> ConstPtr;
}; // struct PCLPointCloud2
相互装换
PointCloud<PointXYZ>和PointCloud<PointXYZRGB>
PointCloud<PointXYZ> cloud_xyz;
// [...]
PointCloud<PointXYZRGB> cloud_xyzrgb;
copyPointCloud(cloud_xyz, cloud_xyzrgb);
cloud_filtered_blob 声明的数据格式为pcl::PCLPointCloud2::Ptr cloud_filtered_blob (new pcl::PCLPointCloud2);
cloud_filtered 申明的数据格式 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>)
pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered);
void pcl::fromPCLPointCloud(const pcl:PCLPointCloud2 & msg pcl::PointCloud<PointT> & cloud const MsgFieldMap & filed_map)
void pcl::fromPCLPointCloud2(const pcl::PCLPointCloud & msg pcl::PointCloud<pointT> &cloud )
void pcl::fromROSMsg(const pcl:PCLPointCloud2 & msg pcl::PointCloud<PointT> & cloud )
参考:http://docs.ros.org/hydro/api/pcl/html/namespacepcl.html
滤波 filter
PassThrough
- 空间切割
只保留设定范围内的点,超出边界的就过滤掉了。
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);
pass.setFilterFieldName ("z");
pass.setFilterLimits (0.0, 1.0);
//pass.setFilterLimitsNegative (true);
pass.filter (*cloud_filtered);
代表了是否显示被过滤掉的点,如果设置为true则将被过滤的以红色表示,没过滤的用绿色表示。默认是false.
cloud就是需要过滤的点云,cloud_filtered就是过滤后的点云,使用setFilterFieldName来设置过滤Z轴,用setFilterLimits来设置范围,也就是只保留z座标在0-1之间的点,其他的全部不要了。
- 圆形滤波
遍历图像中每一个点,如果他周围给定半径内点的数量小于自己设置的一个阈值,那么这一个点将被忽略。
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);
pass.setRadiusSearch (0.2);
pass.setMinNeighborsInRadius (20);
pass.filter (*cloud_filtered);