shah
shah

Reputation: 311

Read YAML file in OpenCV

I am using OpenCV to save the .yml. Here is my code that I used

FileStorage fs;
fs.open("test", FileStorage::WRITE);
for (unsigned int i = 0; i < (block_hist_size * blocks_per_img.area()) ; i++ )
{
fs << "features" << dest_ptr[i];
}
fs.release();

Here is the output of the YAML file

%YAML:1.0
features: 1.5302167832851410e-01
features: 1.0552208870649338e-01
features: 1.6659785807132721e-01
features: 2.3539969325065613e-01
features: 2.0810306072235107e-01
features: 1.2627227604389191e-01
features: 8.0759152770042419e-02
features: 6.4930714666843414e-02
features: 6.1364557594060898e-02
features: 2.1614919602870941e-01
features: 1.4714729785919189e-01
features: 1.5476198494434357e-01

Can someone help me to read the yml file back to dest_ptr. I only need floating point values

Upvotes: 0

Views: 4314

Answers (2)

Anthon
Anthon

Reputation: 76712

You must have misread the YAML specification, because what you produce with your code is not a YAML file.
In a YAML file mapping keys need to be unique as per the Definition for generic mapping (and you are using a generic mapping as you are not specifying a tag):

Definition:

    Represents an associative container, where each key is unique in the
    association and mapped to exactly one value. YAML places no restrictions on
    the type of keys; in particular, they are not restricted to being  scalars. 
    Example bindings to native types include Perl’s hash, Python’s dictionary,
    and Java’s Hashtable.

The real problem is that you try to make a simple YAML emitter doing string writes yourself. You should have created the data structure that you need in C++ and emitted that structure, then the YAML would have been correct (assuming the emitter is not buggy).

Depending on what kind of file structure you choose you might have gotten:

%YAML:1.0
- features: 1.5302167832851410e-01
- features: 1.0552208870649338e-01
- features: 1.6659785807132721e-01
- features: 2.3539969325065613e-01
- features: 2.0810306072235107e-01
- features: 1.2627227604389191e-01
- features: 8.0759152770042419e-02
- features: 6.4930714666843414e-02
- features: 6.1364557594060898e-02
- features: 2.1614919602870941e-01
- features: 1.4714729785919189e-01
- features: 1.5476198494434357e-01

(a sequence of single key/value mappings) or:

%YAML:1.0
features: 
- 1.5302167832851410e-01
- 1.0552208870649338e-01
- 1.6659785807132721e-01
- 2.3539969325065613e-01
- 2.0810306072235107e-01
- 1.2627227604389191e-01
- 8.0759152770042419e-02
- 6.4930714666843414e-02
- 6.1364557594060898e-02
- 2.1614919602870941e-01
- 1.4714729785919189e-01
- 1.5476198494434357e-01

(a mapping of a single key to a single value that is a sequence)

As you experienced yourself it is non-trivial to create correct YAML for a data structure even simpler than this, using string writing. If you start with the appropriate data structure and emit that structure, you also know that you can use the same structure to read it back in.


In my experience the same holds true for generating XML/HTML/CSV/INI files, there having the correct data structure and using an emitter circumvents errors in the output format as well, compensating for any slightly higher complexity of the initial code.

Upvotes: 1

Tal Darom
Tal Darom

Reputation: 1409

You can't use the same key for multiple values. In your case you should store it as a vector of features. See code below

FileStorage fs, fs2;
fs.open("test.yml", FileStorage::WRITE);
fs << "features" << "[";
for (unsigned int i = 0; i < 20; i++) {
    fs << 1.0 / (i + 1);
}
fs << "]";
fs.release();

fs2.open("test.yml", FileStorage::READ);
vector<float> a;
fs2["features"] >> a;

Upvotes: 2

Related Questions