Octomap使用记录_2

本文详细介绍了Octomap文件的内容结构,包括八叉树的使用、文件头的重要性,以及bt和.ot两种格式的区别。同时涵盖了文件的读写和格式转换方法,如将PCD转换为bt,以及bt和ot之间的相互转换。
摘要由CSDN通过智能技术生成

Octomap文件

内容

octomap文件内容如下:

文件头:第一行很重要,和文件后缀一样,是表明文件类型的。Octomap读取文件会首先对第一行进行判断

# Octomap OcTree file
# (feel free to add / change comments, but leave the first line as it is!)
#

id、size、res:tree的类型、大小、分辨率

data: 包含了八叉树结构及其节点的信息,以及每个节点的占据状态。

八叉树结构信息:包括节点的层级、坐标、索引等。八叉树将三维空间划分为立方体,每个立方体可以进一步细分为八个子立方体。这个结构以二进制的方式存储在文件中。

节点的占据信息:每个节点包含了有关相应立方体的占据信息。这表示节点是占据(occupied)、自由(free)还是未知(unknown)。占据信息用于表示八叉树中的对象是否存在,自由表示该立方体为空间的一部分,未知表示在当前分辨率下无法确定状态。

颜色信息:只有.ot文件可以储存颜色信息。

文件格式

octomap文件有两种格式,.bt和.ot

区别在于:

1. 文件头不同;

2. 对应tree的类型不同,.bt为Octree,.ot无直接读的接口,多数用于可视化;

3. bt文件内存更小

4. bt不能存放颜色,ot可以存放颜色

文件读写和格式转换

octomap中是有ot,bt转换的程序的,convert_octree,简单改了一下,并加了bt和pcd互转的功能,我比较懒,没有把他集成到一个函数里,写了四个。

pcd2bt:核心方法就是OcTree的updateNode()方法

bt2pcd:核心方法是用OcTree的leaf_iterator遍历叶子节点,再用PointCloud的push_back()方法加点

bt2ot:直接用write是写不了的,octomap的write是写binaryfile的,所以要用这种方式

ot2bt:注意,这是ot文件我目前发现的唯一的打开方式,AbstractOctree和ColorOctree都不能直接打开ot文件,对比起来Octree就可以直接load一个bt文件,如果不需要颜色,bt很明显更适合开发

#include <iostream>
#include <fstream>
#include <pcl/io/pcd_io.h>
#include <octomap/OcTree.h>
#include <octomap/OcTreeBase.h>

//load pcd, ot, bt
//convert pcd, ot, bt

using namespace std;
using namespace octomap;

void convertPcdToBt(const string& pcd_filename, const string& octomap_filename) {
    // Load PCD file
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ>(pcd_filename, *cloud) == -1) {
        cerr << "Error loading PCD file: " << pcd_filename << endl;
        return;
    }

    // Create OctoMap
    octomap::OcTree tree(0.05);

    // Insert points into OctoMap
    for (const auto& point : *cloud) {
        tree.updateNode(octomap::point3d(point.x, point.y, point.z), true);
    }

    // Save OctoMap to file
    tree.writeBinary(octomap_filename);
}

void convertBtToPcd(const string& octomap_filename, const string& pcd_filename) {
    // Load OctoMap
    octomap::OcTree tree(octomap_filename);

    // Extract points from OctoMap
    pcl::PointCloud<pcl::PointXYZ> cloud;
    for (octomap::OcTree::leaf_iterator it = tree.begin_leafs(), end = tree.end_leafs(); it != end; ++it) {
        if (tree.isNodeOccupied(*it)) {
            cloud.push_back(pcl::PointXYZ(it.getX(), it.getY(), it.getZ()));
        }
    }

    // Save PCD file
    pcl::io::savePCDFileBinary(pcd_filename, cloud);
}


void convertOtToBt(const string& inputFilename, const string& outputFilename) {
    std::ifstream file(inputFilename.c_str(), std::ios_base::in | std::ios_base::binary);

    if (!file.is_open()) {
        cerr << "Filestream to " << inputFilename << " not open, nothing read." << endl;
        exit(-1);
    }

    AbstractOcTree* tree = AbstractOcTree::read(file);
    file.close();

    if (!tree) {
        cerr << "Could not detect OcTree in file." << endl;
        exit(-1);
    }

    // Write binary (BonsaiTree) file
    if (outputFilename.length() > 3 && (outputFilename.compare(outputFilename.length()-3, 3, ".bt") == 0)) {
        cerr << "Writing binary (BonsaiTree) file" << endl;
        AbstractOccupancyOcTree* octree = dynamic_cast<AbstractOccupancyOcTree*>(tree);
        if (octree) {
            if (!octree->writeBinary(outputFilename)) {
                cerr << "Error writing to " << outputFilename << endl;
                exit(-2);
            }
        } else {
            cerr << "Error: Writing to .bt is not supported for this tree type: " << tree->getTreeType() << endl;
            exit(-2);
        }
    } else {
        cerr << "Output file must have a .bt extension for conversion." << endl;
        exit(-1);
    }

    cout << "Finished writing to " << outputFilename << endl;
}

// Function to convert .bt file to .ot file
void convertBtToOt(const string& inputFilename, const string& outputFilename) {
    std::ifstream file(inputFilename.c_str(), std::ios_base::in | std::ios_base::binary);

    if (!file.is_open()) {
        cerr << "Filestream to " << inputFilename << " not open, nothing read." << endl;
        exit(-1);
    }

    OcTree* binaryTree = new OcTree(0.1);

    if (binaryTree->readBinary(file) && binaryTree->size() > 1) {
        // Write general OcTree file
        cerr << "Writing general OcTree file" << endl;
        if (!binaryTree->write(outputFilename)) {
            cerr << "Error writing to " << outputFilename << endl;
            exit(-2);
        }
    } else {
        cerr << "Could not detect binary OcTree format in file." << endl;
        exit(-1);
    }

    file.close();
    delete binaryTree;

    cout << "Finished writing to " << outputFilename << endl;
}



int main() {

    convertPcdToBt("60.pcd", "61.bt");
    //convertBtToPcd("input_octomap.bt", "output_cloud.pcd");  
    //convertOtToBt("input.ot", "output.bt");
    //convertBtToOt("input.bt", "output.ot");

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Caesala

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值