利用pcl的icp方法实现对两个点云的配准及可视化显示

利用pcl的icp方法实现对两个点云的配准

1.读取点云数据

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ>);
if(argc != 3)
{
    cerr<<"输入点云数量不对!"<<endl;
    exit(1);
}

string input_filename = argv[1];
string output_filename = argv[2];

std::string format = input_filename.substr(input_filename.length()-4, 4);
std::cout<<"pointcloud format:"<<format<<std::endl;
if(format == ".ply")
{
    pcl::io::loadPLYFile(input_filename, *cloud_in);
    pcl::io::loadPLYFile(output_filename, *cloud_out);
}
else if(format == ".pcd")
{
    pcl::io::loadPCDFile(input_filename, *cloud_in);
    pcl::io::loadPCDFile(output_filename, *cloud_out);
}

2.定义icp对象

pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(cloud_in);
icp.setInputTarget(cloud_out);
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;
std::cout << icp.getFinalTransformation() << std::endl;

Eigen::Matrix4d T(4,4);
T= icp.getFinalTransformation().cast<double> ();//getFinalTransformation()输出的是float 转成double

3.可视化

pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->setBackgroundColor (0, 0, 0);

pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color1 (cloud_out, 0, 255, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color2 (Final, 255, 0, 0);
viewer->addPointCloud<pcl::PointXYZ> (cloud_out, color1, "target");
viewer->addPointCloud<pcl::PointXYZ> (Final, color2, "final");
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
viewer->addCoordinateSystem (1.0);
viewer->initCameraParameters ();

while (!viewer->wasStopped ())
{
    viewer->spinOnce (100);
    boost::this_thread::sleep (boost::posix_time::microseconds (100000));
}

结果展示

输出结果:源点云到目标点云的变换矩阵

has converged:1 score: 0.0264682
 0.918355  0.298267  -0.26012   5.70218
-0.339217    0.9318 -0.129158   9.53576
 0.203856   0.20685    0.9569  -0.52615
        0         0         0         1

配准前:
在这里插入图片描述
配准后
在这里插入图片描述

附上完整代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/registration/icp.h>
#include <pcl/io/ply_io.h>
#include <string>
#include <pcl/visualization/pcl_visualizer.h>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/Dense>
using namespace std;


int main (int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ>);
    if(argc != 3)
    {
        cerr<<"输入点云数量不对!"<<endl;
        exit(1);
    }

    string input_filename = argv[1];
    string output_filename = argv[2];

    std::string format = input_filename.substr(input_filename.length()-4, 4);
    std::cout<<"pointcloud format:"<<format<<std::endl;
    if(format == ".ply")
    {
        pcl::io::loadPLYFile(input_filename, *cloud_in);
        pcl::io::loadPLYFile(output_filename, *cloud_out);
    }
    else if(format == ".pcd")
    {
        pcl::io::loadPCDFile(input_filename, *cloud_in);
        pcl::io::loadPCDFile(output_filename, *cloud_out);
    }


    pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
    //将输入点云对齐到输出点云上
    icp.setInputSource(cloud_in);
    icp.setInputTarget(cloud_out);
    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;
    std::cout << icp.getFinalTransformation() << std::endl;

    Eigen::Matrix4d T(4,4);
    T= icp.getFinalTransformation().cast<double> ();//getFinalTransformation()输出的是float 转成double

    //cout << T.block<3,3>(0,0) << endl << endl;
    Eigen::Matrix3d R = T.block<3,3>(0,0);// = Eigen::Matrix3f::Identity();
    Eigen::Quaterniond q = Eigen::Quaterniond(R);
    cout<<"R = \n"<<R<<endl;
    cout<<"Quaternion = \n"<<q.coeffs()<<endl;

    Eigen::MatrixXd t_mat  = T.topRightCorner(3, 1).transpose();
    Eigen::Vector3d t;
    t<<t_mat(0), t_mat(1), t_mat(2);
    cout<<"t = "<<t<<endl;

    ofstream outfile("Transform.txt");
    if(!outfile)
    {
        cerr<<"open error!"<<endl;
        exit(1);
    }
    outfile<<icp.getFinalTransformation();
    outfile.close();

    //对点云进行旋转 结果与icp计算的相同
    //pcl::transformPointCloud(*cloud_in, *cloud_tran, T);

    //点云可视化
    pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
    viewer->setBackgroundColor (0, 0, 0);

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color1 (cloud_out, 0, 255, 0);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color2 (Final, 255, 0, 0);
    viewer->addPointCloud<pcl::PointXYZ> (cloud_out, color1, "target");
    viewer->addPointCloud<pcl::PointXYZ> (Final, color2, "final");
    viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
    viewer->addCoordinateSystem (1.0);
    viewer->initCameraParameters ();

    while (!viewer->wasStopped ())
    {
        viewer->spinOnce (100);
        boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }
    return (0);
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

project(icp)
find_package(PCL 1.7 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
add_executable (icp main.cpp)
target_link_libraries (icp ${PCL_LIBRARIES})
  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值