我们可以将various OpenCV 的 data strucures 以及C++ 中的primitive data structures 写入到XML 格式 或者 YAML 格式的文件中去, 也可以从这些文件中读取我们存储进去的Open data structures 或者 primitive data structures。 XML 文件就是可扩展标记语言。 用来标记数据, 定义数据类型。
使用如下的procedures 进行write something to xml or yaml, xml 和yaml 格式的文件的后缀名字是'.xml' 和 '.yml'/ '.yaml'。
(1)创建 FileStorage 的 object, 并open it for writing。 可以使用FileStorage::FileStorage() 的constructor进去文件名字。 也可以先使用default constructor, 然后
调用 FileStorage::open()。
(2)使用 << 写入到文件中, >> 读取文件中的数据。
(3) 使用 FileStorage::release() close the file。 FileStorage 的destructor also closes the file。
为了解释下面的程序, 我们需要介绍如下的几个程序:
头文件<ctime>
//defined in header file <ctime>
// typedef /*unspecified*/ time_t
// arithmetic type capable of representing times
// almost always an integral value holding the number of seconds since 00:00, Jan 1, 1970 UTC
time_t
函数 std:: time也定义在<ctime>下面:
函数的prototype:
std::time_t time( std::time_t *time );
description:
Returns the current calendar time encoded as a std::time_t object.
如果time 指针不是NULL, 即不是 time(nullptr), 而是time(seconds)形式, 那么返回的值也存储在seconds中指向的位置。
<ctime>中localtime() 函数:
作用是converts time since epoch to calendar time expressed as local time。
std::tm* localtime( const std::time_t *time );
其中tm 是一个time的structure:
struct tm {
int tm_sec; /* seconds, range 0 to 59 */
int tm_min; /* minutes, range 0 to 59 */
int tm_hour; /* hours, range 0 to 23 */
int tm_mday; /* day of the month, range 1 to 31 */
int tm_mon; /* month, range 0 to 11 */
int tm_year; /* The number of years since 1900 */
int tm_wday; /* day of the week, range 0 to 6 */
int tm_yday; /* day in the year, range 0 to 365 */
int tm_isdst; /* daylight saving time */
};
<ctime>中asctime() 函数:
prototype:
char* asctime( const std::tm* time_ptr );
如下作用:
Converts given calendar time std::tm to a textual representation. The resulting string has the following format:
Www Mmm dd hh:mm:ss yyyy
Www - the day of the week (one of Mon, Tue, Wed, Thu, Fri, Sat, Sun).
Mmm - the month (one of Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec).
dd - the day of the month
hh - hours
mm - minutes
ss - seconds
yyyy - years
测试程序如下:
#include <ctime>
#include <iostream>
int main()
{
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result))
<< result << " seconds since the Epoch\n";
}
Output:
Wed Sep 21 10:27:52 2011
1316615272 seconds since the Epoch
#define<span style="white-space:pre"> </span>RAND_MAX<span style="white-space:pre"> </span>0x7FFF
) 注意产生的随机数的范围为[0, RAND_MAX].
产生规定范围的随机数的方法如下:
v1 = rand() % 100; // v1 in the range 0 to 99
v2 = rand() % 100 + 1; // v2 in the range 1 to 100
v3 = rand() % 30 + 1985; // v3 in the range 1985-2014
另外, 还有函数srand() 函数, 需要喂进去一种子。例如:
srand (time(NULL));
最后关于C++的 bit shift operator:
分为左移和右移, 左移是在数字的二进制表示后面移位补0,右移是在左边移位补0(右移的时候, 如果是有符号的数, 需要extends the top bit) :
The shift operators bitwise shift the value on their left by the number of bits on their right:-
<< shifts left and adds zeros at the right end.
>> shifts right and adds either 0s, if value is an unsigned type, or extends the top bit (to preserve the sign) if its a signed type.
所以有:
2 << 4 为32,
-8 >> 3 是 -1。
opencv 相关程序如下:
#include <opencv2/opencv.hpp>
#include <ctime>
using namespace cv;
int main() {
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "frameCount" << 5;
time_t rawtime;
time(&rawtime);
fs << "calibrate" << asctime(localtime(&rawtime));
Mat cameraMatrix = (Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
Mat distCoeffs = (Mat_<double>(5, 1) << 0.1, 0.01, -0.01, 0, 0);
fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
fs << "features" << "[";
for(int i = 0; i < 3; i++) {
int x = rand() % 640; // [0, 639]
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();
return 0;
}
运行后test.yml 文件如下:
%YAML:1.0
frameCount: 5
calibrate: "Tue Jan 06 13:57:03 2015\n"
cameraMatrix: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
distCoeffs: !!opencv-matrix
rows: 5
cols: 1
dt: d
data: [ 1.0000000000000001e-001, 1.0000000000000000e-002,
-1.0000000000000000e-002, 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 ] }
现在将上述的程序的行:
FileStorage fs("test.yml", FileStorage::WRITE);
改为.xml 的文件后缀 其余不变:
FileStorage fs("test.xml", FileStorage::WRITE);
再次编译运行程序, 打开test.xml 文件, 内容如下:
<?xml version="1.0"?>
<opencv_storage>
<frameCount>5</frameCount>
<calibrate>"Tue Jan 06 14:04:03 2015
"</calibrate>
<cameraMatrix type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
1000. 0. 320. 0. 1000. 240. 0. 0. 1.</data></cameraMatrix>
<distCoeffs type_id="opencv-matrix">
<rows>5</rows>
<cols>1</cols>
<dt>d</dt>
<data>
1.0000000000000001e-001 1.0000000000000000e-002
-1.0000000000000000e-002 0. 0.</data></distCoeffs>
<features>
<_><x>41</x>
<y>227</y>
<lbp>
0 1 1 1 1 1 0 1</lbp></_>
<_><x>260</x>
<y>449</y>
<lbp>
0 0 1 1 0 1 1 0</lbp></_>
<_><x>598</x>
<y>78</y>
<lbp>
0 1 0 0 1 0 1 0</lbp></_></features>
</opencv_storage>