zoukankan      html  css  js  c++  java
  • PCL学习(三) SAC-IA 估记object pose

    SAC-IA是基于RANSAC算法的对齐算法

    通过降采样提高法向计算、FPFH特征的计算

    最后通过SAC-IA计算得到对齐的旋转和平移

    #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 <string>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    // Types
    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;
    
    //handle the param of the align in the txt to save the fucking time of complie
    int parseConfigFile(
    	const std::string &filepath,
    	char *objFile,
    	char *sceFile,
    	float *downLeaf
    );
    
    
    // Align a rigid object to a scene with clutter and occlusions
    int main(int argc, char **argv)
    {
    	// Point clouds
    	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);
    
    	// Get input object and scene
    	/*if (argc != 3)
    	{
    	pcl::console::print_error("Syntax is: %s object.pcd scene.pcd
    ", argv[0]);
    	return (1);
    	}*/
    	/*std::string paramFilePath = "data/param.txt";
    	char *obj_filepath = { '' };
    	char *sce_filepath = { '' };
    	float *downsample_leaf = nullptr;
    	parseConfigFile(
    	paramFilePath,
    	obj_filepath,
    	sce_filepath,
    	downsample_leaf
    	);*/
    
    
    	// Load object and scene
    	pcl::console::print_highlight("Loading point clouds...
    ");
    	if (pcl::io::loadPCDFile<PointNT>("data/obj_seg.pcd", *object) < 0 ||//"data/obj_seg.pcd"
    		pcl::io::loadPCDFile<PointNT>("data/sce_seg.pcd", *scene) < 0)   //"data/sce_seg.pcd"
    	{
    		pcl::console::print_error("Error loading object/scene file!
    ");
    		return (1);
    	}
    
    	// Downsample
    	pcl::console::print_highlight("Downsampling...
    ");
    	pcl::VoxelGrid<PointNT> grid;
    	const float leaf = 0.08f;//0.005f == resolution of 5mm
    	grid.setLeafSize(leaf, leaf, leaf);
    	grid.setInputCloud(object);
    	grid.filter(*object);
    	grid.setInputCloud(scene);
    	grid.filter(*scene);
    
    	// Estimate normals for scene
    	pcl::console::print_highlight("Estimating scene normals...
    ");
    	pcl::NormalEstimationOMP<PointNT, PointNT> nest;
    	nest.setRadiusSearch(0.01);
    	nest.setInputCloud(scene);
    	nest.compute(*scene);
    
    	// Estimate features
    	pcl::console::print_highlight("Estimating features...
    ");
    	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);
    
    	// Perform alignment
    	pcl::console::print_highlight("Starting alignment...
    ");
    	pcl::SampleConsensusPrerejective<PointNT, PointNT, FeatureT> align;
    	align.setInputSource(object);
    	align.setSourceFeatures(object_features);
    	align.setInputTarget(scene);
    	align.setTargetFeatures(scene_features);
    	align.setMaximumIterations(100000); // Number of RANSAC iterations 50000
    	align.setNumberOfSamples(3); // Number of points to sample for generating/prerejecting a pose
    	align.setCorrespondenceRandomness(5); // Number of nearest features to use
    	align.setSimilarityThreshold(0.9f); // Polygonal edge length similarity threshold
    	align.setMaxCorrespondenceDistance(2.5f * leaf); // Inlier threshold
    	align.setInlierFraction(0.25f); // Required inlier fraction for accepting a pose hypothesis
    	{
    		pcl::ScopeTime t("Alignment");
    		align.align(*object_aligned);
    	}
    
    	if (align.hasConverged())
    	{
    		// Print results
    		printf("
    ");
    		Eigen::Matrix4f transformation = align.getFinalTransformation();
    		pcl::console::print_info("    | %6.3f %6.3f %6.3f | 
    ", transformation(0, 0), transformation(0, 1), transformation(0, 2));
    		pcl::console::print_info("R = | %6.3f %6.3f %6.3f | 
    ", transformation(1, 0), transformation(1, 1), transformation(1, 2));
    		pcl::console::print_info("    | %6.3f %6.3f %6.3f | 
    ", transformation(2, 0), transformation(2, 1), transformation(2, 2));
    		pcl::console::print_info("
    ");
    		pcl::console::print_info("t = < %0.3f, %0.3f, %0.3f >
    ", transformation(0, 3), transformation(1, 3), transformation(2, 3));
    		pcl::console::print_info("
    ");
    		pcl::console::print_info("Inliers: %i/%i
    ", align.getInliers().size(), object->size());
    
    		// Show alignment
    		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();
    		system("PAUSE");
    	}
    	else
    	{
    		pcl::console::print_error("Alignment failed!
    ");
    		system("PAUSE");
    		return (1);
    	}
    
    	return (0);
    }
    
    int parseConfigFile(
    	const std::string &filepath,
    	char *objFile,
    	char *sceFile,
    	float *downLeaf
    )
    {
    	// open the configuration file
    	FILE *file = fopen(filepath.c_str(), "r");
    	//FILE *stream;//test
    	if (!file)
    	{
    		fprintf(stderr, "Cannot parse configuration file "%s".
    ",
    			filepath.c_str());
    		exit(1);
    	}
    	//read parameters
    	char buf[256];
    	while (fscanf(file, "%s", buf) != EOF) {
    		switch (buf[0]) {
    		case '#':
    			fgets(buf, sizeof(buf), file);
    			break;
    		case'o':
    			fgets(buf, sizeof(buf), file);
    			memcpy(objFile, buf + 1, strlen(buf) - 2);
    			//printf("%s", objFile);
    			break;
    		case's':
    			fgets(buf, sizeof(buf), file);
    			memcpy(sceFile, buf + 1, strlen(buf) - 2);
    			break;
    		case'l':
    			fscanf(file, "%f", downLeaf);
    		}
    	}
    	return 0;
    
    } 

     

    对齐前的点云数据(采集于两帧kinect的扫描深度图)

    对齐后的结果

    对齐的旋转和平移,以及对齐速度

  • 相关阅读:
    [转]了解ASP.NET MVC几种ActionResult的本质:EmptyResult & ContentResult
    [转]XPath 语法
    [转]XSL 语言
    [转]项目经理面试指南
    [转]《精通css》笔记1:css选择器与优先级
    [转]jQuery 简介
    [转]Android 70道面试题
    [书目20130316].NET应用架构设计:原则、模式与实践
    [转]XPath语法 在C#中使用XPath示例
    [转]Android面试3
  • 原文地址:https://www.cnblogs.com/BambooEatPanda/p/8184895.html
Copyright © 2011-2022 走看看