#include <Eigen/Core>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/common/time.h>
#include <pcl/console/print.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/fpfh.h>
#include <pcl/filters/filter.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/pcd_io.h>
#include <pcl/registration/icp.h>
#include <pcl/registration/sample_consensus_prerejective.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>
#pragma comment(lib,"User32.lib")
#pragma comment(lib, "gdi32.lib")
typedef pcl
::PointNormal PointNT
;
typedef pcl
::PointCloud
<PointNT
> PointCloudT
;
typedef pcl
::FPFHSignature33 FeatureT
;
typedef pcl
::FPFHEstimation
<PointNT
, PointNT
, FeatureT
> FeatureEstimationT
;
typedef pcl
::PointCloud
<FeatureT
> FeatureCloudT
;
typedef pcl
::visualization
::PointCloudColorHandlerCustom
<PointNT
> ColorHandlerT
;
int
main(int argc
, char **argv
)
{
PointCloudT
::Ptr
object(new PointCloudT
);
PointCloudT
::Ptr
object_aligned(new PointCloudT
);
PointCloudT
::Ptr
scene(new PointCloudT
);
FeatureCloudT
::Ptr
object_features(new FeatureCloudT
);
FeatureCloudT
::Ptr
scene_features(new FeatureCloudT
);
pcl
::console
::print_highlight("Loading point clouds...\n");
if (pcl
::io
::loadPCDFile
<PointNT
>("chef.pcd", *object
) < 0 ||
pcl
::io
::loadPCDFile
<PointNT
>("rs1.pcd", *scene
) < 0)
{
pcl
::console
::print_error("Error loading object/scene file!\n");
return (1);
}
pcl
::console
::print_highlight("Downsampling...\n");
pcl
::VoxelGrid
<PointNT
> grid
;
const float leaf
= 0.005f;
grid
.setLeafSize(leaf
, leaf
, leaf
);
grid
.setInputCloud(object
);
grid
.filter(*object
);
grid
.setInputCloud(scene
);
grid
.filter(*scene
);
pcl
::console
::print_highlight("Estimating scene normals...\n");
pcl
::NormalEstimation
<PointNT
, PointNT
> nest
;
nest
.setRadiusSearch(0.01);
nest
.setInputCloud(scene
);
nest
.compute(*scene
);
pcl
::console
::print_highlight("Estimating features...\n");
FeatureEstimationT fest
;
fest
.setRadiusSearch(0.025);
fest
.setInputCloud(object
);
fest
.setInputNormals(object
);
fest
.compute(*object_features
);
fest
.setInputCloud(scene
);
fest
.setInputNormals(scene
);
fest
.compute(*scene_features
);
pcl
::console
::print_highlight("Starting alignment...\n");
pcl
::SampleConsensusPrerejective
<PointNT
, PointNT
, FeatureT
> align
;
align
.setInputSource(object
);
align
.setSourceFeatures(object_features
);
align
.setInputTarget(scene
);
align
.setTargetFeatures(scene_features
);
align
.setMaximumIterations(50000);
align
.setNumberOfSamples(3);
align
.setCorrespondenceRandomness(5);
align
.setSimilarityThreshold(0.9f);
align
.setMaxCorrespondenceDistance(2.5f * 0.005);
align
.setInlierFraction(0.25f);
{
pcl
::ScopeTime
t("Alignment");
align
.align(*object_aligned
);
}
if (align
.hasConverged())
{
printf("\n");
Eigen
::Matrix4f transformation
= align
.getFinalTransformation();
pcl
::console
::print_info(" | %6.3f %6.3f %6.3f | \n", transformation(0, 0), transformation(0, 1), transformation(0, 2));
pcl
::console
::print_info("R = | %6.3f %6.3f %6.3f | \n", transformation(1, 0), transformation(1, 1), transformation(1, 2));
pcl
::console
::print_info(" | %6.3f %6.3f %6.3f | \n", transformation(2, 0), transformation(2, 1), transformation(2, 2));
pcl
::console
::print_info("\n");
pcl
::console
::print_info("t = < %0.3f, %0.3f, %0.3f >\n", transformation(0, 3), transformation(1, 3), transformation(2, 3));
pcl
::console
::print_info("\n");
pcl
::console
::print_info("Inliers: %i/%i\n", align
.getInliers().size(), object
->size());
pcl
::visualization
::PCLVisualizer
visu("点云库PCL学习教程第二版-鲁棒位姿估计");
int v1(0), v2(0);
visu
.createViewPort(0, 0, 0.5, 1, v1
);
visu
.createViewPort(0.5, 0, 1, 1, v2
);
visu
.setBackgroundColor(255, 255, 255, v1
);
visu
.addPointCloud(scene
, ColorHandlerT(scene
, 0.0, 255.0, 0.0), "scene", v1
);
visu
.addPointCloud(object_aligned
, ColorHandlerT(object_aligned
, 0.0, 0.0, 255.0), "object_aligned", v1
);
visu
.addPointCloud(object
, ColorHandlerT(object
, 0.0, 255.0, 0.0), "object_before_aligned", v2
);
visu
.addPointCloud(scene
, ColorHandlerT(scene
, 0.0, 0.0, 255.0), "scene_v2", v2
);
visu
.setPointCloudRenderingProperties(pcl
::visualization
::PCL_VISUALIZER_POINT_SIZE
, 3, "scene");
visu
.setPointCloudRenderingProperties(pcl
::visualization
::PCL_VISUALIZER_POINT_SIZE
, 3, "object_aligned");
visu
.setPointCloudRenderingProperties(pcl
::visualization
::PCL_VISUALIZER_POINT_SIZE
, 3, "object_before_aligned");
visu
.setPointCloudRenderingProperties(pcl
::visualization
::PCL_VISUALIZER_POINT_SIZE
, 3, "scene_v2");
visu
.spin();
}
else
{
pcl
::console
::print_error("Alignment failed!\n");
return (1);
}
return (0);
}