点云平面拟合和球面拟合

一、介绍

In this tutorial we learn how to use a RandomSampleConsensus with a plane model to obtain the cloud fitting to this model.

二、代码

cpp 复制代码
#include <iostream>
#include <thread>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/point_cloud.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>

using namespace std::chrono_literals;

pcl::visualization::PCLVisualizer::Ptr simpleVis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{
	pcl::visualization::PCLVisualizer::Ptr 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->addCoordinateSystem (1.0, "global");
	viewer->initCameraParameters();
	return (viewer);
}

void ranFit()
{
	bool is_plane = true;
	bool is_show_final = false;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr final(new pcl::PointCloud<pcl::PointXYZ>);

	cloud->width = 500;
	cloud->height = 1;
	cloud->is_dense = false;
	cloud->points.resize(cloud->width * cloud->height);
	for (int i = 0; i < cloud->size(); ++i)
	{
		if (is_plane==false)
		{
			// x*x+y*y+z*z=1
			(*cloud)[i].x = 2.0 * rand() / (RAND_MAX + 1.0) - 1.0;
			(*cloud)[i].y = 2.0 * rand() / (RAND_MAX + 1.0) - 1.0;
			if ((*cloud)[i].x * (*cloud)[i].x + ((*cloud)[i].y * (*cloud)[i].y) > 1)
				(*cloud)[i].z = 2.0 * rand() / (RAND_MAX + 1.0) - 1.0;
			else if (i % 2 == 0)
				(*cloud)[i].z = sqrt(1 - ((*cloud)[i].x * (*cloud)[i].x) - ((*cloud)[i].y * (*cloud)[i].y));
			else
				(*cloud)[i].z = -sqrt(1 - ((*cloud)[i].x * (*cloud)[i].x) - ((*cloud)[i].y * (*cloud)[i].y));
		}
		else
		{
			// 0.5x+0.5y-z=0
			(*cloud)[i].x = rand() / (RAND_MAX + 1.0);
			(*cloud)[i].y = rand() / (RAND_MAX + 1.0);
			if (i % 3 == 0)
				(*cloud)[i].z = rand() / (RAND_MAX + 1.0);
			else
				(*cloud)[i].z = 0.5 * (*cloud)[i].x + 0.5 * (*cloud)[i].y;
		}
	}

	std::vector<int> inliers;
	std::vector<int> outliers;
	pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr
	model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ>(cloud));
	pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr
	model_p(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud));
	Eigen::VectorXf coef;
	if (is_plane)
	{
		pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_p);
		ransac.setDistanceThreshold(.01);
		ransac.computeModel();
		ransac.getInliers(inliers);
		ransac.getModelCoefficients(coef);
	}
	else
	{
		pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_s);
		ransac.setDistanceThreshold(.01);
		ransac.computeModel();
		ransac.getInliers(inliers);
		ransac.getModelCoefficients(coef);
	}
	std::cout << coef << std::endl;
	pcl::copyPointCloud(*cloud, inliers, *final);

	pcl::visualization::PCLVisualizer::Ptr viewer;
	if (is_show_final)
		viewer = simpleVis(final);
	else
		viewer = simpleVis(cloud);
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		std::this_thread::sleep_for(100ms);
	}
}

int main()
{
	ranFit();
	return (0);
}

三、参考

How to use Random Sample Consensus model --- Point Cloud Library 0.0 documentation

相关推荐
knighthood200120 天前
Ubuntu如何显示pcl版本
pcl
boss-dog1 个月前
订阅ROS2中相机的相关话题并保存RGB、深度和点云图
pcl·ros2
黄晓魚4 个月前
MechMind结构光相机 采图SDK python调用
开发语言·图像处理·python·计算机视觉·pcl·点云处理
stay hungry foolish4 个月前
PCL + Qt + Ribbon 风格(窗口自由组合) demo展示
c++·后端·spring cloud·ribbon·vtk·pcl
coco_1998_24 个月前
Ubuntu22.04 搭建 PCL 环境(VTK源码安装),PCL测试代码
linux·vtk·点云·pcl
RobotsRuning5 个月前
Ubuntu 18.04 安装 PCL 1.14.1
c++·ubuntu·pcl
J ..5 个月前
RandLA-Net 训练自定义数据集
pcl·训练·randla-net
LiDAR点云6 个月前
PCL平面多边形可视化
点云·pcl·多边形可视化
master cat7 个月前
KDTree索引(K近邻搜索,半径R内近邻搜索)——PCL
点云·pcl·kdtree
二进制人工智能8 个月前
【PCL】(二十五)基于Min-Cut的点云分割
pcl