美文网首页
16.物体识别的重要数据文件(XML和YAML文件) --- O

16.物体识别的重要数据文件(XML和YAML文件) --- O

作者: 小嗷_a2e2 | 来源:发表于2018-06-04 11:46 被阅读200次

本文作者:小嗷

微信公众号:aoxiaoji

吹比QQ群:736854977

微信链接:https://mp.weixin.qq.com/s?__biz=MzU1MTgxNjQyMg==&mid=2247483815&idx=1&sn=c2425daece5edecbd46a16766df569ff&chksm=fb8adc2eccfd5538f63cdcb873b1f703217afd5e7e26d392f83d1c8b1fb3f590a8d495460e18#rd


image

Google、百度、face++、凡是涉及有关物体识别公司,他们最值钱不是算法什么,而是那份保存成千上万样本文件。当然,文件格式也是千奇百怪。今天就说说最经常用到文件格式XML。

如果大家有做过人脸识别就可以体会到,用主分量分析法得到的特征脸、平均脸等等数据都会被保存成为XML格式

image

本文你会找到以下问题的答案:

  1. 如何使用YAML或XML文件打印和读取文本条目到文件和OpenCV中?

  2. 如何对OpenCV数据结构进行同样的操作?

  3. 如何为您的数据结构做这些?

  4. 使用OpenCV数据结构,如cv::FileStorage, cv::FileNode或cv::FileNodeIterator。

用途:生成数据文件(如下官方自带生成的识别文件)

image

haarcascadeeye和haarcascadesmile分别代表是眼睛识别和微笑识别的数据文件

image

YAML:http://www.yaml.org

XML :http://www.w3c.org/XML

3.1 FileStorage

XML/YAML/JSON文件存储类,它封装了从文件中写入或读取数据所需的所有信息。

API函数网址:

https://docs.opencv.org/master/da/d56/classcv11FileStorage.html#details

(1)实例化一个FileStorage类的对象,用默认带参数构造,完成初始化,或者用FileStorage::open()成员函数辅助初始化。当然,FileStorage构造函数一共有三个具体情况,视情况而定。

image

如上图FileStorage构造函数第二个:

参数
filename:要打开的文件的名称或文本字符串来读取数据。
flags:选择操作模式。
encoding:文件的编码。
注意,目前不支持UTF-16 XML编码,您应该使用8位编码而不是它。

flags:操作模式有如下

image

读写添加,还有保存在内存缓冲区里,什么格式等等。

(2)使用流操作符<<进行文件写入操作,或者>>进行文件读取操作,类似C++中的文件输入输出流。

(3)使用FileStorage::release()函数析构掉FileStorage类对象,同时关闭文件

也就是我们只需要完成FileStorage三部曲,就学习这种OpenCV基础及重要的XML,JSON,YXML读取写入操作。

当然,各位可能说如何创建一个新的XML文件?

默认打开的时候,如果没有该文件就自动创建文件,打开成功fout返回true,利用true来判断是否创建成功。VC++代码如下:

 1// ConsoleApplication3.cpp : 定义控制台应用程序的入口点。 2// 3#include "stdafx.h" 4#include <iostream> 5#include <fstream> 6using namespace std; 7int main() 8{ 9    char *path;10    string ns = "C://1.txt";11    path = (char*)ns.c_str();12    ofstream fout;13    fout.open(path);14    if (fout) { // 如果创建成功15        fout << 123 << endl; // 使用与cout同样的方式进行写入16        fout.close();  // 执行完操作后关闭文件句柄17    }18    else19    {20        getchar();21    }22    return 0;23}

结果如下

image image

任务一:XML与YAML的文件写入

任务二:XML与YAML的文件写入

步骤:

第一步:XML、YAML文件的打开

在Opencv中,使用FileStorage进行文件读写。XML文件操作与YAML一样,不过存在一些细小差别。

1string fileName = "abc.xml" 2// write file3FileStorage fs(fileName , FileStorage::WRITE);4// read file5FileStorage fs2(fileName, FileStorage::READ);6// or use: cv::FileStorage::open7fs2.open(fileName , FileStorage::READ);

文档打开后很关心的一件事就是,进行确认是否成功。FileStorage有自己的成员函数返回文件打开状态:

 1// bool FileStorage::isOpened() const; 2if ( !fs.isOpened() ) // failed 3{ 4    cout<<"Save File Failed!"<<endl; 5    return ; 6} 7else // succeed 8{ 9    ...10}

第二步:进行文件读写操作

FileStorage文件读与写的方法与C++语言中的文件流对象的使用很像,对>>和<<进行了重载,分别用于文件读取和写入。很棒的是,FileStorage支持一些常用格式的直接读写,例如字符、字符串、数字、cv::Mat等。对于不支持的数据结构,只能按照规则自己去写啦~

1fs << "frameCount" << 5;  // 字符和数字2Mat_<double> cameraMat = Mat_<double>::zeros(3, 3); 3fs << "Camera Intrinsic Matrix" << cameraMat; 

注意:

  • fs << "frameCount" <<5中""内输出的字符串是有限制的,对于YAML有效范围是:[a-z],[A-Z],[0-9],”-“,”_”和空格。XML与YAML基本一致,但是YAML字符之间加空格是允许的,XML不允许。如果出现以下BUG,请不要慌张,检查一下输入的字符是否有效就OK~
image

读取

文件读取的方法有两种:

1// first method: use (type) operator on FileNode.2int frameCount = (int)fs2["frameCount"];3// second second method: use cv::FileNode::operator >>4int frameCount;5fs2["frameCount"] >> frameCount;

读写还有类型如下

  1. Input and Output of text and numbers.

  2. Input/Output of OpenCV Data structures. (opencv自带Mat)

  3. Input/Output of vectors (arrays) and associative maps.(数组和maps)

  4. Read and write your own data structures.(你自己的数据类型)

具体查考:

https://docs.opencv.org/master/dd/d74/tutorialfileinputyml.htmlwithxmlyml.html

第三步:文件关闭

fs.release();

写入XML或YAML文件

代码如下

image
 1//---------------------------------【头文件、命名空间包含部分】------------------------------- 2//      描述:包含程序所使用的头文件和命名空间 3//------------------------------------------------------------------------------------------------ 4#include "opencv2/opencv.hpp"   5#include <time.h>   6using namespace cv;   7//-----------------------------------【main( )函数】-------------------------------------------- 8//  描述:控制台应用程序的入口函数,我们的程序从这里开始 9//-----------------------------------------------------------------------------------------------10int main( )  11{  12    //改变console字体颜色13    system("color 5F"); 14    //初始化15    FileStorage fs("test.yaml", FileStorage::WRITE);  16    //开始文件写入17    fs << "frameCount" << 5;  18    time_t rawtime; time(&rawtime);  19    fs << "calibrationDate" << asctime(localtime(&rawtime));  20    Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);  21    Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);  22    fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;  23    fs << "features" << "[";  24    for( int i = 0; i < 3; i++ )  25    {  26        int x = rand() % 640;  27        int y = rand() % 480;  28        uchar lbp = rand() % 256;  29        fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";  30        for( int j = 0; j < 8; j++ )  31            fs << ((lbp >> j) & 1);  32        fs << "]" << "}";  33    }  34    fs << "]";  35    fs.release();  36    printf("\n文件读写完毕,请在工程目录下查看生成的文件~");37    getchar();38    return 0;  39}  

读XML或YAML文件

代码如下:

image.gif
 1//---------------------------------【头文件、命名空间包含部分】------------------------------- 2//      描述:包含程序所使用的头文件和命名空间 3//------------------------------------------------------------------------------------------------        4#include "opencv2/opencv.hpp"   5#include <time.h>   6using namespace cv; 7using namespace std; 8int main() 9{10    //改变console字体颜色11    system("color 6F");12    //初始化13    FileStorage fs2("test.yaml", FileStorage::READ);14    // 第一种方法,对FileNode操作15    int frameCount = (int)fs2["frameCount"];16    std::string date;17    // 第二种方法,使用FileNode运算符> > 18    fs2["calibrationDate"] >> date;19    Mat cameraMatrix2, distCoeffs2;20    fs2["cameraMatrix"] >> cameraMatrix2;21    fs2["distCoeffs"] >> distCoeffs2;22    cout << "frameCount: " << frameCount << endl23        << "calibration date: " << date << endl24        << "camera matrix: " << cameraMatrix2 << endl25        << "distortion coeffs: " << distCoeffs2 << endl;26    FileNode features = fs2["features"];27    FileNodeIterator it = features.begin(), it_end = features.end();28    int idx = 0;29    std::vector<uchar> lbpval;30    //使用FileNodeIterator遍历序列31    for (; it != it_end; ++it, idx++)32    {33        cout << "feature #" << idx << ": ";34        cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";35        // 我们也可以使用使用filenode > > std::vector操作符很容易的读数值阵列36        (*it)["lbp"] >> lbpval;37        for (int i = 0; i < (int)lbpval.size(); i++)38            cout << " " << (int)lbpval[i];39        cout << ")" << endl;40    }41    fs2.release();42    //程序结束,输出一些帮助文字43    printf("\n文件读取完毕,请输入任意键结束程序~");44    getchar();45    return 0;46}

FileNode类的API网址:

https://docs.opencv.org/master/de/dd9/classcv11FileNode.html

如果不懂的话,QQ或者微信公众号通知一声。

image.gif

1.写操作效果图

image

2.读操作效果图

image image
  1. 本人是抱着玩一玩的心态,学习opencv(其实深度学习没有外界说的这么高深,小嗷是白板,而且有工作在身并且于代码无关)

  2. 大家可以把我的数学水平想象成初中水平,毕竟小嗷既不是代码靠吃饭又不是靠数学吃饭,毕业N年

  3. 写文章主要是为了后人少走点弯路,多交点朋友,一起学习

  4. 如果有好的图像识别群拉我进去QQ:631821577

  5. 就我一个白板,最后还是成的,你们别怕,慢慢来把

image

分享可以无数次,转载成自己文章QQ邮箱通知一下,未经授权请勿转载。

推荐文章:

11.VS2015+OpenCV3.2+QT软件/插件(QT篇1) --- OpenCV从零开始到图像(人脸 + 物体)识别系列

12.QT + OpenCV打包成应用(以及QT图标问题详细) --- OpenCV从零开始到图像(人脸 + 物体)识别系列

相关文章

网友评论

      本文标题:16.物体识别的重要数据文件(XML和YAML文件) --- O

      本文链接:https://www.haomeiwen.com/subject/wizcsftx.html