PCL 基于反投影法寻找对应点对(Registration_CorrespondenceEstimationBackProjection)

1.原理

类似于2D下的反投影法,即基于某个特征的直方图数据,用已知图像的某些特征来突出其它图像中此类特征的一种方法。

(1)统计已知图像某个特征的直方图,PCL中通常用法向量特征来统计直方图,并把直方图表示为概率的形式。

(2)经过滤波处理后的投影数据被反投影回物体空间。这个过程是通过计算每个投影角度下射线穿过物体的路径,并将滤波后的投影数据按照这些路径均匀地分布回去,从而得到一个初步的结果。

(3)计算源点云和目标点云的直方图数据,并对二者进行点对匹配,得到最终结果。

用2D中两个手掌图像举例子:

(1)已知手掌图像A,然后通过反投影法计算它的特征直方图A_FEATURE:

(2)对另一只手掌图像B,也通过反投影法计算它的特征直方图B_FEATURE:

(3)匹配两个手掌图像的直方图特征,得到mask图像,即得到最终的点对匹配结果:

2.关键函数

(1)本类类定义

pcl::registration::CorrespondenceEstimationBackProjection<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> registration;

(2)设置源点云及目标点云法线

	registration.setSourceNormals(normalsSc);								// 设置源点云法线
	registration.setTargetNormals(normalsTr);								// 设置目标点云法线

(3)设置邻域搜索的点个数

registration.setKSearch(50);

(4)对应点结果和匹配点之间的最短距离

pcl::Correspondences correspondences;
	registration.determineCorrespondences(correspondences, 5);				// 对应点结果和匹配点之间的最短距离

3.代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/registration/correspondence_estimation_backprojection.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>

int main()
{
	/****************基于反投法寻找对应点对********************/
	pcl::PointCloud<pcl::PointXYZ>::Ptr source(new pcl::PointCloud<pcl::PointXYZ>);			// 源点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr target(new pcl::PointCloud<pcl::PointXYZ>);			// 目标点云
	pcl::io::loadPCDFile("D:/code/csdn/data/person2.pcd", *source);
	pcl::io::loadPCDFile("D:/code/csdn/data/person3.pcd", *target);

	// 基于反投法寻找对应点对
	// 对源点云进行法线估计
	pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> neSc;
	pcl::search::KdTree<pcl::PointXYZ>::Ptr treeSc(new pcl::search::KdTree<pcl::PointXYZ>);
	neSc.setNumberOfThreads(8);
	neSc.setInputCloud(source);
	neSc.setSearchMethod(treeSc);
	neSc.setKSearch(50);
	pcl::PointCloud<pcl::Normal>::Ptr normalsSc(new pcl::PointCloud<pcl::Normal>);
	neSc.compute(*normalsSc);

	// 对目标点云进行法线估计
	pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> neTr;
	pcl::search::KdTree<pcl::PointXYZ>::Ptr treeTr(new pcl::search::KdTree<pcl::PointXYZ>);
	neTr.setNumberOfThreads(8);
	neTr.setInputCloud(target);
	neTr.setSearchMethod(treeTr);
	neTr.setKSearch(50);
	pcl::PointCloud<pcl::Normal>::Ptr normalsTr(new pcl::PointCloud<pcl::Normal>);
	neTr.compute(*normalsTr);

	// 获取匹配点对
	pcl::registration::CorrespondenceEstimationBackProjection<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> registration;
	registration.setInputSource(source);
	registration.setSourceNormals(normalsSc);								// 设置源点云法线
	registration.setTargetNormals(normalsTr);								// 设置目标点云法线
	registration.setInputTarget(target);									// 设置目标点云
	registration.setKSearch(50);											// 设置邻域搜索的点个数
	pcl::Correspondences correspondences;
	registration.determineCorrespondences(correspondences, 5);				// 对应点结果和匹配点之间的最短距离

	/****************展示********************/
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("CorrespondenceEstimationBackProjection"));
	viewer->addPointCloud<pcl::PointXYZ>(source, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(source, 0, 255, 0), "source");
	viewer->addPointCloud<pcl::PointXYZ>(target, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(target, 255, 0, 0), "target");
	viewer->addCorrespondences<pcl::PointXYZ>(source, target, correspondences, "correspondence");
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return 0;
}

4.结果展示

相关原理解释:

《数值方法:原理、算法及应用》第19.3课

反向投影法

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值