XML\YAML文件在OpenCV中的数据结构为FileStorage,打开操作例如:
[cpp]view plaincopy
- stringfilename="I.xml";
- FileStoragefs(filename,FileStorage::WRITE);
- \\...
- fs.open(filename,FileStorage::READ);
文件关闭操作会在FileStorage结构销毁时自动进行,但也可调用如下函数实现
[cpp]view plaincopy
- fs.release();
2.文本和数字的输入和输出
写入文件使用 << 运算符,例如:
[cpp]view plaincopy
- fs<<"iterationNr"<<100;
读取文件,使用 >> 运算符,例如
[cpp]view plaincopy
- intitNr;
- fs["iterationNr"]>>itNr;
- itNr=(int)fs["iterationNr"];
3. OpenCV数据结构的输入和输出,和基本的C++形式相同
[cpp]view plaincopy
- MatR=Mat_<uchar>::eye(3,3),
- T=Mat_<double>::zeros(3,1);
- fs<<"R"<<R;//Writecv::Mat
- fs<<"T"<<T;
- fs["R"]>>R;//Readcv::Mat
- fs["T"]>>T;
4. vector(arrays)和 maps的输入和输出
vector要注意在第一个元素前加上“[”,在最后一个元素前加上"]"。例如:
[cpp]view plaincopy
- fs<<"strings"<<"[";//text-stringsequence
- fs<<"image1.jpg"<<"Awesomeness"<<"baboon.jpg";
- fs<<"]";//closesequence
对于map结构的操作使用的符号是"{"和"}",例如:
[cpp]view plaincopy
- fs<<"Mapping";//text-mapping
- fs<<"{"<<"One"<<1;
- fs<<"Two"<<2<<"}";
读取这些结构的时候,会用到FileNode和FileNodeIterator数据结构。
对FileStorage类的[]操作符会返回FileNode数据类型,对于一连串的node,可以使用FileNodeIterator结构,例如:
[cpp]view plaincopy
- FileNoden=fs["strings"];//Readstringsequence-Getnode
- if(n.type()!=FileNode::SEQ)
- {
- cerr<<"stringsisnotasequence!FAIL"<<endl;
- return1;
- }
- FileNodeIteratorit=n.begin(),it_end=n.end();//Gothroughthenode
- for(;it!=it_end;++it)
- cout<<(string)*it<<endl;
5. 读写自己的数据结构
这部分比较复杂,参考最后的实例中的MyData结构自己领悟吧
最后,我这里上一个实例,供大家参考。
[cpp]view plaincopy
- #include<opencv2/core/core.hpp>
- #include<iostream>
- #include<string>
- usingnamespacecv;
- usingnamespacestd;
- voidhelp(char**av)
- {
- cout<<endl
- <<av[0]<<"showstheusageoftheOpenCVserializationfunctionality."<<endl
- <<"usage:"<<endl
- <<av[0]<<"outputfile.yml.gz"<<endl
- <<"TheoutputfilemaybeeitherXML(xml)orYAML(yml/yaml).Youcanevencompressitby"
- <<"specifyingthisinitsextensionlikexml.gzyaml.gzetc..."<<endl
- <<"WithFileStorageyoucanserializeobjectsinOpenCVbyusingthe<<and>>operators"<<endl
- <<"Forexample:-createaclassandhaveitserialized"<<endl
- <<"-useittoreadandwritematrices."<<endl;
- }
- classMyData
- {
- public:
- MyData():A(0),X(0),id()
- {}
- explicitMyData(int):A(97),X(CV_PI),id("mydata1234")//explicittoavoidimplicitconversion
- {}
- voidwrite(FileStorage&fs)const//Writeserializationforthisclass
- {
- fs<<"{"<<"A"<<A<<"X"<<X<<"id"<<id<<"}";
- }
- voidread(constFileNode&node)//Readserializationforthisclass
- {
- A=(int)node["A"];
- X=(double)node["X"];
- id=(string)node["id"];
- }
- public://DataMembers
- intA;
- doubleX;
- stringid;
- };
- //ThesewriteandreadfunctionsmustbedefinedfortheserializationinFileStoragetowork
- voidwrite(FileStorage&fs,conststd::string&,constMyData&x)
- {
- x.write(fs);
- }
- voidread(constFileNode&node,MyData&x,constMyData&default_value=MyData()){
- if(node.empty())
- x=default_value;
- else
- x.read(node);
- }
- //Thisfunctionwillprintourcustomclasstotheconsole
- ostream&operator<<(ostream&out,constMyData&m)
- {
- out<<"{id="<<m.id<<",";
- out<<"X="<<m.X<<",";
- out<<"A="<<m.A<<"}";
- returnout;
- intmain(intac,char**av)
- {
- if(ac!=2)
- {
- help(av);
- return1;
- stringfilename=av[1];
- {//write
- MyDatam(1);
- FileStoragefs(filename,FileStorage::WRITE);
- fs<<"iterationNr"<<100;
- fs<<"strings"<<"[";//text-stringsequence
- fs<<"image1.jpg"<<"Awesomeness"<<"baboon.jpg";
- fs<<"]";//closesequence
- fs<<"Mapping";//text-mapping
- fs<<"{"<<"One"<<1;
- fs<<"Two"<<2<<"}";
- fs<<"R"<<R;//cv::Mat
- fs<<"T"<<T;
- fs<<"MyData"<<m;//yourowndatastructures
- fs.release();//explicitclose
- cout<<"WriteDone."<<endl;
- {//read
- cout<<endl<<"Reading:"<<endl;
- FileStoragefs;
- fs.open(filename,FileStorage::READ);
- intitNr;
- //fs["iterationNr"]>>itNr;
- itNr=(int)fs["iterationNr"];
- cout<<itNr;
- if(!fs.isOpened())
- {
- cerr<<"Failedtoopen"<<filename<<endl;
- FileNoden=fs["strings"];//Readstringsequence-Getnode
- if(n.type()!=FileNode::SEQ)
- return1;
- }
- FileNodeIteratorit=n.begin(),it_end=n.end();//Gothroughthenode
- for(;it!=it_end;++it)
- cout<<(string)*it<<endl;
- n=fs["Mapping"];//Readmappingsfromasequence
- cout<<"Two"<<(int)(n["Two"])<<";";
- cout<<"One"<<(int)(n["One"])<<endl<<endl;
- MyDatam;
- MatR,T;
- fs["R"]>>R;//Readcv::Mat
- fs["T"]>>T;
- fs["MyData"]>>m;//Readyourownstructure_
- cout<<endl
- <<"R="<<R<<endl;
- cout<<"T="<<T<<endl<<endl;
- cout<<"MyData="<<endl<<m<<endl<<endl;
- //Showdefaultbehaviorfornonexistingnodes
- cout<<"AttempttoreadNonExisting(shouldinitializethedatastructurewithitsdefault).";
- fs["NonExisting"]>>m;
- cout<<endl<<"NonExisting="<<endl<<m<<endl;
- }
- cout<<endl
- <<"Tip:Openup"<<filename<<"withatexteditortoseetheserializeddata."<<endl;
- return0;
- }
编译后,在命令行进入到文件目录,执行test test.xml,运行结果如下,生成一个test . xml文件,内容如下:
[html]view plaincopy
- <?xmlversion="1.0"?>
- -<opencv_storage>
- <iterationNr>100</iterationNr>
- <strings>image1.jpgAwesomenessbaboon.jpg</strings>
- -<Mapping>
- <One>1</One>
- <Two>2</Two>
- </Mapping>
- -<Rtype_id="opencv-matrix">
- <rows>3</rows>
- <cols>3</cols>
- <dt>u</dt>
- <data>100010001</data>
- </R>
- -<Ttype_id="opencv-matrix">
- <rows>3</rows>
- <cols>1</cols>
- <dt>d</dt>
- <data>0.0.0.</data>
- </T>
- -<MyData>
- <A>97</A>
- <X>3.1415926535897931e+000</X>
- <id>mydata1234</id>
- </MyData>
- </opencv_storage>