pcl 添加源点云与目标点云匹配点到Correspondences中,并用随机采样算法(ransac)筛选内点

本文介绍了一种基于点云的匹配方法,通过使用RANSAC算法进行点云配准,实现了从二维图像到三维空间的转换。示例代码展示了如何随机生成点云数据,构造目标点云,并通过RANSAC算法筛选出有效的对应点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

匹配点一般通过发现计算或者先图像匹配在通过相机坐标参数变换转化为三维对应关系。。。


#include <iostream>                 //标准输入输出头文件
#include <pcl/io/pcd_io.h>         //I/O操作头文件
#include <pcl/point_types.h>        //点类型定义头文件
#include <pcl/registration/icp.h>   //ICP配准类相关头文件
#include <pcl/registration/correspondence_rejection_sample_consensus.h>
int main(int argc, char** argv)
{
	typedef pcl::PointXYZ Point;
	//创建两个pcl::PointCloud<pcl::PointXYZ>共享指针,并初始化它们
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZ>);
// 随机填充点云
	cloud_in->width = 300;               //设置点云宽度
	cloud_in->height = 1;               //设置点云为无序点
	cloud_in->is_dense = false;
	cloud_in->points.resize(cloud_in->width * cloud_in->height);
	for (size_t i = 0; i < cloud_in->points.size(); ++i)
	{
		cloud_in->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud_in->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud_in->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
	}
	std::cout << "Saved " << cloud_in->points.size() << " data points to input:"//打印处点云总数
		<< std::endl;

	for (size_t i = 0; i < cloud_in->points.size(); ++i) std::cout << "    " <<    //打印处实际坐标
		cloud_in->points[i].x << " " << cloud_in->points[i].y << " " <<
		cloud_in->points[i].z << std::endl;
	*cloud_out = *cloud_in;
	std::cout << "size:" << cloud_out->points.size() << std::endl;

	//实现一个简单的点云刚体变换,以构造目标点云
	for (size_t i = 0; i < cloud_in->points.size(); ++i)
		cloud_out->points[i].x = cloud_in->points[i].x + 0.7f;
	std::cout << "Transformed " << cloud_in->points.size() << " data points:"
		<< std::endl;
	for (size_t i = 0; i < cloud_out->points.size(); ++i)     //打印构造出来的目标点云
		std::cout << "    " << cloud_out->points[i].x << " " <<
		cloud_out->points[i].y << " " << cloud_out->points[i].z << std::endl;
	boost::shared_ptr<pcl::Correspondences> correspondence_all(new pcl::Correspondences);
	boost::shared_ptr<pcl::Correspondences> correspondence_inlier(new pcl::Correspondences);
	pcl::Correspondences correspondences;
	//随机产生匹配点索引
	for (int i = 0; i < 20; i++)
	{
		pcl::Correspondence Correspondence;
		Correspondence.index_match = i;   //目标点云
		Correspondence.index_query = i * 3;//源点云
		correspondences.push_back(Correspondence);
	}
	*correspondence_all = correspondences;


	pcl::registration::CorrespondenceRejectorSampleConsensus<Point> ransac;
	ransac.setInputSource(cloud_in);
	ransac.setInputTarget(cloud_out);
	ransac.setMaxIterations(200);
	ransac.setInlierThreshold(3);
	ransac.getRemainingCorrespondences(*correspondence_all, *correspondence_inlier);

	std::cout << "ransac前:\n ";
	for (int i = 0; i < correspondence_inlier->size(); i++)
	{
		std::cout << "here are correspondence_inlier " << i << "index_match:" << correspondence_all->at(i).index_match << "index_query" << correspondence_all->at(i).index_query << "\n";
	}

	std::cout << "ransac后:\n ";
	for (int i = 0; i < correspondence_inlier->size(); i++)
	{
		std::cout << "here are correspondence_inlier " << i << "index_match:" << correspondence_inlier->at(i).index_match << "index_query" << correspondence_inlier->at(i).index_query << "\n";
	}
	return (0);
}
以下是使用 PCL 库实现的汉明距离特征匹配对的示例代码: ```cpp #include <pcl/features/fpfh.h> #include <pcl/features/normal_3d_omp.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/registration/correspondence_rejection_sample_consensus.h> #include <pcl/registration/icp.h> #include <pcl/visualization/pcl_visualizer.h> typedef pcl::PointXYZ PointT; typedef pcl::PointCloud<PointT> PointCloudT; typedef pcl::FPFHSignature33 FeatureT; typedef pcl::PointCloud<FeatureT> FeatureCloudT; int main(int argc, char** argv) { // 加载点云数据 PointCloudT::Ptr source_cloud(new PointCloudT); PointCloudT::Ptr target_cloud(new PointCloudT); pcl::io::loadPCDFile("source.pcd", *source_cloud); pcl::io::loadPCDFile("target.pcd", *target_cloud); // 计算法向量 pcl::NormalEstimationOMP<PointT, pcl::Normal> ne; ne.setNumberOfThreads(8); ne.setInputCloud(source_cloud); pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>()); ne.setSearchMethod(tree); pcl::PointCloud<pcl::Normal>::Ptr source_normals(new pcl::PointCloud<pcl::Normal>); ne.setRadiusSearch(0.03); ne.compute(*source_normals); ne.setInputCloud(target_cloud); pcl::PointCloud<pcl::Normal>::Ptr target_normals(new pcl::PointCloud<pcl::Normal>); ne.compute(*target_normals); // 计算特征向量 pcl::FPFHEstimation<PointT, pcl::Normal, FeatureT> fe; fe.setInputCloud(source_cloud); fe.setInputNormals(source_normals); fe.setSearchMethod(tree); FeatureCloudT::Ptr source_features(new FeatureCloudT); fe.setRadiusSearch(0.05); fe.compute(*source_features); fe.setInputCloud(target_cloud); fe.setInputNormals(target_normals); FeatureCloudT::Ptr target_features(new FeatureCloudT); fe.compute(*target_features); // 找到匹配pcl::CorrespondencesPtr correspondences(new pcl::Correspondences); for (size_t i = 0; i < source_features->size(); ++i) { int k = -1; float min_distance = std::numeric_limits<float>::max(); for (size_t j = 0; j < target_features->size(); ++j) { float distance = 0; for (int k = 0; k < 33; ++k) { if (source_features->points[i].histogram[k] != target_features->points[j].histogram[k]) { distance++; } } if (distance < min_distance) { min_distance = distance; k = j; } } if (k >= 0) { correspondences->push_back(pcl::Correspondence(i, k, min_distance)); } } // 根据匹配对进行 ICP 变换 pcl::IterativeClosestPoint<PointT, PointT> icp; icp.setInputSource(source_cloud); icp.setInputTarget(target_cloud); icp.setMaxCorrespondenceDistance(0.05); pcl::CorrespondencesPtr correspondences_filtered(new pcl::Correspondences); pcl::registration::CorrespondenceRejectorSampleConsensus<PointT>::Ptr ransac(new pcl::registration::CorrespondenceRejectorSampleConsensus<PointT>()); ransac->setInputSource(source_cloud); ransac->setInputTarget(target_cloud); ransac->setInlierThreshold(0.05); ransac->setMaximumIterations(1000); ransac->setInputCorrespondences(correspondences); ransac->getCorrespondences(*correspondences_filtered); icp.setCorrespondences(correspondences_filtered); PointCloudT::Ptr aligned_cloud(new PointCloudT); icp.align(*aligned_cloud); // 可视化结果 pcl::visualization::PCLVisualizer viewer("PCL Viewer"); viewer.addPointCloud(source_cloud, "source_cloud"); viewer.addPointCloud(target_cloud, "target_cloud"); viewer.addPointCloud(aligned_cloud, "aligned_cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "source_cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0.0, 1.0, 0.0, "target_cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0.0, 0.0, 1.0, "aligned_cloud"); viewer.spin(); return 0; } ``` 以上代码实现了通过汉明距离计算特征匹配对,并使用 ICP 算法进行配准的功能。在代码中,我们首先使用 PCL 库计算点云数据的法向量和特征向量,然后遍历所有的特征向量,计算它们之间的汉明距离,并找到它们之间的匹配对。最后,使用 ICP 算法源点目标点云进行配准,并将结果可视化展示出来。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值