无序点云预处理

点云的预处理主要包括:点云去噪和点云的简化
点云的去噪主要是去除离群点点云的平滑处理
去除离群点方法:半径滤波和统计滤波
平滑处理方法:双边滤波和导向滤波
点云简化:体素滤波

去除背景:主要是去除地面
方法:渐进形态学滤波,平面拟合,布料法

点云体素滤波

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

using namespace std;

int
main(int argc, char** argv)
{
	// -------------------------------读入点云数据--------------------------------
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PCDReader reader;
	reader.read("data//table_scene_lms400.pcd", *cloud);
	cout << "PointCloud before filtering: " << *cloud << endl;
	// --------------------------------VoxelGrid----------------------------------
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::VoxelGrid<pcl::PointXYZ> vg;
	vg.setInputCloud(cloud);             // 输入点云
	vg.setLeafSize(0.3,0.3,0.3); // 设置最小体素边长
	vg.filter(*cloud_filtered);          // 进行滤波
	cout << "PointCloud after filtering: " << *cloud_filtered << endl;
	// ---------------------------------保存结果----------------------------------
	pcl::PCDWriter writer;
	writer.write<pcl::PointXYZ>("2f.pcd", *cloud_filtered, false);
	// ---------------------------------结果可视化--------------------------------
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ShowCloud"));

	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
	viewer->setBackgroundColor(0, 0, 0, v1);
	viewer->addText("Raw point clouds", 10, 10, "v1_text", v1);
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
	viewer->setBackgroundColor(0.1, 0.1, 0.1, v2);
	viewer->addText("filtered point clouds", 10, 10, "v2_text", v2);
	viewer->setWindowName("VoxelGrid");
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud", v1);
	viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered, "cloud_filtered", v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "sample cloud", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cloud_filtered", v2);
	//view->addCoordinateSystem(1.0);
	//view->initCameraParameters();
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return 0;
}

统计滤波

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/filters/radius_outlier_removal.h>

using namespace std;




void VisualizeCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& filter_cloud) {
    //-----------------------显示点云-----------------------
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("显示点云"));

    int v1(0), v2(0);
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer->setBackgroundColor(0, 0, 0, v1);
    viewer->addText("point clouds", 10, 10, "v1_text", v1);
    viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
    viewer->setBackgroundColor(0.1, 0.1, 0.1, v2);
    viewer->addText("filtered point clouds", 10, 10, "v2_text", v2);
   
    // 按照z字段进行渲染,将z改为x或y即为按照x或y字段渲染
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z");
    viewer->addPointCloud<pcl::PointXYZ>(cloud, fildColor, "sample cloud", v1);

    viewer->addPointCloud<pcl::PointXYZ>(filter_cloud, "cloud_filtered", v2);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cloud_filtered", v2);
   
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "cloud_out", v3);
    //viewer->addCoordinateSystem(1.0);
    //viewer->initCameraParameters();
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

int
main()
{
   // pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOrign(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    //读入点云数据
    pcl::PCDReader reader;
    reader.read<pcl::PointXYZ>("d://PCD//11.pcd", *cloud);
    cout << "Cloud before filtering:\n " << cloud->size() << endl;
    // -----------------统计滤波-------------------
    // 创建滤波器,对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1  这意味着如果一
    // 个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
    sor.setInputCloud(cloud);   //设置待滤波的点云
    sor.setMeanK(50);           //设置在进行统计时考虑查询点邻近点数
    sor.setStddevMulThresh(10);  //设置判断是否为离群点的阈值,里边的数字表示标准差的倍数,1个标准差以上就是离群点。
    //即:当判断点的k近邻平均距离(mean distance)大于全局的1倍标准差+平均距离(global distances mean and standard),则为离群点。
  

    sor.filter(*cloud_filtered); //存储内点
    cout << "Cloud after filtering: \n" << cloud_filtered->size() << endl;
    // 保存点云
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZ> ("d://filter.pcd", *cloud_filtered, true);
     // 可视化
    VisualizeCloud(cloud, cloud_filtered);

    return (0);
}


半径滤波


}

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/filters/radius_outlier_removal.h>

using namespace std;




void VisualizeCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& filter_cloud) {
    //-----------------------显示点云-----------------------
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("显示点云"));

    int v1(0), v2(0);
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer->setBackgroundColor(0, 0, 0, v1);
    viewer->addText("point clouds", 10, 10, "v1_text", v1);
    viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
    viewer->setBackgroundColor(0.1, 0.1, 0.1, v2);
    viewer->addText("filtered point clouds", 10, 10, "v2_text", v2);
   
    // 按照z字段进行渲染,将z改为x或y即为按照x或y字段渲染
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z");
    viewer->addPointCloud<pcl::PointXYZ>(cloud, fildColor, "sample cloud", v1);

    viewer->addPointCloud<pcl::PointXYZ>(filter_cloud, "cloud_filtered", v2);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cloud_filtered", v2);
   
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "cloud_out", v3);
    //viewer->addCoordinateSystem(1.0);
    //viewer->initCameraParameters();
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

int
main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    //读入点云数据
    pcl::PCDReader reader;
    reader.read<pcl::PointXYZ>("d://PCD//11.pcd", *cloud);
    cout << "Cloud before filtering:\n " << cloud->size() << endl;
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> radius;
    radius.setInputCloud(cloud);
    radius.setRadiusSearch(radius_search);
    radius.setMinNeighborsInRadius(num);
    radius.filter(*cloud_filtered);

    cout << "Cloud after filtering: \n" << cloud_filtered->size() << endl;
    // 保存点云
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZ> ("d://filter.pcd", *cloud_filtered, true);
     // 可视化
    VisualizeCloud(cloud, cloud_filtered);

    return (0);
}


导向滤波
GuildFilter.h

#pragma once
#include<pcl/point_types.h>
#include <pcl/common/centroid.h>
#include <pcl/search/kdtree.h> // for KdTree
namespace plug
{

	template<typename PointTin, typename PointTout>
	class GuildFilter : public pcl::PointCloud<PointTin>
	{
	protected:

		using SearcherPtr = typename pcl::search::Search<PointTin>::Ptr;

	public:
		// 输入点云
		inline bool
			setInputCloud(pcl::PointCloud<PointTin>::Ptr& input_cloud)
		{
			m_input = input_cloud;
			return true;
		};
		// k近邻搜索的邻域点数
		inline void
			setKsearch(int nr_k)
		{
			m_k = nr_k;
		}

		// 参数阈值
		inline void
			setEpsilonThresh(double epsilon)
		{
			m_epsilon = epsilon;
		}

		// 导向滤波实现过程
		void filter(pcl::PointCloud<PointTout>& output)
		{
			output = *m_input;
			if (!m_searcher)
				m_searcher.reset(new pcl::search::KdTree<PointTin>(false));

			m_searcher->setInputCloud(m_input);
			// The arrays to be used
			pcl::Indices nn_indices(m_k);
			std::vector<float> nn_dists(m_k);

			for (int i = 0; i < static_cast<int> (m_input->size()); ++i)
			{

				if (m_searcher->nearestKSearch(m_input->points[i], m_k, nn_indices, nn_dists) > 0)
				{
					Eigen::Vector4f point_mean;
					pcl::compute3DCentroid(*m_input, nn_indices, point_mean);

					double neigh_mean_2 = 0.0;
					for (size_t idx = 0; idx < nn_indices.size(); ++idx)
					{
						neigh_mean_2 += m_input->points[nn_indices[idx]].getVector3fMap().squaredNorm();
					}

					neigh_mean_2 /= nn_indices.size();

					double point_mean_2 = point_mean.head<3>().squaredNorm();
					double a = (neigh_mean_2 - point_mean_2) / (neigh_mean_2 - point_mean_2 + m_epsilon);
					pcl::PointXYZ b;
					b.x = (1.0 - a) * point_mean[0];
					b.y = (1.0 - a) * point_mean[1];
					b.z = (1.0 - a) * point_mean[2];


					output.points[i].x = a * m_input->points[i].x + b.x;
					output.points[i].y = a * m_input->points[i].y + b.y;
					output.points[i].z = a * m_input->points[i].z + b.z;
				}
			}
		}


	private:
		pcl::PointCloud<PointTin>::Ptr m_input;

		SearcherPtr m_searcher;
		int m_k = 20;
		double m_epsilon = 0.05;
	};
}



main

#include <iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_cloud.h>
#include"GuildFilter.h"
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

using namespace std;

int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile<pcl::PointXYZ>("bunnyAddGausiss.pcd", *cloud);
	// -----------------------------导向滤波---------------------------------
	plug::GuildFilter<pcl::PointXYZ, pcl::PointXYZ>gf;
	gf.setInputCloud(cloud);
	gf.setKsearch(20);
	gf.setEpsilonThresh(0.05);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOut(new pcl::PointCloud<pcl::PointXYZ>);
	gf.filter(*cloudOut);
	pcl::io::savePCDFileBinary("guild_filter.pcd", *cloudOut);
	// ------------------------------可视化---------------------------------
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ShowCloud"));
	viewer->setWindowName("点云导向滤波");
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
	viewer->setBackgroundColor(0, 0, 0, v1);
	viewer->addText("Raw point clouds", 10, 10, "v1_text", v1);
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
	viewer->setBackgroundColor(0.1, 0.1, 0.1, v2);
	viewer->addText("filtered point clouds", 10, 10, "v2_text", v2);
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> Color(cloud, "z");
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> FilterColor(cloudOut, "z");
	viewer->addPointCloud<pcl::PointXYZ>(cloud, Color, "sample cloud", v1);
	viewer->addPointCloud<pcl::PointXYZ>(cloudOut, FilterColor, "cloud_filtered", v2);
	
	//view->addCoordinateSystem(1.0);
	//view->initCameraParameters();
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return 0;
}


  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值