Opencv学习九输入输出XML和YAML文件

**

前言

**
感觉自己写的内容乱七八糟的啊。没什么东西,内容空洞。
这篇其实是文件操作,每次遇到文件操作,遇到指针传递就感觉难受。

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编程入门》

猜你喜欢

转载自blog.csdn.net/weixin_41374099/article/details/86583796