PCL点云的提取关键点特征描述一致性估计最后进行精配准并附上代码
以下是基于PCL库的点云处理流程,包括点云关键点提取,特征描述,一致性估计和精配准。
- 点云关键点提取
点云关键点提取是指从点云中提取出代表点云特征的关键点。PCL库提供了多种点云关键点提取算法,包括Harris Keypoint,ISS Keypoint,SIFT Keypoint等。
以ISS Keypoint为例,代码如下:
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 读取点云数据
pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss_detector;
iss_detector.setInputCloud(cloud);
iss_detector.setSalientRadius(6 * resolution); // 设置感兴趣区域大小
iss_detector.setNonMaxRadius(4 * resolution); // 设置非极大值抑制区域大小
iss_detector.setThreshold21(0.975); // 设置第二个曲率阈值
iss_detector.setThreshold32(0.975); // 设置第三个曲率阈值
iss_detector.setMinNeighbors(5); // 设置最小邻居数
iss_detector.compute(*keypoints); // 计算关键点
- 特征描述
特征描述是指对点云关键点进行描述,以便后续进行匹配。PCL库提供了多种特征描述算法,包括FPFH,SHOT,VFH等。
以FPFH为例,代码如下:
pcl::PointCloud<pcl::FPFHSignature33>::Ptr features(new pcl::PointCloud<pcl::FPFHSignature33>);
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
// 计算点云法向量
fpfh.setInputCloud(keypoints);
fpfh.setInputNormals(normals);
fpfh.setRadiusSearch(2 * resolution); // 设置搜索半径
fpfh.compute(*features); // 计算特征描述子
- 一致性估计
一致性估计是指对点云匹配结果进行评估,以确定匹配结果的可靠性。PCL库提供了多种一致性估计算法,包括Sample Consensus Initial Alignment(SAC-IA),Sample Consensus Prerejective(SAC-PR)等。
以SAC-IA为例,代码如下:
pcl::SampleConsensusInitialAlignment<pcl::PointXYZ, pcl::PointXYZ, pcl::FPFHSignature33> sac_ia;
sac_ia.setInputSource(keypoints_src);
sac_ia.setInputTarget(keypoints_tgt);
sac_ia.setSourceFeatures(features_src);
sac_ia.setTargetFeatures(features_tgt);
sac_ia.setMaximumIterations(1000); // 设置最大迭代次数
sac_ia.setEuclideanFitnessEpsilon(1e-6); // 设置收敛阈值
sac_ia.align(*aligned_keypoints); // 进行初始配准
if (sac_ia.hasConverged()) {
std::cout << "SAC-IA converged!" << std::endl;
}
- 精配准
精配准是指对点云进行最终的配准,以获得更高精度的匹配结果。PCL库提供了多种精配准算法,包括Iterative Closest Point(ICP),Generalized Iterative Closest Point(GICP)等。
以ICP为例,代码如下:
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(cloud_src);
icp.setInputTarget(cloud_tgt);
icp.setMaxCorrespondenceDistance(2 * resolution); // 设置最大对应距离
icp.setMaximumIterations(100); // 设置最大迭代次数
icp.setTransformationEpsilon(1e-6); // 设置收敛阈值
icp.align(*aligned_cloud); // 进行精配准
if (icp.hasConverged()) {
std::cout << "ICP converged!" << std::endl;
}
完整代码如下:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/keypoints/iss_3d.h>
#include <pcl/features/fpfh.h>
#include <pcl/registration/sample_consensus_initial_alignment.h>
#include <pcl/registration/icp.h>
int main(int argc, char** argv) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " source.pcd target.pcd" << std::endl;
return -1;
}
float resolution = 0.01f; // 设置分辨率
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_src(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tgt(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr aligned_cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_src(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_tgt(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr aligned_keypoints(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::FPFHSignature33>::Ptr features_src(new pcl::PointCloud<pcl::FPFHSignature33>);
pcl::PointCloud<pcl::FPFHSignature33>::Ptr features_tgt(new pcl::PointCloud<pcl::FPFHSignature33>);
pcl::io::loadPCDFile(argv[1], *cloud_src);
pcl::io::loadPCDFile(argv[2], *cloud_tgt);
pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss_detector;
iss_detector.setInputCloud(cloud_src);
iss_detector.setSalientRadius(6 * resolution);
iss_detector.setNonMaxRadius(4 * resolution);
iss_detector.setThreshold21(0.975);
iss_detector.setThreshold32(0.975);
iss_detector.setMinNeighbors(5);
iss_detector.compute(*keypoints_src);
iss_detector.setInputCloud(cloud_tgt);
iss_detector.compute(*keypoints_tgt);
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
pcl::PointCloud<pcl::Normal>::Ptr normals_src(new pcl::PointCloud<pcl::Normal>);
pcl::PointCloud<pcl::Normal>::Ptr normals_tgt(new pcl::PointCloud<pcl::Normal>);
ne.setSearchMethod(tree);
ne.setInputCloud(cloud_src);
ne.setRadiusSearch(2 * resolution);
ne.compute(*normals_src);
ne.setInputCloud(cloud_tgt);
ne.compute(*normals_tgt);
pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
fpfh.setInputCloud(keypoints_src);
fpfh.setInputNormals(normals_src);
fpfh.setRadiusSearch(2 * resolution);
fpfh.compute(*features_src);
fpfh.setInputCloud(keypoints_tgt);
fpfh.setInputNormals(normals_tgt);
fpfh.compute(*features_tgt);
pcl::SampleConsensusInitialAlignment<pcl::PointXYZ, pcl::PointXYZ, pcl::FPFHSignature33> sac_ia;
sac_ia.setInputSource(keypoints_src);
sac_ia.setInputTarget(keypoints_tgt);
sac_ia.setSourceFeatures(features_src);
sac_ia.setTargetFeatures(features_tgt);
sac_ia.setMaximumIterations(1000);
sac_ia.setEuclideanFitnessEpsilon(1e-6);
sac_ia.align(*aligned_keypoints);
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(cloud_src);
icp.setInputTarget(cloud_tgt);
icp.setMaxCorrespondenceDistance(2 * resolution);
icp.setMaximumIterations(100);
icp.setTransformationEpsilon(1e-6);
icp.align(*aligned_cloud);
if (sac_ia.hasConverged()) {
std::cout << "SAC-IA converged!" << std::endl;
}
if (icp.hasConverged()) {
std::cout << "ICP converged!" << std::endl;
}
pcl::io::savePCDFileBinary("aligned_keypoints.pcd", *aligned_keypoints);
pcl::io::savePCDFileBinary("aligned_cloud.pcd", *aligned_cloud);
return 0;
}
``
原文地址: http://www.cveoy.top/t/topic/crWv 著作权归作者所有。请勿转载和采集!