octomap点云压缩

如果点云文件比较大,可以利用octomap库对点云进行压缩。

octomap以八叉树结构对点云进行组织,是一种有损压缩,定义不同的分辨率可以保存不同尺度的数据。

这里以rabbit.pcd文件为例,分别将点云保存为文本格式(.txt),二进制格式(.bin),八叉树格式(.ot),八叉树二进制模式(.bt),对比存为不同格式文件的大小。

程序运行需要安装pcl和octomap,示例如下:

#include <iostream>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <octomap/octomap.h>
#include <octomap/OcTree.h>

using namespace std;

class PointCloudInfo
{
public:
    typedef boost::shared_ptr<PointCloudInfo> Ptr;            /*!< Point cloud information shared point */
    typedef boost::shared_ptr<const PointCloudInfo> ConstPtr; /*!< Point cloud information shared point (const)*/

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud; /*!< Pcl point cloud */
    double octo_min_x{ 0 };                    /*!< Minimum x-axis value of octomap */
    double octo_min_y{ 0 };                    /*!< Minimum y-axis value of octomap */
    double octo_min_z{ 0 };                    /*!< Minimum z-axis value of octomap */
    double octo_max_x{ 0 };                    /*!< Maximum x-axis value of octomap */
    double octo_max_y{ 0 };                    /*!< Maximum y-axis value of octomap */
    double octo_max_z{ 0 };                    /*!< Maximum z-axis value of octomap */
    double octo_resol{ 0 };                    /*!< Octomap Resolution */
};

struct xyz
{
    float x;
    float y;
    float z;
};

int main()
{

    pcl::PointCloud<pcl::PointXYZ> cloud;
    pcl::io::loadPCDFile<pcl::PointXYZ> ( "rabbit.pcd", cloud );    

    octomap::OcTree tree( 0.001 );
    vector<xyz> vp;
    xyz m_p;
    FILE *fp = fopen("rabbit.txt","w");        

    for (auto p:cloud.points)
    {
        m_p.x = p.x;
        m_p.y = p.y;
        m_p.z = p.z;
        vp.emplace_back(m_p);

        tree.updateNode( octomap::point3d(p.x, p.y, p.z), true );
        fprintf(fp,"%f %f %f\n",p.x,p.y,p.z);
    }
    fclose(fp);

    fp = fopen("rabbit.bin","wb");
    fwrite(&vp[0],vp.size()*sizeof(xyz),1,fp);
    fclose(fp);

    tree.updateInnerOccupancy();
    tree.write("rabbit.ot");
    tree.writeBinary("rabbit.bt");

    ///////////////////////////read bt///////////////////////////////////////
    octomap::OcTree octo_tree(0.001);
    octo_tree.readBinary("rabbit.bt");
    
    PointCloudInfo::Ptr pc_info(new PointCloudInfo());
    octo_tree.getMetricMin(pc_info->octo_min_x, pc_info->octo_min_y, pc_info->octo_min_z);
    octo_tree.getMetricMax(pc_info->octo_max_x, pc_info->octo_max_y, pc_info->octo_max_z);
    pc_info->octo_resol = octo_tree.getResolution();


    pc_info->cloud.reset(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::PointXYZ point;
    for (octomap::OcTree::leaf_iterator it = octo_tree.begin_leafs(); it != octo_tree.end_leafs(); ++it)
    {
        if (it != nullptr && octo_tree.isNodeOccupied(*it))
        {
            point.x = static_cast<float>(it.getX());
            point.y = static_cast<float>(it.getY());
            point.z = static_cast<float>(it.getZ());
            pc_info->cloud->push_back(point);
        }
    }

    return 0;
}

保存后的ot或bt文件可以利用octovis查看,输入octovis rabbit.bt即可。

下表是不同文件的大小:

rabbit.pcd 1.2M
rabbit.txt 1.0M
rabbit.bin 431.4K
rabbit.ot 282.8K
rabbit.bt 44.2K

可以看出bt文件压缩率还是很高的,虽然是有损压缩,不过在很多情况下已经够用了。

posted @ 2020-05-02 19:44  Dsp Tian  阅读(1465)  评论(0编辑  收藏  举报