利用PCA建立点云局部坐标系

利用PCA建立点云局部坐标系

摘要

在利用给定目标模型和现场可视点云评价二者相似程度的任务中,需要确定离线模型可视点云和现场分割各部点云的局部坐标系,用于在同一坐标系下注册模型可视点云和分割点云用于后续相似性度量。本文使用PCA方法确定给定点云的特征值和特征向量,使用特征向量作为三个主轴,构建局部坐标系。对于相似的两个点云,其主轴方向是相似的,所以基于PCA的局部坐标系构建有利于提高后续使用最近邻方法选择对应点进行相似性度量的准确性。

实现

pca转换

void pca_centriod(PointCloudT::Ptr cloud_in,PointCloudT::Ptr &cloud_out)
{
	Eigen::Vector4f pcaCentroid;
	pcl::compute3DCentroid(*cloud_in, pcaCentroid);
	Eigen::Matrix3f covariance;
	pcl::computeCovarianceMatrixNormalized(*cloud_in, pcaCentroid, covariance);

	Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);
	Eigen::Matrix3f eigenVectorsPCA = eigen_solver.eigenvectors();

	Eigen::Matrix4f transform(Eigen::Matrix4f::Identity());
	transform.block<3, 3>(0, 0) = eigenVectorsPCA.transpose();
	transform.block<3, 1>(0, 3) = -1.0f * (transform.block<3, 3>(0, 0)) * (pcaCentroid.head<3>());
	pcl::transformPointCloud(*cloud_in, *cloud_out, transform);
}

测试

#include <string>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>		  
#include <vector>
#include <pcl/visualization/pcl_visualizer.h>
#include <Eigen/Core>
#include <pcl/common/transforms.h>

bool con_info = false;
using namespace std;
using namespace pcl;

typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<pcl::PointXYZ> PointCloudT;
typedef pcl::Normal NormalType;

void pca_centriod(PointCloudT::Ptr cloud_in,PointCloudT::Ptr &cloud_out)
{
	Eigen::Vector4f pcaCentroid;
	pcl::compute3DCentroid(*cloud_in, pcaCentroid);
	Eigen::Matrix3f covariance;
	pcl::computeCovarianceMatrixNormalized(*cloud_in, pcaCentroid, covariance);

	Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);
	Eigen::Matrix3f eigenVectorsPCA = eigen_solver.eigenvectors();

	Eigen::Matrix4f transform(Eigen::Matrix4f::Identity());
	transform.block<3, 3>(0, 0) = eigenVectorsPCA.transpose();
	transform.block<3, 1>(0, 3) = -1.0f * (transform.block<3, 3>(0, 0)) * (pcaCentroid.head<3>());
	pcl::transformPointCloud(*cloud_in, *cloud_out, transform);
}
void visualize_pca_centriod(PointCloudT::Ptr cloud_in, PointCloudT::Ptr &cloud_out)
{
	visualization::PCLVisualizer::Ptr view(new visualization::PCLVisualizer);
	visualization::PointCloudColorHandlerCustom<PointT>cloud_color(cloud_in, 200, 0, 0);
	visualization::PointCloudColorHandlerCustom<PointT>result_color(cloud_out, 100, 255, 200);
	view->addPointCloud(cloud_in, cloud_color, "cloud");
	view->addPointCloud(cloud_out, result_color, "result");
	view->setBackgroundColor(0, 0, 0);
	view->addCoordinateSystem(0.1f);
	while (!view->wasStopped())
	{
		view->spinOnce(100);
	}
}

int main() {
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	
	if (pcl::io::loadPCDFile("C:/Users/chensi/Desktop/data/pcl/cup.pcd", *cloud) == -1)
	{
		PCL_ERROR("filed load target point cloud \n");
		return (-1);	
	}
	PointCloudT::Ptr result(new PointCloudT);
	pca_centriod(cloud, result);
	visualize_pca_centriod(cloud, result);
	return 0;
}

结果

PCA.jpg

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wdmcs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值