PCL ISS关键点提取
目录
PCL点云算法汇总及实战案例汇总的目录地址链接:
一、概述
ISS(Intrinsic Shape Signatures)关键点提取是一种基于几何特征的方法,能够从点云中提取具有局部显著性的点。ISS算法基于协方差矩阵的特征值来检测局部稳定点。它通过设置显著性半径和非极大值抑制等参数,有效地去除冗余点,从而提取代表性强的关键点。
1.1原理
ISS算法的基本思想是通过分析局部区域的形状特征,从中提取具有显著性特征的关键点。对于每个点,通过计算协方差矩阵的特征值,得到该点的局部形状描述。具体来说:
- 协方差矩阵计算:在给定半径内,计算点云局部邻域的协方差矩阵。
- 特征值分析:通过协方差矩阵的特征值来分析局部结构。通常,通过特征值比率(λ2/λ1和λ3/λ2)来筛选出那些局部形状显著的点。
- 非极大值抑制:为确保提取出的关键点具有较强的显著性,需要对点云进行非极大值抑制处理,确保最终结果中的关键点彼此距离较远且具有显著性。
1.2实现步骤
- 读取点云数据。
- 设置ISS算法参数,如协方差矩阵计算半径、非极大值抑制半径等。
- 应用ISS关键点提取算法,得到关键点。
- 将原始点云与提取的关键点进行可视化对比。
1.3应用场景
- 三维形状分析:在物体识别、形状匹配等应用中,提取局部显著性强的关键点。
- 点云简化:对点云进行显著性简化,仅保留最具代表性的点。
- 特征点匹配:在配准、特征匹配中,提取关键点并进行特征匹配。
二、代码实现
2.1关键函数
2.1.1 ISS关键点提取
void extractISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
iss.setInputCloud(cloud); // 输入点云
iss.setSearchMethod(tree); // 设置搜索方法
iss.setNumberOfThreads(4); // 使用4个线程进行计算
iss.setSalientRadius(1.0f); // 协方差矩阵计算的半径
iss.setNonMaxRadius(1.5f); // 非极大值抑制半径
iss.setThreshold21(0.65); // 特征值比率阈值
iss.setThreshold32(0.5); // 特征值比率阈值
iss.setMinNeighbors(10); // 最少邻居数
iss.compute(*keypoints); // 计算关键点
}
2.1.2 可视化函数
void visualizeISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ISS Keypoints Viewer"));
int v1(0), v2(0);
viewer->createViewPort(0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, v1); // 设置白色背景
viewer->addText("Original Point Cloud", 10, 10, "v1_text", v1);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, v2); // 设置灰色背景
viewer->addText("ISS Keypoints", 10, 10, "v2_text", v2);
// 原始点云显示为红色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> original_color(cloud, 255, 0, 0);
viewer->addPointCloud(cloud, original_color, "original_cloud", v1);
// 关键点显示为绿色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color(keypoints, 0, 255, 0);
viewer->addPointCloud(keypoints, keypoints_color, "keypoints_cloud", v2);
// 设置点大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "original_cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "keypoints_cloud");
// 添加坐标系
viewer->addCoordinateSystem(1.0);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
2.2完整代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/keypoints/iss_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
// ISS关键点提取函数
void extractISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
iss.setInputCloud(cloud); // 设置输入点云
iss.setSearchMethod(tree); // 设置搜索方法
iss.setNumberOfThreads(4); // 使用4个线程进行计算
iss.setSalientRadius(1.0f); // 设置显著性半径
iss.setNonMaxRadius(1.5f); // 非极大值抑制半径
iss.setThreshold21(0.65); // 第二个和第一个特征值比的上限
iss.setThreshold32(0.5); // 第三个和第二个特征值比的上限
iss.setMinNeighbors(10); // 设置最小邻居数
iss.compute(*keypoints); // 计算关键点
}
// 可视化函数
void visualizeISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ISS Keypoints Viewer"));
int v1(0), v2(0);
viewer->createViewPort(0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, v1); // 设置白色背景
viewer->addText("Original Point Cloud", 10, 10, "v1_text", v1);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, v2); // 设置灰色背景
viewer->addText("ISS Keypoints", 10, 10, "v2_text", v2);
// 原始点云显示为红色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> original_color(cloud, 255, 0, 0);
viewer->addPointCloud(cloud, original_color, "original_cloud", v1);
// 关键点显示为绿色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color(keypoints, 0, 255, 0);
viewer->addPointCloud(keypoints, keypoints_color, "keypoints_cloud", v2);
// 设置点大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "original_cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "keypoints_cloud");
// 添加坐标系
viewer->addCoordinateSystem(1.0);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
int main(int, char** argv)
{
// 读取点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("Armadillo.pcd", *cloud) == -1)
{
PCL_ERROR("Could not read file\n");
return -1;
}
std::cout << "读取点云个数: " << cloud->points.size() << std::endl;
// 提取ISS关键点
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>());
extractISSKeypoints(cloud, keypoints);
std::cout << "ISS关键点提取结果: " << keypoints->points.size() << std::endl;
// 可视化
visualizeISSKeypoints(cloud, keypoints);
return 0;
}
三、实现效果
原文地址:https://blog.csdn.net/qq_47947920/article/details/142780688
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!