PCL点云处理之无序点云的空间变化检测octree(四十五)

239 篇文章 1218 订阅 ¥19.90 ¥99.00
239 篇文章 411 订阅 ¥29.90 ¥99.00

PCL点云处理之基于octree的点云空间变化检测(四十五)

前言

一、空间变化检测?

比如树木生长或者新建设施,都会引起点云的空间变化,如新增。

octree是一种用于管理稀疏3D数据的树状数据结构,学习如何利用octree实现用于多个无序点云之间的空间变化检测,这些点云可能在尺寸、分辨率、密度和点顺序等方面有所差异。通过递归地比较octree的树结构,可以鉴定出由octree产生的体素组成之间的区别所代表的空间变化

二、使用步骤

1.代码


#include <QtCore/QCoreApplication>
//这头文件直接全垒上来算了,省的麻烦

#include <iostream>							//标准C++库中的输入输出
#include <pcl/io/pcd_io.h>					//PCD文件的读写
#include <pcl/point_types.h>				//点类型定义
#include <pcl/point_cloud.h>				//点云类定义
#include <pcl/kdtree/kdtree_flann.h>		//KD-Tree搜索


/*common模块*/
#include <pcl/common/common.h>				//标准的C以及C++类,是其他common 函数的父类;getMinMax3D()函数所需头文件,获得点云三维坐标的最值
#include <pcl/common/angles.h>				//定义了标准的C接口的角度计算函数
#include <pcl/common/centroid.h>			//定义了中心点的估算以及协方差矩阵的计算
#include <pcl/common/distances.h>			//定义标准的C接口用于计算距离
#include <pcl/common/file_io.h>				//定义了一些文件帮助写或者读方面的功能。
#include <pcl/common/random.h>				//定义一些随机点云生成的函数
#include <pcl/common/geometry.h>			//定义一些基本的几何功能的函数
#include <pcl/common/intersections.h>		//定义了线与线相交的函数
#include <pcl/common/norms.h>				//定义了标准的C方法计算矩阵的正则化
#include <pcl/common/time.h>				//定义了时间计算的函数


/*surface模块*/
#include <pcl/surface/mls.h>				//最小二乘平滑处理
#include <pcl/surface/concave_hull.h>		//创建凹多边形
#include <pcl/surface/gp3.h>				//贪婪投影三角化算法
#include <pcl/surface/organized_fast_mesh.h>

/*feature模块*/
#include <pcl/features/normal_3d.h>			//法线特征估计
#include <pcl/features/normal_3d_omp.h>		//法线特征估计加速
#include <pcl/features/pfh.h>				//PFH特征估计
#include <pcl/features/fpfh.h>				//FPFH特征估计
#include <pcl/features/fpfh_omp.h>			//FPFH特征估计加速
#include <pcl/features/vfh.h>				//VFH特征估计
#include <pcl/features/narf.h>				//NARF特征估计
#include <pcl/features/boundary.h>			//边界提取
#include <pcl/features/integral_image_normal.h>

/*registration模块*/
#include <pcl/registration/icp.h>			//ICP配准
#include <pcl/registration/icp_nl.h>		//非线性ICP配准
#include <pcl/registration/ndt.h>			//NDT配准
#include <pcl/registration/transforms.h>	//变换矩阵
#include <pcl/registration/ia_ransac.h>		//sac-ia类头文件
#include <pcl/registration/correspondence_estimation.h>					//直方图配准
#include <pcl/registration/correspondence_rejection_features.h>			//特征的错误对应关系去除
#include <pcl/registration/correspondence_rejection_sample_consensus.h>	//随机采样一致性去除 

/*filters模块*/
#include <pcl/filters/filter.h>				//滤波相关头文件
#include <pcl/filters/passthrough.h>		//滤波相关类头文件
#include <pcl/filters/project_inliers.h>	//滤波相关类头文件,点云投影
#include <pcl/filters/extract_indices.h>	//索引提取
#include <pcl/filters/voxel_grid.h>			//基于体素网格化的滤波
#include <pcl/filters/approximate_voxel_grid.h>			//体素网格过滤器滤波
#include <pcl/filters/statistical_outlier_removal.h>	//统计离群点

/*segmentation模块*/
#include <pcl/ModelCoefficients.h>						//采样一致性模型
#include <pcl/sample_consensus/method_types.h>			//随机参数估计方法
#include <pcl/sample_consensus/model_types.h>			//模型定义
#include <pcl/segmentation/sac_segmentation.h>			//基于采样一致性分割
#include <pcl/segmentation/region_growing.h>			//区域生长头文件
#include <pcl/segmentation/region_growing_rgb.h>		//基于颜色的区域生长
#include <pcl/segmentation/supervoxel_clustering.h>		//超体聚类
#include <pcl/segmentation/lccp_segmentation.h>			//基于凹凸性分割

/*visualization模块*/
#include <pcl/visualization/cloud_viewer.h>				//CloudViewer类可视化
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>

/*range_image模块*/
#include <pcl/range_image/range_image.h>		//深度图像相关
#include <pcl/range_image/range_image_planar.h>

/*Eigen模块*/
#include <Eigen/StdVector>
#include <Eigen/Geometry>

/*console模块*/
#include <pcl/console/print.h>
#include <pcl/console/time.h>
#include <pcl/console/parse.h>


#include <pcl/io/io.h>	//IO相关头文件
#include <boost/make_shared.hpp>			//boost指针相关头文件
#include <pcl/point_representation.h>		//点表示相关头文件
#include <pcl/io/openni2_grabber.h>	//OpenNI数据流获取类相关头文件

//这里有重复的自己删一删把
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include<pcl/visualization/pcl_visualizer.h>
#include <stdlib.h>
#include <time.h>

#include <iostream>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/features/boundary.h>
#include <math.h>
#include <boost/make_shared.hpp>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/pcd_io.h>

#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/features/normal_3d.h>

#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/covariance_sampling.h>
#include <pcl/filters/normal_space.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/boundary.h>


#include <pcl/io/ply_io.h>
#include <pcl/common/common_headers.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/point_cloud.h>
#include <pcl/octree/octree_pointcloud_changedetector.h>
#include <vector>
#include <ctime>
#include <pcl/point_types.h>


using namespace std;
using namespace Eigen;

int main(int argc, char** argv) {

    //octree 变化检测器
    float resolution = 0.1f;//八叉树体素分辨率
    pcl::octree::OctreePointCloudChangeDetector<pcl::PointXYZ> octree(resolution);//创建检测类的对象
                                                                                                                                                            
    //创建点云容器
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>);//待检测点云1
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZ>);//待检测点云2
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud12_bianhua(new pcl::PointCloud<pcl::PointXYZ>);//发生变化的点云12,这里应该是2中新增的点云

    //加载点云
    pcl::io::loadPCDFile<pcl::PointXYZ>("D:\\shuju\\c1.pcd", *cloud1);
    pcl::io::loadPCDFile<pcl::PointXYZ>("D:\\shuju\\c2.pcd", *cloud2);

    //构建八叉树
    octree.setInputCloud(cloud1);//输入点云cloud1
    octree.addPointsFromInputCloud();//点云cloud1构建八叉树
    octree.switchBuffers();//交换八叉树缓存,但是cloud1对应的八叉树结构仍在内存中
    octree.setInputCloud(cloud2);//输入点云cloud2
    octree.addPointsFromInputCloud();//点云cloud2构建八叉树

    //变化点云输出
    std::vector<int> newPointIdxVector;//存储新加点的索引
    octree.getPointIndicesFromNewVoxels(newPointIdxVector);//获取新增点的索引

    //将新增点按照索引从cloud2中取出,放到cloud12_bianhua中
    for (size_t i = 0; i < newPointIdxVector.size(); ++i)
    {
        cloud12_bianhua->push_back(cloud2->points[newPointIdxVector[i]]);
    }

    //保存文件
    pcl::io::savePCDFileASCII("result.pcd", *cloud12_bianhua);//将计算结果存放到result.pcd
    std::cout << "变化点的个数: " << cloud12_bianhua->points.size() << endl;




    //显示

    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer1(new pcl::visualization::PCLVisualizer("点云1")); //创建视窗对象,定义标题栏名称“3D Viewer”
    viewer1->addPointCloud<pcl::PointXYZ>(cloud1, "cloud1_cloud");	//将点云添加到视窗对象中,并定义对应的ID“original_cloud”
    //用于改变显示点云的尺寸,可以利用该方法控制点云在视窗中的显示方法,1设置显示点云大小
    viewer1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud1_cloud");//PCL_VISUALIZER_POINT_SIZE点大小设置,
    viewer1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 1, 1, "cloud1_cloud"); //PCL_VISUALIZER_COLOR颜色设置 RGB

    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer2(new pcl::visualization::PCLVisualizer("点云2")); //创建视窗对象,定义标题栏名称“3D Viewer”
    viewer2->addPointCloud<pcl::PointXYZ>(cloud2, "cloud1_cloud");	//将点云添加到视窗对象中,并定义对应的ID“original_cloud”
    //用于改变显示点云的尺寸,可以利用该方法控制点云在视窗中的显示方法,1设置显示点云大小
    viewer2->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud1_cloud");//PCL_VISUALIZER_POINT_SIZE点大小设置,
    viewer2->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 1, 1, "cloud1_cloud"); //PCL_VISUALIZER_COLOR颜色设置 RGB




    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("点云变化12")); //创建视窗对象,定义标题栏名称“3D Viewer”
    viewer->addPointCloud<pcl::PointXYZ>(cloud2, "cloud2_cloud");	//将点云添加到视窗对象中,并定义对应的ID“original_cloud”
    //用于改变显示点云的尺寸,可以利用该方法控制点云在视窗中的显示方法,1设置显示点云大小
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud2_cloud");//PCL_VISUALIZER_POINT_SIZE点大小设置,
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 1, 1, "cloud2_cloud"); //PCL_VISUALIZER_COLOR颜色设置 RGB

    viewer->addPointCloud<pcl::PointXYZ>(cloud12_bianhua, "cloud12_bianhua_cloud");	//将点云添加到视窗对象中,并定义对应的ID“original_cloud”
    //用于改变显示点云的尺寸,可以利用该方法控制点云在视窗中的显示方法,1设置显示点云大小
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "cloud12_bianhua_cloud");//PCL_VISUALIZER_POINT_SIZE点大小设置,
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0.5, "cloud12_bianhua_cloud"); //PCL_VISUALIZER_COLOR颜色设置 RGB



    //防止显示窗口一闪而过
    while (!viewer1->wasStopped())
    {
        viewer1->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }

    while (!viewer2->wasStopped())
    {
        viewer2->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }

    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }




    system("pause");
    return 0;
 
}

2.效果

cloud1
在这里插入图片描述
cloud2
在这里插入图片描述
cloud变化的点
红色,2相对1新增的点
在这里插入图片描述

总结

只能检测出点云2相对于点云1新增的点。减少的点就检测不到了

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云学徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值