opencv之写入和读取yaml文件
写入和读取yaml\xml文件的步骤:
- 创建
cv::FileStorage
对象,并打开文件。 - 使用
<<
写入数据, 或者使用>>
读取数据。 - 使用
cv::FileStorage::release()
关闭文件。
写入yaml\xml文件实例
#include <opencv2/opencv.hpp>
#include <time.h>
#include <iostream>
int main(int argc, char** argv)
{
//write a yaml file
cv::FileStorage fs_write("/home/temp/test.yaml", cv::FileStorage::WRITE);
fs_write << "frameCount" << 5;
time_t rawtime;
time(&rawtime);
fs_write << "calibrationDate" << asctime(localtime(&rawtime));
std::vector<int> image_size = {1920, 1200};
fs_write << "imgize" << image_size;
cv::Mat camera_matrix = (cv::Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
cv::Mat distort_coefficient = (cv::Mat_<double>(5, 1) << 0.1, 0.01, -0.001, 0, 0);
fs_write << "cameraMatrix" << camera_matrix << "distCoeffs" << distort_coefficient;
fs_write << "features" << "[";
for (int i = 0; i < 3; i++)
{
int x = rand() % 640;
int y = rand() % 480;
uchar lbp = rand() % 256;
fs_write << "{:" << "x" << x << "y" << y << "lbp" << "[:";
for (int j = 0; j < 8; j ++)
fs_write << ((lbp >> j) & 1);
fs_write << "]" << "}";
}
fs_write << "]";
fs_write.release();
return 0;
}
- 注: 上例中在yaml文件中存储了整数,字符串,opencv矩阵,自定义结构体。
生成的yaml文件如下所示:
%YAML:1.0
frameCount: 5
calibrationDate: "Fri Jun 17 14:09:29 2011\n"
imgize: [1920, 1200]
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:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] }
- { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] }
- { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] }
-
The produced YAML (and XML) consists of heterogeneous collections that can be nested. There are 2 types of collections: named collections (mappings) and unnamed collections (sequences). In mappings each element has a name and is accessed by name. This is similar to structures and
std::map
in C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by indices. This is similar to arrays andstd::vector
in C/C++ and lists, tuples in Python. “Heterogeneous” means that elements of each single collection can have different types. -
When you write to a mapping (a structure), you write element name followed by its value. When you write to a sequence, you simply write the elements one by one. OpenCV data structures (such as cv::Mat) are written in absolutely the same way as simple C data structures - using
<<
operator. -
To write a mapping, you first write the special string “{“ to the storage, then write the elements as pairs (
fs <<<element_name> << <element_value>
) and then write the closing “}”. -
To write a sequence, you first write the special string “[“, then write the elements, then write the closing “]”.
-
In YAML (but not XML), mappings and sequences can be written in a compact Python-like inline form. In the sample above matrix elements, as well as each feature, including its lbp value, is stored in such inline form. To store a mapping/sequence in a compact form, put ”:” after the opening character, e.g. use “{:” instead of “{“ and “[:” instead of “[“. When the data is written to XML, those extra ”:” are ignored.
# opencv之cv::Mat创建与访问读取yaml\xml文件实例
int main(int argc, char** argv)
{
//read a yaml file
cv::FileStorage fs_read("/home/temp/test.yaml", cv::FileStorage::READ);
// first method:use (type) operator on FIleNode
int frame_count = (int)fs_read["frameCount"];
std::string date;
//second method:use FileNode::operator >>
fs_read["calibrationDate"] >> date;
std::vecotr<int> image_size;
fs_read["imgize"] >> image_size;
cv::Mat camera_matrix, distort_coefficient;
fs_read["camera_matrix"] >> camera_matrix;
fs_read["distort_coefficient"] >> distort_coefficient;
std::cout << "frame_count: " << frame_count << std::endl
<< "calibration data: " << date << std::endl
<< "camera matrix: " << camera_matrix <<std::endl
<< "distortion coeffs: " << distort_coefficient << std::endl;
cv::FileNode features = fs_read["features"];
cv::FileNodeIterator it = features.begin(), it_end = features.end();
int idx = 0;
std::vector<uchar> lbpval;
//iterator through a sequence using FileNodeIterator
for (; it != it_end; ++it, idx++)
{
std::cout << "feature #" << idx << ": ";
std::cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
(*it)["lbp"] >> l# opencv之cv::Mat创建与访问
bpval;
for (int i = 0; i < (int)lbpval.size(); i++)
std::cout << " " << (int)lbpval[i];
std::cout << ")" << std::endl;
}
fs_read.release();
return 0;
}
- 注1:读取yaml文件中的数据,有三种方法,见上面。
- 注2:使用std::vector<>来接收yaml中的数组。
FileStorage
FileStorage::FileStorage
FileStorage::FileStorage()
FileStorage::FileStorage(const string& source, int flags, const string& encoding=string())
注:
flags –
Mode of operation. Possible values are:
- FileStorage::READ Open the file for reading.
- FileStorage::WRITE Open the file for writing.
- FileStorage::APPEND Open the file for appending.
- FileStorage::MEMORY Read data from source or write data to the internal buffer (which is returned by FileStorage::release)
FileStorage::open
bool FileStorage::open(const string& filename, int flags, const string& encoding=string())
FileStorage::release
void FileStorage::release()
注意事项
opencv的yaml读取方式不能读取bool变量, 应该会按照string处理, 然后转为bool向量, 因此false
和true
经过转化后都是true