Overview


Work Summary

  1. Add Base64 support for storing numerical data.
  2. 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.

results matching ""

    No results matching ""