下面的代码实现了ICP配准按一次空格进行配准一次的功能。
#define _USE_MATH_DEFINES
#include <math.h>
#include <iostream>
#include <string>
#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/console/time.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/common/transforms.h>
#define BOOST_TYPEOF_EMULATION
#include <pcl/registration/icp.h>
using namespace pcl;
using namespace pcl::io;
using namespace std;
void keyboardEventOccurred(const pcl::visualization::KeyboardEvent& event,
void* nothing)
{
if (event.getKeySym() == "space" && event.keyDown())
next_iteration = true;
}
int main() {
pcl::PointCloud<pcl::PointXYZ>::Ptr iphonetest7_sample_filter(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("iphonetest7_sample_filter.pcd", *iphonetest7_sample_filter) == -1) {
PCL_ERROR("Cloudn't read file!\n");
return(-1);
}
else { cout << "CAD模型的点云数量为\t" << iphonetest7_sample_filter->points.size() << endl; }
pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud_backplane(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("transformed_cloud_backplane.pcd", *transformed_cloud_backplane) == -1) {
PCL_ERROR("Cloudn't read file!\n");
return(-1);
}
else { cout << "背盖的点云数量为\t" << transformed_cloud_backplane->points.size() << endl; }
int i = 0;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tr(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("transformed_cloud_backplane.pcd", *cloud_tr) == -1) {
PCL_ERROR("Cloudn't read file!\n");
return(-1);
}
int iterations = 1;
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setMaximumIterations(iterations);
icp.setInputSource(transformed_cloud_backplane);
icp.setInputTarget(iphonetest7_sample_filter);
timer.tic();
icp.align(*transformed_cloud_backplane);
std::cout << "Applied 1 ICP iteration in " << timer.toc() << " ms" << std::endl;
i = i + 1;
std::cout << "\n" << "迭代了" << i << "次" << std::endl;
icp.setMaximumIterations(1);
if (icp.hasConverged())
{
std::cout << "ICP has converged, score is " << icp.getFitnessScore() << std::endl;
std::cout << "ICP transformation " << i << " : 背壳平面 -> 采样后的CAD模型" << std::endl;
std::cout << icp.getFinalTransformation()<< std::endl;
SUMtransform = icp.getFinalTransformation();
}
else
{
PCL_ERROR("\nICP has not converged.\n");
return (-1);
}
pcl::visualization::PCLVisualizer viewer("ICP demo");
int v1(0);
int v2(1);
viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
float bckgr_gray_level = 0.0;
float txt_gray_lvl = 1.0 - bckgr_gray_level;
pcl::visualization::PointCloudColorHandlerCustom<PointXYZ> cloud_in_color_h(iphonetest7_sample_filter, (int)255 * txt_gray_lvl, (int)255 * txt_gray_lvl,
(int)255 * txt_gray_lvl);
viewer.addPointCloud(iphonetest7_sample_filter, cloud_in_color_h, "cloud_in_v1", v1);
viewer.addPointCloud(iphonetest7_sample_filter, cloud_in_color_h, "cloud_in_v2", v2);
pcl::visualization::PointCloudColorHandlerCustom<PointXYZ> cloud_tr_color_h(cloud_tr, 20, 180, 20);
viewer.addPointCloud(cloud_tr, cloud_tr_color_h, "cloud_tr_v1", v1);
pcl::visualization::PointCloudColorHandlerCustom<PointXYZ> cloud_icp_color_h(transformed_cloud_backplane, 180, 20, 20);
viewer.addPointCloud(transformed_cloud_backplane, cloud_icp_color_h, "cloud_icp_v2", v2);
viewer.addText("White: Original point cloud\nGreen: Matrix transformed point cloud", 10, 15, 16, txt_gray_lvl, txt_gray_lvl, txt_gray_lvl, "icp_info_1", v1);
viewer.addText("White: Original point cloud\nRed: ICP aligned point cloud", 10, 15, 16, txt_gray_lvl, txt_gray_lvl, txt_gray_lvl, "icp_info_2", v2);
std::stringstream ss;
ss << iterations;
std::string iterations_cnt = "ICP iterations = " + ss.str();
viewer.addText(iterations_cnt, 10, 60, 16, txt_gray_lvl, txt_gray_lvl, txt_gray_lvl, "iterations_cnt", v2);
viewer.setBackgroundColor(bckgr_gray_level, bckgr_gray_level, bckgr_gray_level, v1);
viewer.setBackgroundColor(bckgr_gray_level, bckgr_gray_level, bckgr_gray_level, v2);
viewer.setCameraPosition(0, 0, -500, 0, 0, 0, 0);
viewer.setSize(1280, 1024);
viewer.registerKeyboardCallback(&keyboardEventOccurred, (void*)NULL);
while (!viewer.wasStopped())
{
viewer.spinOnce();
if (next_iteration)
{
timer.tic();
icp.align(*transformed_cloud_backplane);
i = i + 1;
std::cout << "\n\n" << "迭代了" << i << "次" << std::endl;
std::cout << "Applied 1 ICP iteration in " << timer.toc() << " ms" << std::endl;
if (icp.hasConverged())
{
printf("ICP has converged, score is %+.0e\n", icp.getFitnessScore());
std::cout << "ICP transformation " << i << " : 背壳平面 -> 采样后的CAD模型" << std::endl;
SUMtransform = SUMtransform * icp.getFinalTransformation();
std::cout << SUMtransform.matrix() << std::endl;
ss.str("");
iterations++;
ss << iterations;
std::string iterations_cnt = "ICP iterations = " + ss.str();
viewer.updateText(iterations_cnt, 10, 60, 16, txt_gray_lvl, txt_gray_lvl, txt_gray_lvl, "iterations_cnt");
viewer.updatePointCloud(transformed_cloud_backplane, cloud_icp_color_h, "cloud_icp_v2");
}
else
{
PCL_ERROR("\nICP has not converged.\n");
return (-1);
}
}
next_iteration = false;
}
return(0);
}