16.物体识别的重要数据文件(XML和YAML文件) --- OpenCV从零开始到图像(人脸 + 物体)识别系列


本文作者:小嗷

微信公众号: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从零开始到图像(人脸 + 物体)识别系列

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容