OpenCV读取XML/YML文件的方法

前端之家收集整理的这篇文章主要介绍了OpenCV读取XML/YML文件的方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载地址:> http://blog.skyoung.org/2014/04/25/write-and-read-xml-yml-file/

在平时写一些程序的时候,需要一些配置参数的文件,最简单的方法是使用txt文件存储参数,但当参数较多时,为了让存储的参数更美观有序且方便读取,一些其他库提供的一些数据存储方法就显得很方便了,例如libconfig。当然这里并不打算着重讲解这个库,而是主要说一说OpenCV中关于数据存储的方法——读取XML/YML文件。XML是一种可扩展标记语言,YML和它类似,但是更适合人阅读。关于XML格式的文件除了OpenCV可以读写外,还有其他一些专门的库提供了读写的API,例如比较轻量级的TinyXML

XML/YML的写

文件的写的过程相对简单,类似C++中数据流的写的过程,使用<<。文件的创建是用类FileStorage,释放时调用FileStorage::release()并且关闭文件。列举一个OpenCV手册中例子如下:

  1. #include "opencv2/opencv.hpp"
  2. #include <time.h>
  3.  
  4. using namespace cv;
  5.  
  6. int main(int,char** argv)
  7. {
  8. FileStorage fs("test.yml",FileStorage::WRITE);
  9.  
  10. fs << "frameCount" << 5;
  11. time_t rawtime; time(&rawtime);
  12. fs << "calibrationDate" << asctime(localtime(&rawtime));
  13. Mat cameraMatrix = (Mat_<double>(3,3) << 1000,0,320,1000,240,1);
  14. Mat distCoeffs = (Mat_<double>(5,1) << 0.1,0.01,-0.001,0);
  15. fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
  16. fs << "features" << "[";
  17. for( int i = 0; i < 3; i++ )
  18. {
  19. int x = rand() % 640;
  20. int y = rand() % 480;
  21. uchar lbp = rand() % 256;
  22.  
  23. fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
  24. for( int j = 0; j < 8; j++ )
  25. fs << ((lbp >> j) & 1);
  26. fs << "]" << "}";
  27. }
  28. fs << "]";
  29. fs.release();
  30. return 0;
  31. }

这样得到的test.yml文件中的内容存储情况如下:

  1. %YAML:1.0
  2. frameCount: 5
  3. calibrationDate: "Fri Apr 25 16:55:42 2014\n"
  4. cameraMatrix: !!opencv-matrix
  5. rows: 3
  6. cols: 3
  7. dt: d
  8. data: [ 1000.,0.,320.,1000.,240.,1. ]
  9. distCoeffs: !!opencv-matrix
  10. rows: 5
  11. cols: 1
  12. dt: d
  13. data: [ 1.0000000000000001e-01,1.0000000000000000e-02,-1.0000000000000000e-03,0.,0. ] features:
  14. - { x:103,y:166,lbp:[ 1,1,0 ] } - { x:115,y:113,1 ] } - { x:586,y:12,0 ] }

OpenCV产生的yml文件中有两种collection,分别是mappings和sequences,mapping中的元素是有名字,名字对应其数值,其数值的获取是通过名字得到的,如上面test.yml文件所示的feature下对应的几个mappings。而sequences是没有名字的,通过索引获取数值的,例如上面的cameraMatrix里面的data对应的数值以及feature里面的lbp对应的数值以及feature本身。

当写入mapping元素的时候,使用<<依次输入数据的名字和数值,当输入sequences元素的时候,只需要依次输入数据的数值即可。

当写入mapping的时候,首先写入{然后依次写入各个mapping元素然,最后写入}。写入sequence的时候首先写入[,然后依次写入各个sequence元素,最后写入]。在{或者[后面加上:可以让这些数据呈inline模式显示,即一行,否则会每个元素都换行。

XML/YML的读

文件的读的过程有三种方法,一种是和文件的写对应的,即使用>>读取,如下面的示例代码第8行;另一种是使用类型强制转换成相应数据,如下面实例代码第4行;最后一种是针对多个数据的读取,使用FileNode对应的迭代器FileNodeIterator进行逐个读取数据,如下面实例代码第28行。

  1. FileStorage fs2("test.yml",FileStorage::READ);
  2.  
  3. // first method: use (type) operator on FileNode.
  4. int frameCount = (int)fs2["frameCount"];
  5.  
  6. std::string date;
  7. // second method: use FileNode::operator >>
  8. fs2["calibrationDate"] >> date;
  9.  
  10. Mat cameraMatrix2,distCoeffs2;
  11. fs2["cameraMatrix"] >> cameraMatrix2;
  12. fs2["distCoeffs"] >> distCoeffs2;
  13.  
  14. cout << "frameCount: " << frameCount << endl
  15. << "calibration date: " << date << endl
  16. << "camera matrix: " << cameraMatrix2 << endl
  17. << "distortion coeffs: " << distCoeffs2 << endl;
  18.  
  19. FileNode features = fs2["features"];
  20. FileNodeIterator it = features.begin(),it_end = features.end();
  21. int idx = 0;
  22. std::vector<uchar> lbpval;
  23.  
  24. // iterate through a sequence using FileNodeIterator
  25. for( ; it != it_end; ++it,idx++ )
  26. {
  27. cout << "feature #" << idx << ": ";
  28. cout << "x" << (int)(*it)["x"] << ",y" << (int)(*it)["y"] << ",lbp: (";
  29. // you can also easily read numerical arrays using FileNode >> std::vector operator.
  30. (*it)["lbp"] >> lbpval;
  31. for( int i = 0; i < (int)lbpval.size(); i++ )
  32. cout << " " << (int)lbpval[i];
  33. cout << ")" << endl;
  34. }
  35. fs.release();

之前一直使用libconfig作为参数配置的库,但是既然OpenCV也有这方面的功能,考虑到不需要安装额外的库,还是打算转向使用这个东西,这里做个简单介绍算是以后查询使用

猜你在找的XML相关文章