PCL学习笔记--利用矩阵对点云进行刚体变换(ICP)(提醒了我很多思路)附rabbit的效果图

利用矩阵对点云进行刚体变换 
在这篇教程中,我们会学习如何用一个4*4的矩阵对点云进行变换。我们会加载一个点云,然后对其进行刚体变换(旋转加平移),并可视化结果,最后通过ICP算法对点云进行配准。

**程序**
/*
* 功能: 点云刚体变换
* 头文件: #include <pcl/common/transforms.h>
* 功能函数: pcl::transformPointCloud(*cloud, *cloudOut, transform_1);
*/
#include "stdafx.h"
#include <iostream>
#include <pcl\common\transforms.h>
#include <pcl\io\pcd_io.h>
#include <pcl\visualization\pcl_visualizer.h>
#include <pcl\registration\icp.h>


int _tmain(int argc, _TCHAR* argv[])
{
    //读入点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile("rabbit.pcd", *cloud);

    //可视化初始化
    pcl::visualization::PCLVisualizer viewer;
    viewer.setCameraFieldOfView(0.785398);//fov 45°  视场角
    viewer.setBackgroundColor(0.2, 0.2, 0.2);
    viewer.setCameraPosition(
        0, 0, 0,
        0, 0, -1,
        0, 0, 0);

    //点云旋转
    Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();//单位矩阵
    float theta = M_PI / 20;
    //给矩阵赋值
    transform_1(0, 0) = cos(theta);
    transform_1(0, 1) = -sin(theta);
    transform_1(1, 0) = sin(theta);
    transform_1(1, 1) = cos(theta);

    //沿x轴平移0.025
    transform_1(0, 3) = 0.01;
    printf("Method #1: using a Matrix4f\n");
    std::cout << transform_1 << std::endl;

    //方法2 
    Eigen::Affine3f transform_2 = Eigen::Affine3f::Identity();
    transform_2.translation() << 0.025, 0.0, 0.0;
    transform_2.rotate(Eigen::AngleAxisf(theta, Eigen::Vector3f::UnitZ()));
    // 打印变换矩阵
    printf("\nMethod #2: using an Affine3f\n");
    std::cout << transform_2.matrix() << std::endl;
    //执行变换

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOut(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::transformPointCloud(*cloud, *cloudOut, transform_1);

    //点云可视化
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> incloudHandler(cloud, 255, 255, 255);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> outcloudHandler(cloudOut, 225, 30, 30);
    viewer.addPointCloud(cloud, incloudHandler, "In");
    viewer.addPointCloud(cloudOut, outcloudHandler, "Out");
    viewer.addCoordinateSystem(0.1, "cloud", 0);

    int v2 = 1;
    viewer.createViewPort(0.5, 0, 1, 1, v2);
    viewer.createViewPortCamera(v2);
    viewer.setCameraFieldOfView(0.785398,v2);//fov 45°  视场角
    viewer.setBackgroundColor(0.0, 0.2, 1.0,v2);
    viewer.setCameraPosition(
        0, 0, 0,
        0, 0, -1,
        0, 0, 0,v2);

    // ICP  
   // pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;  
   // pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1 (new pcl::search::KdTree<pcl::PointXYZ>);  
   // tree1->setInputCloud(cloud_source);  
   // pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2 (new pcl::search::KdTree<pcl::PointXYZ>);  
   // tree2->setInputCloud(cloud_target);  
   // icp.setSearchMethodSource(tree1);  
   // icp.setSearchMethodTarget(tree2);  
   // icp.setInputSource(cloud_source);  
   // icp.setInputTarget(cloud_target);  
   // icp.setMaxCorrespondenceDistance(1500);  
   // icp.setTransformationEpsilon(1e-10);  
   // icp.setEuclideanFitnessEpsilon(0.1);  
   // icp.setMaximumIterations(300);  
   // icp.align(*cloud_source_registration);  
   // Eigen::Matrix4f transformation = icp.getFinalTransformation();

    //ICP配准
    pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
    icp.setInputSource(cloud);
    icp.setInputTarget(cloudOut);
    pcl::PointCloud<pcl::PointXYZ>::Ptr Final(new pcl::PointCloud<pcl::PointXYZ>);
    icp.align(*Final);

    std::cout << "has converged:" << icp.hasConverged() << " score: " <<
        icp.getFitnessScore() << std::endl;
    //输出最终的变换矩阵(4x4)
    std::cout << icp.getFinalTransformation() << std::endl;

    //点云可视化
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> incloudHandler1(cloud, 255, 255, 255);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> outcloudHandler1(cloudOut, 225, 30, 30);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> FinalcloudHandler1(Final, 0, 255, 0);
    //viewer.addPointCloud(cloud, incloudHandler1, "In22",v2);
    viewer.addPointCloud(cloudOut, outcloudHandler1, "Out22",v2);
    viewer.addPointCloud(Final, FinalcloudHandler1, "Final22",v2);
    viewer.addCoordinateSystem(0.1, "cloud22", v2);

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

    system("pause");
    return 0;
}

这里写图片描述 
这里写图片描述

这里写图片描述

转:https://blog.csdn.net/u014801811/article/details/79423942

猜你喜欢

转载自blog.csdn.net/eric_e/article/details/80687184