• 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 国际许可协议进行许可。

  • 相关阅读:
    解决大量TCPIP连接后出现“因为系统缺乏足够缓冲区空间或者因为队列已满无法执行套接字上操作”的问题
    网站/网页 变灰的方法
    [收藏]General things to take into consideration while doing socket programming.
    数据库主体在该数据库中拥有 架构,无法删除解决方法
    Word字体与像素的对应关系
    50个网站设计开发必备的资源素材网站
    apache实现页面重定向(地址跳转)
    JS eval(function(p,a,c,k,e,r){e=function(c)*****解密
    JS打印指定区域内容
    如何才能做到网站高并发访问? .
  • 原文地址:https://www.cnblogs.com/fourseas/p/5519681.html
Copyright © 2020-2023  润新知