rpfly3
rpfly3

Reputation: 13

Yaml File Format used in OpenCV

Here is a example (part of code) from OpenCV (https://docs.opencv.org/3.4.0/d4/da4/group__core__xml.html):

test.yml

%YAML:1.0
---
frameCount: 5

read.cpp

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

using namespace cv;
using namespace std;

int main()
{
    FileStorage fs("test.yml", FileStorage::READ);
    int frameCount = (int) fs["frameCount"];
    cout << frameCount << endl;
    return 0;
}

Given the code, it works well and reads the yaml file. But when I remove %YAML:1.0, the code throws:

OpenCV Error: Unknown error code -49 (Input file is empty) in cvOpenFileStorage, file /home/pengfei/Documents/opencv-3.3.1/modules/core/src/persistence.cpp, line 4484
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/pengfei/Documents/opencv-3.3.1/modules/core/src/persistence.cpp:4484: error: (-49) Input file is empty in function cvOpenFileStorage

[1]    27146 abort (core dumped)  ./Read

But I checked the yaml.org. There is no rule stating %YAML:1.0 is necessary. (http://yaml.org/start.html)

**My questions are (updated according to answer from @zindarod ): **

1. Is this OpenCV specific feature??

Yes, this is OpenCV specific requirment.

const char* yaml_signature = "%YAML";
const char* json_signature = "{";
const char* xml_signature  = "<?xml";

OpenCV checks the file signature, then decide how to interpret the file.

2. How to know the yaml version I should use??

The yaml verison doesn't matter too much.

But it's better to use 1.0 specification. Probably OpenCV cannot parse other new specifications.

Upvotes: 1

Views: 1546

Answers (1)

zindarod
zindarod

Reputation: 6468

In OpenCV-3.3.1 in function cvOpenFileStorage located at /modules/core/src/persistence.cpp:

...

else
    {
        if( mem )
        {
            fs->strbuf = filename;
            fs->strbufsize = fnamelen;
        }

        size_t buf_size = 1 << 20;
        const char* yaml_signature = "%YAML";
        const char* json_signature = "{";
        const char* xml_signature  = "<?xml";
        char buf[16];
        icvGets( fs, buf, sizeof(buf)-2 );
        char* bufPtr = cv_skip_BOM(buf);
        size_t bufOffset = bufPtr - buf;

        if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0)
            fs->fmt = CV_STORAGE_FORMAT_YAML;
        else if(strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0)
            fs->fmt = CV_STORAGE_FORMAT_JSON;
        else if(strncmp( bufPtr, xml_signature, strlen(xml_signature) ) == 0)
            fs->fmt = CV_STORAGE_FORMAT_XML;
        else if(fs->strbufsize  == bufOffset)
            CV_Error(CV_BADARG_ERR, "Input file is empty");

...

OpenCV checks for file signature (json, yaml and xml). The version of YAML does not matter, as long as the first line contains the string "%YAML" in it.

Upvotes: 3

Related Questions