zoukankan      html  css  js  c++  java
  • 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 国际许可协议进行许可。

  • 相关阅读:
    Apache Solr 远程命令+XXE执行漏洞(CVE-2017-12629)
    Apache Shiro RememberMe 1.2.4 反序列化漏洞
    ActiveMQ任意文件写入漏洞(CVE-2016-3088)
    ssrf对redis未授权访问写webshell
    fastjson<1.2.47 RCE 漏洞复现
    Redis基于主从复制的RCE(redis4.x 5.x)复现
    本机浏览器无法访问linux的tomcat
    测试覆盖率工具EclEmma安装与使用
    eclemma怎么安装 eclemma的安装与简单使用图文教程(附下载)
    .bat脚本基本命令语法
  • 原文地址:https://www.cnblogs.com/fourseas/p/5519681.html
Copyright © 2011-2022 走看看