Question

J'ai une série de OpenCV fichiers générés YAML et souhaite les analyser avec YAML-cpp

Je vais bien sur des choses simples, mais la représentation matricielle se révèle difficile.

# Center of table
tableCenter: !!opencv-matrix
   rows: 1
   cols: 2
   dt: f
   data: [ 240,    240]

Ceci devrait la carte dans le vecteur

240
240

avec le type float . Mon code ressemble à:

#include "yaml.h"
#include <fstream>
#include <string>

struct Matrix {
    int x;
};

void operator >> (const YAML::Node& node, Matrix& matrix) {
   unsigned rows;
   node["rows"] >> rows;
}

int main()
{
   std::ifstream fin("monsters.yaml");
   YAML::Parser parser(fin);
   YAML::Node doc;

    Matrix m;
    doc["tableCenter"] >> m;

   return 0;
}

Mais je reçois

terminate called after throwing an instance of 'YAML::BadDereference'
  what():  yaml-cpp: error at line 0, column 0: bad dereference
Abort trap

Je cherchai autour de la documentation pour yaml-cpp, mais il ne semble pas y avoir, en dehors d'un court exemple d'introduction sur l'analyse syntaxique et d'émettre. Malheureusement, aucun de ces deux aide dans ce cas particulier.

Si je comprends bien, le !! indique que c'est un type défini par l'utilisateur, mais je ne vois pas yaml-cpp comment analyser cela.

Était-ce utile?

La solution

Vous devez dire yaml-cpp comment analyser ce type. Puisque C ++ n'est pas typé dynamiquement, il ne peut pas détecter quel type de données que vous voulez et créer à partir de zéro - il faut le dire directement. Le marquage d'un noeud est vraiment seulement pour vous-même, pas pour l'analyseur (il vous reste plus qu'à conserver fidèlement pour vous).

Je ne suis pas sûr de savoir comment une matrice de OpenCV est stockée, mais si elle est quelque chose comme ceci:

class Matrix {
public:
   Matrix(unsigned r, unsigned c, const std::vector<float>& d): rows(r), cols(c), data(d) { /* init */ }
   Matrix(const Matrix&) { /* copy */ }
   ~Matrix() { /* delete */ }
   Matrix& operator = (const Matrix&) { /* assign */ }

private:
   unsigned rows, cols;
   std::vector<float> data;
};

vous pouvez écrire quelque chose comme

void operator >> (const YAML::Node& node, Matrix& matrix) {
   unsigned rows, cols;
   std::vector<float> data;
   node["rows"] >> rows;
   node["cols"] >> cols;
   node["data"] >> data;
   matrix = Matrix(rows, cols, data);
}

Modifier Il semble que vous êtes ok jusqu'à ici; mais vous manquez l'étape où l'analyseur charge les informations dans le YAML::Node. Au lieu de cela, il tilisez comme:

std::ifstream fin("monsters.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc); // <-- this line was missing!

Matrix m;
doc["tableCenter"] >> m;

Note: Je devine que des moyens de dt: f "type de données est float". Si tel est le cas, ça va vraiment dépendre de la façon dont les poignées de classe Matrix cela. Si vous avez une classe différente pour chaque type de données (ou une classe templated), vous devrez lire ce champ premier , puis choisissez le type d'instancier. (Si vous connaissez il sera toujours flottant, qui va vous rendre la vie plus facile, bien sûr.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top