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文件压缩率还是很高的,虽然是有损压缩,不过在很多情况下已经够用了。