cv::FileStorage读写文件

#转载于https://blog.csdn.net/learning_tortosie/article/details/97815514

数据存储

OpenCV提供了一种序列化和反序列化的机制,用于将不同数据类型的数据以YAML或XML格式写入磁盘或者从磁盘读取。这种方法可以用来加载或者保存任何OpenCV的数值变量(包括基本数据变量,像int和float等)到一个文件中。

上述文件读写的基本机制是建立在cv::FileStorage对象基础上的,cv::FileStorage实际代表磁盘中的一个文件,但与普通方式不同的是,它让人们以一种简单而自然的方式访问文件中的数据。

cv::FileStorage的写入

cv::FileStorage对象代表一个YAML或XML格式的文件。你可以给定文件名参数创建一个cv::FileStorage对象或者使用默认构造函数创建一个未打开的cv::FileStorage对象,稍后再使用cv::FileStorage::open()函数打开。flag参数可以为cv::FileStorage::WRITE或cv::FileStorage::APPEND。

FileStorage::open(string fileName, int flag);

   
   
  • 1

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

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

myFileStorage << "someInteger" << 27;                               //保存一个整数
myFileStorage << "anArray" << cv::Mat::eye(3,3,CV_32F);             //保存一个数组

   
   
  • 1
  • 2

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

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

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

   
   
  • 1
  • 2
  • 3

一旦完成创建一个mapping,需要按顺序输入条目名以及对应的值。如果创建的是sequence,只需要一个接一个地输入元素即可,知道sequence结束。

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

   
   
  • 1
  • 2
  • 3

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

示例:使用cv::FileStorage创建一个test.yaml文件

#include <opencv2/opencv.hpp>
#include <time.h>

using namespace cv;

int main() {

FileStorage <span class="token function">fs</span><span class="token punctuation">(</span><span class="token string">"test.yaml"</span><span class="token punctuation">,</span> FileStorage<span class="token punctuation">:</span><span class="token punctuation">:</span>WRITE<span class="token punctuation">)</span><span class="token punctuation">;</span>

fs <span class="token operator">&lt;&lt;</span> <span class="token string">"frameCount"</span> <span class="token operator">&lt;&lt;</span> <span class="token number">5</span><span class="token punctuation">;</span>

time_t rawtime<span class="token punctuation">;</span> <span class="token function">time</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>rawtime<span class="token punctuation">)</span><span class="token punctuation">;</span>
fs <span class="token operator">&lt;&lt;</span> <span class="token string">"calibrationDate"</span> <span class="token operator">&lt;&lt;</span> <span class="token function">asctime</span><span class="token punctuation">(</span><span class="token function">localtime</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>rawtime<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

Mat cameraMatrix <span class="token operator">=</span> <span class="token punctuation">(</span>
        Mat_<span class="token operator">&lt;</span><span class="token keyword">double</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span>
                <span class="token operator">&lt;&lt;</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">320</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token number">240</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span>
        <span class="token punctuation">)</span><span class="token punctuation">;</span>

Mat distCoeffs <span class="token operator">=</span> <span class="token punctuation">(</span>
        Mat_<span class="token operator">&lt;</span><span class="token keyword">double</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span>
                <span class="token operator">&lt;&lt;</span> <span class="token number">0.1</span><span class="token punctuation">,</span> <span class="token number">0.01</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.001</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span>
        <span class="token punctuation">)</span><span class="token punctuation">;</span>

fs <span class="token operator">&lt;&lt;</span> <span class="token string">"cameraMatrix"</span> <span class="token operator">&lt;&lt;</span> cameraMatrix <span class="token operator">&lt;&lt;</span> <span class="token string">"distCoffes"</span> <span class="token operator">&lt;&lt;</span> distCoeffs<span class="token punctuation">;</span>

fs <span class="token operator">&lt;&lt;</span> <span class="token string">"features"</span> <span class="token operator">&lt;&lt;</span> <span class="token string">"["</span><span class="token punctuation">;</span>
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    <span class="token keyword">int</span> x <span class="token operator">=</span> <span class="token function">rand</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">640</span><span class="token punctuation">;</span>
    <span class="token keyword">int</span> y <span class="token operator">=</span> <span class="token function">rand</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">480</span><span class="token punctuation">;</span>
    uchar lbp <span class="token operator">=</span> <span class="token function">rand</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">256</span><span class="token punctuation">;</span>

    fs <span class="token operator">&lt;&lt;</span> <span class="token string">"{:"</span> <span class="token operator">&lt;&lt;</span> <span class="token string">"x"</span> <span class="token operator">&lt;&lt;</span> x <span class="token operator">&lt;&lt;</span> <span class="token string">"y"</span> <span class="token operator">&lt;&lt;</span> y <span class="token operator">&lt;&lt;</span> <span class="token string">"lbp"</span> <span class="token operator">&lt;&lt;</span> <span class="token string">"[:"</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">8</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>
        fs <span class="token operator">&lt;&lt;</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>lbp <span class="token operator">&gt;&gt;</span> j<span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    fs <span class="token operator">&lt;&lt;</span> <span class="token string">"]"</span> <span class="token operator">&lt;&lt;</span> <span class="token string">"}"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
fs <span class="token operator">&lt;&lt;</span> <span class="token string">"]"</span><span class="token punctuation">;</span>

fs<span class="token punctuation">.</span><span class="token function">release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

CmakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(write_yaml_using_FileStorage)

set(CMAKE_CXX_STANDARD 14)

set(OpenCV_DIR “/opt/ros/kinetic/share/OpenCV-3.3.1-dev”)
message(${ OpenCV_DIR})
find_package( OpenCV 3 REQUIRED )

add_executable(write_yaml_using_FileStorage main.cpp)

target_link_libraries( write_yaml_using_FileStorage ${ OpenCV_LIBS} )

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

程序运行结果如下:

%YAML:1.0
---
frameCount: 5
calibrationDate: "Tue Jul 30 20:48:34 2019\n"
cameraMatrix: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
distCoffes: !!opencv-matrix
   rows: 5
   cols: 1
   dt: d
   data: [ 1.0000000000000001e-01, 1.0000000000000000e-02,
       -1.0000000000000000e-03, 0., 0. ]
features:
   - { x:103, y:166, lbp:[ 1, 0, 0, 1, 0, 1, 1, 0 ] }
   - { x:115, y:113, lbp:[ 1, 1, 1, 1, 1, 1, 1, 1 ] }
   - { x:586, y:12, lbp:[ 1, 0, 0, 1, 0, 1, 0, 0 ] }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这个示例代码中,你会注意到有时候mapping或sequence的所有数据在一行,有时候每个元素一行。这并不是自动格式化造成的,而是由于mapping的起始字符"{:“和”}",sequence的起始字符"[:“和”]"的变化造成的。这个特点只对YAML格式的输出有意义,如果输出文件是XML格式,那么这些细微的差别将会被忽略,mapping与sequence的存储将不会有区别。

使用cv::FileStorage读取文件

cv::FileStorage对象在打开之后,既可以用来写入,也可以用来读取。唯一的区别是flag的值为cv::FileStorage::READ。跟写入时一样,也可以用默认构造函数创建一个未打开的FileStorage对象,之后再通过调用cv::FileStorage::open()函数打开。

FileStorage::open(string fileName, int flag);

 
 
  • 1

一旦文件被打开,接下来便可对其中的数据进行读取,首先需要确定你要访问的数据名
,即FileStorage最顶层的mapping中的关键字,可以通过重载操作符cv::FileStorage::operator获取自己需要的数据。然而,该操作符的返回值并不是你想要的数据,而是一个FileNode对象。

接下里,如果该值是基本数据类型,则可以通过强制类型转换直接读取,如果该数据是一个mapping对象,可以通过重载操作符[ ],并给定所需关键字访问,如果该数据为sequence对象,可以通过重载的[ ]和一个整型参数访问其中的数据,也可以通过cv::FileNodeIterator迭代器进行访问。在完成读取之后,记得调用成员函数cv::FileStorage::release()关闭文件。

cv::FileNode

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

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

 
 
  • 1
  • 2

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

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

 
 
  • 1
  • 2

与下面这种方式等价:

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

 
 
  • 1
  • 2

使用迭代器可以完成对FileNode的遍历。给定一个cv::FileNode对象,成员函数cv::FileNode::begin()和cv::FileNode::end()可以分别返回该mapping或sequence的首元素的迭代器和末尾元素的迭代器。该迭代对象可以通过cv::FileNodeIterator::operator*()操作符来进行解引用操作并返回迭代器对应的位置的FileNode对象。这些迭代器支持常见的自增以及自减操作符。

示例:使用cv::FileNode读取test.yaml文件

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(){
cv::FileStorage fs2(“test.yaml”, cv::FileStorage::READ);

<span class="token keyword">int</span> frameCount <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>fs2<span class="token punctuation">[</span><span class="token string">"frameCount"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

std<span class="token punctuation">:</span><span class="token punctuation">:</span>string date<span class="token punctuation">;</span>
fs2<span class="token punctuation">[</span><span class="token string">"calibrationDate"</span><span class="token punctuation">]</span> <span class="token operator">&gt;&gt;</span> date<span class="token punctuation">;</span>

cv<span class="token punctuation">:</span><span class="token punctuation">:</span>Mat cameraMatrix<span class="token punctuation">,</span> distCoeffs2<span class="token punctuation">;</span>
fs2<span class="token punctuation">[</span><span class="token string">"cameraMatrix"</span><span class="token punctuation">]</span> <span class="token operator">&gt;&gt;</span> cameraMatrix<span class="token punctuation">;</span>
fs2<span class="token punctuation">[</span><span class="token string">"distCoffes"</span><span class="token punctuation">]</span> <span class="token operator">&gt;&gt;</span> distCoeffs2<span class="token punctuation">;</span>


cout <span class="token operator">&lt;&lt;</span> <span class="token string">"frameCount: "</span>         <span class="token operator">&lt;&lt;</span> frameCount     <span class="token operator">&lt;&lt;</span> endl
      <span class="token operator">&lt;&lt;</span> <span class="token string">"calibration date: "</span>   <span class="token operator">&lt;&lt;</span> date          <span class="token operator">&lt;&lt;</span> endl
      <span class="token operator">&lt;&lt;</span> <span class="token string">"camera matrix: "</span>      <span class="token operator">&lt;&lt;</span> cameraMatrix  <span class="token operator">&lt;&lt;</span> endl
      <span class="token operator">&lt;&lt;</span> <span class="token string">"distoration coeffs: "</span> <span class="token operator">&lt;&lt;</span> distCoeffs2   <span class="token operator">&lt;&lt;</span> endl<span class="token punctuation">;</span>

cv<span class="token punctuation">:</span><span class="token punctuation">:</span>FileNode features <span class="token operator">=</span> fs2<span class="token punctuation">[</span><span class="token string">"features"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
cv<span class="token punctuation">:</span><span class="token punctuation">:</span>FileNodeIterator it <span class="token operator">=</span> features<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> it_end <span class="token operator">=</span> features<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> idx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
std<span class="token punctuation">:</span><span class="token punctuation">:</span>vector<span class="token operator">&lt;</span>uchar<span class="token operator">&gt;</span> lbpval<span class="token punctuation">;</span>
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token punctuation">;</span> it <span class="token operator">!=</span> it_end<span class="token punctuation">;</span> <span class="token operator">++</span>it<span class="token punctuation">,</span> <span class="token operator">++</span>idx<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
    cout <span class="token operator">&lt;&lt;</span> <span class="token string">"feature #"</span> <span class="token operator">&lt;&lt;</span> idx <span class="token operator">&lt;&lt;</span> <span class="token string">": "</span><span class="token punctuation">;</span>
    cout <span class="token operator">&lt;&lt;</span> <span class="token string">"x="</span> <span class="token operator">&lt;&lt;</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token string">"x"</span><span class="token punctuation">]</span> <span class="token operator">&lt;&lt;</span> <span class="token string">", y="</span> <span class="token operator">&lt;&lt;</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token string">"y"</span><span class="token punctuation">]</span> <span class="token operator">&lt;&lt;</span> <span class="token string">", lbp: ("</span><span class="token punctuation">;</span>

    <span class="token punctuation">(</span><span class="token operator">*</span>it<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token string">"lbp"</span><span class="token punctuation">]</span> <span class="token operator">&gt;&gt;</span> lbpval<span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>lbpval<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">" "</span> <span class="token operator">&lt;&lt;</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>lbpval<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
    cout <span class="token operator">&lt;&lt;</span> <span class="token string">")"</span> <span class="token operator">&lt;&lt;</span> endl<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
fs2<span class="token punctuation">.</span><span class="token function">release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

程序运行结果如下:
在这里插入图片描述

参考

《学习OpenCV 3》(中文版)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值