----输入和输出XML和YAML
FileStorage(const string& source, int flags, const string& encoding=string());
第一个参数:表示存储或读取数据的文件名
第二个参数:表示操作模式
FileStorage::READ 打开文件进行读操作
FileStorage::WRITE 打开文件进行写操作
FileStorage::APPEND 打开文件进行附加操作
FileStorage::MEMORY 从source读数据,或向内部缓存写入数据(由FileStorage::release返回)
第三个参数:表示文件的编码方式。目前不支持UTF-16 XML 编码,应使用 8-bit 编码
FileStorage fs("xxx.xml", FileStorage::WRITE);
FileStorage( );
FileStorage fs;
fs.open("xxx.xml", FileStorage::WRITE);
template FileStorage& operator<<(FileStorage& fs, const _Tp& value);
第一个参数:表示需要写入数据的文件
第二个参数:表示待写入的数据
template
第一个参数:表示需要写入数据的文件
第二个参数:表示待写入的向量值
fs << "year" << 2021;
fs << "hello" << "world";
Mat R = Mat_<uchar>::eye(3, 3);
fs << "R" << R;
int Year = (int)fs["year"];
cout << "year: " << Year << endl;
std::string str;
fs["hello"] >> str;
cout << "hello: " << str << endl;
Mat R;
fs["R"] >> R;
cout << "R = " << R << endl;
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "src" << "{" << "src1" << "[" << 1 << 2 << 3 << "]"
<< "src2" << "[" << 4 << 5 << 6 << "]" << "}";
fs.release();
代码同上
创建一个yaml父节点(map),包含两个子节点(vector)
boolFileStorage::open(const string& filename, int flags, const string&encoding=string());
第一个参数:表示存储或读取数据的文件名。其扩展名(.xml 或 .yml/.yaml) 决定文件格式(XML 或 YAML)
第二个参数:表示操作模式
第三个参数:表示文件的编码方式
boolFileStorage::isOpened();
返回true:打开
返回false:其他情况
FileStorage fs1("xxx.yml", FileStorage::READ);
FileStorage fs2("test.yml", FileStorage::READ);
bool flag1 = fs1.isOpened();
bool flag2 = fs2.isOpened();
cout << "flag1 = " << flag1 << endl;
cout << "flag2 = " << flag2 << endl;
void FileStorage::release();
FileStorage fs("xxx.yml", FileStorage::WRITE);
...
fs.release();
FileStorage::getFirstTopLevelNode();
FileStorage fs2("test.yml", FileStorage::READ);
string FirstNode = fs2.getFirstTopLevelNode();
cout << "The first top level node is " << FirstNode << endl;
FileNode FileStorage::root(int streamidx = 0);
第一个参数:表示从0开始的字符串索引。大部分情况文件中只有一个串,但YAML支持多个串,因此可以有多个。
写入文件中
FileStorage fs("test.yml", FileStorage::WRITE);
Mat src = (Mat_<double>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
fs << "src1" << src;
fs << "src2" << src;
fs.release();
读取文件中
FileStorage fs2("test.yml", FileStorage::READ);
FileNode rootnode = fs2.root();
FileNodeIterator it;
for (it = rootnode.begin();it < rootnode.end();it++)
{
Mat dst;
(*it) >> dst;
cout << dst << endl;
}
FileNode FileStorage::operator[](const string& nodename) const;
FileNode FileStorage::operator[](const char* nodename) const;
第一个参数:表示文件的节点名
Mat R;
fs["R"] >> R;
cout << "R = " << R << endl;
以XML为例,若想输出YAML文件(.yaml或.yml)甚至txt和doc,更改后缀名即可。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace cv;
int main()
{
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 distCoeffs = (Mat_<double>(5, 1) << 0.1, 0.01, -0.001, 0, 0);
fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
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();
printf("文件读写完毕\n");
getchar();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace cv;
using namespace std;
int main()
{
system("color 6F");
FileStorage fs2("test.yml", FileStorage::READ);
int frameCount = (int)fs2["frameCount"];
std::string date;
fs2["calibrationDate"] >> date;
Mat cameraMatrix2, distCoeffs2;
fs2["cameraMatrix"] >> cameraMatrix2;
fs2["distCoeffs"] >> distCoeffs2;
cout << "frameCount: " << frameCount << endl
<< "calibration date: " << date << endl
<< "camera matrix: " << cameraMatrix2 << endl
<< "distortion coeffs" << distCoeffs2 << endl;
FileNode features = fs2["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;
}
fs2.release();
printf("\n文件读取完毕!\n");
getchar();
return 0;
}
FileNode::FileNode();
FileNode::FileNode(const CvFileStorage* fs, const CvFileNode* node);
FileNode::FileNode(const FileNode& node);
写入
OpenCV 最重要的 Mat 类型在存储时是以 map 方式写入的。
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "seq_node" << "[";
for (int i = 0; i < 3; ++i)
fs << i;
fs << "]";
fs << "map_node" << "{";
for (int i = 0; i < 3; ++i)
fs << "node_" + std::to_string(i) << i;
fs << "}";
fs.release();
读取
(1)seq
以索引的方式去获得子节点,也可以用迭代器去访问子节点。
(2)map
用子节点的名字,即一个字符串去获得子节点(字符串为键,节点为值)。
FileStorage fs("test.yml", FileStorage::READ);
FileNode seq_node = fs["seq_node"];
for (int i = 0; i < 3; i++)
{
int num;
seq_node[i] >> num;
cout << num << endl;
}
FileNode map_node = fs["map_node"];
for (int i = 0; i < 3; i++)
{
int n;
map_node["node_" + to_string(i)] >> n;
cout << "node_" + to_string(i) << ": " << n << endl;
}
关于map型读取的分析:
---->父节点:map_code,内含三个子节点:node_0, node_1, node_2;
---->通过FileNode map_node = fs2["map_node"];
找到父节点map_node;再在父节点内寻找子节点map_node["node_" + to_string(i)]
,得到值
---->若用fs["node_" + to_string(i)]
是找不到值的,因为父节点没有node_0, node_1, node_2
用于迭代访问序列(sequences)和映射表(mappings)。是一种典型的STL符号,通过node.begin()和node.end()来标识序列的开始和结束位置。
FileNodeIterator::FileNodeIterator();
FileNodeIterator::FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
FileNodeIterator::FileNodeIterator(const FileNodeIterator& it);
FileStorage fs("test.yml", FileStorage::READ);
FileNode seq_node = fs["seq_node"];
FileNodeIterator it = seq_node.begin();
for (; it != seq_node.end(); ++it) {
int i;
*it >> i;
cout << i << endl;
}