1. 简介
该算法根据数据集获得满足一定条件的参数估计,实现利用尽可能少的数据获得尽可能大的一致性数据集。具体来说,
- 步骤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)
- 结果