opencv对xml文件的创建,写入,读操作

1.CvFileStorage结构

  1. //3-16   CvFileStorage结构,数据通过CxCore数据存储函数访问  
  2. typedef struct CvFileStorage  
  3.  
  4.     ...  //hidden fields  
  5. }CvFileStorage;  

2.写入简单的数据和结构

  1. #include "stdafx.h"  
  2. #include <cv.h>  
  3. #include <highgui.h>  
  4.   
  5. int main(int argc,char** argv)  
  6.  
  7.     CvFileStorage* fs=cvOpenFileStorage("cfg.xml",0,CV_STORAGE_WRITE);//打开存储文件  
  8.     cvWriteInt(fs,"frame_count",10);//写入整数型  
  9.     cvStartWriteStruct(fs,"frame_size",CV_NODE_SEQ);//开始写入新的数据结构  
  10.     cvWriteInt(fs,0,320);  
  11.     cvWriteInt(fs,0,200);  
  12.     cvEndWriteStruct(fs);//结束写入数据结构  
  13.     cvReleaseFileStorage(&fs);//释放存储的数据  
  14.     return 0;  
  15.  

运行结果:

  1. <?xml version="1.0"?>  
  2. <opencv_storage>  
  3. <frame_count>10</frame_count>  
  4. <frame_size>  
  5.   320 200</frame_size>  
  6. </opencv_storage>  

3.写入一个对象

  1. #include "stdafx.h"  
  2. #include <cv.h>  
  3. #include <highgui.h>  
  4. #include <cxcore.h>  
  5.   
  6. int main(int argc,char** argv)  
  7.  
  8.     CvMat* mat=cvCreateMat(3,3,CV_32F);//创建一个矩阵  
  9.     CvFileStorage* fs=cvOpenFileStorage("example.xml",0,CV_STORAGE_WRITE);//打开文件,用来存储  
  10.   
  11.     cvSetIdentity(mat);  
  12.     cvWrite(fs,"A",mat,cvAttrList(0,0));//写入一个对象,如CvMat  
  13.   
  14.     cvReleaseFileStorage(&fs);//释放文件  
  15.     cvReleaseMat(&mat);//释放矩阵空间  
  16.   
  17.     return 0;  
  18.  

运行结果:

  1. <?xml version="1.0"?>  
  2. <opencv_storage>  
  3. <A type_id="opencv-matrix">  
  4.   <rows>3</rows>  
  5.   <cols>3</cols>  
  6.   <dt>f</dt>  
  7.   <data>  
  8.     1. 0. 0. 0. 1. 0. 0. 0. 1.</data></A>  
  9. </opencv_storage>  

4.二合一

  1. main()里面的内容  
  2.   
  3. CvFileStorage* fs=cvOpenFileStorage("cfgFinal.xml",0,CV_STORAGE_WRITE);//打开存储文件  
  4.       
  5.     cvWriteInt(fs,"frame_count",10);//写入整数型  
  6.     cvStartWriteStruct(fs,"frame_size",CV_NODE_SEQ);//开始写入新的数据结构  
  7.     cvWriteInt(fs,0,320);  
  8.     cvWriteInt(fs,0,200);  
  9.     cvEndWriteStruct(fs);//结束写入数据结构  
  10.   
  11.     CvMat* mat=cvCreateMat(3,3,CV_32F);//创建一个矩阵  
  12.     cvSetIdentity(mat);  
  13.     cvWrite(fs,"color_cvt_matrix",mat,cvAttrList(0,0));//写入一个对象,如CvMat  
  14.   
  15.     cvReleaseFileStorage(&fs);//释放存储的数据  
  16.     cvReleaseMat(&mat);//释放矩阵空间

运行结果:

  1. <?xml version="1.0"?>  
  2. <opencv_storage>  
  3. <frame_count>10</frame_count>  
  4. <frame_size>  
  5.   320 200</frame_size>  
  6. <color_cvt_matrix type_id="opencv-matrix">  
  7.   <rows>3</rows>  
  8.   <cols>3</cols>  
  9.   <dt>f</dt>  
  10.   <data>  
  11.     1. 0. 0. 0. 1. 0. 0. 0. 1.</data></color_cvt_matrix>  
  12. </opencv_storage>  



 在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的方式打开一个文件。

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

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


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

2. FileStorage类读XML/YML文件

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

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

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

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

         例子如下:

FileStorage fs("test.yml", FileStorage::READ);

    //方式一: []操作符
    int frameCount = (int)fs["frameCount"];
    
    //方式二: FileNode::operator >>()
    string date;
    fs["calibrationDate"] >> date;
    
    Mat cameraMatrix2, distCoeffs2;
    fs["cameraMatrix"] >> cameraMatrix2;
    fs["distCoeffs"] >> distCoeffs2;
    
    //注意FileNodeIterator的使用,似乎只能用一维数组去读取里面所有的数据
    FileNode features = fs["features"];
    FileNodeIterator it = features.begin(), it_end = features.end();
    int idx = 0;
    std::vector<uchar> lbpval;
    for( ; it != it_end; ++it, idx++ )
    {
        cout << "feature #" << idx << ": ";
        cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
        (*it)["lbp"] >> lbpval;  //直接读出一维向量

        for( int i = 0; i < (int)lbpval.size(); i++ )
            cout << " " << (int)lbpval[i];
        cout << ")" << endl;
    }
    fs.release();

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值