三维点云变换

对三维点云可以进行旋转,平移,缩放等变换。用于表示旋转,平移,缩放等变换的矩阵的定义原理参看相机标定原理

  1. 方式1:使用Eigen::Matrix4f定义旋转平移矩阵
#include <iostream>

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/transforms.h>

using namespace std;

int main() {
    pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::io::loadPCDFile("dataset/rabbit.pcd", *point_cloud);

    // 使用旋转平移矩阵绕z轴进行变换
    
    // 定义一个4*4的单位阵
    Eigen::Matrix4f transform_matrix = Eigen::Matrix4f::Identity();
    // 旋转PI/4
    float theta = M_PI / 4;     
    transform_matrix(0, 0) = cos(theta);
    transform_matrix(0, 1) = -sin(theta);
    transform_matrix(1, 0) = sin(theta);
    transform_matrix(1, 1) = cos(theta);
    // 在 X 轴上定义一个 2.5 米的平移.
    transform_matrix(0, 3) = 2.5;

    pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::transformPointCloud(*point_cloud, *transformed_cloud, transform_matrix);

    pcl::visualization::PCLVisualizer viewer("Matrix transformation example");
    
    int v1(0), v2(1);
    viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);

    // 为点云定义 R,G,B 颜色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_cloud_color_handler(point_cloud, 255, 255, 0);
    // 输出点云到查看器,使用颜色管理
    viewer.addPointCloud(point_cloud, source_cloud_color_handler, "original_cloud", v1);

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> transformed_cloud_color_handler(transformed_cloud, 0, 255, 0);
    viewer.addPointCloud(transformed_cloud, transformed_cloud_color_handler, "transformed_cloud", v2);

    viewer.addCoordinateSystem(4.0, "cloud", 0);
    viewer.setBackgroundColor(0.05, 0.05, 0.05, 0); // 设置背景为深灰
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "transformed_cloud");

    while (!viewer.wasStopped()) { 
        viewer.spinOnce();
    }

    return 0;
}
  1. 方式2:使用Eigen::Affine3f定义旋转平移矩阵。
 // 使用旋转平移矩阵绕z轴进行变换

 // 定义一个4*4的单位阵
 Eigen::Affine3f transform_matrix = Eigen::Affine3f::Identity();
 // 绕x轴平移2.5
 transform_matrix.translation() << 2.5, 0, 0;

 float theta = M_PI / 2; 
 transform_matrix.rotate(Eigen::AngleAxisf(theta, Eigen::Vector3f::UnitZ()));
 
 pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>());
 pcl::transformPointCloud(*point_cloud, *transformed_cloud, transform_matrix);

  1. 运行结果如下所示: