PCL

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/daoer_sofu/article/details/96117273

PCL

http://www.pointclouds.org/documentation/tutorials/#filtering-tutorial 每个模块点击进去后,有demo可以查看

源码编译打开option开关with_docs true,生成html文档

PCD

width、height绘制的网格中,height>1有序点云,height==1无序点云 sensor_origin_ 中心点 sensor_orientation_ 模型矩阵 point类型(体素类型),不同类型的点数据,加载出来的图像不同

  • PointXYZ 常用无色点云数据
  • PointXYZI i表示强度(intensity),距离越近强度越高
  • PointXYZRGB RGB颜色使用float存储,彩色点云

filed:concatenateFields拼接点云的数据坐标和法线数据等 PointCloud–>PointCloudNormal 点云数据合并 a+b=c点云

Segment

  • 欧几里德
std::vector<pcl::PointIndices> cluster_indices;
//欧式分割器
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance (0.02); // 2cm
ec.setMinClusterSize (100);
ec.setMaxClusterSize (25000);
//搜索策略树
ec.setSearchMethod (tree);
ec.setInputCloud (cloud_filtered);
ec.extract (cluster_indices);
  • 区域生长
//一个点云团队列,用于存放聚类结果
std::vector <pcl::PointIndices> clusters;
//区域生长分割器
pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
//输入分割目标
reg.setSearchMethod (tree);
reg.setNumberOfNeighbours (30);
reg.setInputCloud (cloud);
//reg.setIndices (indices);
reg.setInputNormals (normals);
//设置限制条件及先验知识
reg.setMinClusterSize (50);
reg.setMaxClusterSize (1000000);
reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI);
reg.setCurvatureThreshold (1.0);
reg.extract (clusters);
  • ransac带阈值的最小而乘法
pcl::SACSegmentation<pcl::PointXYZ> seg;
seg.setOptimizeCoefficients (true);
seg.setModelType (pcl::SACMODEL_PLANE);
seg.setMethodType (pcl::SAC_RANSAC);
seg.setDistanceThreshold (0.01);
seg.setInputCloud (cloud);
seg.segment (*inliers, *coefficients);
  • 分割后遍历各个子集
for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); it++)
    {    
        pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZRGB>);
        for (std::vector<int>::const_iterator itor = it->indices.begin(); itor != it->indices.end(); itor++)
        {
            cloud_cluster->points.push_back(colored_cloud->points[*itor]); //*
            cloud_cluster->width = cloud_cluster->points.size();
            cloud_cluster->height = 1;
            cloud_cluster->is_dense = true;

ModelCoefficients平面参数

Common

PosesFromMatches姿态估计 getMinMax包围和估计

Filter

过滤点云(下采样),保持形状不变减少点云数量 VoxelGrid体素网格,可以做下采样 setLeafSize设置体素的过滤大小m为单位,0.01(1cm^3)

pcl::VoxelGrid<pcl::PCLPointCloud2> sor;  //创建滤波对象
sor.setInputCloud (cloud);            //设置需要过滤的点云给滤波对象
sor.setLeafSize (0.01f, 0.01f, 0.01f);  //设置滤波时创建的体素体积为1cm的立方体
sor.filter (*cloud_filtered);           //执行滤波处理,存储输出

PassThrough过滤或保留不再给定范围内的值

pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);            //设置输入点云
pass.setFilterFieldName ("z");          //设置过滤时所需要点云类型的Z字段
pass.setFilterLimits (0.0, 1.0);          //设置在过滤字段的范围
//pass.setFilterLimitsNegative (true);     //设置保留范围内还是过滤掉范围内
pass.filter (*cloud_filtered);             //执行滤波,保存过滤结果在cloud_filtered

UniformSampling 均匀采样

pcl::UniformSampling<pcl::PointXYZ> filter;
filter.setInputCloud(cloud);
filter.setRadiusSearch(0.01f);
pcl::PointCloud<int> keypointIndices;
filter.compute(keypointIndices);
pcl::copyPointCloud(*cloud, keypointIndices.points, *filteredCloud);

Feature

  • 模型边界 BoundaryEstimation,模型
	Eigen::Vector4f pcaCentroid;
	Eigen::Matrix3f covariance;
    pcl::compute3DCentroid(*scene, pcaCentroid);
    pcl::computeCovarianceMatrixNormalized(*scene, pcaCentroid, covariance);  //协方差矩阵
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);
    Eigen::Matrix3f eigenVectorsPCA = eigen_solver.eigenvectors();
    //viewer.addCoordinateSystem(1,pcaCentroid.x(),pcaCentroid.y(),pcaCentroid.z());
    viewer.addCube(Eigen::Vector3f(tmpCenter.x,tmpCenter.y,tmpCenter.z),Eigen::Quaternionf(eigenVectorsPCA),width,height,depth,"bbox");
  • 法线估计
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
//创建法线估计估计向量
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud (cloud);
//创建一个空的KdTree对象,并把它传递给法线估计向量
//基于给出的输入数据集,KdTree将被建立
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
ne.setSearchMethod (tree);
//使用半径在查询点周围3厘米范围内的所有临近元素
ne.setRadiusSearch (0.03);
//计算特征值
ne.compute (*cloud_normals);
  • 点特征直方图PFH描述

查找特征点云P,得到P点最临近元素,对领域内的每对点,计算三个角度特征参数,输出直方图,点区域特征和权重

//其他相关操作
pcl::PointCloud<pcl::PointXYZ>::Ptrcloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::Normal>::Ptrnormals(new pcl::PointCloud<pcl::Normal>());
//打开点云文件估计法线等
//创建PFH估计对象pfh,并将输入点云数据集cloud和法线normals传递给它
pcl::PFHEstimation<pcl::PointXYZ,pcl::Normal,pcl::PFHSignature125> pfh;
pfh.setInputCloud(cloud);
pfh.setInputNormals(normals);
//如果点云是类型为PointNormal,则执行pfh.setInputNormals (cloud);
//创建一个空的kd树表示法,并把它传递给PFH估计对象。
//基于已给的输入数据集,建立kdtree
pcl::KdTreeFLANN<pcl::PointXYZ>::Ptrtree(new pcl::KdTreeFLANN<pcl::PointXYZ>());
pfh.setSearchMethod(tree);
//输出数据集
pcl::PointCloud<pcl::PFHSignature125>::Ptrpfhs(new pcl::PointCloud<pcl::PFHSignature125>());
//使用半径在5厘米范围内的所有邻元素。
//注意:此处使用的半径必须要大于估计表面法线时使用的半径!!!
pfh.setRadiusSearch(0.05);
//计算pfh特征值
pfh.compute(*pfhs);

Surface

三维重建 霍夫曼变换(Hough)、哈里斯角点(Harris)

Sample Consensus

单个模型拟合去噪,RANSAC算法(带阈值的最小二乘法)

KdTree

查找特征点附近的K个临近点。由一个有其他约束条件的二叉树组成。

OCTree

查找临近点。描述三维坐标系中的8个象限。

ICP算法

注册模型,匹配模型姿态矫正 Icp算法,点集对点集配准方法,通过算法不断迭代,找到模型的匹配姿态。

IterativeClosestPoint<PointXYZ, PointXYZ> icp;
icp.setInputCloud (cloud_source);
icp.setInputTarget (cloud_target);
icp.setMaxCorrespondenceDistance (0.05);
icp.setMaximumIterations (50);
icp.setTransformationEpsilon (1e-8);
icp.setEuclideanFitnessEpsilon (1);
icp.align (cloud_source_registered);
Eigen::Matrix4f transformation = icp.getFinalTransformation ();

recongnise

Linemod,目标检测算法

LineRGBD<PointXYZRGBA> line_rgbd;
std::vector<LineRGBD<PointXYZRGBA>::Detection> detections;
line_rgbd.setGradientMagnitudeThreshold (10.0);
line_rgbd.setDetectionThreshold (0.75);
line_rgbd.loadTemplates ("*.lmt");   //输入训练好的lmt文件
line_rgbd.setInputCloud (cloud);
line_rgbd.setInputColors (cloud);
line_rgbd.detect (detections);

VTK(OPenGL的封装)

pcl::visualization对VTK做封装,包含pcd点云显示等功能

Eigen编译错误

EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE eigen类型不匹配会,通过编译宏断言设置错误 Eigen::Vector3f(pcl::PointRGB.getVector3fMap())

点做旋转变换,注意旋转矩阵的左乘和右乘

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏吉林乌拉

锁消除

锁消除的意思是说虚拟机在运行时,虽然代码进行了同步,但是如果虚拟机检测到不存在数据竞争时,虚拟机就会自动把锁进行消除。锁消除主要的判定依据是如果堆上的所有数据都...

6410
来自专栏前端自习课

【Webpack】315- 手把手教你搭建基于 webpack4 的 vue2 多页应用

前司和现司都会存在这种业务场景:有很多 H5 页面是不相关的,如果使用 SPA 的话,对于很多落地页和活动页不太友好,有一些纯前端页面加载过慢,所以就萌生了创建...

21110
来自专栏acoolgiser_zhuanlan

warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

原文链接:https://www.zhaokeli.com/article/8276.html

48320
来自专栏Java技术栈

Java 11 快要来了,编译 & 运行一个命令搞定!

在我们的认知里面,要运行一个 Java 源代码必须先编译,再运行,两步执行动作。而在未来的 Java 11 版本中,通过一个 java 命令就直接搞定了,如以下...

9230
来自专栏吉林乌拉

Spring框架中的国际化支持

我们在开发项目时,常常会需要支持多国语言,这时就会要求我们的程序支持国际化,也就是可以根据客户端系统的语言类型显示相应的文案与界面。在spring中可以很方便的...

19620
来自专栏kk大数据

Java虚拟机:我们写的java代码究竟是如何运行起来的

首先假设咱们写好了一份Java代码,那这份Java代码中,是不是会包含很多的“.java”为后缀的代码文件?

19730
来自专栏kk大数据

如何阅读源码,这一篇应该够了

很多人一定和我一样的感受:源码在工作中有用吗?用处大吗?很长一段时间,我也有这样的疑问,认为那些有事没事扯源码的人,就是在装,只是为了提高他们的逼格而已。

12520
来自专栏FunTester

java和groovy混合编程时提示找不到符合错误解决办法

本人在使用java和groovy混合编程时,发现一个问题,当java和groovy相互调用的过程中在本机执行没有任何问题,但当弄到Jenkins上之后总是报错,...

23250
来自专栏sofu456

cmake

例如:添加三方库 include_directiories(/usr/include/curl) target_link_libraries(myprogr...

13630
来自专栏Super 前端

单页应用优化--懒加载

最近查阅了一些帖子,发现了一个极其强大的方法,其兼容性有待提高~~(但已有相关的的Polyfill方式)

10420

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励