从xml或yml文件中读取数据

来源:互联网 发布:电子软件是什么专业 编辑:程序博客网 时间:2024/05/16 08:14


CvFileStorage:文件存储器,这是数据持久化和RTTI部分基础的数据结构,该部分的其他函数均通过此结构来访问文件。

typedef struct CvFileStorage
{
    int flags;
    int is_xml;
    int write_mode;
    int is_first;
    CvMemStorage* memstorage;
    CvMemStorage* dststorage;
    CvMemStorage* strstorage;
    CvStringHash* str_hash;
    CvSeq* roots;
    CvSeq* write_stack;
    int struct_indent;
    int struct_flags;
    CvString struct_tag;
    int space;
    char* filename;
    FILE* file;
    char* buffer;
    char* buffer_start;
    char* buffer_end;
    int wrap_margin;
    int lineno;
    int dummy_eof;
    const char* errmsg;
    char errmsgbuf[128];
    CvStartWriteStruct start_write_struct;
    CvEndWriteStruct end_write_struct;
    CvWriteInt write_int;
    CvWriteReal write_real;
    CvWriteString write_string;
    CvWriteComment write_comment;
    CvStartNextStream start_next_stream;
    //CvParse parse;
}
CvFileStorage;

CvFileStorage结构是一个“黑箱”,代表着和磁盘上文件相关联的文件存储器。下面介绍的一些函数使用CvFileStorage作为输入并允许用户去存储或装入分层次的集合,包括标量值、标准的CXCORE对象(如矩阵、序列、图像)和用户定义的对象等。

函数cvGetFileNodeByName通过结点名找到结点。此结点在map中找,或者如果map指针为NULL就从文件存储器的顶层结点以此查找。 在maps和cvGetSeqElem (或序列读对象)中,使用此函数可以方便的穿梭于文件存储器中。要加速对特定关键词的多查询(如,数组结构情况下),可以同时使用cvGetHashedKey和cvGetFileNode。

CvFileNode* cvGetFileNodeByName( const CvFileStorage* fs,
                                 const CvFileNode* map,
                                 const char* name );

fs
文件存储器。
map
父map,如果为NULL函数将从第一个开始查找所有顶层结点(流)。
name
文件结点名


XML:

<?xml version="1.0"><opencv_storage><A type_id="opencv-matrix">  <rows>3</rows>  <cols>3</cols>  <dt>f</dt>  <data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data></A></opencv_storage>


YML:

%YAML:1.0A: !!opencv-matrix  rows: 3  cols: 3  dt: f  data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
如例子中所示,XML使用嵌套标记来表示层次,而YAML使用缩进来实现(类似Python编程语言)。

同样的CXCORE函数都可以使用这两种格式来读和写,具体使用那种格式由打开的文件的扩展名来确定,是.xml则为XML文件,.yml或.yaml则为YAML文件。


#include "cxcore.h"#include "stdio.h"#pragma comment(lib, "cxcore.lib")/************************************************************************//* 使用OpenCV从文件读二维数组的实例                   *//* 作者:jink2005                    *//* 来源:http://www.aiseminar.cn/bbs/                                   *//************************************************************************/int main( int argc, char** argv ){ CvFileStorage *fs = cvOpenFileStorage("iris.xml", NULL, CV_STORAGE_READ); // 读数据 CvFileNode *pa = cvGetFileNodeByName(fs, NULL, "A"); CvFileNode *par = cvGetFileNodeByName(fs, pa, "rows"); CvFileNode *pac = cvGetFileNodeByName(fs, pa, "cols"); CvFileNode *pad = cvGetFileNodeByName(fs, pa, "data"); int r = cvReadInt(par, 0); int c = cvReadInt(pac, 0); printf("r = %d, c = %d\n", r, c); // 取数据 if (CV_NODE_IS_SEQ(pad->tag)) {  CvSeq *seq = pad->data.seq;  int total = seq->total;  CvSeqReader reader;  cvStartReadSeq(seq, &reader, 0);  for (int i = 0; i < total; i ++)  {   CvFileNode *pt = (CvFileNode *)reader.ptr;   double x = cvReadReal(pt);   printf("%f ", x);   if ((i + 1) % c == 0)    printf("\n");   CV_NEXT_SEQ_ELEM(seq->elem_size, reader);  } }  // 释放所用结构 cvReleaseFileStorage(&fs);    return 0;}





来自:http://www.aiseminar.cn/bbs/forum.php?mod=viewthread&tid=817

感谢~




=====================================

以下来自: http://blog.csdn.net/lzg188/article/details/5556518

/*写一个配置文件*/

 CvFileStorage *fs = cvOpenFileStorage(".//config.xml",NULL,CV_STORAGE_WRITE);
 float matrix_data[9] = {1,0,0,0,1,0,0,0,1};
 CvMat cmatrix = cvMat( 3, 3, CV_32F, matrix_data );  
 cvWriteInt( fs, "frame_count", 10 );

 cvStartWriteStruct( fs, "frame_size", CV_NODE_SEQ ); 
 cvWriteInt( fs, 0, 320 ); 
 cvWriteInt( fs, 0, 200 ); 
 cvEndWriteStruct(fs);  
 cvSave( "E://config.xml", &cmatrix );

 cvReleaseFileStorage(&fs);

 

 /*读一个配置文件*/
 CvFileStorage *fs = cvOpenFileStorage("D://config.xml",NULL,CV_STORAGE_READ);
 cvReadIntByName(fs,NULL,"frame_count",0);
 CvSeq *s = cvGetFileNodeByName(fs,0,"frame_size")->data.seq;
 int frame_width = cvReadInt((CvFileNode*)cvGetSeqElem(s,0),0);
 int frame_height = cvReadInt((CvFileNode*)cvGetSeqElem(s,1),0);
 cvReleaseFileStorage(&fs);

 

上面的代码的文件节点为序列的,没有名字,使用起来可能不方便,

可以使用map形式的文件节点,下面是实例的代码及其效果。

<?xml version="1.0"?>
<opencv_storage>
<High_calibration>
  <first_levle_calibration>320</first_levle_calibration>
  <second_levle_calibration>200</second_levle_calibration></High_calibration>
</opencv_storage>

 

 CvFileStorage *fs = NULL;
 fs = cvOpenFileStorage(".//config.xml",NULL,CV_STORAGE_WRITE);
 cvStartWriteStruct( fs, "High_calibration", CV_NODE_MAP ); 
 cvWriteInt( fs, "first_levle_calibration", 320 ); 
 cvWriteInt( fs, "second_levle_calibration", 200 ); 
 cvEndWriteStruct(fs);  
 cvReleaseFileStorage(&fs);

 

CvFileStorage *fs1 = NULL;
 fs1 = cvOpenFileStorage(".//config.xml",NULL, CV_STORAGE_READ);
 CvFileNode *fn = cvGetFileNodeByName(fs1,NULL,"High_calibration");
 int i_first_level = cvReadIntByName(fs1,fn,"first_levle_calibration",0);
 int i_secont_level = cvReadIntByName(fs1,fn,"second_levle_calibration",0);
 cvReleaseFileStorage(&fs1);

 

另外,对于同一个配置文件,重新创建一个CvFileStorage之后,再重新读写后,原来的文件中的内容将会消失,建议在不同的文件,块中写入同一个配置文件时,最好建立一个全局的CvFileStorage变量。

 

 

 

 

 


原创粉丝点击