点云处理相关程序(1)

点云处理相关程序(1)

本文所运行的程序均在Ubuntu编译通过,源码分为CMakeLists以及各功能源码
需要读者事先安装好pcl点云库
Ubuntu环境下,将所有源码放于同一目录,运行命令即可:

mkdir build
cd build
cmake ..
make
./aaa bbb.pcd

其中、aaa表示可执行程序,bbb表示需要处理的pcd点云数据

直接上代码。

(1)CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "-std=c++11 -O2")
find_package(PCL REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable(passthrough passthrough.cpp)
target_link_libraries(passthrough ${PCL_LIBRARIES})

add_executable(voxel voxel.cpp)
target_link_libraries(voxel ${PCL_LIBRARIES})

add_executable(statistical statistical.cpp)
target_link_libraries(statistical ${PCL_LIBRARIES})

add_executable(outrem outrem.cpp)
target_link_libraries(outrem ${PCL_LIBRARIES})

add_executable(xyz xyz.cpp)
target_link_libraries(xyz ${PCL_LIBRARIES})

add_executable(poisson poisson.cpp)
target_link_libraries(poisson ${PCL_LIBRARIES})

add_executable(viewpcl viewpcl.cpp)
target_link_libraries(viewpcl ${PCL_LIBRARIES})

add_executable(section1 section1.cpp)
target_link_libraries(section1 ${PCL_LIBRARIES})

add_executable(section2 section2.cpp)
target_link_libraries(section2 ${PCL_LIBRARIES})

add_executable(plytopcd plytopcd.cpp)
target_link_libraries(plytopcd ${PCL_LIBRARIES})

add_executable(pcdtoply pcdtoply.cpp)
target_link_libraries(pcdtoply ${PCL_LIBRARIES})

add_executable(changexyz changexyz.cpp)
target_link_libraries(changexyz ${PCL_LIBRARIES})

add_executable(correctxyz correctxyz.cpp)
target_link_libraries(correctxyz ${PCL_LIBRARIES})

(2)点云可视化viewpcl.cpp

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
using namespace std;
float max_x;
float min_x;
float max_y;
float min_y;
float max_z;
float min_z;

int main(int argc,char **argv) {
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1],*cloud_in);
 
    //可视化pcd
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
 
    viewer->initCameraParameters();
 	
    std::cout<<"open succeed"<<std::endl;
    //输出点云三个维度最大值/最小值
    max_x = cloud_in->points[0].x;
    min_x = cloud_in->points[0].x;

    max_y = cloud_in->points[0].y;
    min_y = cloud_in->points[0].y;

    max_z = cloud_in->points[0].z;
    min_z = cloud_in->points[0].z;
	
    for(size_t i=0;i<cloud_in->points.size();++i)
    {
		if(cloud_in->points[i].x >= max_x)
		{
			max_x = cloud_in->points[i].x;
		}
		if(cloud_in->points[i].x <= min_x)
		{
			min_x = cloud_in->points[i].x;
		}

		if(cloud_in->points[i].y >= max_y)
		{
			max_y = cloud_in->points[i].y;
		}
		if(cloud_in->points[i].y <= min_y)
		{
			min_y = cloud_in->points[i].y;
		}

		if(cloud_in->points[i].z >= max_z)
		{
			max_z = cloud_in->points[i].z;
		}
		if(cloud_in->points[i].z <= min_z)
		{
			min_z = cloud_in->points[i].z;
		}
    }
    std::cout<<"Finished"<<std::endl;
    std::cout<<"pointx:("<<min_x<<","<<max_x<<")"<<std::endl;
    std::cout<<"pointy:("<<min_y<<","<<max_y<<")"<<std::endl;
    std::cout<<"pointz:("<<min_z<<","<<max_z<<")"<<std::endl;

    int v1(0);
    viewer->createViewPort(0,0,1,1,v1);
    viewer->setBackgroundColor(0,0,0,v1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud_in,255,255,255);//统一显示黑色
    //pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> rgb(cloud_in, "z");//z方向渐变色
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color,"cloud_in",v1);//注意此处的显示点云名称
    viewer->addCoordinateSystem(1);
    viewer->spin();
    return 0;

(3)直通滤波passthrough.cpp

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>//直通滤波器文件
#include <pcl/visualization/pcl_visualizer.h>
 
int main(int argc,char **argv) {
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1],*cloud_in);
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    cloud_filtered->width = cloud_in->width;
    cloud_filtered->height = cloud_in->height;
    cloud_filtered->is_dense = false;
    cloud_filtered->resize(cloud_filtered->height*cloud_filtered->width);
 
    //直通滤波
    pcl::PassThrough<pcl::PointXYZ> pass; //实例化直通滤波器
    pass.setInputCloud(cloud_in); //设置输入点云
    pass.setFilterFieldName("z");//设置滤波的field
    pass.setFilterLimits(1.7,2.5);//上述field的滤波范围
    pass.setFilterLimitsNegative(false);//设置要保存哪一部分点云,默认为false(field范围内部的点云)
    pass.filter(*cloud_filtered);//输出点云到*cloud_filtered

    //save cloud_filtered.pcd
    pcl::io::savePCDFileASCII("./cloud_filtered.pcd",*cloud_filtered);
    std::cout<<"save succeed"<<std::endl;
 
    //可视化pcd
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
 
    viewer->initCameraParameters();
 
 
    int v1(0);
    viewer->createViewPort(0,0,0.5,1,v1);
    viewer->setBackgroundColor(0,0,0,v1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud_filtered,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered,single_color,"cloud_filtered",v1);//注意此处的显示点云名称
 
    int v2(0);
    viewer->createViewPort(0.5,0,1,1,v2);
    viewer->setBackgroundColor(0,0,0,v2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v2);//PCL_Visualizer类大多数函数会有一个view_port,这个一定要加上,否则会出现点云不按照自己的目的显示的问题
 
    viewer->addCoordinateSystem(1);
     viewer->spin();
    return 0;
}


(4)体素滤波voxel.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>

int main (int argc, char** argv)
{
  pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
  pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());

  // Fill in the cloud data
  pcl::PCDReader reader;
  // Replace the path below with the path where you saved your file
  //reader.read ("./result.pcd", *cloud); // Remember to download the file first!
  reader.read (argv[1], *cloud); // Remember to download the file first!
  std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height 
       << " data points (" << pcl::getFieldsList (*cloud) << ").";

  // Create the filtering object
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud (cloud);
  sor.setLeafSize (0.03f, 0.03f, 0.03f);
  sor.filter (*cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height 
       << " data points (" << pcl::getFieldsList (*cloud_filtered) << ").";

  pcl::PCDWriter writer;
  writer.write ("result_voxel.pcd", *cloud_filtered, 
         Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false);

  return (0);
}


(5)统计滤波statistical.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>	//统计滤波器头文件

//统计滤波器
int main(int argc, char **argv)
{
	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>(argv[1], *cloud);
 
	std::cerr << "Cloud before filtering: " << std::endl;
	std::cerr << *cloud << std::endl;
 
	// 创建滤波器,对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1  这意味着如果一
	//个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;  //创建滤波器对象
	sor.setInputCloud(cloud);                           //设置待滤波的点云
	sor.setMeanK(30);                               	//设置在进行统计时考虑查询点临近点数
	sor.setStddevMulThresh(1.0);                      	//设置判断是否为离群点的阀值
	sor.filter(*cloud_filtered);                    	//存储
  
	std::cerr << "Cloud after filtering: " << std::endl;
	std::cerr << *cloud_filtered << std::endl;
	
	//保存滤波后的点云
	pcl::PCDWriter writer;
	writer.write<pcl::PointXYZ>("after_filter.pcd", *cloud_filtered, false);
 
	//sor.setNegative(true);
	//sor.filter(*cloud_filtered);
	//writer.write<pcl::PointXYZ>("1_outliers.pcd", *cloud_filtered, false);
 
	return (0);
}


(6)半径滤波outrem.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>	//统计滤波器头文件

//统计滤波器
int main(int argc, char **argv)
{
	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>(argv[1], *cloud);
 
	std::cerr << "Cloud before filtering: " << std::endl;
	std::cerr << *cloud << std::endl;

     pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
     outrem.setInputCloud(cloud);
	outrem.setRadiusSearch(0.04);//设置在0.04半径的范围内找邻近点
	outrem.setMinNeighborsInRadius(8);//设置查询点的邻近点集数小于8的删除
	outrem.filter(*cloud_filtered);

	
	//保存滤波后的点云
	pcl::PCDWriter writer;
	writer.write<pcl::PointXYZ>("outrem_filter.pcd", *cloud_filtered, false);
 
	//sor.setNegative(true);
	//sor.filter(*cloud_filtered);
	//writer.write<pcl::PointXYZ>("1_outliers.pcd", *cloud_filtered, false);
 
	return (0);
}


(7)手动点云切片与拼接section1.cpp

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>//直通滤波器文件
#include <pcl/visualization/pcl_visualizer.h>
 
float max_x;
float min_x;
float max_y;
float min_y;
float max_z;
float min_z;
float step;
int main(int argc,char **argv) {
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1],*cloud_in);
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    cloud_filtered->width = cloud_in->width;
    cloud_filtered->height = cloud_in->height;
    cloud_filtered->is_dense = false;
    cloud_filtered->resize(cloud_filtered->height*cloud_filtered->width);
 
    //输出点云三个维度最大值/最小值
    max_x = cloud_in->points[0].x;
    min_x = cloud_in->points[0].x;

    max_y = cloud_in->points[0].y;
    min_y = cloud_in->points[0].y;

    max_z = cloud_in->points[0].z;
    min_z = cloud_in->points[0].z;
	
    for(size_t i=0;i<cloud_in->points.size();++i)
    {
		if(cloud_in->points[i].x >= max_x)
		{
			max_x = cloud_in->points[i].x;
		}
		if(cloud_in->points[i].x <= min_x)
		{
			min_x = cloud_in->points[i].x;
		}

		if(cloud_in->points[i].y >= max_y)
		{
			max_y = cloud_in->points[i].y;
		}
		if(cloud_in->points[i].y <= min_y)
		{
			min_y = cloud_in->points[i].y;
		}

		if(cloud_in->points[i].z >= max_z)
		{
			max_z = cloud_in->points[i].z;
		}
		if(cloud_in->points[i].z <= min_z)
		{
			min_z = cloud_in->points[i].z;
		}
    }
    step = (max_z-min_z)/6;
    //点云切片1
    pcl::PassThrough<pcl::PointXYZ> pass; //实例化直通滤波器
    pass.setInputCloud(cloud_in); //设置输入点云
    pass.setFilterFieldName("z");//设置滤波的field
    pass.setFilterLimits(min_z,min_z+step);//上述field的滤波范围
    pass.setFilterLimitsNegative(false);//设置要保存哪一部分点云,默认为false(field范围内部的点云)
    pass.filter(*cloud_filtered);//输出点云到*cloud_filtered
    
    //点云切片2
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered2(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PassThrough<pcl::PointXYZ> pass2; //实例化直通滤波器
    pass2.setInputCloud(cloud_in); //设置输入点云
    pass2.setFilterFieldName("z");//设置滤波的field
    pass2.setFilterLimits(min_z+step*2,min_z+step*3);//上述field的滤波范围
    pass2.setFilterLimitsNegative(false);
    pass2.filter(*cloud_filtered2);//输出点云到*cloud_filtered2 
    
    //点云切片3

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered3(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PassThrough<pcl::PointXYZ> pass3; //实例化直通滤波器
    pass3.setInputCloud(cloud_in); //设置输入点云
    pass3.setFilterFieldName("z");//设置滤波的field
    pass3.setFilterLimits(min_z+step*4,min_z+step*5);//上述field的滤波范围
    pass3.setFilterLimitsNegative(false);
    pass3.filter(*cloud_filtered3);

    //点云拼接
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    *cloud = (*cloud_filtered) + (*cloud_filtered2);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>);
    *cloud1 = (*cloud) + (*cloud_filtered3);

    //save cloud_filtered.pcd
    pcl::io::savePCDFileASCII("./cloud_filtered.pcd",*cloud1);
    std::cout<<"save succeed"<<std::endl;
 
    //可视化pcd
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
 
    viewer->initCameraParameters();
 
 
    int v1(0);
    viewer->createViewPort(0,0,0.5,1,v1);
    viewer->setBackgroundColor(0,0,0,v1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud1,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud1,single_color,"cloud1",v1);//注意此处的显示点云名称
 
    int v2(0);
    viewer->createViewPort(0.5,0,1,1,v2);
    viewer->setBackgroundColor(0,0,0,v2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v2);//PCL_Visualizer类大多数函数会有一个view_port,这个一定要加上,否则会出现点云不按照自己的目的显示的问题
    viewer->addCoordinateSystem(1);
    viewer->spin();
    return 0;
}


(8)自动点云切片与拼接section2.cpp

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>//直通滤波器文件
#include <pcl/visualization/pcl_visualizer.h>
 
float max_x;
float min_x;
float max_y;
float min_y;
float max_z;
float min_z;
float step;
int n=0,num=16;//num个点云切片

int main(int argc,char **argv) {
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1],*cloud_in);
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    cloud_filtered->width = cloud_in->width;
    cloud_filtered->height = cloud_in->height;
    cloud_filtered->is_dense = false;
    cloud_filtered->resize(cloud_filtered->height*cloud_filtered->width);
 
    //输出点云三个维度最大值/最小值
    max_x = cloud_in->points[0].x;
    min_x = cloud_in->points[0].x;

    max_y = cloud_in->points[0].y;
    min_y = cloud_in->points[0].y;

    max_z = cloud_in->points[0].z;
    min_z = cloud_in->points[0].z;
	
    for(size_t i=0;i<cloud_in->points.size();++i)
    {
		if(cloud_in->points[i].x >= max_x)
		{
			max_x = cloud_in->points[i].x;
		}
		if(cloud_in->points[i].x <= min_x)
		{
			min_x = cloud_in->points[i].x;
		}

		if(cloud_in->points[i].y >= max_y)
		{
			max_y = cloud_in->points[i].y;
		}
		if(cloud_in->points[i].y <= min_y)
		{
			min_y = cloud_in->points[i].y;
		}

		if(cloud_in->points[i].z >= max_z)
		{
			max_z = cloud_in->points[i].z;
		}
		if(cloud_in->points[i].z <= min_z)
		{
			min_z = cloud_in->points[i].z;
		}
    }
	step = (max_z-min_z)/(num*2);
        
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	
	while(num--)
   {
		
	    pcl::PassThrough<pcl::PointXYZ> pass; //实例化直通滤波器
		pass.setInputCloud(cloud_in); //设置输入点云
	     pass.setFilterFieldName("z");//设置滤波的field
		pass.setFilterLimits(min_z+n*step,min_z+(n+1)*step);//上述field的滤波范围
		pass.setFilterLimitsNegative(false);//设置要保存哪一部分点云,默认为false(field范围内部的点云)
		pass.filter(*cloud_filtered);//输出点云到*cloud_filtered

		
		//点云拼接
		
		(*cloud) = (*cloud) + (*cloud_filtered);
		n+=4;
		//if(num=10)
		//{
		//	pcl::io::savePCDFileASCII("./cloud_filtered.pcd",*cloud);
		//}
  
   }


    //save cloud_filtered.pcd
    pcl::io::savePCDFileASCII("./cloud_filtered.pcd",*cloud);
    std::cout<<"save succeed"<<std::endl;
 
    //可视化pcd
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
 
    viewer->initCameraParameters();
 
 
    int v1(0);
    viewer->createViewPort(0,0,0.5,1,v1);
    viewer->setBackgroundColor(0,0,0,v1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud,single_color,"cloud",v1);//注意此处的显示点云名称
 
    int v2(0);
    viewer->createViewPort(0.5,0,1,1,v2);
    viewer->setBackgroundColor(0,0,0,v2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v2);//PCL_Visualizer类大多数函数会有一个view_port,这个一定要加上,否则会出现点云不按照自己的目的显示的问题
 
    viewer->addCoordinateSystem(1);
    viewer->spin();
    return 0;
}


(9)泊松重建poisson.cpp

/*
三维重构之泊松重构
pcl::Poisson<pcl::PointNormal> pn ;
*/
 
//点的类型的头文件
#include <pcl/point_types.h>
//点云文件IO(pcd文件和ply文件)
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
//kd树
#include <pcl/kdtree/kdtree_flann.h>
//特征提取
#include <pcl/features/normal_3d_omp.h>// 法线特征
#include <pcl/features/normal_3d.h>
//重构
//#include <pcl/surface/gp3.h> // 贪婪投影三角化算法
#include <pcl/surface/poisson.h>// 泊松算法进行重构
//可视化
#include <pcl/visualization/pcl_visualizer.h>
//多线程
#include <boost/thread/thread.hpp>
// std
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
 
int main(int argc, char** argv)
{
    if(argc<2){ 
	  std::cout << "need ply/pcd file. " << std::endl;
          return -1;
	}
    // 确定文件格式
    char tmpStr[100];
    strcpy(tmpStr,argv[1]);
    char* pext = strrchr(tmpStr, '.');
    std::string extply("ply");
    std::string extpcd("pcd");
    if(pext){
        *pext='\0';
        pext++;
    }
    std::string ext(pext);
    //如果不支持文件格式,退出程序
    if (!((ext == extply)||(ext == extpcd))){
        std::cout << "文件格式不支持!" << std::endl;
        std::cout << "支持文件格式:*.pcd和*.ply!" << std::endl;
        return(-1);
    }
 
    //根据文件格式选择输入方式
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
   //创建点云对象指针,用于存储输入
    if (ext == extply){
        if (pcl::io::loadPLYFile(argv[1] , *cloud) == -1){
            PCL_ERROR("Could not read ply file!\n") ;
            return -1;
        }
    }
    else{
        if (pcl::io::loadPCDFile(argv[1] , *cloud) == -1){
            PCL_ERROR("Could not read pcd file!\n") ;
            return -1;
        }
    }
    // 计算法向量 x,y,x + 法向量 + 曲率
    pcl::PointCloud<pcl::PointNormal>::Ptr  cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); //法向量点云对象指针
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;//法线估计对象
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);//存储估计的法线的指针
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
    tree->setInputCloud(cloud);
    n.setInputCloud(cloud);
    n.setSearchMethod(tree);
    n.setKSearch(20);//20个邻居
    n.compute(*normals);//计算法线,结果存储在normals中
    // 将点云和法线放到一起
    pcl::concatenateFields(*cloud,  *normals,  *cloud_with_normals);
    //创建搜索树
    pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
    tree2->setInputCloud(cloud_with_normals);
    //创建Poisson对象,并设置参数
    pcl::Poisson<pcl::PointNormal> pn;
    pn.setConfidence(false); //是否使用法向量的大小作为置信信息。如果false,所有法向量均归一化。
    pn.setDegree(2); //设置参数degree[1,5],值越大越精细,耗时越久。
    pn.setDepth(8); 
     //树的最大深度,求解2^d x 2^d x 2^d立方体元。
     // 由于八叉树自适应采样密度,指定值仅为最大深度。
 
    pn.setIsoDivide(8); //用于提取ISO等值面的算法的深度
    pn.setManifold(false); //是否添加多边形的重心,当多边形三角化时。 
// 设置流行标志,如果设置为true,则对多边形进行细分三角话时添加重心,设置false则不添加
    pn.setOutputPolygons(false); //是否输出多边形网格(而不是三角化移动立方体的结果)
    pn.setSamplesPerNode(3.0); //设置落入一个八叉树结点中的样本点的最小数量。无噪声,[1.0-5.0],有噪声[15.-20.]平滑
    pn.setScale(1); //设置用于重构的立方体直径和样本边界立方体直径的比率。
    pn.setSolverDivide(8); //设置求解线性方程组的Gauss-Seidel迭代方法的深度
    //pn.setIndices();
 
    //设置搜索方法和输入点云
    pn.setSearchMethod(tree2);
    pn.setInputCloud(cloud_with_normals);
    //创建多变形网格,用于存储结果
    pcl::PolygonMesh mesh;
    //执行重构
    pn.performReconstruction(mesh);
 
    //保存网格图
    pcl::io::savePLYFile("result.ply", mesh);
 
    // 显示结果图
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer")) ;
    viewer->setBackgroundColor(0 , 0 , 0);//背景 黑色
    viewer->addPolygonMesh(mesh , "my");//mesh
    //viewer->addCoordinateSystem (0.10);//坐标系
    viewer->initCameraParameters();//相机参数
    while (!viewer->wasStopped()){
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
 
    return 0;
}

(10)pcd文件转txt文件xyz.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <fstream>
using namespace std;
 
int main(int argc,char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
 	ofstream outfile;
	outfile.open("data.txt", ios::binary | ios::app | ios::in | ios::out);
	//注意,里面有iOS::app,表示打开文件后,在写入的文件不会覆盖原文件中的内容,也就是原来文件中的数据会得到保存。
	if(pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1],*cloud)==-1)//*打开点云文件
	{
		PCL_ERROR("Couldn't read file test_pcd.pcd\n");
		return(-1);
	}
	std::cout<<"Loading... "<<std::endl;

	for(size_t i=0;i<cloud->points.size();++i)
	{
		outfile<<cloud->points[i].x <<" "<<cloud->points[i].y<<" "<<cloud->points[i].z<<std::endl;
	}
	std::cout<<"Finished"<<std::endl;
	outfile.close();//关闭文件,保存文件。 
	return(0);
}

(11)pcd文件转ply文件pcdtoply.cpp

#include <iostream>          //输入输出流头文件
#include <pcl/io/pcd_io.h>   //打开关闭pcd类定义头文件
#include <pcl/point_types.h> //所有点类型定义头文件
#include <pcl/io/ply_io.h>   //打开关闭ply类定义头文件
#include <pcl/point_types.h> //打印的头文件
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	
         pcl::io::loadPCDFile(argv[1],*cloud);
	//显示点云数量
	std::cout << "point number: "
		<< cloud->width * cloud->height
		<< std::endl;

	
	std::string filename("11.ply");
	pcl::PLYWriter writer;    
	writer.write("11.ply", *cloud);  //保存文件
	

	return (0);
}



(12)ply文件转pcd文件plytopcd.cpp

#include <iostream>
#include <pcl/common/io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/PolygonMesh.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/vtk_lib_io.h>

using namespace std;

int main()
{
            pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
            pcl::PolygonMesh mesh;
            vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
            pcl::io::loadPolygonFilePLY("Stone.ply", mesh);
            pcl::io::mesh2vtk(mesh, polydata);
            pcl::io::vtkPolyDataToPointCloud(polydata, *cloud);
            pcl::io::savePCDFileASCII("Stone.pcd", *cloud);
            return 0;
}

(13)三维点云90度旋转changexyz.cpp

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>//直通滤波器文件
#include <pcl/visualization/pcl_visualizer.h>

int main(int argc,char **argv) {
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1],*cloud_in);
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    cloud_filtered->width = cloud_in->width;
    cloud_filtered->height = cloud_in->height;
    cloud_filtered->is_dense = false;
    cloud_filtered->resize(cloud_filtered->height*cloud_filtered->width);
 

	
    for(size_t i=0;i<cloud_in->points.size();++i)
    {
		cloud_filtered->points[i].x = cloud_in->points[i].z;
		cloud_filtered->points[i].y = cloud_in->points[i].x;
		cloud_filtered->points[i].z = -(cloud_in->points[i].y);
    }
    //save cloud_filtered.pcd
    pcl::io::savePCDFileASCII("./changedxyz.pcd",*cloud_filtered);
    std::cout<<"save succeed"<<std::endl;
 
    //可视化pcd
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
 
    viewer->initCameraParameters();
 
 
    int v1(0);
    viewer->createViewPort(0,0,0.5,1,v1);
    viewer->setBackgroundColor(0,0,0,v1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud_filtered,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered,single_color,"cloud_filtered",v1);//注意此处的显示点云名称
 
    int v2(0);
    viewer->createViewPort(0.5,0,1,1,v2);
    viewer->setBackgroundColor(0,0,0,v2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v2);//PCL_Visualizer类大多数函数会有一个view_port,这个一定要加上,否则会出现点云不按照自己的目的显示的问题
 
    viewer->addCoordinateSystem(1);
 
    viewer->spin();
 
 
    return 0;
}

(14)三维点云原点坐标校正correctxyz.cpp

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
 
float max_x;
float min_x;
float max_y;
float min_y;
float max_z;
float min_z;
 
int main(int argc,char **argv) {
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1],*cloud_in);
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    cloud_filtered->width = cloud_in->width;
    cloud_filtered->height = cloud_in->height;
    cloud_filtered->is_dense = false;
    cloud_filtered->resize(cloud_filtered->height*cloud_filtered->width);
    //输出点云三个维度最大值/最小值
    max_x = cloud_in->points[0].x;
    min_x = cloud_in->points[0].x;

    max_y = cloud_in->points[0].y;
    min_y = cloud_in->points[0].y;

    max_z = cloud_in->points[0].z;
    min_z = cloud_in->points[0].z;
	
    for(size_t i=0;i<cloud_in->points.size();++i)
    {
		if(cloud_in->points[i].x >= max_x)
		{
			max_x = cloud_in->points[i].x;
		}
		if(cloud_in->points[i].x <= min_x)
		{
			min_x = cloud_in->points[i].x;
		}

		if(cloud_in->points[i].y >= max_y)
		{
			max_y = cloud_in->points[i].y;
		}
		if(cloud_in->points[i].y <= min_y)
		{
			min_y = cloud_in->points[i].y;
		}

		if(cloud_in->points[i].z >= max_z)
		{
			max_z = cloud_in->points[i].z;
		}
		if(cloud_in->points[i].z <= min_z)
		{
			min_z = cloud_in->points[i].z;
		}
    }

    for(size_t i=0;i<cloud_in->points.size();++i)
    {
		cloud_filtered->points[i].x = cloud_in->points[i].x-min_x;
		cloud_filtered->points[i].y = cloud_in->points[i].y-min_y;
		cloud_filtered->points[i].z = cloud_in->points[i].z-min_z;
    }


    //save cloud_filtered.pcd
    pcl::io::savePCDFileASCII("./correctxyz.pcd",*cloud_filtered);
    std::cout<<"save succeed"<<std::endl;
 
    //可视化pcd
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
 
    viewer->initCameraParameters();
 
 
    int v1(0);
    viewer->createViewPort(0,0,0.5,1,v1);
    viewer->setBackgroundColor(0,0,0,v1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud_filtered,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered,single_color,"cloud_filtered",v1);//注意此处的显示点云名称
 
    int v2(0);
    viewer->createViewPort(0.5,0,1,1,v2);
    viewer->setBackgroundColor(0,0,0,v2);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,255,255,255);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v2);//PCL_Visualizer类大多数函数会有一个view_port,这个一定要加上,否则会出现点云不按照自己的目的显示的问题
 
    viewer->addCoordinateSystem(1);
 
    viewer->spin();
 
    return 0;
}
 
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值