点云处理【五】(点云特征提取)

编程入门 行业动态 更新时间:2024-10-28 16:25:31

点云处理【五】(点云<a href=https://www.elefans.com/category/jswz/34/1769701.html style=特征提取)"/>

点云处理【五】(点云特征提取)

第一章 点云数据采集
第二章 点云滤波
第三章 点云降采样


1.点云特征与关键点的区别?

关键点提取关键的一些点,旨在减少数据量;而特征提取旨在为每个点提供一个可用于后续任务的描述。
通常点云特征与关键点结合使用。

2.特征提取算法(本数据单位为mm,通常数据单位为m,取半径之类得参数要除1000)

2.1 法线估计

每一个点的位置都有垂直于点表面的的矢量,但是这种方式比较耗时。

PCL

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/kdtree/kdtree_flann.h>int main() {// 1. Load Point Cloud from PCD filepcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::io::loadPCDFile("second_radius_cloud.pcd", *cloud);// 2. Setup the normal estimationpcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;normal_estimation.setInputCloud(cloud);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());normal_estimation.setSearchMethod(tree);normal_estimation.setRadiusSearch(30);// 3. Compute the normalspcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());normal_estimationpute(*normals);// 4. Visualizationpcl::visualization::PCLVisualizer viewer("Normals Viewer");viewer.setBackgroundColor(0, 0, 0);viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud");viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 10, 50, "normals");viewer.initCameraParameters();viewer.saveScreenshot("screenshot.png");viewer.spin();return 0;
}

2.2 SHOT

每一个点的位置都有垂直于点表面的的矢量,但是这种方式比较耗时。

PCL
在这里可视化了shot的前三个维度。

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/shot.h>
#include <pcl/visualization/pcl_visualizer.h>int main() {// Load Point Cloud from PCD filepcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::io::loadPCDFile("second_radius_cloud.pcd", *cloud);// Compute Normalspcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());normal_estimation.setInputCloud(cloud);normal_estimation.setSearchMethod(tree);normal_estimation.setRadiusSearch(30);normal_estimationpute(*normals);// Compute SHOT descriptorspcl::SHOTEstimation<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> shot;pcl::PointCloud<pcl::SHOT352>::Ptr shot_descriptors(new pcl::PointCloud<pcl::SHOT352>());shot.setInputCloud(cloud);shot.setInputNormals(normals);shot.setRadiusSearch(3);shotpute(*shot_descriptors);// Convert SHOT values to colorspcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud(new pcl::PointCloud<pcl::PointXYZRGB>());colored_cloud->resize(cloud->size());for (size_t i = 0; i < cloud->size(); ++i) {pcl::PointXYZRGB point;point.x = (*cloud)[i].x;point.y = (*cloud)[i].y;point.z = (*cloud)[i].z;// Use the first three dimensions of the SHOT descriptor to color the pointpoint.r = static_cast<uint8_t>(255 * std::min(1.0f, shot_descriptors->points[i].descriptor[0]));point.g = static_cast<uint8_t>(255 * std::min(1.0f, shot_descriptors->points[i].descriptor[1]));point.b = static_cast<uint8_t>(255 * std::min(1.0f, shot_descriptors->points[i].descriptor[2]));colored_cloud->points[i] = point;}// Visualizationpcl::visualization::PCLVisualizer viewer("SHOT Features Viewer");viewer.setBackgroundColor(0, 0, 0);viewer.addPointCloud<pcl::PointXYZRGB>(colored_cloud, "colored cloud"););viewer.spin();return 0;
}

2.3 PFH

PFH通过参数化查询点与邻域点之间的空间差异,并形成一个多维直方图对点的k邻域几何属性进行描述。直方图所在的高维超空间为特征表示提供了一个可度量的信息空间,对点云对应曲面的6维姿态来说它具有不变性,并且在不同的采样密度或邻域的噪音等级下具有鲁棒性。点特征直方图(PFH)表示法是基于点与其k邻域之间的关系以及它们的估计法线,简言之,它考虑估计法线方向之间所有的相互作用,试图捕获最好的样本表面变化情况,以描述样本的几何特征。

PCL

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/pfh.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/visualization/pcl_visualizer.h>int main() {// 1. Load Point Cloud from PCD filepcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::io::loadPCDFile("second_radius_cloud.pcd", *cloud);// 2. Compute the normalspcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;normal_estimation.setInputCloud(cloud);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());normal_estimation.setSearchMethod(tree);normal_estimation.setRadiusSearch(30);pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());normal_estimationpute(*normals);// 3. Compute PFH descriptorspcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> pfh_estimation;pfh_estimation.setInputCloud(cloud);pfh_estimation.setInputNormals(normals);pfh_estimation.setSearchMethod(tree);pfh_estimation.setRadiusSearch(80);pcl::PointCloud<pcl::PFHSignature125>::Ptr pfhs(new pcl::PointCloud<pcl::PFHSignature125>());pfh_estimationpute(*pfhs);// 4. Convert PFH values to colors for visualizationpcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud(new pcl::PointCloud<pcl::PointXYZRGB>());colored_cloud->resize(cloud->size());for (size_t i = 0; i < cloud->size(); ++i) {pcl::PointXYZRGB point;point.x = (*cloud)[i].x;point.y = (*cloud)[i].y;point.z = (*cloud)[i].z;// Use the first dimension of the PFH descriptor to color the pointpoint.r = static_cast<uint8_t>(255 * std::min(1.0f, pfhs->points[i].histogram[0] / 100.0f));point.g = 0;point.b = 0;colored_cloud->points[i] = point;}// 5. Visualizationpcl::visualization::PCLVisualizer viewer("PFH Visualization");viewer.setBackgroundColor(0, 0, 0);viewer.addPointCloud<pcl::PointXYZRGB>(colored_cloud, "colored cloud");viewer.spin();return 0;
}

2.4 FPFH

快速点特征直方图(Fast Point Feature Histograms, FPFH)是PFH计算方式的简化形式。它的思想在于分别计算查询点的k邻域中每一个点的简化点特征直方图(Simplified Point Feature Histogram,SPFH),再通过一个公式将所有的SPFH加权成最后的快速点特征直方图。FPFH把算法的计算复杂度降低到了O(nk) ,但是任然保留了PFH大部分的识别特性。

PCL

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/fpfh.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/visualization/pcl_visualizer.h>int main() {// 1. Load Point Cloud from PCD filepcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::io::loadPCDFile("second_radius_cloud.pcd", *cloud);// 2. Compute the normalspcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;normal_estimation.setInputCloud(cloud);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());normal_estimation.setSearchMethod(tree);normal_estimation.setRadiusSearch(300);pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());normal_estimationpute(*normals);// 3. Compute FPFH descriptorspcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh_estimation;fpfh_estimation.setInputCloud(cloud);fpfh_estimation.setInputNormals(normals);fpfh_estimation.setSearchMethod(tree);fpfh_estimation.setRadiusSearch(500);pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>());fpfh_estimationpute(*fpfhs);// 4. Convert FPFH values to colors for visualizationpcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud(new pcl::PointCloud<pcl::PointXYZRGB>());colored_cloud->resize(cloud->size());for (size_t i = 0; i < cloud->size(); ++i) {pcl::PointXYZRGB point;point.x = (*cloud)[i].x;point.y = (*cloud)[i].y;point.z = (*cloud)[i].z;// Use the first dimension of the FPFH descriptor to color the pointpoint.r = static_cast<uint8_t>(255 * std::min(1.0f, fpfhs->points[i].histogram[0] / 100.0f));point.g = 0;point.b = 0;colored_cloud->points[i] = point;}// 5. Visualizationboost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("FPFH Visualization"));viewer->setBackgroundColor(0, 0, 0);viewer->addPointCloud<pcl::PointXYZRGB>(colored_cloud, "colored cloud");viewer->spin();return 0;
}

2.5 VFH

FPFH有很好的速度和辨别能力,VFH在此基础上添加视点方差,同时保持尺度不变性。

PCL

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/vfh.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <sstream>int main() {// 1. Load Point Cloud from PCD filepcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::io::loadPCDFile("second_radius_cloud.pcd", *cloud);// 2. Compute the normalspcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;normal_estimation.setInputCloud(cloud);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());normal_estimation.setSearchMethod(tree);normal_estimation.setRadiusSearch(30);pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());normal_estimationpute(*normals);// 3. Compute VFH descriptorspcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh_estimation;vfh_estimation.setInputCloud(cloud);vfh_estimation.setInputNormals(normals);vfh_estimation.setSearchMethod(tree);pcl::PointCloud<pcl::VFHSignature308>::Ptr vfhs(new pcl::PointCloud<pcl::VFHSignature308>());vfh_estimationpute(*vfhs);// 4. Visualizationboost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("VFH Visualization"));viewer->setBackgroundColor(0, 0, 0);viewer->addPointCloud<pcl::PointXYZ>(cloud, "cloud");// Display some VFH dimensions as textfor (size_t i = 0; i < 5; ++i) {std::stringstream ss;ss << "VFH value at dim " << i << ": " << vfhs->points[0].histogram[i];viewer->addText(ss.str(), 10, 20 + i * 20, 20, 1.0, 1.0, 1.0, "vfh_val" + std::to_string(i));}viewer->spin();return 0;
}

更多推荐

点云处理【五】(点云特征提取)

本文发布于:2023-12-06 23:07:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1669264.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:特征

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!