OpenCV4入门系列教程70:文件之YAML读写

入门系列索引:OpenCV入门系列教程索引目录

上一篇:OpenCV4入门系列教程69:文件之XML读写

YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达数据序列化的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC 2822)中获得灵感。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。当前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。
YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。

YAML的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。尽管它比较适合用来表达层次结构式(hierarchical model)的数据结构,不过也有精致的语法可以表示关系性(relational model)的数据。由于YAML使用空白字符和分行来分隔数据,使得它特别适合用grep/Python/Perl/Ruby操作。其让人最容易上手的特色是巧妙避开各种封闭符号,如:引号、各种括号等,这些符号在嵌套结构时会变得复杂而难以辨认。

写部分测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//--------------------------------------【程序说明】-------------------------------------------
// 程序说明:《OpenCV3编程入门》OpenCV3版书本配套示例程序29
// 程序描述:XML和YAML文件的写入
// 2014年11月 Created by @浅墨_毛星云
// 2014年12月 Revised by @浅墨_毛星云
//------------------------------------------------------------------------------------------------

//---------------------------------【头文件、命名空间包含部分】-------------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include "opencv2/opencv.hpp"
#include <time.h>
using namespace cv;

//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main() {
//初始化
FileStorage fs("test.yaml", 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;
}

执行完成之后,会在可执行文件目录下输出结果文件,内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
%YAML:1.0
---
frameCount: 5
calibrationDate: "Sun Jun 21 18:53:26 2020\n"
cameraMatrix: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
distCoeffs: !!opencv-matrix
rows: 5
cols: 1
dt: d
data: [ 1.0000000000000001e-01, 1.0000000000000000e-02,
-1.0000000000000000e-03, 0., 0. ]
features:
- { x:490, y:187, lbp:[ 0, 1, 0, 0, 1, 0, 0, 0 ] }
- { x:376, y:331, lbp:[ 1, 1, 0, 1, 0, 1, 1, 0 ] }
- { x:33, y:360, lbp:[ 0, 1, 0, 1, 1, 1, 0, 1 ] }

读取部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//--------------------------------------【程序说明】-------------------------------------------
// 程序说明:《OpenCV3编程入门》OpenCV3版书本配套示例程序30
// 程序描述:XML和YAML文件的读取
// 2014年11月 Created by @浅墨_毛星云
// 2014年12月 Revised by @浅墨_毛星云
//------------------------------------------------------------------------------------------------

//---------------------------------【头文件、命名空间包含部分】-------------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include "opencv2/opencv.hpp"
#include <time.h>
using namespace cv;
using namespace std;

int main() {
//初始化
FileStorage fs2("test.yaml", FileStorage::READ);

// 第一种方法,对FileNode操作
int frameCount = (int)fs2[ "frameCount" ];

std::string date;
// 第二种方法,使用FileNode运算符> >
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;

//使用FileNodeIterator遍历序列
for (; it != it_end; ++it, idx++) {
cout << "feature #" << idx << ": ";
cout << "x=" << (int)(*it)[ "x" ] << ", y=" << (int)(*it)[ "y" ] << ", lbp: (";
// 我们也可以使用使用filenode > > std::vector操作符很容易的读数值阵列
(*it)[ "lbp" ] >> lbpval;
for (int i = 0; i < (int)lbpval.size(); i++)
cout << " " << (int)lbpval[ i ];
cout << ")" << endl;
}
fs2.release();

//程序结束,输出一些帮助文字
printf("\n文件读取完毕,请输入任意键结束程序~");
getchar();

return 0;
}

执行输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ./30_Read_XML_and_YAML_File 
frameCount: 5
calibration date: Sun Jun 21 18:53:26 2020

camera matrix: [1000, 0, 320;
0, 1000, 240;
0, 0, 1]
distortion coeffs: [0.1;
0.01;
-0.001;
0;
0]
feature #0: x=490, y=187, lbp: ( 0 1 0 0 1 0 0 0)
feature #1: x=376, y=331, lbp: ( 1 1 0 1 0 1 1 0)
feature #2: x=33, y=360, lbp: ( 0 1 0 1 1 1 0 1)

文件读取完毕,请输入任意键结束程序~

下一篇:OpenCV4入门系列教程71:图像直方图