Fork me on GitHub

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 and std::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向量, 因此falsetrue经过转化后都是true

参考

posted @ 2021-06-27 11:01  chrislzy  阅读(2749)  评论(1编辑  收藏  举报