Frage

Ich habe eine Reihe von OpenCV erzeugt YAML-Dateien und mag, dass sie mit yaml-cpp analysieren

Ich mache in Ordnung auf einfache Sachen, aber die Matrix-Darstellung erweist sich als schwierig.

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

Dies sollte in den Vektor

Karte
240
240

mit Typ float . Mein Code sieht aus wie:

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

Aber ich bekomme

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

suchte ich für einige Dokumentation für yaml-CPP um, aber es scheint nicht zu sein, abgesehen von einem kurzen einleitenden Beispiel auf dem Parsen und emittieren. Leider keine dieser beiden Hilfe in diesem besonderen Umstand.

Wie ich verstehe, die !! zeigt, dass dies ein benutzerdefinierter Typ ist, aber ich sehe nicht, mit yaml-CPP, wie das analysieren.

War es hilfreich?

Lösung

Sie haben yaml-cpp zu sagen, wie diese Art zu analysieren. Da C ++ ist nicht dynamisch typisierte, kann es nicht erkennen, was Sie Daten eingeben möchten, und es von Grund auf neu erstellen - Sie haben direkt davon zu erzählen. Tagging einen Knoten ist wirklich nur für sich selbst, nicht für den Parser (es wird sie nur treu speichern für Sie).

Ich bin mir nicht wirklich sicher, wie eine OpenCV Matrix gespeichert ist, aber wenn es so etwas wie folgt aus:

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

, dann können Sie so etwas wie

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

Bearbeiten Es scheint, dass Sie in Ordnung, bis hier; aber Sie fehlen den Schritt, in dem der Parser die Informationen in das YAML::Node lädt. Stattdessen se es wie:

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

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

Hinweis: Ich vermute, dt: f bedeutet „Datentyp float“. Sollte dies der Fall ist, wird es wirklich davon abhängen, wie die Matrix Klasse verarbeitet diese. Wenn Sie eine andere Klasse für jeden Datentyp (oder eine Templat-Klasse) haben, müssen Sie dieses Feld lesen müssen zuerst , und dann entscheiden, welche Art zu instanziieren. (Wenn Sie wissen es wird immer Schwimmer sein, die Ihr Leben wird einfacher, natürlich.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top