• OpenCV FileStorage 使用记录


    FileStorage

    OpenCV 中的 FileStorage 类能够读写硬盘中的.xml.yaml文件,这里我们只讨论对 .xml 的以下几种操作:

    • 写入(FileStorage::WRITE,覆盖写)
    • 追加(FileStorage::APPEND,追加写)
    • 读取(FileStorage::WRITE

    FileStorageFileNode 为单位存储数据,且无法删改某个已有 FileNode的内容,想实现删改功能,得自己造轮子……

    写入FileNode

    FileNode有两种类型,seqmap

    FileStorage fs("data.xml", FileStorage::WRITE);
    
    // seq_node 是一个 seq 型的节点, 以它为父节点,存入10个数据
    fs << "seq_node" << "[";
    for(size_t i = 0; i < 10; ++i){
      fs << i;
    }
    fs << "]";
    
    // map_node 是一个 map 型节点, 以它为父节点,存入10个数据
    fs << "map_node" << "{";
    for(size_t i = 0; i < 10; ++i){
      fs << "node_" + to_string(i) << i;
    }
    fs << "}";
    
    fs.release();
    

    通过上面这段代码,我们可以看到 seqmap 这两种类型的节点,在写入数据时的差别:前者在子节点间,写入一对方括号[], 而后者写入花括号{};前者在写入子节点的时候,无法为子节点命名,而后者可以。OpenCV 最重要的 Mat 类型在存储时是以 map 方式写入的。

    读入FileNode

    seqmap 节点在读入数据的时候,前者以索引的方式去获得子节点,后者用子节点的名字,即一个字符串去获得子节点(字符串为键,节点为值):

    FileStorage fs("data.xml", FileStorage::READ);
    vector<int> a, b;
    
    // seq_node 是一个 seq 型的节点
    FileNode seq_node = fs["seq_node"];
    for(size_t i = 0; i < 10; ++i){
      seq_node[i] >> a[i];
    }
    
    // map_node 是一个 map 型节点
    FileNode map_node = fs["map_node"];
    for(size_t i = 0; i < 10; ++i){
      fs["node_" + to_string(i)] >> b[i];
    }
    
    fs.release();
    

    seq 型节点既然能以索引去取子节点,那自然有人会想到,能不能用迭代器去访问子节点呢?答案是可以。OpenCV为我们提供了FileNode的迭代器:

    // seq_node 是一个 seq 型的节点
    FileNode seq_node = fs["seq_node"];
    FileNodeIterator it = seq_node.begin();
    for(; it != seq_node.end(); ++it){
      *it >> a[i];
    }
    

    自定义类型的读写

    需要重载 writeread 函数:

    struct MyData{
      int i;
      string str;
      Mat I;
    }
    
    // 自定义写入
    void write(FileStorage &fs, const string &, const MyData &mydata){
      fs << "{"
         << "index" << mydata.i
         << "str"   << mydata.str
         << "img"   << mydata.I
         << "}"
    }
    
    // 自定义读取
    void read(const FileNode &node, MyData &mydata, const MyData &default_val = MyData()){
      if(node.empty()) mydata = default_val;
      else {
        node["index"] >> mydata.i;
        node["str"] >> mydata.str;
        node["img"] >> mydata.I;
      }
    }
    
    

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

  • 相关阅读:
    redis 配置文件说明
    Python 详解命令行解析
    Python 的字符编码
    pt-online-schema-change utf8mb4 错误解决方法【转】
    [MySQL 5.6] Innodb新特性之export/import 表文件
    查找数据库大小和表大小
    MySQL 增删列
    使用MySQL Shell创建MGR
    Qingcloud_MySQL Plus(Xenon) 高可用搭建实验
    MySQL事务提交流程
  • 原文地址:https://www.cnblogs.com/fourseas/p/5519681.html
Copyright © 2020-2023  润新知