来自pcl点库从入门到精通
- 提取指定区域
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/io/pcd_io.h>
using namespace std;
using namespace pcl;
boost::shared_ptr<pcl::visualization::PCLVisualizer> Simple_viwer(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud,const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud2){
//创建句柄
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
viewer->initCameraParameters ();
int v1(0),v2(1);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
//设置背景颜色
viewer->setBackgroundColor(0,0,0,v1);
viewer->setBackgroundColor(0,0,0,v2);
//添加点云
viewer->addPointCloud<pcl::PointXYZ>(cloud,"all data",v1);
viewer->addPointCloud<pcl::PointXYZ>(cloud2,"filter data",v2);
//设置点云属性
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"all data",v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"filter data",v2);
//显示坐标系
viewer->addCoordinateSystem(1.0,v1);
viewer->addCoordinateSystem(1.0,v2);
//初始化相机位置
return(viewer);
}
int main(int argc, const char** argv) {
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>());
PointCloud<PointXYZ>::Ptr cloudout(new PointCloud<PointXYZ>());
PointCloud<PointXYZ>::Ptr cloudextract(new PointCloud<PointXYZ>());
PointCloud<PointXYZ>::Ptr cloudouter(new PointCloud<PointXYZ>());
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());//系数
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
//ModelCoefficients:以下两部分
// ::pcl::PCLHeader header;
// std::vector<float> indices;
pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());//内点索引
//PointIndices:以下两部分构成
// ::pcl::PCLHeader header;
// std::vector<int> indices;
PCDReader rd;
rd.read("/home/n1/notes/pcl/extract/test.pcd",*cloud);
//离群点
StatisticalOutlierRemoval<PointXYZ> SOR;// 初始化对像
SOR.setInputCloud(cloud);
SOR.setMeanK(50); ///最临近距离求取均值点的个数
SOR.setStddevMulThresh(1); //设置阈值 阈值=均值+设置系数*标准差 小于阈值为内点,大于阈值为离群点
SOR.filter(*cloud);
//降采样
VoxelGrid<PointXYZ> VOX;
VOX.setLeafSize(0.01f,0.01f,0.01f);
VOX.setInputCloud(cloud);
VOX.filter(*cloudout);
//点云分割
pcl::SACSegmentation<PointXYZ> seg;
seg.setOptimizeCoefficients(true); //细化系数
seg.setModelType(SACMODEL_PLANE); //设置切割的类型
seg.setMethodType (pcl::SAC_RANSAC);
seg.setMaxIterations(1000); //最大迭代次数
seg.setDistanceThreshold(0.01); //距离阈值
//创建滤波器对象
pcl::ExtractIndices<PointXYZ> extract;
int i=0;
int filter_size=cloudout->size();
while(cloudout->size()>0.3*filter_size){//点云剩余大小超过0.3
PointCloud<PointXYZ>::Ptr temp(new PointCloud<PointXYZ>());
seg.setInputCloud(cloudout);
seg.segment(*inliers,*coefficients); //内点和系数
if (inliers->indices.size () == 0)
{
std::cerr << "已经无法分割." << std::endl;
break;
}
//提取内部点云
extract.setInputCloud(cloudout);
extract.setIndices(inliers); //索引点
extract.setNegative(false); //false 提取 true 剔除
extract.filter(*temp);
*cloudextract+=*temp;
std::cerr << "平面点云大小::"<<cloudextract->size() << std::endl;
//提取外部
extract.setNegative (true);
extract.filter (*cloudouter);
cloudout.swap (cloudouter); //删除一寸部分
}
viewer=Simple_viwer(cloud,cloudextract);
while (!viewer->wasStopped ())
{
viewer->spinOnce (100);
boost::this_thread::sleep (boost::posix_time::microseconds (100000));
}
return 0;
}
- 条件剔除&半径剔除
半径剔除:剔除在点指定邻域半径R内,点的数量少于指定数量的点
条件剔除:注意如何设置条件
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
using namespace pcl;
using namespace std;
void create_points(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud){
srand((unsigned int)time(0));
cloud->width=30;
cloud->height=1;
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.0f);
cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
}
}
boost::shared_ptr<pcl::visualization::PCLVisualizer> Simple_viwer(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud,const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud2,const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud3){
//创建句柄
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
viewer->initCameraParameters ();
int v1(0),v2(1),v3(2);
viewer->createViewPort(0.0, 0.0, 0.33, 1.0, v1);
viewer->createViewPort(0.33, 0.0, 0.66, 1.0, v2);
viewer->createViewPort(0.66, 0.0, 1, 1.0, v3);
//设置背景颜色
viewer->setBackgroundColor(0,0,0,v1);
viewer->setBackgroundColor(0,0,0,v2);
viewer->setBackgroundColor(0,0,0,v3);
//添加点云
viewer->addPointCloud<pcl::PointXYZ>(cloud,"all data",v1);
viewer->addPointCloud<pcl::PointXYZ>(cloud2,"filter data",v2);
viewer->addPointCloud<pcl::PointXYZ>(cloud3,"filter1 data",v3);
//设置点云属性
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"all data",v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"filter data",v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1,"filter1 data",v3);
//显示坐标系
viewer->addCoordinateSystem(1.0,v1);
viewer->addCoordinateSystem(1.0,v2);
viewer->addCoordinateSystem(1.0,v3);
//初始化相机位置
return(viewer);
}
int main(int argc,char** argv){
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>());
PointCloud<PointXYZ>::Ptr cloudout(new PointCloud<PointXYZ>());
PointCloud<PointXYZ>::Ptr cloudout2(new PointCloud<PointXYZ>());
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("simple viewer"));
pcl::RadiusOutlierRemoval<pcl::PointXYZ> ROR;//初始化对象
create_points(cloud);
ROR.setInputCloud(cloud); //输入点云
ROR.setRadiusSearch(0.8); //搜索半径
ROR.setMinNeighborsInRadius(2); //在半径点内临近点个数少于该值的点会被删除
ROR.filter(*cloudout);
pcl::ConditionAnd<PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<PointXYZ>()); //创建条件 ConditionOr或
range_cond->addComparison(pcl::FieldComparison<PointXYZ>::ConstPtr (new pcl::FieldComparison<PointXYZ>("z",pcl::ComparisonOps::GT,0.0)));//大于0.0
//pcl::ComparisonOps
// GT:大于, GE:大于等于 LT:小于 LE:小于等于 EQ:等于
range_cond->addComparison(pcl::FieldComparison<PointXYZ>::ConstPtr(new pcl::FieldComparison<PointXYZ>("z",pcl::ComparisonOps::LE,0.5)));//小于0.5
pcl::ConditionalRemoval<PointXYZ> COND(range_cond);//创建滤波器
COND.setInputCloud(cloud);
COND.setKeepOrganized(true); //是否保存剔除点,默认false:剔除 可能会破坏结构 true:重定义点,保存原始结构
COND.filter(*cloudout2);
viewer=Simple_viwer(cloud,cloudout,cloudout2);
while(!viewer->wasStopped()){
viewer->spinOnce();
boost::this_thread::sleep (boost::posix_time::microseconds (100000));
}
return 0;
}