基于FPFH点云特征粗配准
#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_omp.h>
#include <pcl/features/fpfh_omp.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>
typedef pcl::PointNormal PointNT;
typedef pcl::PointCloud<PointNT> PointCloudT;
typedef pcl::FPFHSignature33 FeatureT;
typedef pcl::FPFHEstimationOMP<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>("data//registration/bun090.pcd", *object) < 0 ||
pcl::io::loadPCDFile<PointNT>("data//registration/bun045.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::NormalEstimationOMP<PointNT, PointNT> nest;
nest.setRadiusSearch(0.01);
nest.setInputCloud(scene);
nest.compute(*scene);
nest.setInputCloud(object);
nest.compute(*object);
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 * leaf);
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("Alignment");
visu.addPointCloud(scene, ColorHandlerT(scene, 0.0, 255.0, 0.0), "scene");
visu.addPointCloud(object_aligned, ColorHandlerT(object_aligned, 0.0, 0.0, 255.0), "object_aligned");
visu.spin();
}
else
{
pcl::console::print_error("Alignment failed!\n");
return (1);
}
return (0);
}
基于PCA粗配准
#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_omp.h>
#include <pcl/features/fpfh_omp.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>
#include <pcl/common/transforms.h>
#include <pcl/common/common.h>
#include <pcl/common/pca.h>
typedef pcl::PointXYZRGB PointXYZRGB;
typedef pcl::PointNormal PointNT;
typedef pcl::PointCloud<PointXYZRGB> PointCloudT;
void PCA_registration(pcl::PointCloud<PointXYZRGB>::Ptr &input_obj, pcl::PointCloud<PointXYZRGB>::Ptr &input_scene, pcl::PointCloud<PointXYZRGB>::Ptr &projected_obj, Eigen::Matrix4f &result_transform)
{
using PointType = PointXYZRGB;
pcl::PCA<PointType> pca;
pcl::PointCloud<PointType> objProj;
pca.setInputCloud(input_obj);
pca.project(*input_obj, objProj);
Eigen::Matrix3f EigenSpaceObj = pca.getEigenVectors();
Eigen::Vector3f PcaTransObj(pca.getMean()(0), pca.getMean()(1), pca.getMean()(2));
Eigen::Matrix4f transform_obj;
transform_obj << EigenSpaceObj(0, 0), EigenSpaceObj(0, 1), EigenSpaceObj(0, 2), PcaTransObj(0),
EigenSpaceObj(1, 0), EigenSpaceObj(1, 1), EigenSpaceObj(1, 2), PcaTransObj(1),
EigenSpaceObj(2, 0), EigenSpaceObj(2, 1), EigenSpaceObj(2, 2), PcaTransObj(2),
0, 0, 0, 1;
std::cout << transform_obj << std::endl;
Eigen::Matrix3f EigenSpaceObjT = EigenSpaceObj.transpose();
Eigen::Vector3f PcaTransObj_inv = -EigenSpaceObjT * PcaTransObj;
Eigen::Matrix4f transform_obj_inv;
transform_obj_inv << EigenSpaceObjT(0, 0), EigenSpaceObjT(0, 1), EigenSpaceObjT(0, 2), PcaTransObj_inv(0),
EigenSpaceObjT(1, 0), EigenSpaceObjT(1, 1), EigenSpaceObjT(1, 2), PcaTransObj_inv(1),
EigenSpaceObjT(2, 0), EigenSpaceObjT(2, 1), EigenSpaceObjT(2, 2), PcaTransObj_inv(2),
0, 0, 0, 1;
std::cout << transform_obj_inv << std::endl;
pcl::PointCloud<PointType> sceneProj;
pca.setInputCloud(input_scene);
pca.project(*input_scene, sceneProj);
Eigen::Matrix3f EigenSpaceScene = pca.getEigenVectors();
Eigen::Vector4f PcaTransScene = pca.getMean();
Eigen::Matrix4f transform_scene;
transform_scene << EigenSpaceScene(0, 0), EigenSpaceScene(0, 1), EigenSpaceScene(0, 2), PcaTransScene(0),
EigenSpaceScene(1, 0), EigenSpaceScene(1, 1), EigenSpaceScene(1, 2), PcaTransScene(1),
EigenSpaceScene(2, 0), EigenSpaceScene(2, 1), EigenSpaceScene(2, 2), PcaTransScene(2),
0, 0, 0, 1;
std::cout << transform_scene << std::endl;
result_transform = transform_scene * transform_obj_inv;
pcl::transformPointCloud(*input_obj, *projected_obj, result_transform);
pcl::io::savePCDFileBinaryCompressed("data//registration//projected.pcd", *projected_obj);
return;
};
int main(int argc, char **argv)
{
PointCloudT::Ptr object(new PointCloudT);
PointCloudT::Ptr projected_obj(new PointCloudT);
PointCloudT::Ptr scene(new PointCloudT);
pcl::io::loadPCDFile("data//registration/room_scan1.pcd", *object);
pcl::io::loadPCDFile("data//registration/room_scan2.pcd", *scene);
Eigen::Matrix4f result_transform;
PCA_registration(object, scene, projected_obj, result_transform);
return (0);
}
4PCS算法粗配准
#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_omp.h>
#include <pcl/features/fpfh_omp.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>
#include <pcl/common/transforms.h>
#include <pcl/common/common.h>
#include <pcl/common/pca.h>
typedef pcl::PointXYZ PointXYZRGB;
typedef pcl::PointCloud<PointXYZRGB> PointCloudT;
#include <pcl/registration/ia_fpcs.h>
void _4PCS(pcl::PointCloud<pcl::PointXYZ>::Ptr& target_cloud,
pcl::PointCloud<pcl::PointXYZ>::Ptr& source_cloud)
{
pcl::registration::FPCSInitialAlignment<pcl::PointXYZ, pcl::PointXYZ> fpcs;
fpcs.setInputSource(source_cloud);
fpcs.setInputTarget(target_cloud);
fpcs.setApproxOverlap(0.7);
fpcs.setDelta(0.01);
fpcs.setNumberOfSamples(100);
pcl::PointCloud<pcl::PointXYZ>::Ptr pcs(new pcl::PointCloud<pcl::PointXYZ>);
fpcs.align(*pcs);
cout << "变换矩阵:" << fpcs.getFinalTransformation() << endl;
pcl::transformPointCloud(*source_cloud, *pcs, fpcs.getFinalTransformation());
pcl::io::savePCDFileBinaryCompressed("data//registration//pcs.pcd", *pcs);
}
int main(int argc, char **argv)
{
PointCloudT::Ptr object(new PointCloudT);
PointCloudT::Ptr projected_obj(new PointCloudT);
PointCloudT::Ptr scene(new PointCloudT);
pcl::io::loadPCDFile("data//registration/bun090.pcd", *object);
pcl::io::loadPCDFile("data//registration/bun270.pcd", *scene);
Eigen::Matrix4f result_transform;
_4PCS(object, scene);
return (0);
}