**
前言
**
感觉自己写的内容乱七八糟的啊。没什么东西,内容空洞。
这篇其实是文件操作,每次遇到文件操作,遇到指针传递就感觉难受。
XML和YAML文件都是一种“语言”。XML是元标记,即开发者可以根据自身需要定义自己的标记,比如定义标记。任何满足XML命名规则的名称都可以标记,这就向不同的应用程序打开了大门。此外,XML是一种语义、结构化语言,它描述了文档的结构和语义。YAML强调这种语义以数据为中心,不是以标记为重点,而用反哺词进行重新命名。YAML是可读性高,用来表达资料序列的格式。参考了XML、C语言、Python、Perl以及电子邮件格式RFC2822。
**
XML、YAML文件的写入
**
FileStorage类的操作,这个和C语言中的FILE类似。
废话不多说,示例:
#include<opencv2/opencv.hpp>
#include<ctime>
#include<iostream>
using namespace cv;
struct tag {
char data[128];
}x;
struct tag getTimeString() {
//获取时间
time_t now;
time(&now);
//转换成tm类型
struct tm today;
localtime_s(&today,&now);
//转换成字符串
sprintf_s(x.data, "%3dd%3dw%3dm%3ds:%3dm:%3dh%5dy",
today.tm_mday, //天
today.tm_wday, //周
today.tm_mon + 1,//月
today.tm_sec,//秒
today.tm_min,//分
today.tm_hour,//时
today.tm_year + 1900);//年
std::cout << x.data<<std::endl;
return x;
}
int main() {
FileStorage fs("test.yaml", FileStorage::WRITE);
if (!fs.isOpened()) {
std::cout << "打开失败";
system("pause");
}
fs << "frameCount" << 5;
//读入时间的字符串
struct tag receive = getTimeString();
std::cout << receive.data << std::endl;
fs << "calibrationDate" << receive.data;
Mat cameraMatrix = (Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); //又一种Mat初始化方式
Mat distCoeffs = (Mat_<double>(5, 1) << 0.1, 0.01, -0.001, 0, 0);
fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
//features为一个大小为3的向量,其中每个元素由随机数x,y和大小为8的uchar数组组成
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();
std::cout << "文件读取完毕,请在工程目录下查看生成的文件~";
getchar();
}
程序运行结果:
打开文件test.yaml:
上面的代码中,需要把得到的时间转换成字符串再传回来,由于笔者实在辣鸡,对于char
类型数组接受后就显示不出了,那么也就传进文件都是乱码。
所以,上面用结构体传递是走了捷径,本质上是全局变量的使用。
如果对char
数组的接受很清楚的话,希望得到回复。
YAML文件后缀.yml和.yaml结果一样。
上面的如果是写入test.yml,显示一样。但是如果写成test.xml,显示为:
- FileStorage::APPEND追加
- FileStorage::WRITE重写
- FileStorage::READ读取
**
XML、YAML文件的读取
**
#include<opencv2/opencv.hpp>
#include<ctime>
#include<iostream>
#include<iomanip>
using namespace cv;
int main() {
//改变console颜色,背景6,前景F
system("color 6F");
//初始化
FileStorage fs("test.yaml", FileStorage::READ);
//第一种方法,对FileNode操作
int frameCount = (int)fs["frameCount"];
//第二种方法,使用>>
std::string date;
fs["calibrationDate"] >> date;
Mat cameraMatrix, distCoeffs;
fs["cameraMatrix"] >> cameraMatrix;
fs["distCoeffs"] >> distCoeffs;
std::cout << "frameCount:" << frameCount << "\n"
<< "calibration date:" << date << "\n"
<< "camera matrix:" << cameraMatrix << "\n"
<< "distortion coeffs:" << distCoeffs << std::endl;
FileNode features = fs["features"];
FileNodeIterator it = features.begin();
FileNodeIterator it_end = features.end();
int index = 0;
std::vector<uchar> lbp_value;
for (; it != it_end; ++it,++index) {
std::cout << "feature #" <<std::setw(4)<< index << ": ";
std::cout << "x=" << (int)(*it)["x"] << ",y=" << (int)(*it)["y"] << ",lbp: (";
//可以使用filenode>>std::vector操作很容易读取阵列
(*it)["lbp"] >> lbp_value;
for (int i = 0; i < (int)lbp_value.size(); ++i) {
std::cout << " " << (int)lbp_value[i];
}
std::cout << " )" << std::endl;
}
fs.release();
std::cout << "文件的读取完毕,请输入任意键结束程序~";
getchar();
}
运行结果:
参考:《Opecv3编程入门》