Domanda

Ho un serie di OpenCV genera file YAML e vorrebbe analizzare loro con YAML-cpp

che sto facendo bene su cose semplici, ma la rappresentazione di matrice si sta rivelando difficile.

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

Questo dovrebbe mappare nel vettore

240
240

di tipo float . I miei sguardi codice come:

#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;
}

Ma ottengo

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

Ho cercato in giro per un po 'di documentazione per YAML-cpp, ma non sembra essere qualsiasi, a parte un breve esempio introduttivo sul parsing ed emettendo. Purtroppo, nessuno di questi due aiuto in questa particolare circostanza.

Per quanto ho capito, il !! indica che si tratta di un tipo definito dall'utente, ma non vedo con YAML-cpp come analizzare questo.

È stato utile?

Soluzione

Devi dire yaml-cpp come analizzare questo tipo. Dal momento che C ++ non è digitato in modo dinamico, non è in grado di rilevare il tipo di dati che si desidera e creare da zero - si deve dire direttamente. Tagging un nodo è in realtà solo per te stesso, non per il parser (sarà solo fedelmente conservarlo per voi).

Non sono davvero sicuro di come una matrice OpenCV è memorizzato, ma se si tratta di qualcosa di simile:

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;
};

allora si può scrivere qualcosa come

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);
}

Modifica Sembra che stai bene fino a qui; ma ti manca il passaggio in cui il parser carica le informazioni nel YAML::Node. Invece, SE piace:

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

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

Nota: Sto indovinando mezzi dt: f "tipo di dati è float". Se questo è il caso, sarà davvero dipenderà da come le maniglie di classe Matrix questo. Se si dispone di una classe diversa per ciascun tipo di dati (o di una classe su modelli), si dovrà leggere quel campo prima , e poi scegliere quale tipo di istanziare. (Se sa che sarà sempre galleggiante, che farà la vita più facile, ovviamente.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top