平台: ubuntu10.04 + OpenCV2.3 + cmake
1. XML、YAML文件的打开和关闭
XML\YAML文件在OpenCV中的数据结构为FileStorage,打开操作例如:
string filename = "test.xml";
FileStorage fs(filename, FileStorage::WRITE);
\\或者
fs.open(filename, FileStorage::WRITE);
// 文件读写模式
// file storage mode
enum
{
READ=0, //! read mode
WRITE=1, //! write mode
APPEND=2 //! append mode
};
文件关闭操作会在FileStorage结构销毁时自动进行,但也可调用如下函数实现
fs.release();
2.文本和数字的输入和输出
写入文件使用 << 运算符,例如:
fs << "iterationNr" << 100;
读取文件,使用 >> 运算符,例如
int itNr;
fs["iterationNr"] >> itNr;
itNr = (int) fs["iterationNr"];
3. OpenCV数据结构的输入和输出,和基本的C++形式相同
Mat R = Mat_<uchar >::eye (3, 3),
T = Mat_<double>::zeros(3, 1);
fs << "R" << R; // Write cv::Mat
fs << "T" << T;
fs["R"] >> R; // Read cv::Mat
fs["T"] >> T;
4. vector(arrays) 和 maps的输入和输出
vector要注意在第一个元素前加上“[”,在最后一个元素前加上"]"。例如:
fs << "strings" << "["; // text - string sequence
fs << "image1.jpg" << "Awesomeness" << "baboon.jpg";
fs << "]"; // close sequence
对于map结构的操作使用的符号是"{"和"}",例如:
fs << "Mapping"; // text - mapping
fs << "{" << "One" << 1;
fs << "Two" << 2 << "}";
读取这些结构的时候,会用到FileNode和FileNodeIterator数据结构。对FileStorage类的[]操作符会返回FileNode数据类型,对于一连串的node,可以使用FileNodeIterator结构,例如:
FileNode n = fs["strings"]; // Read string sequence - Get node
if (n.type() != FileNode::SEQ)
{
cerr << "strings is not a sequence! FAIL" << endl;
return 1;
}
FileNodeIterator it = n.begin(), it_end = n.end(); // Go through the node
for (; it != it_end; ++it)
cout << (string)*it << endl;
//!FileNode的类型
//! type of the file storage node
enum
{
NONE=0, //!< empty node
INT=1, //!< an integer
REAL=2, //!< floating-point number
FLOAT=REAL, //!< synonym or REAL
STR=3, //!< text string in UTF-8 encoding
STRING=STR, //!< synonym for STR
REF=4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
SEQ=5, //!< sequence
MAP=6, //!< mapping
TYPE_MASK=7,
FLOW=8, //!< compact representation of a sequence or mapping. Used only by YAML writer
USER=16, //!< a registered object (e.g. a matrix)
EMPTY=32, //!< empty structure (sequence or mapping)
NAMED=64 //!< the node has a name (i.e. it is element of a mapping)
};
5. 文件读写源码
### xml2.cpp
#############################################################################
// XML/YAML File Storage Class.
//
// The class describes an object associated with XML or YAML file.
// It can be used to store data to such a file or read and decode the data.
//
// The storage is organized as a tree of nested sequences (or lists) and mappings.
// Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator.
// Mapping is analogue of std::map or C structure, which elements are accessed by names.
// The most top level structure is a mapping.
// Leaves of the file storage tree are integers, floating-point numbers and text strings.
//
// For example, the following code:
#include"opencv2/core/core.hpp"
#include<iostream>
#include<string>
using namespace std;
using namespace cv;
int main(int agc, char** agv)
{
// open file storage for writing. Type of the file is determined from the extension
{
FileStorage fs("test.xml", FileStorage::WRITE);
fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH";
fs << "test_mat" << Mat::eye(3,3,CV_32F);
fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
"{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
fs << "]" << "}";
}
// open file storage for reading.
// Type of the file is determined from the content, not the extension
{
FileStorage fs("test.xml", FileStorage::READ);
int test_int = (int)fs["test_int"];
double test_real = (double)fs["test_real"];
string test_string = (string)fs["test_string"];
cout << "test_int " << test_int << " test_real " << test_real << " test_string " << test_string << endl;
Mat M;
fs["test_mat"] >> M;
cout << "test_mat " << M << endl;
FileNode tl = fs["test_list"];
CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6);
double tl0 = (double)tl[0];
int tl1 = (int)tl[1];
double tl2 = (double)tl[2];
int tl3 = (int)tl[3];
string tl4 = (string)tl[4];
CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3);
int month = (int)tl[5]["month"];
int day = (int)tl[5]["day"];
int year = (int)tl[5]["year"];
cout << "test_list" << endl;
cout << "tl0 " << tl0 << " tl1 " << tl1 << " tl2 " << tl2 << " tl3 " << tl3 << " tl4 " << tl4 << endl;
cout << "tl5 " << " month " << month << " day " << day << " year " << year << endl;
FileNode tm = fs["test_map"];
int x = (int)tm["x"];
int y = (int)tm["y"];
int width = (int)tm["width"];
int height = (int)tm["height"];
cout << "test_map " << " x " << x << " y " << y << " width " << width << " height " << height << endl;
int lbp_val = 0;
FileNodeIterator it = tm["lbp"].begin();
for(int k = 0; k < 8; k++, ++it)
{
lbp_val |= ((int)*it) << k;
}
cout << "blp " << lbp_val << endl;
}
return 0;
}
######################################################################
6、XML文件 test.xml
###########################################
<?xml version="1.0"?>
<opencv_storage>
<test_int>5</test_int>
<test_real>3.1000000000000001e+00</test_real>
<test_string>ABCDEFGH</test_string>
<test_mat type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>f</dt>
<data>
1. 0. 0. 0. 1. 0. 0. 0. 1.</data></test_mat>
<test_list>
1.0000000000000000e-13 2 3.1415926535897931e+00 -3435345
"2-502 2-029 3egegeg"
<_><month>12</month>
<day>31</day>
<year>1969</year></_></test_list>
<test_map>
<x>1</x>
<y>2</y>
<width>100</width>
<height>200</height>
<lbp>
0 1 1 0 1 1 0 1</lbp></test_map>
</opencv_storage>
##########################################
7、YML文件 tet.yml 运行时需将Filename改为test.yml
##########################################
%YAML:1.0
test_int: 5
test_real: 3.1000000000000001e+00
test_string: ABCDEFGH
test_mat: !!opencv-matrix
rows: 3
cols: 3
dt: f
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ]
test_list:
- 1.0000000000000000e-13
- 2
- 3.1415926535897931e+00
- -3435345
- "2-502 2-029 3egegeg"
- { month:12, day:31, year:1969 }
test_map:
x: 1
y: 2
width: 100
height: 200
lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ]
#########################################
8、CMakeList.txt文件
########################################
PROJECT(xml)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
FIND_PACKAGE( OpenCV REQUIRED )
# Declare the target (an executable)
ADD_EXECUTABLE(xml xml.cpp)
TARGET_LINK_LIBRARIES(xml ${OpenCV_LIBS})
#MESSAGE(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}")
#################################################
编译执行:
cd currentPath
cmake -Unix
make
./xml2