Bootstrap

ROS::点云PCL(4)降采样

理解

通过体素网格实现降采样,可以减少点数量的同时,保证点云的形状特征,可以提高配准、曲面重建、形状识别等算法的速度,并保证准确性。

先来看看降采前的点云

#include <ros/ros.h> 
#include <pcl/point_cloud.h> 
#include <sensor_msgs/PointCloud2.h> 

#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>

#include <pcl/PCLPointCloud2.h>
#include <pcl/conversions.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_types_conversion.h>


main (int argc, char **argv) 
{ 

    ros::init (argc, argv, "pcl_create"); 

    ros::NodeHandle nh; 
    ros::Publisher pcl_pub = nh.advertise<sensor_msgs::PointCloud2> ("pcl_output", 1);  
	
	pcl::PCLPointCloud2 cloud;  
	sensor_msgs::PointCloud2 output;

	pcl::io::loadPCDFile("/home/zjh/cloud_test/table_scene_lms400.pcd",cloud);
	
	pcl_conversions::moveFromPCL(cloud, output); 

    output.header.frame_id = "odom"; 
    ros::Rate loop_rate(1); 

    while (ros::ok()) { 
		pcl_pub.publish(output);
		ros::spinOnce(); 
		loop_rate.sleep(); 
    } 

    return 0;
}

在这里插入图片描述

开始降采样

#include <typeinfo>
#include "boost/range.hpp"
#include <ros/ros.h> 
#include <pcl/point_cloud.h> 
#include <pcl_conversions/pcl_conversions.h> 
#include <sensor_msgs/PointCloud2.h> 

#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>

#include <iostream>
#include <vector>
#include <ctime>

#include <pcl/filters/voxel_grid.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/conversions.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_types_conversion.h>

main (int argc, char **argv) 
{ 

    ros::init (argc, argv, "pcl_create"); 

    ros::NodeHandle nh; 
    ros::Publisher pcl_pub = nh.advertise<sensor_msgs::PointCloud2> ("pcl_output", 1);  

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2 (new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);	
	pcl::PCLPointCloud2 cloud;
	sensor_msgs::PointCloud2 output;

	pcl::io::loadPCDFile("/home/zjh/cloud_test/table_scene_lms400.pcd",cloud);
	pcl::fromPCLPointCloud2 (cloud,*cloud2);
    std::cout << typeid(cloud).name() << "     "<<   typeid(*cloud2).name() <<std::endl;
   
	// 创建一个长宽高分别是3cm的体素过滤器,cloud作为输入数据,cloud_filtered作为输出数据
	float leftSize = 0.03f;

	pcl::VoxelGrid<pcl::PointXYZ> sor;
	sor.setInputCloud (cloud2);
	sor.setLeafSize (leftSize, leftSize, leftSize);
	sor.filter(*cloud_filtered);
	std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height 
       << " data points (" << pcl::getFieldsList (*cloud_filtered) << ").";
	std::cout << cloud2->width << "     "<< cloud2->height  << "   " << cloud_filtered->width <<" " << cloud_filtered->height <<std::endl;

	pcl::toROSMsg(*cloud_filtered, output); 
    output.header.frame_id = "odom"; 
    ros::Rate loop_rate(1); 

    while (ros::ok()) { 
		pcl_pub.publish(output);
		ros::spinOnce(); 
		loop_rate.sleep(); 
    } 
    return 0;
}

看一下输出:
PointCloud after filtering: 5544 data points (x y z).460400 1 5544 1
由之前的460400 个点降到了 5544个点
为了效果明显参数设置的很了点,看一下降采的效果

点的密度明显有了变化。

;