C/C++开发,opencv基于FileStorage读写文件介绍及示例

目录

一、FileStorage类

        1.1 FileStorage类说明

        1.2 FileStorage类写入说明

        1.3 FileStorage类读取说明

二、FileStorage类应用示例

        2.1 应用代码

        2.2 工程组织(Makefile)

        2.3 编译及测试


一、FileStorage类

        1.1 FileStorage类说明

        FileStorage类在opencv2\core\persistence.hpp中定义:

namespace cv {
//...class CV_EXPORTS_W FileStorage{//...};
}

        FileStorage类支持XML(.xml,<http://www.w3c.org/XML>)、YAML(.yml or .yaml,<http://www.yaml.org>)、JSON(.json,<http://www.json.org/>)格式的文件读写。XML使用嵌套标记来表示层次结构,而YAML则使用缩进(类似于Python编程语言)。

XML:
@code{.xml}<?xml version="1.0"><opencv_storage><A type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>f</dt><data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data></A></opencv_storage>
@endcode
YAML:
@code{.yaml}%YAML:1.0A: !!opencv-matrixrows: 3cols: 3dt: fdata: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
@endcode

        FileStorage类支持默认构造或指定文件名的构造方式:

CV_WRAP FileStorage();
CV_WRAP FileStorage(const String& filename, int flags, const String& encoding=String());

        如果采用默认构造时,需要稍后使用open函数打开指定文件:

CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());

        一旦成功打开了想要写入的文件,便可以像对标准输出流输出数据一样使用操作符cv::FileStorage::operator<<()进行写入操作,或cv::FileStorage::operator>>()进行读取操作。可以以这种简单的方式写入,是因为函数内部为调用开发者完成了许多复杂的工作。

        cv::FileStorage支持读写、追加内容等文件操作,通过内置的枚举值Mode来明确的,需要进行flags指定,flags可以是多个枚举值的并集,例如READ|WRITE。同时还内置了操作状态State,在cv::FileStorage类进行写入数据操作(operator <<)时需要进行cv::FileStorage对象的状态判断:

    //! file storage modeenum Mode{READ        = 0, //!< value, open the file for readingWRITE       = 1, //!< value, open the file for writingAPPEND      = 2, //!< value, open the file for appendingMEMORY      = 4, /**< flag, read data from source or write data to the internal buffer (which isreturned by FileStorage::release) */FORMAT_MASK = (7<<3), //!< mask for format flagsFORMAT_AUTO = 0,      //!< flag, auto formatFORMAT_XML  = (1<<3), //!< flag, XML formatFORMAT_YAML = (2<<3), //!< flag, YAML formatFORMAT_JSON = (3<<3), //!< flag, JSON formatBASE64      = 64,     //!< flag, write rawdata in Base64 by default. (consider using WRITE_BASE64)WRITE_BASE64 = BASE64 | WRITE, //!< flag, enable both WRITE and BASE64};enum State{UNDEFINED      = 0,VALUE_EXPECTED = 1,NAME_EXPECTED  = 2,INSIDE_MAP     = 4};

        1.2 FileStorage类写入说明

        cv::FileStorage内部数据的存储主要有两种形式,“mapping”(键/值对)和“sequence”(一系列未命名的条目)。在最顶层,所写入的数据都在一个mapping中,在该mapping中,可以放置其他的mappings或者sequences,甚至在mapping中继续放入mapping等,只要愿意。

myFileStorage <<"someInteger"<< 27;// save an array
myFileStorage <<"anArray"<<cv::Mat::eye(3,3,CV_32F);// save an integer

        如果要创建一个序列条目,首先你得为它提供一个string类型的名字,接下来才是序列数据。条目内容可以是数字(整型或浮点型等),一个字符串或者别的OpenCV数据类型。

        如果想要创建一个新的mapping或者sequence,可以使用特殊符号{(用于mapping)或者[(用于sequence)。一旦开始创建,就可以为其添加元素,最终以}或者]分别结束一个mapping或者sequence。

myFileStorage <<"theCat"<<"{";
myFileStorage <<"fur"<<"gray"<<"eyes"<<"green"<<"weightLbs"<< 16;
myFileStorage <<"}";

        一旦完成创建一个mapping,需要按顺序输入条目名以及对应的值,像你在最顶层的mapping完成的工作一样。如果创建的是sequence,只需要一个接一个地输入元素即可,直到sequence结束。

myFileStorage<<"theTeam"<<"[";
myFileStorage <<"eddie"<<"tom"<<"scott";
myFileStorage <<"]";

        一旦完成写工作,便可以使用成员函数cv::FileStorage::release()关闭该文件。

        1.3 FileStorage类读取说明

        FileStorage类在使用操作符cv::FileStorage::operator>>()进行读取操作时,实际返回时FileNode类的实例对象。

        FileNode类同样定义在opencv2\core\persistence.hpp中:

namespace cv {
//...class CV_EXPORTS_W_SIMPLE FileNode{//...};
}

        当成功构建一个cv::FileNode对象之后,便可以利用它来完成许多工作。如果它直接表示一个实际的对象(或者一个数字或者字符串),你就可以直接使用重载操作符cv::FileNode::operator>>(),将它的值加载到对应类型的变量之中。

cv::Mat anArray;
myFileStorage["calibrationMatrix"]>> anArray;

       cv::FileNode对象同样支持直接赋值给一些基本数据类型。 cv::FileNode类支持的数据类型如下:

    //! type of the file storage nodeenum{NONE      = 0, //!< empty nodeINT       = 1, //!< an integerREAL      = 2, //!< floating-point numberFLOAT     = REAL, //!< synonym or REALSTR       = 3, //!< text string in UTF-8 encodingSTRING    = STR, //!< synonym for STRSEQ       = 4, //!< sequenceMAP       = 5, //!< mappingTYPE_MASK = 7,FLOW      = 8,  //!< compact representation of a sequence or mapping. Used only by YAML writerUNIFORM   = 8,  //!< if set, means that all the collection elements are numbers of the same type (real's or int's).//!< UNIFORM is used only when reading FileStorage; FLOW is used only when writing. So they share the same bitEMPTY     = 16, //!< empty structure (sequence or mapping)NAMED     = 32  //!< the node has a name (i.e. it is element of a mapping).};

        通过cv::FileNode对象输出操作符获取数据和采用赋值操作符获取数据是等价的:

int aNumber;
myFileStorage["someInteger"]>> aNumber;

        与下面这种方式等价:

int aNumber;
aNumber =(int)myFileStorage["someInteger"];

        针对cv::FileNode类,还提供了一种标准的STL表示法, 即FileNodeIterator,node.begin(),node.end()表示序列的开始和结束,存储在node中,也可以通过operator ++ ()或operator ++ (int)进行移动。

namespace cv {
//...class CV_EXPORTS FileNodeIterator{//...};
}

二、FileStorage类应用示例

        2.1 应用代码

        在opencv2\core\persistence.hpp中,还给出了FileStorage类写入及读取.yml文件的示例代码,本文将在基于该示例代码上,编写一个完整的案例工程,先创建.yml格式文件并写入内容,再通过一个新的FileStorage实例对象读取该文件内存,并解析打印显示相关内容;

        先创建一个目录文件file_storage,在该文件目录下,创建文件main.cpp和Makefile文件,其中main.cpp如下,通过fileCreateAndSave函数创建 一个tets.yml文件并写入数据,再通过fileReadAndShow函数读取该文件内容并打印输出显示。其中main.cpp源码如下:

#include <opencv2/opencv.hpp>
#include <time.h>
#include <iostream>void fileCreateAndSave()
{cv::FileStorage fs("test.yml",cv::FileStorage::WRITE);fs <<"frameCount"<< 5;time_t rawtime; time(&rawtime);fs<<"calibrationDate"<< asctime(localtime(&rawtime));cv::Mat cameraMatrix =(cv::Mat_<double>(3,3)<<1000,0,320,0,1000,240,0,0,1);cv::Mat distCoeffs =(cv::Mat_<double>(5,1)<<0.1,0.01,-0.001,0,0);fs <<"cameraMatrix"<< cameraMatrix<<"distCoeffs"<< distCoeffs;fs <<"features"<<"[";for( int i=0; i<3;i++){int x = rand()% 640;int y = rand()% 480;uchar lbp = rand()% 256;fs<<"{:"<<"x"<<x<<"y"<<y<<"lbp"<<"[:";for( int j=0;j<8;j++)fs <<((lbp >>j)&1);fs<<"]"<<"}";}fs<<"]";fs.release();}void fileReadAndShow()
{cv::FileStorage fs2("test.yml",cv::FileStorage::READ);// first method: use (type) operator on FileNode.int frameCount =(int)fs2["frameCount"];// second method: use cv::FileNode::operator >>//std::string date;fs2["calibrationDate"]  >> date;cv::Mat cameraMatrix2, distCoeffs2;fs2["cameraMatrix"]     >> cameraMatrix2;fs2["distCoeffs"]       >> distCoeffs2;std::cout <<"frameCount:"       << frameCount   <<std::endl<<"calibration date:"   << date         <<std::endl<<"camera matrix:"      << cameraMatrix2<<std::endl<<"distortion coeffs:"  << distCoeffs2  <<std::endl;cv::FileNode features  = fs2["features"];cv::FileNodeIterator it = features.begin(), it_end = features.end();int idx=0;std::vector<uchar> lbpval;// iterate through a sequence using FileNodeIteratorfor(; it != it_end;++it,idx++){std::cout <<"feature #"<<idx<<":";std::cout <<"x="<<(int)(*it)["x"]<<",y="<<(int)(*it)["y"]<<",lbp:(";//(Note: easily read numerical arrays using FileNode >> std::vector.)//(*it)["lbp"]>>lbpval;for( int i=0; i<(int)lbpval.size(); i++)std::cout <<""<<(int)lbpval[i];std::cout <<")"<<std::endl;}fs2.release();
}int main( int argc,char* argv[])
{fileCreateAndSave();fileReadAndShow();return 0;
};

        2.2 工程组织(Makefile)

        工程组织Makefile文件如下(本文是采用win下MinGW方式编译的,如何搭建opencv库+MinGW编译的请参考本专栏的opencv库安装编译博文,C/C++开发,win下OpenCV+MinGW编译环境搭建_搭建mingw编译环境_py_free-物联智能的博客-CSDN博客)。

#/bin/sh
CX= g++ BIN 		:= ./
TARGET      :=  fileStorage.exe
FLAGS		:= -std=c++11 -static
SRCDIR 		:= ./
#INCLUDES
INCLUDEDIR 	:= -I"../../opencv_MinGW/include" 
staticDir   := ../../opencv_MinGW/x64/mingw/staticlib/LIBDIR 	    := -L $(staticDir) -lopencv_world460 -lade -lIlmImf -lquirc -lzlib \-llibjpeg-turbo -llibopenjp2 -llibpng -llibprotobuf -llibtiff -llibwebp \-lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
source		:= $(wildcard $(SRCDIR)/*.cpp) $(TARGET) :$(CX) $(FLAGS) $(INCLUDEDIR) $(source)  -o $(BIN)/$(TARGET) $(LIBDIR)clean:rm  $(BIN)/$(TARGET)

        2.3 编译及测试

        进入file_storage目录,make -j*编译案例,如下:

         运行程序如下:

         输出的test.yml文件如下:

%YAML:1.0
---
frameCount: 5
calibrationDate: "Sun Jul  2 16:49:48 2023\n"
cameraMatrix: !!opencv-matrixrows: 3cols: 3dt: ddata: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
distCoeffs: !!opencv-matrixrows: 5cols: 1dt: ddata: [ 1.0000000000000001e-01, 1.0000000000000000e-02,-1.0000000000000000e-03, 0., 0. ]
features:- { x:41, y:227, lbp:[ 0, 1, 1, 1, 1, 1, 0, 1 ] }- { x:260, y:449, lbp:[ 0, 0, 1, 1, 0, 1, 1, 0 ] }- { x:598, y:78, lbp:[ 0, 1, 0, 0, 1, 0, 1, 0 ] }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/9444.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux搭建Discuz论坛

环境&#xff1a;redhat 9 mysql 8 Discuz 3.5 题目要求&#xff1a;在 bbs.example.com 主机上创建 Discuz 论坛&#xff0c;数据库服务器使用 db.example.com 主机的 bbs 数据库实例&#xff0c;该实例由 MySQL数据库软件提供服务。 题目要求没有说是在一台虚拟机…

jenkins使用ftp工具,上传文件至服务器报错“Could not write file”

一、错误说明 使用ftp上传文件 ERROR: Exception when publishing, exception message [Could not write file. Server message: [553 Could not create file.]]11:12:45 FTP: Connecting from host [test-xxx-java-user-service-3-932ft-hsb69-t5wmf] 11:12:45 FTP: Conne…

Openlayers实战:自定义版权属性信息

Openlayers地图中,通常会展示地图的一个版权信息,这里面涉及到地图层的版权信息内容,还涉及到control中的Attribution的设置,本实战示例中,通过灵活的属性配置,显示了还是大剑师兰特的博客版权信息,点击是可以跳转的。 效果图 源代码 /* * @Author: 大剑师兰特(xiaoz…

亚马逊云科技自研芯片,为企业云服务提高性价比

6月27日至28日&#xff0c;2023亚马逊云科技中国峰会于上海顺利召开。在本次峰会上&#xff0c;似乎找寻到了云计算领域竞争对手均日渐成熟&#xff0c;而亚马逊云科技却能一直保持领先地位的原因——过去的十几年里&#xff0c;亚马逊云科技“基于客户需求&#xff0c;快速进行…

2023,中国电商重回元老时代

中国的历史上不缺“太上皇”&#xff0c;但“太上皇”再度站到台前的很少。公元1457年&#xff0c;被囚禁在南宫的“太上皇”朱祁镇复位&#xff0c;上演了中国历史上少见的南宫复辟。而危机时刻被推举为皇帝的朱祁钰&#xff0c;后来的庙号是代宗&#xff0c;阴阳怪气十足。 …

【Unity实战】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(二)

文章目录 前言一、火箭筒1. 编写火箭筒脚本2. 创建火箭弹和新爆炸特效的预制体3. 编写火箭弹脚本4. 设置好火箭弹和火箭筒的脚本和参数5. 运行效果 二、激光枪1. 编写激光枪脚本2. 先运行游戏&#xff0c;看看效果3. 美化射线4. 完善代码5. 再次运行游戏6. 升级URP项目7. 后处理…

Elasticsearch(1)——倒排索引与HTTP操作Elasticsearch

文章目录 1 前言2 Elasticsearch 安装3 数据格式4 倒排索引5 常用HTTP请求操作Elasticsearch5.1 创建索引5.2 查询索引信息5.3 删除索引5.4 创建/修改文档5.5查找文档5.6局部修改文档5.7删除文档5.8分页查询 1 前言 Elastic Stack 核心产品包括 Elasticsearch【存储数据】、Ki…

【观察者模式】 ——每天一点小知识

&#x1f4a7; 观察者模式 \color{#FF1493}{观察者模式} 观察者模式&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 《数据结构与算法》专栏的文章图文并茂&#x1f995;…

Lucene介绍与入门使用

https://github.com/apache/lucene Lucene简介 Lucene是apache软件基金会4 jakarta项目组的一个子项目&#xff0c;是一个开放源代码的全文检索引擎工具包&#xff0c;但它不是一个完整的全文检索引擎&#xff0c;而是一个全文检索引擎的架构&#xff0c;提供了完整的查询引擎…

【可爱少女】InsCode Stable Diffusion 美图活动一期

在线运行地址 https://inscode.csdn.net/inscode/Stable-Diffusion 模型相关版本和参数配置 Steps&#xff08;采样迭代步数&#xff09;: 20 Sampler&#xff08;采样方法&#xff09;: Euler a 采样迭代步数(Steps)Sampling steps&#xff1a;20 生成批次&#xff1a;1 批次…

QScintilla自制代码编辑器系列(1)编译库文件与运行测试例子

1.下载工程源码 我本人机器上的QT是6.4 可以下载最新的代码 https://www.riverbankcomputing.com/static/Downloads/QScintilla/2.14.0/QScintilla_src-2.14.0.zip 2. 编译生成文件 无需改动可以顺利生成库文件 3. 运行例子 1&#xff09;拷贝头文件 将整个Qsci文件夹拷…

Spark计算引擎介绍

1. Spark是什么 Apache Spark是专为大规模数据处理而设计的快速通用的计算引擎。 Spark是加州大学伯克利分校的AMP实验室&#xff08;Algorithms, Machines and People Lab&#xff09;开源的类Hadoop MapReduce的通用并行框架&#xff0c;拥有Hadoop MapReduce所具有的优点&…