PCL入门(五):随机采样一致性算法RANSAC简单使用

1. 简介

参考博客《随机抽样一致性(RANSAC)算法详解》

该算法根据数据集获得满足一定条件的参数估计,实现利用尽可能少的数据获得尽可能大的一致性数据集。具体来说,

  • 步骤1:从数据集中随机获得一定量的数据;
  • 步骤2:根据获取数据,做参数估计,并拟合模型;
  • 步骤3:计算数据集中的每一个点在该模型下的距离或者损失,据此将数据集分为内部点集合和外部点集合;
  • 步骤4:若迭代次数未超过阈值,则返回步骤1;
  • 步骤5:将内部点集合中数据最多的模型作为最终输出模型
    在这里插入图片描述

2. 简单使用

给定一个球形点云,其中有部分噪声点云,希望对点云做处理,拿到球形点云,如下
在这里插入图片描述
主要参考双愚的代码

  • random_sample_consensus.cpp
#include <iostream>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/sample_consensus/sac_model_sphere.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

// 定义3d点云显示函数
boost::shared_ptr<pcl::visualization::PCLVisualizer> simpleVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{
    
    
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor (0, 0, 0);
	viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
	viewer->initCameraParameters();
	return (viewer);
}

int main(int argc, char** argv)
{
    
    
	// 步骤一:定义球形点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr final_cloud (new pcl::PointCloud<pcl::PointXYZ>);
	cloud->width = 500;
	cloud->height = 1;
	cloud->is_dense = false;
	cloud->points.resize(cloud->width * cloud->height);
	for (size_t i=0; i<cloud->points.size(); ++i)
	{
    
    
		cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0);
		cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0);
		if (i % 5 == 0)
		{
    
    
			cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0); //噪声点的z轴数据
		}
		else if (i % 2 == 0)
		{
    
    
			cloud->points[i].z = sqrt(1 - (cloud->points[i].x * cloud->points[i].x) - (cloud->points[i].y * cloud->points[i].y)); //球形点云的z轴数据
		}
		else
		{
    
    
			cloud->points[i].z = -sqrt(1 - (cloud->points[i].x * cloud->points[i].x) - (cloud->points[i].y * cloud->points[i].y)); //球形点云的z轴数据
		}
	}
	
	std::vector<int> inliers; // RANSAC算法的内部点数据集
	
	// 步骤二:定义RANSAC算法
	pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ>(cloud));
	pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_s);
	ransac.setDistanceThreshold(0.01);
	ransac.computeModel(); // ransac算法结果
	ransac.getInliers(inliers); //将算法结果给inliers
	
	// 步骤三:可视化
	pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *final_cloud); //将算法结果嵌入到final_cloud点云中
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
	viewer = simpleVis(final_cloud);
	//viewer = simpleVis(cloud);
	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 FATAL_ERROR)

project(cloud_viewer)

find_package(PCL 1.2 REQUIRED)

add_executable(random_sample_consensus random_sample_consensus.cpp)
target_link_libraries(random_sample_consensus ${PCL_LIBRARIES} pthread boost_thread)

  • 结果
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_30841655/article/details/132824919