PCL常用代码总结(二):kdtree & octree

1. kdtree近邻搜索

#include <pcl/point_cloud.h> //定义PointCloud格式点云
#include <pcl/kdtree/kdtree_flann.h> //KdTreeFLANN是一种KD-tree结构,使用FLANN( 快速最近邻逼近搜索函数库)实现高效搜索

//【1】定义kdtree对象
pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
//将点云集输入到kdtree中
kdtree.setInputCloud (cloud);

//【2】设置搜索目标点
pcl::PointXYZ searchPoint;
searchPoint.x=1024.0f* rand () / (RAND_MAX +1.0f);
searchPoint.y=1024.0f* rand () / (RAND_MAX +1.0f);
searchPoint.z=1024.0f* rand () / (RAND_MAX +1.0f);

//【3】K近邻搜索
int K =10; //搜索近邻个数
std::vector<int>pointIdxNKNSearch(K); //存放近邻点在原点云集的索引
std::vector<float>pointNKNSquaredDistance(K); //对应近邻的平方距离
std::cout<<"K nearest neighbor search at ("<<searchPoint.x
<<" "<<searchPoint.y
<<" "<<searchPoint.z
<<") with K="<< K <<std::endl;

// 开始kdtree K近邻搜索
if ( kdtree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) >0 )
  {
for (size_t i=0; i<pointIdxNKNSearch.size (); ++i)
std::cout<<"    "<<   cloud->points[ pointIdxNKNSearch[i] ].x 
<<" "<< cloud->points[pointIdxNKNSearch[i] ].y 
<<" "<< cloud->points[pointIdxNKNSearch[i] ].z 
<<" (squared distance: "<<pointNKNSquaredDistance[i] <<")"<<std::endl;
  }

//【4】或者在半径r内搜索
float radius =256.0f* rand () / (RAND_MAX +1.0f); //设置搜索半径
std::vector<int> pointIdxRadiusSearch; //存放搜索到的点在原点云集中的索引
std::vector<float> pointRadiusSquaredDistance; //搜索到的点与目标点的平方距离

// 开始在半径r中搜索
if ( kdtree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) >0 )
  {
for (size_t i=0; i<pointIdxRadiusSearch.size (); ++i)
std::cout<<"    "<<   cloud->points[ pointIdxRadiusSearch[i] ].x 
<<" "<< cloud->points[pointIdxRadiusSearch[i] ].y 
<<" "<< cloud->points[pointIdxRadiusSearch[i] ].z 
<<" (squared distance: "<<pointRadiusSquaredDistance[i] <<")"<<std::endl;

2. octree近邻搜索

#include <pcl/point_cloud.h> //定义PointCloud格式点云
#include <pcl/octree/octree.h> //OcTree

//【1】定义一个octree搜索对象,分辨率参数
pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(resolution);
//将点云集输入到octree中
octree.setInputCloud (cloud);
//Add points from input point cloud to octree
octree.addPointsFromInputCloud ();

//【2】设置搜索目标点
pcl::PointXYZ searchPoint;
searchPoint.x=1024.0f* rand () / (RAND_MAX +1.0f);
searchPoint.y=1024.0f* rand () / (RAND_MAX +1.0f);
searchPoint.z=1024.0f* rand () / (RAND_MAX +1.0f);

//【3】K近邻搜索
int K =10; //搜索近邻个数
std::vector<int>pointIdxNKNSearch; //存放近邻点在原点云集的索引
std::vector<float>pointNKNSquaredDistance; //对应近邻的平方距离
std::cout<<"K nearest neighbor search at ("<<searchPoint.x
<<" "<<searchPoint.y
<<" "<<searchPoint.z
<<") with K="<< K <<std::endl;

// 开始octree K近邻搜索
if (octree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) >0)
  {
for (size_t i=0; i<pointIdxNKNSearch.size (); ++i)
std::cout<<"    "<<   cloud->points[ pointIdxNKNSearch[i] ].x 
<<" "<< cloud->points[pointIdxNKNSearch[i] ].y 
<<" "<< cloud->points[pointIdxNKNSearch[i] ].z 
<<" (squared distance: "<<pointNKNSquaredDistance[i] <<")"<<std::endl;
  }

//【4】或者在半径r内搜索
float radius =256.0f* rand () / (RAND_MAX +1.0f); //设置搜索半径
std::vector<int> pointIdxRadiusSearch; //存放搜索到的点在原点云集中的索引
std::vector<float> pointRadiusSquaredDistance; //搜索到的点与目标点的平方距离

// 开始在半径r中搜索
if (octree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) >0)
  {
for (size_t i=0; i<pointIdxRadiusSearch.size (); ++i)
std::cout<<"    "<<   cloud->points[ pointIdxRadiusSearch[i] ].x 
<<" "<< cloud->points[pointIdxRadiusSearch[i] ].y 
<<" "<< cloud->points[pointIdxRadiusSearch[i] ].z 
<<" (squared distance: "<<pointRadiusSquaredDistance[i] <<")"<<std::endl;
  }

//【5】体素内近邻搜索
std::vector<int> pointIdxVec;
// 在一个体素内寻找近邻
if (octree.voxelSearch (searchPoint, pointIdxVec))
  {
std::cout<<"Neighbors within voxel search at ("<<searchPoint.x
<<" "<<searchPoint.y
<<" "<<searchPoint.z<<")"
<<std::endl;
for (size_t i=0; i<pointIdxVec.size (); ++i)
std::cout<<"    "<< cloud->points[pointIdxVec[i]].x 
<<" "<< cloud->points[pointIdxVec[i]].y 
<<" "<< cloud->points[pointIdxVec[i]].z <<std::endl;
  }

3. octree点云压缩

#include <pcl/point_cloud.h> //PointCloud格式
#include <pcl/point_types.h> //PointT类型
#include <pcl/compression/octree_pointcloud_compression.h> //octree压缩

//【1】定义压缩和解压缩对象
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA>*PointCloudEncoder;
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA>*PointCloudDecoder;

// 将压缩相关的统计信息打印到标准输出
bool showStatistics=true;
// 压缩配置文件,表示5立方毫米,有颜色,快速在线编码
pcl::io::compression_Profiles_e compressionProfile=pcl::io::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;

//【2】实例化压缩与解压缩对象
PointCloudEncoder=new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> (compressionProfile, showStatistics);
PointCloudDecoder=new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> ();

//【3】压缩和解压缩
/*其中cloud为形参,pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& cloud*/
// 存储压缩点云的字节流
std::stringstream compressedData;
// 压缩点云
PointCloudEncoder->encodePointCloud (cloud, compressedData);
// 解压缩点云
PointCloudDecoder->decodePointCloud (compressedData, cloudOut);

4. octree无序点云差异检测

#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>

//【1】定义octree变化检测对象
// 八叉树分辨率 即体素的大小
float resolution =32.0f;
// 实例空间变化检测对象
pcl::octree::OctreePointCloudChangeDetector<pcl::PointXYZ> octree (resolution);

//【2】添加两个PointCloud数据集
//添加cloudA到八叉树,建立八叉树
octree.setInputCloud (cloudA);
octree.addPointsFromInputCloud ();
// 交换八叉树缓存,但是cloudA对应的八叉树仍在内存中
octree.switchBuffers ();

//添加 cloudB到八叉树
octree.setInputCloud (cloudB);
octree.addPointsFromInputCloud ();

//【3】octree查找差异点(A中没有,B中有)
std::vector<int> newPointIdxVector; // 查找到的点索引存放的数组
//获取前一cloudA对应的八叉树在cloudB对应八叉树中没有的体素
octree.getPointIndicesFromNewVoxels (newPointIdxVector);
//打印输出点
std::cout<<"Output from getPointIndicesFromNewVoxels:"<<std::endl;
for (size_t i=0; i<newPointIdxVector.size (); ++i)
std::cout<<i<<"# Index:"<<newPointIdxVector[i]
<<"  Point:"<<cloudB->points[newPointIdxVector[i]].x <<" "
<<cloudB->points[newPointIdxVector[i]].y <<" "
<<cloudB->points[newPointIdxVector[i]].z <<std::endl;

☆参考

点云PCL从入门到精通

https://pcl.readthedocs.io/projects/tutorials/en/latest/index.html

在qt中运行以下程序提示报错 #include &lt;pcl/io/pcd_io.h&gt; #include &lt;pcl/point_types.h&gt; #include &lt;pcl/filters/voxel_grid.h&gt; #include &lt;pcl/kdtree/kdtree_flann.h&gt; #include &lt;pcl/common/time.h&gt; //计时 #include &lt;pcl/filters/passthrough.h&gt; #include &lt;pcl/filters/statistical_outlier_removal.h&gt; #include &lt;pcl/ModelCoefficients.h&gt; // 模型系数 #include &lt;pcl/sample_consensus/model_types.h&gt; // 分割模型类型 #include &lt;pcl/segmentation/sac_segmentation.h&gt; // RANSAC #include &lt;pcl/filters/model_outlier_removal.h&gt; // 模型滤波器 #include &lt;pcl/visualization/cloud_viewer.h&gt; // 可视化 #include &lt;pcl/visualization/pcl_visualizer.h&gt; #include &lt;pcl/sample_consensus/sac_model_cylinder.h&gt; // 圆柱 #include &lt;pcl/filters/extract_indices.h&gt; #include &lt;pcl/common/pca.h&gt; #include &lt;pcl/sample_consensus/ransac.h&gt; // RANSAC #include &lt;pcl/search/kdtree.h&gt; // KDtree搜索 #include &lt;pcl/features/normal_3d.h&gt; // 法线估计 #include &lt;pcl/features/normal_3d_omp.h&gt; #include &lt;pcl/segmentation/region_growing.h&gt; //区域生长 #include &lt;pcl/common/angles.h&gt; #include &lt;pcl/search/search.h&gt; #include &lt;pcl/filters/project_inliers.h&gt; #include &lt;pcl/filters/crop_box.h&gt; #include &lt;pcl/features/moment_of_inertia_estimation.h&gt; #include &lt;pcl/sample_consensus/sac_model_circle3d.h&gt; // 拟合3D圆 #include &lt;pcl/visualization/pcl_visualizer.h&gt; #include &lt;pcl/common/common.h&gt; #include&lt;pcl/octree/octree.h&gt; #include &lt;opencv2/opencv.hpp&gt; #include &lt;opencv2/core.hpp&gt; #include &lt;opencv2/core/core_c.h&gt; #include &lt;opencv2/imgproc.hpp&gt; #include &lt;opencv2/calib3d.hpp&gt; #include &lt;opencv2/core/eigen.hpp&gt; #include &quot;EuclideanCluster.h&quot; #include &lt;pcl/console/time.h&gt; // 控制台计算时间 #include &lt;QApplication&gt; #include &lt;iostream&gt; #include &lt;opencv2/opencv.hpp&gt; using namespace cv; using namespace std; using pcl::visualization::PointCloudColorHandlerGenericField; using pcl::visualization::PointCloudColorHandlerCustom; typedef struct Point3D { Mat_&lt;double&gt; mat1 ; float angle; }; pcl::PointCloud&lt;pcl::PointXYZ&gt;::Ptr Voxel_Grid_Filtering(pcl::PointCloud&lt;pcl::PointXYZ&gt;::Ptr &amp;cloud,int numb
最新发布
03-19
&lt;think&gt;好的,我现在要解决用户在QT环境中编译或运行PCL程序时遇到的错误。首先,我需要理解用户的问题。用户提到了多个PCL模块,比如pcd_io、point_types等,还涉及到OpenCV,可能是在编译时链接库出现问题。根据用户提供的引用内容,他们的CMakeLists.txt可能存在配置问题,尤其是链接库的部分。 首先,用户引用了几个CMake配置的例子,其中提到需要正确链接PCL_LIBRARIES。例如,引用1中用户发现没有链接PCL_LIBRARIES,添加后解决了问题。这说明在QT项目中,正确配置CMakeLists.txt,特别是target_link_libraries部分,是非常重要的。 接下来,用户引用2展示了另一个CMakeLists.txt的例子,其中正确使用了find_package和target_link_libraries。用户可能没有正确设置这些部分,导致编译器找不到PCL的库文件。另外,引用3提到在find_package时需要指定正确的组件,如common、io等,这可能也是用户的问题所在,没有包含所有必要的组件。 用户引用4提到了通过环境变量添加包含路径,但可能没有正确配置CMake的include_directories,导致头文件找不到。特别是在QT项目中,可能需要显式地包含PCL和Eigen的路径,因为PCL依赖Eigen。 然后,我需要考虑用户在QT中使用PCL可能遇到的其他问题。例如,QT的.pro文件是否配置正确,或者是否在CMake中正确设置了C++标准(如C++11),因为PCL可能需要特定的标准。引用2中提到了设置-std=c++11,这也是需要注意的。 另外,用户提到的错误可能包括未定义的引用(undefined reference),这通常是由于链接库缺失或顺序不正确造成的。PCL的库需要按照依赖顺序链接,可能需要先链接PCL的组件,再链接其他库如OpenCV。 还有,用户的环境变量是否正确设置?比如PCL_ROOT是否指向正确的安装路径。如果PCL安装在非标准位置,可能需要通过CMake的find_package参数指定路径,或者在系统中设置相应的环境变量。 最后,用户可能需要检查他们的代码是否正确引用了PCL的头文件,例如是否使用了正确的命名空间,或者是否存在拼写错误。此外,运行时错误可能与动态链接库的路径有关,比如LD_LIBRARY_PATH是否包含PCL的库路径。 综合以上分析,解决步骤可能包括:检查CMakeLists.txt是否正确配置find_package和target_link_libraries;确保所有必要的PCL组件都被包含;检查包含路径是否正确;确认C++标准设置正确;以及确保环境变量和动态库路径正确。&lt;/think&gt;针对QT环境中PCL程序编译/运行报错的解决方案如下: ### 一、基础环境配置 1. **确认PCL安装完整性** - 检查`/usr/include/pcl-1.8`或`/usr/local/include/pcl-1.8`目录是否存在核心头文件[^4] - 验证PCL依赖的第三方库(如Eigen3、Boost)是否安装: ```bash sudo apt-get install libeigen3-dev libboost-all-dev ``` ### 、CMake配置优化 2. **完善CMakeLists.txt** ```cmake cmake_minimum_required(VERSION 3.5) project(QtPclDemo) set(CMAKE_CXX_STANDARD 14) # 必须使用C++11及以上标准 # QT配置 find_package(Qt5 COMPONENTS Widgets REQUIRED) # PCL配置(必须包含所有使用的组件) find_package(PCL 1.8 REQUIRED COMPONENTS common io search visualization filters kdtree octree ) # OpenCV配置 find_package(OpenCV REQUIRED) include_directories( ${PCL_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} /usr/include/eigen3 # 显式包含Eigen路径 ) add_executable(${PROJECT_NAME} main.cpp) target_link_libraries(${PROJECT_NAME} Qt5::Widgets ${PCL_LIBRARIES} ${OpenCV_LIBS} ) ``` ### 三、常见问题处理 3. **头文件包含规范** - 在代码中必须使用完整路径包含PCL头文件: ```cpp #include &lt;pcl/io/pcd_io.h&gt; // 正确格式 #include &lt;pcl/filters/voxel_grid.h&gt; ``` 4. **动态库路径配置** - 在QT Creator中添加运行时库路径: ``` Projects &rarr; Build Environment &rarr; 添加: LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH ``` ### 四、高级调试技巧 5. **依赖验证方法** - 使用`ldd`命令检查可执行文件的依赖项: ```bash ldd ./QtPclDemo | grep pcl ``` - 通过`pcl-config --cflags`验证包含路径[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值