目录
一、概述
1.1原理
1.2实现步骤
1.3应用场景
二、代码实现
2.1关键函数
2.2完整代码
三、实现效果
PCL点云算法汇总及实战案例汇总的目录地址链接:
PCL点云算法与项目实战案例汇总(长期更新)
一、概述
本文将介绍如何使用PCL库中的 addLine 方法可视化K近邻搜索的结果。K近邻搜索(K-Nearest Neighbors, KNN)用于查找点云中与查询点最近的K个点。可视化K近邻搜索的结果有助于直观地理解点与其邻居之间的空间关系。我们将在点云中绘制查询点与其K个最近邻点之间的连线,并将其可视化。
1.1原理
K近邻搜索的基本原理是通过KD树(k-D Tree)对点云数据进行高效的空间索引和查询。KD树通过递归地将数据空间划分为多个超平面,以便快速查找与查询点距离最近的K个点。通过在查询点与这些邻近点之间绘制连线,我们可以直观地看到查询点与其最近邻点的关系。
1.2实现步骤
- 读取点云数据并构建KD树。
- 执行K近邻搜索,找到与查询点最近的K个点。
- 在查询点与其K个最近邻点之间绘制连线。
- 将原始点云、查询点及其近邻关系进行可视化展示。
1.3应用场景
- 邻域分析:分析点云中某点的局部邻域结构,应用于点云滤波、配准等任务。
- 数据可视化:通过可视化邻域关系,直观展示点云数据中点的分布及空间关系。
- 3D特征检测:在3D特征提取中,通过邻域关系识别点云中的几何特征。
二、代码实现
2.1关键函数
- nearestKSearch:执行K近邻搜索,找到指定点的K个最近邻点。
- addLine:在查询点与其K个最近邻点之间绘制连线。
- pcl::visualization::PCLVisualizer:用于可视化点云和K近邻搜索结果。
2.2完整代码
#include <iostream>
#include <vector>
#include <pcl/io/pcd_io.h> // 用于加载PCD文件
#include <pcl/point_types.h> // PCL点类型定义
#include <pcl/kdtree/kdtree_flann.h> // KD树近邻搜索
#include <pcl/visualization/pcl_visualizer.h> // PCL可视化相关定义
using namespace std;
int main()
{
// --------------------------------读取点云------------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 加载PCD文件中的点云数据
if (pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud) == -1)
{
PCL_ERROR("Couldn't read file!"); // 如果文件加载失败,输出错误信息
return -1; // 返回错误代码并退出程序
}
// -----------------------------K近邻搜索---------------------------------
pcl::KdTreeFLANN<pcl::PointXYZ> kdtree; // 创建KD树对象
kdtree.setInputCloud(cloud); // 设置KD树的输入点云
// 定义查询点,选择点云中的某个点作为查询点
pcl::PointXYZ searchPoint = cloud->points[2000]; // 这里假设使用点云中的第2000个点
int K = 1000; // 设置K值,表示查找的最近邻点的数量
vector<int> pointIdxNKNSearch(K); // 用于存储最近邻点的索引
vector<float> pointNKNSquaredDistance(K); // 用于存储最近邻点与查询点之间的距离平方值
// 执行K近邻搜索
if (kdtree.nearestKSearch(searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
{
// 如果搜索成功,将搜索到的邻近点存储到pointIdxNKNSearch中
}
// -----------------------------结果可视化------------------------------------
// 创建PCLVisualizer对象,用于显示点云和邻近关系
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(0, 0, 0); // 设置背景颜色为黑色
// 将原始点云添加到可视化窗口,并设置颜色为绿色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); // 绿色
viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");
// 将查询点标记为红色
pcl::PointCloud<pcl::PointXYZ>::Ptr searchPointCloud(new pcl::PointCloud<pcl::PointXYZ>());
searchPointCloud->points.push_back(searchPoint);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red_color(searchPointCloud, 255, 0, 0); // 红色
viewer->addPointCloud<pcl::PointXYZ>(searchPointCloud, red_color, "search point");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "search point"); // 设置查询点的大小
// 在查询点与其K个最近邻点之间绘制连线
for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i)
{
// 获取最近邻点的坐标
pcl::PointXYZ neighborPoint = cloud->points[pointIdxNKNSearch[i]];
// 添加从查询点到该邻近点的连线,颜色为白色
viewer->addLine<pcl::PointXYZ>(searchPoint, neighborPoint, 255, 255, 255, "line" + std::to_string(i));
}
// 进入主循环,保持窗口打开
while (!viewer->wasStopped())
{
viewer->spinOnce(100); // 刷新窗口
//boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0; // 程序结束
}