一、简介
点云采样一般有三种方式,上采样,下采样,平均采样
原理介绍
下采样:
一般是采样是通过构建一个三维体素的格栅,然后在每个体素内用体素的重心近似的作为这个体素的整体特征,也就是说用这一个体素的重心来表示这个体素内的所有点。这样我们正在处理点云的过程中就会起到滤波的作用,同时也减少了很多数据在点云配准的过程当中大大加快了速度。
上采样:
类似于二维图像中的线性插值等,上采样是在增加点的个数,我们可以细想一下,一个点云中当点间距足够小的时候,点会连接起来这样的话就形参了一个曲面,因此上采样从另外一种程度上来说也可以说的是曲面重建的一种方式
有步骤如下
1、创建一个采样的对象
2、创建kdtree
3、设置 kdtree 的搜索范围
4、设置采样对象的方法
5、设置采样对象的半径和步长
6、开始上采样
二、降(下)采样
核心代码:
pcl::PointCloud<pcl::PointXYZ>::Ptr newcloud(new pcl::PointCloud<pcl::PointXYZ>);
// 对这个点云进行下采样
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(m_current_cloud);
sor.setLeafSize(0.1f,0.1f,0.1f); // 采样间隔
sor.filter(*newcloud); // 采样 并输出到新的点云里面
整体代码:
#if 1 // 点云下采样
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr m_current_cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (-1 == pcl::io::loadPCDFile("empty desktop.pcd", *m_current_cloud))//放到与工程中的主.cpp同一位置的文件夹下
{
cout << "加载文件失败!" << endl;
return -1;
}
cout << "原始点云的点数: " << m_current_cloud->points.size() << endl;
pcl::PointCloud<pcl::PointXYZ>::Ptr newcloud(new pcl::PointCloud<pcl::PointXYZ>);
// 对这个点云进行下采样
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(m_current_cloud);
sor.setLeafSize(0.1f,0.1f,0.1f); // 采样间隔
sor.filter(*newcloud); // 采样 并输出到新的点云里面
cout <<"降采样之后的点云的点数: " << newcloud->points.size() << endl;
// 可视化
// boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("Normal viewer"));
pcl::visualization::PCLVisualizer viewer("demo");
// 设置点云的显示两个点云到同一个viewer 中
int v1(0);
int v2(1);
viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
// 设置点云颜色
float bckgr_gray_level = 0.0;
float txt_gray_lvl = 1.0 - bckgr_gray_level;
// 显示原始点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_in_color_h(m_current_cloud, (int)255 * txt_gray_lvl, (int)255 * txt_gray_lvl, (int)255 * txt_gray_lvl);
viewer.addPointCloud(m_current_cloud, cloud_in_color_h, "cloud_in_v1", v1);
// 显示降采样之后的滤波
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_green(newcloud, 50, 180, 70);
viewer.addPointCloud(newcloud, cloud_out_green, "cloud_out", v2);
// 这种背景 只设置
viewer.setBackgroundColor(bckgr_gray_level, bckgr_gray_level, bckgr_gray_level, v2);
// 这种vtk窗口的大小
viewer.setSize(1280, 1024);
// 点云显示
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return 0;
}
#endif