这篇文章跟大家分享如何使用PCL库实现两个点云公共点的提取。
实现这一目标的方式有很多,这里我简单介绍两种常用的方法:
方法一:
自己写一个判断,也就是通过判断点的坐标是否相等 ,具体实现如下。
bool isEqual(const pcl::PointXYZRGB& point1, const pcl::PointXYZRGB& point2)
{
float epsilon = 1e-6; // 阈值,用于判断浮点数相等性
return (std::abs(point1.x - point2.x) <= epsilon &&
std::abs(point1.y - point2.y) <= epsilon &&
std::abs(point1.z - point2.z) <= epsilon);
}
判断写好后,就可以在主函数里读取点云,在申明一个新的点云用来存公共点。
//读取点云...
// 提取两个点云的公共点
pcl::PointCloud<pcl::PointXYZRGB>::Ptr common_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
for (pcl::PointXYZRGB& point1 : *mergedCloud1)
{
for (const pcl::PointXYZRGB& point2 : *mergedCloud2)
{
if (isEqual(point1, point2))
{
common_cloud->push_back(point1);
break;
}
}
}
方法二:
使用滤波器实现,具体实现如下。
#include <iostream>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/extract_indices.h>
int main() {
// 读取第一个PLY文件
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPLYFile<pcl::PointXYZ>("cloud1.ply", *cloud1);
// 读取第二个PLY文件
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPLYFile<pcl::PointXYZ>("cloud2.ply", *cloud2);
// 创建滤波器对象,提取两个点云中的公共点云
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud(cloud1);
pass.setFilterFieldName("x");
pass.setFilterLimits(-std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity());
pass.filter(*cloud1);
pass.setInputCloud(cloud2);
pass.filter(*cloud2);
// 合并两个点云
pcl::PointCloud<pcl::PointXYZ>::Ptr merged_cloud(new pcl::PointCloud<pcl::PointXYZ>);
*merged_cloud = *cloud1 + *cloud2;
// 保存合并后的点云为新的PLY文件
pcl::io::savePLYFileBinary("merged_cloud.ply", *merged_cloud);
std::cout << "Merged cloud saved as merged_cloud.ply" << std::endl;
return 0;
}
以上就是实现公共点获取的方法,如果是三个或者多个点云的公共部分获取,可能会需要较长的时间,但是也是同理的。
草稿代码可能不是那么严谨,但运行起来问题不大。