zoukankan      html  css  js  c++  java
  • OpenCV FileStorage类读写XML/YML文件

          本文转自:http://www.cnblogs.com/summerRQ/articles/2524560.html

          在OpenCV程序中,需要保存中间结果的时候常常会使用.xml / .yml文件,opencv2.0之前都是使用C风格的代码,当时读写XML文件分别使用函数cvLoad()和cvSave()。在2.0以后的OpenCV转为支持C++,这一举措大大减少了代码量以及编程时需要考虑的细节。

          新版本的OpenCV的C++接口中,imwrite()和imread()只能保存整数数据,且需要以图像格式。当需要保存浮点数据或者XML/YML文件时,之前的C语言接口cvSave()函数已经在C++接口中被删除,代替它的是FileStorage类。这个类非常的方便,封装了很多数据结构的细节,编程的时候可以根据统一的接口对数据结构进行保存。

        1. FileStorage类写XML/YML文件

             •   新建一个FileStorage对象,以FileStorage::WRITE的方式打开一个文件。

             •   使用 << 操作对该文件进行操作。

             •   释放该对象,对文件进行关闭。

            例子如下:

     1 FileStorage fs("test.yml", FileStorage::WRITE);
     2     fs << "frameCount" << 5;
     3     time_t rawtime; time(&rawtime);
     4     fs << "calibrationDate" << asctime(localtime(&rawtime));
     5     Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); //又一种Mat初始化方式
     6     Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);
     7     fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
     8     
     9     //features为一个大小为3的向量,其中每个元素由随机数x,y和大小为8的uchar数组组成
    10     fs << "features" << "[";
    11     for( int i = 0; i < 3; i++ )
    12     {
    13         int x = rand() % 640;
    14         int y = rand() % 480;
    15         uchar lbp = rand() % 256;
    16         fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
    17         for( int j = 0; j < 8; j++ )
    18             fs << ((lbp >> j) & 1);
    19         fs << "]" << "}";
    20     }
    21     fs << "]";
    22     fs.release();

           2. FileStorage类读XML/YML文件

           FileStorage对存储内容在内存中是以层次的节点组成的,每个节点类型为FileNode,FileNode可以使单个的数值、数组或者一系列FileNode的集合。FileNode又可以看做是一个容器,使用iterator接口可以对该节点内更小单位的内容进行访问,例如访问到上面存储的文件中"features"的内容。步骤与写文件类似:

             •   新建FileStorage对象,以FileStorage::READ 方式打开一个已经存在的文件

             •   使用FileStorage::operator []()函数对文件进行读取,或者使用FileNode和FileNodeIterator

             •   使用FileStorage::release()对文件进行关闭

             例子如下:

     1     FileStorage fs("test.yml", FileStorage::READ);
     2 
     3     //方式一: []操作符
     4     int frameCount = (int)fs["frameCount"];
     5     
     6     //方式二: FileNode::operator >>()
     7     string date;
     8     fs["calibrationDate"] >> date;
     9     
    10     Mat cameraMatrix2, distCoeffs2;
    11     fs["cameraMatrix"] >> cameraMatrix2;
    12     fs["distCoeffs"] >> distCoeffs2;
    13     
    14     //注意FileNodeIterator的使用,似乎只能用一维数组去读取里面所有的数据
    15     FileNode features = fs["features"];
    16     FileNodeIterator it = features.begin(), it_end = features.end();
    17     int idx = 0;
    18     std::vector<uchar> lbpval;
    19     for( ; it != it_end; ++it, idx++ )
    20     {
    21         cout << "feature #" << idx << ": ";
    22         cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
    23         (*it)["lbp"] >> lbpval;  //直接读出一维向量
    24 
    25         for( int i = 0; i < (int)lbpval.size(); i++ )
    26             cout << " " << (int)lbpval[i];
    27         cout << ")" << endl;
    28     }
    29     fs.release();

            另外,注意在新建FileStorage对象之后,并以READ或WRITE模式打开文件之后,可以用FileStorage::isOpened()查看文件状态,判断是否成功打开了文件。

  • 相关阅读:
    金蝶数据库执行语句
    金蝶 更新价格分录表触发器
    金蝶触发器,生成条码信息
    SQL从中文中获取拼音首字母
    C语言 typedef用法
    这姑娘漂亮不,说实话,有糖吃
    条码开发的意义在哪里
    ERP开发,重点不在功能
    金蝶出入库数据库表里加字段后出现的问题解决
    解决金蝶未检测到K/3许可文件,并且该账套已超过演示版期限问题
  • 原文地址:https://www.cnblogs.com/freshmen/p/4123683.html
Copyright © 2011-2022 走看看