• 读取并显示.pcd/.ply/.txt/.bin/.stl格式的点云


    1. 读取显示.pcd/.ply格式的点云

    • 通过loadPCDFile/loadPLYFile或者loadPLYFile/PLYReader来载入点云数据
    • pcd格式
    #include 
    #include 
    #include 
    //1.直接载入 实际上loadPCDFile调用PCDReader实现
    pcl::PointCloud<PointXYZ >::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile<pcl::PointXYZ>("tree.pcd", *cloud);
    //2.创建点云对象读取
    pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
    pcl::PCDReader reader;
    reader.read ("cat.pcd", *cloud); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • ply格式
    #include 
    #include  
    #include 
    //1.直接载入
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPLYFile <pcl::PointXYZ>("tree.pcd", *cloud);
    //2.创建点云对象读取
    pcl::PCLPointCloud2::Ptr cloud_blob(new pcl::PCLPointCloud2);
    pcl::PLYReader reader;
    reader.read("cat.pcd", *cloud);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    • 以下均读取为点类型为PointXYZ的点云中,即在调用这些函数前cloud_为pcl::PointCloud::Ptr cloud(new pcl::PointCloud);

    2. 读取显示.txt格式的点云

    • 将txt文件每一行的数据读入到点point中,再将点push_back到点云中
    • 注意此处适用于每行中点的数据以空格分割的数据,以逗号分割的稍有不同(有空补充)
    • cloudPath为txt文件路径
    void readTxtCloud(std::string cloudPath)
    {
    	std::string line;
    	pcl::PointXYZ point;
    	std::ifstream txtfile(cloudPath.c_str());
    	if(!txtfile)
    	{
    	    std::cout<<"open txt file fail"<<std::endl;
    	}
    	while(getline(txtfile, line))
    	{
    	    std::stringstream ss(line);
    	    //以空格分割遇到逗号结束
    	    ss >> point.x;
    	    ss >> point.y;
    	    ss >> point.z;
    	    cloud->push_back(point);
    	}
    	txtfile.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3. 读取显示.bin格式的点云

    • 此处读取过程中直接舍弃了intensity强度信息(将其存到a里),保存点x,y,z坐标到点类型为PointXYZ的点云中
    void readBinCloud(std::string cloudPath)
    {
       pcl::PointXYZ point;
       float a=0;
       std::ifstream binfile(cloudPath.c_str(),ios::in|ios::binary);
       if(!binfile.good())
       {
           std::cout<<"open bin file fail"<<std::endl;
       }
       for(int i=0;binfile.good()&&!binfile.eof();i++)
       {
           binfile.read((char *)&point.x,3*sizeof (float));
           binfile.read((char *)&a,sizeof (float));
           cloud->push_back(point);
       }
       binfile.close(); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4. 读取显示.stl格式的点云

    • 首先通过vtkSTLReader读取.stl点云,将其转换为Poly格式再转换为pcl::PointCloud
    void readStlCloud(std::string cloudPath)
    {
    	vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
    	reader->SetFileName(cloudPath.c_str());
    	reader->Update();
    	vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
    	polydata = reader->GetOutput();
    	polydata->GetNumberOfPoints();
    	pcl::io::vtkPolyDataToPointCloud(polydata,*cloud);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5. 读取.pcd/.ply/.txt/.bin/.stl任一格式的点云

    • 传入需要读取的点云数据的路径cloudPath,判断字符串的后缀名,分别对不同的后缀进行不同的读取方式
    • 由于读取.txt/.bin文件时是将点push_back到点云中的,所以加上了cloud->clear();清空点云,否则多次调用函数读取.txt/.bin会导致出现多片点云。
    • find_last_of表示从字符串右边开始寻找指定字符,返回该字符在最右处的索引值
    • substr,str.substr(size_t pos = 0, size_t len = npos)表示拷贝字符串str从pos开始的len个字符,pos不指定则从0开始拷贝,len不指定的话则默认从pos开始拷贝到字符串末尾
    void readPointCloud(std::string cloudPath)
    {
        cloud_->clear();
        //判断文件的后缀,以确定打开的方式
        if (cloudPath.substr(cloudPath.find_last_of('.')) == ".pcd")
        {
            try
            {
                pcl::io::loadPCDFile(cloudPath, *cloud);
            }
            catch(...)
            {
                std::cout << "load pcd file error" << std::endl;
            }
        }
        else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".ply")
        {
            try
            {
                pcl::io::loadPLYFile(cloudPath,*cloud);
            }
            catch (...)
            {
                std::cout<<"load ply file error"<<std::endl;
            }
        }
        else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".txt")
        {
            try
            {
                std::string line;
                pcl::PointXYZ point;
                std::ifstream txtfile(cloudPath.c_str());
                if(!txtfile)
                {
                    std::cout<<"open txt file fail"<<std::endl;
                }
                while(getline(txtfile, line))
                {
                    std::stringstream ss(line);
                    //以空格分割遇到逗号结束
                    ss >> point.x;
                    ss >> point.y;
                    ss >> point.z;
                    cloud->push_back(point);
                    std::cout<<point<<std::endl;
                }
                txtfile.close();
            }
            catch(...)
            {
               std::cout<<"load ply file error"<<std::endl;
            }
        }
        else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".bin")
        {
            try
            {
                pcl::PointXYZ point;
                float a=0;
                std::ifstream binfile(cloudPath.c_str(),ios::in|ios::binary);
                if(!binfile.good())
                {
                    std::cout<<"open bin file fail"<<std::endl;
                }
                for(int i=0;binfile.good()&&!binfile.eof();i++)
                {
                    binfile.read((char *)&point.x,3*sizeof (float));
                    binfile.read((char *)&a,sizeof (float));
                    cloud->push_back(point);
                }
                binfile.close();
            }
            catch(...)
            {
                std::cout<<"load bin file error"<<std::endl;
            }
        }
        else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".stl")
        {
            try
            {
                vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
                reader->SetFileName(cloudPath.c_str());
                reader->Update();
                vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
                polydata = reader->GetOutput();
                polydata->GetNumberOfPoints();
                pcl::io::vtkPolyDataToPointCloud(polydata,*cloud);
            }
            catch(...)
            {
                std::cout<<"load stl file error"<<std::endl;
            }
        }
        //对读取到的点云保存为pcd格式
        pcl::io::savePCDFile<pcl::PointXYZ>("wind.pcd", *cloud);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    6. 显示上述格式的点云数据

    • 调用显示函数showPointCloud前,先调用readPointCloud函数读入点云
    void showPointCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
    {
        //显示点云前设置背景颜色,清空上次显示所有形状以及点云
        viewer_->setBackgroundColor(0,0,0);
        viewer_->removeAllShapes();
        viewer_->removeAllPointClouds();
        viewer_->removeAllCoordinateSystems();
        pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud,"z");
        viewer_->addPointCloud<pcl::PointXYZ>(cloud,fildColor);
        //重设相机视角
        viewer_->resetCamera();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

  • 相关阅读:
    移动安全实战分享
    java实现数据库自动异地备份
    10-3 Prometheus远端存储VictoriaMetrics集群版
    JVM启动参数详解(含调优)
    express学习30-多人管理22验证joi
    机器学习强基计划0-2:什么是机器学习?和AI有什么关系?
    金仓数据库KingbaseES客户端编程开发框架-SQLAlchemy(4. 程序示例)
    IPSec&GRE
    使用CMake进行C++项目管理
    【每日一题】找出数组的串联值
  • 原文地址:https://blog.csdn.net/m0_68312479/article/details/127660101