Overview
- Year: 2016
- Project: Update OpenCV FileStorage
- Organization: OpenCV
- Mentor: Vadim Pisarevsky
- Student: Iric Wu
Work Summary
- Add Base64 support for storing numerical data.
- Add JSON support for persistence.
Pull Request | Status | Description |
---|---|---|
#6697 | Merged | Add Base64 support for reading and writing XML\YML file. |
#6949 | Merged | Update Base64 functions, tests and docs. Make it user-friendly. |
#7088 | Merged | Add JSON support, tests and docs. |
New Features
Base64 Support
Why
When a matrix contains lots of data, we don't care about readability but want to store data in a faster way. Base64 encoding will be much faster than the old way.
Example
Code:
cv::Mat mat = (cv::Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
cv::FileStorage fs("test.yml", cv::FileStorage::WRITE); // or cv::FileStorage::WRITE_BASE64
fs << "mat" << mat;
fs.release();
Non-Base64 Output (old):
%YAML 1.0
---
mat: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
Base64 Output (new):
%YAML 1.0
---
mat: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: !!binary |
MWQgICAgICAgICAgICAgICAgICAgICAgAAAAAABAj0AAAAAAAAAAAAAAAAAAAHRA
AAAAAAAAAAAAAAAAAECPQAAAAAAAAG5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPA/
JSON Support
Why
JSON is popular in recent years. But cv::FileStorage
doesn't support it. I add this feature.
Example
Code:
#include "opencv2/opencv.hpp"
#include <time.h>
using namespace cv;
int main(int, char** argv)
{
FileStorage fs("test.json?base64", FileStorage::WRITE);
fs << "frameCount" << 5;
time_t rawtime; time(&rawtime);
fs << "calibrationDate" << 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.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();
return 0;
}
JSON Output:
{
"frameCount": 5,
"calibrationDate": "Thu Aug 18 23:09:36 2016\n",
"cameraMatrix": {
"type_id": "opencv-matrix",
"rows": 3,
"cols": 3,
"dt": "d",
"data": "$base64$MWQgICAgICAgICAgICAgICAgICAgICAgAAAAAABAj0AAAAAAAAAAAAAAAAAAAHRAAAAAAAAAAAAAAAAAAECPQAAAAAAAAG5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPA/"
},
"distCoeffs": {
"type_id": "opencv-matrix",
"rows": 5,
"cols": 1,
"dt": "d",
"data": "$base64$MWQgICAgICAgICAgICAgICAgICAgICAgmpmZmZmZuT97FK5H4XqEP/yp8dJNYlC/AAAAAAAAAAAAAAAAAAAAAA=="
},
"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 ] }
]
}
Improvement
This is a benchmark on my machine for both writing and reading massive data:
- OpenCV Version: 3.1.0-dev.
- OS: Windows 10.
- Build Type: Win32 + Release.
- CPU: Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz (OpenCL 1.2 (Build 76427))
File Type | Encoding | Data Type | Time (ms) for writing and reading a 1080P matrix |
---|---|---|---|
XML | non | unsigned char | 1082 |
YAML | non | unsigned char | 1010 |
JSON | non | unsigned char | 1082 |
XML | non | float | 8405 |
YAML | non | float | 7408 |
JSON | non | float | 7874 |
XML | Base64 | unsigned char | 573 |
YAML | Base64 | unsigned char | 456 |
JSON | Base64 | unsigned char | 399 |
XML | Base64 | float | 1578 |
YAML | Base64 | float | 1034 |
JSON | Base64 | float | 855 |
The result shows an obvious improve on speed.